0x3f-problem-solution

自定义分数区间显示题目 配合灵茶山艾府题单解题

当前为 2024-07-19 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name 0x3f-problem-solution
  3. // @namespace https://gf.qytechs.cn/zh-CN/users/1326420-wuxin0012
  4. // @version 0.0.2
  5. // @author wuxin0011
  6. // @description 自定义分数区间显示题目 配合灵茶山艾府题单解题
  7. // @license MIT
  8. // @icon https://assets.leetcode.cn/aliyun-lc-upload/users/endlesscheng/avatar_1690721039.png
  9. // @source https://gf.qytechs.cn/zh-CN/users/1326420-wuxin0012
  10. // @match https://leetcode.cn/circle/discuss/*
  11. // @match https://leetcode.cn/problems/*
  12. // @require https://cdn.jsdelivr.net/npm/vue@3.4.31/dist/vue.global.prod.js
  13. // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B
  14. // @require https://unpkg.com/element-plus@2.7.6/dist/index.full.js
  15. // @resource elementPlusCss https://unpkg.com/element-plus@2.7.6/dist/index.css
  16. // @grant GM_addStyle
  17. // @grant GM_getResourceText
  18. // @grant GM_getValue
  19. // @grant GM_registerMenuCommand
  20. // @grant GM_setValue
  21. // ==/UserScript==
  22.  
  23. (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const e=document.createElement("style");e.textContent=t,document.head.append(e)})(" .m-setting-button[data-v-57247c3c]{position:fixed;top:200px;right:0;z-index:100000}.processs-flex[data-v-57247c3c]{display:flex;justify-content:center;align-items:center} ");
  24.  
  25. (function (vue, ElementPlus) {
  26. 'use strict';
  27.  
  28. var _GM_getValue = /* @__PURE__ */ (() => typeof GM_getValue != "undefined" ? GM_getValue : void 0)();
  29. var _GM_registerMenuCommand = /* @__PURE__ */ (() => typeof GM_registerMenuCommand != "undefined" ? GM_registerMenuCommand : void 0)();
  30. var _GM_setValue = /* @__PURE__ */ (() => typeof GM_setValue != "undefined" ? GM_setValue : void 0)();
  31. const _export_sfc = (sfc, props) => {
  32. const target = sfc.__vccOpts || sfc;
  33. for (const [key, val] of props) {
  34. target[key] = val;
  35. }
  36. return target;
  37. };
  38. const _sfc_main$1 = {};
  39. const _hoisted_1$1 = /* @__PURE__ */ vue.createElementVNode("p", null, " 1. 本人目前测试过,没有封号,但是对于查询过题目会缓存在本地,因此尽量不要清空浏览器缓存 ", -1);
  40. const _hoisted_2$1 = /* @__PURE__ */ vue.createElementVNode("p", null, " 2. 脚本会监控题做题提交状态 ,会做一个缓存在本地,如果题单中有这个题目,会直接从缓存中获取 ", -1);
  41. const _hoisted_3$1 = [
  42. _hoisted_1$1,
  43. _hoisted_2$1
  44. ];
  45. function _sfc_render(_ctx, _cache) {
  46. return vue.openBlock(), vue.createElementBlock("div", null, _hoisted_3$1);
  47. }
  48. const Q1 = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render]]);
  49. const isLeetCodeCircleUrl = (url = window.location.href) => url && url.indexOf("https://leetcode.cn/circle") != -1;
  50. const isProblem = (url = window.location.href) => /^https?:\/\/leetcode.cn\/problems\/.*/i.test(url);
  51. const width = 14;
  52. const height = 14;
  53. const problemFinsh = `
  54.  
  55. <svg width="${width}px" height="${height}px" viewBox="0 0 1024 1024" version="1.1"
  56. xmlns="http://www.w3.org/2000/svg">
  57. <path d="M512 512m-448 0a448 448 0 1 0 896 0 448 448 0 1 0-896 0Z" fill="#4CAF50" />
  58. <path
  59. d="M738.133333 311.466667L448 601.6l-119.466667-119.466667-59.733333 59.733334 179.2 179.2 349.866667-349.866667z"
  60. fill="#CCFF90" />
  61. </svg>
  62.  
  63. `;
  64. const problemsTry = `
  65. <svg width="${width}px" height="${height}px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
  66. xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 512 512"
  67. style="enable-background:new 0 0 512 512;" xml:space="preserve">
  68. <path style="fill:#FEDEA1;" d="M256,12.8C121.899,12.8,12.8,121.899,12.8,256S121.899,499.2,256,499.2S499.2,390.101,499.2,256
  69. S390.101,12.8,256,12.8z" />
  70. <g>
  71. <path style="fill:#573A32;" d="M256,115.2c-49.271,0-92.561,25.353-117.726,63.676l18.859,18.859
  72. C177.178,163.806,213.734,140.8,256,140.8c63.625,0,115.2,51.567,115.2,115.2h-38.4l51.2,51.2l51.2-51.2h-38.4
  73. C396.8,178.244,333.764,115.2,256,115.2z" />
  74. <path style="fill:#573A32;" d="M256,0C114.62,0,0,114.62,0,256s114.62,256,256,256s256-114.62,256-256S397.38,0,256,0z M256,486.4
  75. C128.956,486.4,25.6,383.044,25.6,256S128.956,25.6,256,25.6S486.4,128.956,486.4,256S383.044,486.4,256,486.4z" />
  76. <path style="fill:#573A32;" d="M256,371.2c-63.625,0-115.2-51.567-115.2-115.2h38.4L128,204.8L76.8,256h38.4
  77. c0,77.756,63.036,140.8,140.8,140.8c49.272,0,92.561-25.353,117.726-63.676l-18.859-18.859
  78. C334.822,348.194,298.266,371.2,256,371.2z" />
  79. </g>
  80. </svg>
  81.  
  82. `;
  83. const inf = 4e3;
  84. const mi = 1e3;
  85. const __0x3f_problmes_solution__ = "__0x3f_problmes_solution__";
  86. const __0x3f_problmes_urls__ = "__0x3f_problmes_urls__";
  87. const __0x3f_problmes_update__ = "__0x3f_problmes_update__";
  88. const __add_cur__ = "__add_cur__";
  89. const Problems = () => Array.from(document.querySelectorAll(".css-1ayia3m-MarkdownContent li>a"));
  90. const defaultObj = {
  91. min: mi,
  92. max: inf,
  93. visiableMember: true,
  94. onlyUrls: false,
  95. useDefaultSetting: true
  96. };
  97. function isShow(text, min, max) {
  98. if (!text) {
  99. return true;
  100. }
  101. let res = text.match(/\d+/ig);
  102. if (!res) {
  103. return true;
  104. }
  105. if (Array.isArray(res) && res.length < 2) {
  106. return true;
  107. }
  108. let s = 0;
  109. for (let i = res.length - 1; i >= 0; i--) {
  110. s = res[i];
  111. if (s >= mi && s <= inf) {
  112. return s >= min && s <= max;
  113. }
  114. }
  115. return true;
  116. }
  117. let A = [];
  118. function loadProblems() {
  119. if (!Array.isArray(A) || Array.isArray(A) && A.length == 0) {
  120. A = Problems().filter((text) => {
  121. if (text instanceof HTMLAnchorElement) {
  122. return text.href.indexOf("https://leetcode.cn/problems") != -1;
  123. }
  124. return true;
  125. });
  126. }
  127. }
  128. function handlerProblem(data) {
  129. var _a;
  130. loadProblems();
  131. let { min, max, visiableMember, useDefaultSetting, onlyUrls } = data;
  132. if (isNaN(min) || isNaN(max)) {
  133. min = mi;
  134. max = inf;
  135. }
  136. if (min < mi) {
  137. min = mi;
  138. }
  139. if (max < min) {
  140. max = inf;
  141. }
  142. min = Number(min);
  143. max = Number(max);
  144. data.min = min;
  145. data.max = max;
  146. _GM_setValue(__0x3f_problmes_solution__, data);
  147. for (let i = 0; i < A.length; i++) {
  148. let d = (_a = A[i]) == null ? void 0 : _a.parentElement;
  149. if (!d) {
  150. continue;
  151. }
  152. let flag = isShow(d.textContent, min, max);
  153. d.style.display = flag ? "" : "none";
  154. let c = d.textContent && d.textContent.indexOf("会员") != -1;
  155. if (!c) {
  156. continue;
  157. }
  158. d.style.display = visiableMember ? "" : "none";
  159. }
  160. }
  161. const initUrls = () => _GM_getValue(__0x3f_problmes_update__) ? Array.isArray(_GM_getValue(__0x3f_problmes_urls__)) ? _GM_getValue(__0x3f_problmes_urls__) : [] : defaultUrls;
  162. const initObj = () => _GM_getValue(__0x3f_problmes_solution__) ? Object.assign(defaultObj, _GM_getValue(__0x3f_problmes_solution__)) : defaultObj;
  163. const support_plugins = () => {
  164. const u = initObj();
  165. if (!u || !u.onlyUrls) return true;
  166. const url = window.location.href;
  167. const urls = initUrls();
  168. for (let info of urls) {
  169. if (!info || !(info == null ? void 0 : info.link)) {
  170. continue;
  171. }
  172. console.log("url find", info.link.indexOf(url) != -1, info.link, url);
  173. if (info.link.indexOf(url) != -1) {
  174. return true;
  175. }
  176. }
  177. return false;
  178. };
  179. const defaultUrls = [
  180. {
  181. title: "贪心算法(基本贪心策略/反悔/区间/字典序/数学/思维/构造)",
  182. link: "https://leetcode.cn/circle/discuss/g6KTKL/"
  183. },
  184. {
  185. title: "滑动窗口(定长/不定长/多指针)",
  186. link: "https://leetcode.cn/circle/discuss/0viNMK/"
  187. },
  188. {
  189. title: "二分算法(二分答案/最小化最大值/最大化最小值/第K小)",
  190. link: "https://leetcode.cn/circle/discuss/SqopEo/"
  191. },
  192. {
  193. title: "单调栈(矩形面积/贡献法/最小字典序)",
  194. link: "https://leetcode.cn/circle/discuss/9oZFK9/"
  195. },
  196. {
  197. title: "网格图(DFS/BFS/综合应用)",
  198. link: "https://leetcode.cn/circle/discuss/YiXPXW/"
  199. },
  200. {
  201. title: "位运算(基础/性质/拆位/试填/恒等式/贪心/脑筋急转弯)",
  202. link: "https://leetcode.cn/circle/discuss/dHn9Vk/"
  203. },
  204. {
  205. title: "图论算法(DFS/BFS/拓扑排序/最短路/最小生成树/二分图/基环树/欧拉路径)",
  206. link: "https://leetcode.cn/circle/discuss/01LUak/"
  207. },
  208. {
  209. title: "动态规划(入门/背包/状态机/划分/区间/状压/数位/树形/数据结构优化)",
  210. link: "https://leetcode.cn/circle/discuss/tXLS3i/"
  211. },
  212. {
  213. title: "常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)",
  214. link: "https://leetcode.cn/circle/discuss/mOr1u6/"
  215. },
  216. {
  217. title: "数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)",
  218. link: "https://leetcode.cn/circle/discuss/IYT3ss/"
  219. }
  220. ];
  221. function getId(problemUrl) {
  222. if (!isProblem(problemUrl)) {
  223. return null;
  224. }
  225. return problemUrl.replace("https://leetcode.cn/problems/", "").split("/")[0];
  226. }
  227. const local_ok_problem_key = "__local_ok_problem_key__";
  228. const STATUS = {
  229. "AC": "ac",
  230. "NO": "null",
  231. "notac": "notac"
  232. };
  233. function postData(ID) {
  234. return {
  235. "query": "\n query userQuestionStatus($titleSlug: String!) {\n question(titleSlug: $titleSlug) {\n status\n }\n}\n ",
  236. "variables": {
  237. "titleSlug": ID
  238. },
  239. "operationName": "userQuestionStatus"
  240. };
  241. }
  242. function addProcess() {
  243. var _a;
  244. loadProblems();
  245. let problems_doms = A;
  246. const cache = _GM_getValue(local_ok_problem_key) ?? {};
  247. for (let i = 0; i < problems_doms.length; i++) {
  248. let cur = problems_doms[i].parentElement;
  249. if (!(cur instanceof HTMLElement) || (cur == null ? void 0 : cur.mark)) {
  250. continue;
  251. }
  252. const ID = getId((_a = problems_doms[i]) == null ? void 0 : _a.href);
  253. if (!ID) {
  254. continue;
  255. }
  256. if (cache[ID]) {
  257. let status = cache[ID];
  258. console.log(cache[ID]);
  259. if (status == STATUS["notac"]) {
  260. console.log("NO");
  261. }
  262. cur.innerHTML = cur.innerHTML + (status == STATUS["AC"] ? problemFinsh : status == STATUS["notac"] ? problemsTry : "");
  263. } else {
  264. fetch("https://leetcode.cn/graphql/", {
  265. method: "POST",
  266. credentials: "include",
  267. headers: {
  268. "Content-Type": "application/json"
  269. },
  270. body: JSON.stringify(postData(ID))
  271. }).then((res) => res.json()).then((response) => {
  272. var _a2, _b;
  273. const status = (_b = (_a2 = response == null ? void 0 : response.data) == null ? void 0 : _a2.question) == null ? void 0 : _b.status;
  274. if (status == STATUS["AC"]) {
  275. cur.innerHTML = cur.innerHTML + problemFinsh;
  276. } else if (status == STATUS["notac"]) {
  277. cur.innerHTML = cur.innerHTML + problemsTry;
  278. } else ;
  279. cache[ID] = status == null ? "null" : status;
  280. _GM_setValue(local_ok_problem_key, cache);
  281. }).catch((ignore) => {
  282. });
  283. }
  284. cur.mark = true;
  285. }
  286. }
  287. const submitProblems = (url = window.location.href) => {
  288. const ID = getId(url);
  289. if (!ID) {
  290. return;
  291. }
  292. setTimeout(() => {
  293. const cache = _GM_getValue(local_ok_problem_key) ?? {};
  294. console.log("当前题目状态", cache[ID]);
  295. if (cache[ID] != STATUS["AC"]) {
  296. fetch("https://leetcode.cn/graphql/", {
  297. method: "POST",
  298. credentials: "include",
  299. headers: {
  300. "Content-Type": "application/json"
  301. },
  302. body: JSON.stringify(postData(ID))
  303. }).then((res) => res.json()).then((response) => {
  304. var _a, _b;
  305. const status = (_b = (_a = response == null ? void 0 : response.data) == null ? void 0 : _a.question) == null ? void 0 : _b.status;
  306. cache[ID] = status == null ? "null" : status;
  307. console.log("save local status :", cache[ID]);
  308. _GM_setValue(local_ok_problem_key, cache);
  309. }).catch((ignore) => {
  310. });
  311. }
  312. }, 3e3);
  313. };
  314. function getProcess() {
  315. loadProblems();
  316. const cache = _GM_getValue(local_ok_problem_key) ?? {};
  317. let cnt = 0;
  318. for (let i = 0; i < A.length; i++) {
  319. let ID = getId(A[i].href);
  320. if (ID && cache[ID] == STATUS["AC"]) {
  321. cnt++;
  322. }
  323. }
  324. return [cnt, A.length];
  325. }
  326. const _hoisted_1 = { class: "processs-flex" };
  327. const _hoisted_2 = { style: { "text-align": "center" } };
  328. const _hoisted_3 = { class: "dialog-footer" };
  329. const formLabelWidth = "44px";
  330. const _sfc_main = {
  331. __name: "App",
  332. setup(__props) {
  333. let totProblem = vue.ref(0);
  334. let finishProblem = vue.ref(0);
  335. const drawer = vue.ref(false);
  336. const viewSetting = () => {
  337. drawer.value = !drawer.value;
  338. let [cur, tot] = getProcess();
  339. finishProblem.value = cur;
  340. totProblem.value = tot;
  341. };
  342. const finishProcess = vue.computed(() => parseFloat((finishProblem.value / totProblem.value).toFixed(1)) * 100);
  343. const processStatus = vue.computed(
  344. () => {
  345. let val = finishProcess.value;
  346. console.log("value:", val, totProblem.value, finishProblem.value);
  347. if (val < 50) {
  348. return "";
  349. } else if (60 <= val && val < 70) {
  350. return "warning";
  351. } else if (70 <= val && val < 90) {
  352. return "exception";
  353. } else {
  354. return "success";
  355. }
  356. }
  357. );
  358. const fromData = vue.reactive(initObj());
  359. vue.watch(fromData, () => {
  360. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  361. });
  362. let tableData = vue.reactive(initUrls());
  363. const keywords = vue.ref("");
  364. const dialogTableVisible = vue.ref(false);
  365. const urlsData = vue.computed(() => tableData.filter((v) => v && v.title && v.title.indexOf(keywords.value) != -1));
  366. const dialogFormVisible = vue.ref(false);
  367. const info = vue.reactive({
  368. title: "",
  369. link: "",
  370. status: "add"
  371. });
  372. const addlocal = () => {
  373. let ok = false;
  374. for (let a of tableData) {
  375. if (a && a.link.indexOf(window.location.href) != -1) {
  376. ok = true;
  377. }
  378. }
  379. if (ok) {
  380. return;
  381. }
  382. tableData.unshift({ title: document.title, link: window.location.href });
  383. };
  384. const updateIndex = vue.ref(-1);
  385. const showProblems = () => {
  386. dialogTableVisible.value = true;
  387. if (_GM_getValue(__add_cur__)) {
  388. addlocal();
  389. }
  390. };
  391. const handlerProblems = (status, updateInfo = { title: "", link: "" }, index = -1) => {
  392. dialogFormVisible.value = true;
  393. info.status = status;
  394. updateIndex.value = index;
  395. Object.assign(info, updateInfo);
  396. };
  397. const handlerMessage = (u, title, link) => {
  398. const a = u ? "添加" : "修改";
  399. const error = !title || !/https?:\/\/.*/.test(link);
  400. if (error) {
  401. ElementPlus.ElMessage.error(`${a} 失败 请保证标题或者链接有效 `);
  402. } else {
  403. ElementPlus.ElMessage.success(`${a} 成功 `);
  404. }
  405. return !error;
  406. };
  407. const addOrUpdate = () => {
  408. if (!handlerMessage(info.status == "add", info.title, info.link)) {
  409. return;
  410. }
  411. if (info.status == "add") {
  412. tableData.unshift({ title: info.title, link: info.link });
  413. } else {
  414. let index = updateIndex.value;
  415. if (index != -1 && index < tableData.length) {
  416. tableData[index].link = info.link;
  417. tableData[index].title = info.title;
  418. }
  419. }
  420. dialogFormVisible.value = false;
  421. };
  422. const deleteProblems = (index) => {
  423. tableData.splice(index, 1);
  424. _GM_setValue(__0x3f_problmes_urls__, vue.toRaw(tableData));
  425. };
  426. const handlerDefault = () => {
  427. ElementPlus.ElMessageBox.confirm(
  428. "确认使用默认题单,将会重置题单?",
  429. "警告",
  430. {
  431. confirmButtonText: "确认",
  432. cancelButtonText: "取消",
  433. type: "warning"
  434. }
  435. ).then(() => {
  436. for (let i = 0; i < tableData.length; i++) {
  437. delete tableData[i];
  438. }
  439. for (let item of defaultUrls) {
  440. tableData.unshift(item);
  441. }
  442. ElementPlus.ElMessage({
  443. type: "success",
  444. message: "重置成功"
  445. });
  446. }).catch(() => {
  447. ElementPlus.ElMessage({
  448. type: "info",
  449. message: "取消重置"
  450. });
  451. });
  452. };
  453. window.addEventListener("beforeunload", () => {
  454. console.log("save ....");
  455. _GM_setValue(__0x3f_problmes_urls__, vue.toRaw(tableData));
  456. _GM_setValue(__0x3f_problmes_update__, true);
  457. _GM_setValue(__add_cur__, false);
  458. });
  459. vue.onMounted(() => {
  460. if (support_plugins()) {
  461. setTimeout(() => {
  462. handlerProblem(vue.toRaw(Object.assign({}, fromData)));
  463. addProcess();
  464. }, 3e3);
  465. }
  466. });
  467. const q1 = vue.ref(false);
  468. return (_ctx, _cache) => {
  469. const _component_el_button = vue.resolveComponent("el-button");
  470. const _component_el_progress = vue.resolveComponent("el-progress");
  471. const _component_el_divider = vue.resolveComponent("el-divider");
  472. const _component_el_input = vue.resolveComponent("el-input");
  473. const _component_el_col = vue.resolveComponent("el-col");
  474. const _component_el_form_item = vue.resolveComponent("el-form-item");
  475. const _component_el_switch = vue.resolveComponent("el-switch");
  476. const _component_el_tooltip = vue.resolveComponent("el-tooltip");
  477. const _component_el_form = vue.resolveComponent("el-form");
  478. const _component_el_dialog = vue.resolveComponent("el-dialog");
  479. const _component_el_row = vue.resolveComponent("el-row");
  480. const _component_el_link = vue.resolveComponent("el-link");
  481. const _component_el_table_column = vue.resolveComponent("el-table-column");
  482. const _component_el_table = vue.resolveComponent("el-table");
  483. const _component_el_drawer = vue.resolveComponent("el-drawer");
  484. return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [
  485. vue.createElementVNode("div", null, [
  486. vue.createVNode(_component_el_button, {
  487. type: "primary",
  488. style: { "margin-left": "16px" },
  489. onClick: viewSetting,
  490. class: "m-setting-button"
  491. }, {
  492. default: vue.withCtx(() => [
  493. vue.createTextVNode(" 设置 ")
  494. ]),
  495. _: 1
  496. })
  497. ]),
  498. vue.createVNode(_component_el_drawer, {
  499. modelValue: drawer.value,
  500. "onUpdate:modelValue": _cache[14] || (_cache[14] = ($event) => drawer.value = $event),
  501. "with-header": false,
  502. size: "30%"
  503. }, {
  504. default: vue.withCtx(() => [
  505. vue.createElementVNode("div", _hoisted_1, [
  506. vue.createVNode(_component_el_progress, {
  507. type: "circle",
  508. percentage: finishProcess.value,
  509. status: processStatus.value
  510. }, {
  511. default: vue.withCtx(({ percentage }) => [
  512. vue.createElementVNode("p", null, vue.toDisplayString(percentage) + "%", 1)
  513. ]),
  514. _: 1
  515. }, 8, ["percentage", "status"])
  516. ]),
  517. vue.createElementVNode("p", _hoisted_2, vue.toDisplayString(vue.unref(finishProblem)) + " / " + vue.toDisplayString(vue.unref(totProblem)), 1),
  518. vue.createVNode(_component_el_divider),
  519. vue.createVNode(_component_el_form, {
  520. "label-position": "left",
  521. "label-width": "auto",
  522. model: fromData,
  523. style: { "max-width": "600px" }
  524. }, {
  525. default: vue.withCtx(() => [
  526. vue.createVNode(_component_el_form_item, { label: "分数区间" }, {
  527. default: vue.withCtx(() => [
  528. vue.createVNode(_component_el_col, { span: 10 }, {
  529. default: vue.withCtx(() => [
  530. vue.createVNode(_component_el_input, {
  531. modelValue: fromData.min,
  532. "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => fromData.min = $event),
  533. "aria-placeholder": "",
  534. placeholder: " min "
  535. }, null, 8, ["modelValue"])
  536. ]),
  537. _: 1
  538. }),
  539. vue.createVNode(_component_el_col, {
  540. class: "text-center",
  541. span: 1,
  542. style: { "margin": "0 0.5rem" }
  543. }, {
  544. default: vue.withCtx(() => [
  545. vue.createTextVNode("-")
  546. ]),
  547. _: 1
  548. }),
  549. vue.createVNode(_component_el_col, { span: 10 }, {
  550. default: vue.withCtx(() => [
  551. vue.createVNode(_component_el_input, {
  552. modelValue: fromData.max,
  553. "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => fromData.max = $event),
  554. "aria-placeholder": "",
  555. placeholder: " max"
  556. }, null, 8, ["modelValue"])
  557. ]),
  558. _: 1
  559. })
  560. ]),
  561. _: 1
  562. }),
  563. vue.createVNode(_component_el_form_item, { label: "显示会员题" }, {
  564. default: vue.withCtx(() => [
  565. vue.createVNode(_component_el_switch, {
  566. modelValue: fromData.visiableMember,
  567. "onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => fromData.visiableMember = $event)
  568. }, null, 8, ["modelValue"])
  569. ]),
  570. _: 1
  571. }),
  572. vue.createVNode(_component_el_form_item, { label: "只在收藏题单中生效" }, {
  573. default: vue.withCtx(() => [
  574. vue.createVNode(_component_el_tooltip, {
  575. content: "插件只在收藏题单中生效,刷新生效 ",
  576. placement: "bottom-end"
  577. }, {
  578. default: vue.withCtx(() => [
  579. vue.createVNode(_component_el_switch, {
  580. modelValue: fromData.onlyUrls,
  581. "onUpdate:modelValue": _cache[3] || (_cache[3] = ($event) => fromData.onlyUrls = $event)
  582. }, null, 8, ["modelValue"])
  583. ]),
  584. _: 1
  585. })
  586. ]),
  587. _: 1
  588. }),
  589. vue.createVNode(_component_el_form_item, { label: "使用题单" }, {
  590. default: vue.withCtx(() => [
  591. vue.createVNode(_component_el_switch, {
  592. modelValue: fromData.useDefaultSetting,
  593. "onUpdate:modelValue": _cache[4] || (_cache[4] = ($event) => fromData.useDefaultSetting = $event)
  594. }, null, 8, ["modelValue"])
  595. ]),
  596. _: 1
  597. })
  598. ]),
  599. _: 1
  600. }, 8, ["model"]),
  601. fromData.useDefaultSetting ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 0 }, [
  602. vue.createVNode(_component_el_divider),
  603. vue.createVNode(_component_el_button, {
  604. plain: "",
  605. onClick: showProblems
  606. }, {
  607. default: vue.withCtx(() => [
  608. vue.createTextVNode(" 查看收藏的题单 ")
  609. ]),
  610. _: 1
  611. }),
  612. vue.createVNode(_component_el_divider)
  613. ], 64)) : vue.createCommentVNode("", true),
  614. vue.createVNode(_component_el_divider),
  615. vue.createVNode(_component_el_button, {
  616. plain: "",
  617. onClick: _cache[5] || (_cache[5] = ($event) => q1.value = !q1.value)
  618. }, {
  619. default: vue.withCtx(() => [
  620. vue.createTextVNode(" 问题1 ")
  621. ]),
  622. _: 1
  623. }),
  624. vue.createVNode(_component_el_divider),
  625. vue.createVNode(_component_el_dialog, {
  626. modelValue: q1.value,
  627. "onUpdate:modelValue": _cache[6] || (_cache[6] = ($event) => q1.value = $event),
  628. title: "会不会被封号 ?"
  629. }, {
  630. default: vue.withCtx(() => [
  631. vue.createVNode(Q1)
  632. ]),
  633. _: 1
  634. }, 8, ["modelValue"]),
  635. vue.createVNode(_component_el_dialog, {
  636. modelValue: dialogTableVisible.value,
  637. "onUpdate:modelValue": _cache[9] || (_cache[9] = ($event) => dialogTableVisible.value = $event),
  638. title: "题单"
  639. }, {
  640. default: vue.withCtx(() => [
  641. vue.createVNode(_component_el_row, { gutter: 10 }, {
  642. default: vue.withCtx(() => [
  643. vue.createVNode(_component_el_col, { span: 8 }, {
  644. default: vue.withCtx(() => [
  645. vue.createVNode(_component_el_input, {
  646. modelValue: keywords.value,
  647. "onUpdate:modelValue": _cache[7] || (_cache[7] = ($event) => keywords.value = $event),
  648. placeholder: "请输入关键词过滤",
  649. clearable: ""
  650. }, null, 8, ["modelValue"])
  651. ]),
  652. _: 1
  653. }),
  654. vue.createVNode(_component_el_col, { span: 16 }, {
  655. default: vue.withCtx(() => [
  656. vue.createVNode(_component_el_button, {
  657. plain: "",
  658. onClick: addlocal
  659. }, {
  660. default: vue.withCtx(() => [
  661. vue.createTextVNode(" 添加本页 ")
  662. ]),
  663. _: 1
  664. }),
  665. vue.createVNode(_component_el_button, {
  666. plain: "",
  667. onClick: _cache[8] || (_cache[8] = ($event) => handlerProblems("add"))
  668. }, {
  669. default: vue.withCtx(() => [
  670. vue.createTextVNode(" 自定义 ")
  671. ]),
  672. _: 1
  673. }),
  674. vue.createVNode(_component_el_button, {
  675. plain: "",
  676. onClick: handlerDefault
  677. }, {
  678. default: vue.withCtx(() => [
  679. vue.createTextVNode(" 默认 ")
  680. ]),
  681. _: 1
  682. })
  683. ]),
  684. _: 1
  685. })
  686. ]),
  687. _: 1
  688. }),
  689. vue.createVNode(_component_el_table, {
  690. data: urlsData.value,
  691. height: "300",
  692. style: { "width": "100%", "margin-top": "10px" }
  693. }, {
  694. default: vue.withCtx(() => [
  695. vue.createVNode(_component_el_table_column, {
  696. label: "标题",
  697. width: "auto",
  698. align: "center"
  699. }, {
  700. default: vue.withCtx((scope) => [
  701. vue.createVNode(_component_el_link, {
  702. href: scope.row.link,
  703. target: "_blank",
  704. type: "default"
  705. }, {
  706. default: vue.withCtx(() => [
  707. vue.createTextVNode(vue.toDisplayString(scope.row.title), 1)
  708. ]),
  709. _: 2
  710. }, 1032, ["href"])
  711. ]),
  712. _: 1
  713. }),
  714. vue.createVNode(_component_el_table_column, {
  715. label: "操作",
  716. width: "auto",
  717. align: "center"
  718. }, {
  719. default: vue.withCtx((scope) => [
  720. vue.createVNode(_component_el_button, {
  721. type: "primary",
  722. size: "small",
  723. onClick: ($event) => handlerProblems("update", scope.row, scope.$index)
  724. }, {
  725. default: vue.withCtx(() => [
  726. vue.createTextVNode("编辑")
  727. ]),
  728. _: 2
  729. }, 1032, ["onClick"]),
  730. vue.createVNode(_component_el_button, {
  731. type: "danger",
  732. size: "small",
  733. onClick: ($event) => deleteProblems(scope.$index)
  734. }, {
  735. default: vue.withCtx(() => [
  736. vue.createTextVNode("删除")
  737. ]),
  738. _: 2
  739. }, 1032, ["onClick"])
  740. ]),
  741. _: 1
  742. })
  743. ]),
  744. _: 1
  745. }, 8, ["data"])
  746. ]),
  747. _: 1
  748. }, 8, ["modelValue"]),
  749. vue.createVNode(_component_el_dialog, {
  750. modelValue: dialogFormVisible.value,
  751. "onUpdate:modelValue": _cache[13] || (_cache[13] = ($event) => dialogFormVisible.value = $event),
  752. title: `${info.status == "add" ? "添加" : "编辑"}`,
  753. width: "400"
  754. }, {
  755. footer: vue.withCtx(() => [
  756. vue.createElementVNode("div", _hoisted_3, [
  757. vue.createVNode(_component_el_button, {
  758. onClick: _cache[12] || (_cache[12] = ($event) => dialogFormVisible.value = false)
  759. }, {
  760. default: vue.withCtx(() => [
  761. vue.createTextVNode("取消")
  762. ]),
  763. _: 1
  764. }),
  765. vue.createVNode(_component_el_button, {
  766. type: "primary",
  767. onClick: addOrUpdate
  768. }, {
  769. default: vue.withCtx(() => [
  770. vue.createTextVNode(" 确认 ")
  771. ]),
  772. _: 1
  773. })
  774. ])
  775. ]),
  776. default: vue.withCtx(() => [
  777. vue.createVNode(_component_el_form, null, {
  778. default: vue.withCtx(() => [
  779. vue.createVNode(_component_el_form_item, {
  780. label: "标题",
  781. "label-width": formLabelWidth
  782. }, {
  783. default: vue.withCtx(() => [
  784. vue.createVNode(_component_el_input, {
  785. modelValue: info.title,
  786. "onUpdate:modelValue": _cache[10] || (_cache[10] = ($event) => info.title = $event),
  787. autocomplete: "off"
  788. }, null, 8, ["modelValue"])
  789. ]),
  790. _: 1
  791. }),
  792. vue.createVNode(_component_el_form_item, {
  793. label: "链接",
  794. "label-width": formLabelWidth
  795. }, {
  796. default: vue.withCtx(() => [
  797. vue.createVNode(_component_el_input, {
  798. modelValue: info.link,
  799. "onUpdate:modelValue": _cache[11] || (_cache[11] = ($event) => info.link = $event),
  800. autocomplete: "off"
  801. }, null, 8, ["modelValue"])
  802. ]),
  803. _: 1
  804. })
  805. ]),
  806. _: 1
  807. })
  808. ]),
  809. _: 1
  810. }, 8, ["modelValue", "title"])
  811. ]),
  812. _: 1
  813. }, 8, ["modelValue"])
  814. ], 64);
  815. };
  816. }
  817. };
  818. const App = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-57247c3c"]]);
  819. const cssLoader = (e) => {
  820. const t = GM_getResourceText(e);
  821. return GM_addStyle(t), t;
  822. };
  823. cssLoader("elementPlusCss");
  824. const local_url = window.location.href;
  825. function run() {
  826. if (isProblem(local_url)) {
  827. submitProblems(local_url);
  828. setTimeout(() => {
  829. let submitbutton = document.querySelector("div [data-e2e-locator=console-submit-button]");
  830. if (submitbutton) {
  831. submitbutton.addEventListener("click", () => {
  832. submitProblems(local_url);
  833. });
  834. }
  835. }, 1500);
  836. } else if (isLeetCodeCircleUrl(local_url)) {
  837. let Container = null;
  838. const VueApp = vue.createApp(App);
  839. const start = () => {
  840. Container = document.createElement("div");
  841. const body = document.querySelector("body");
  842. body.append(Container);
  843. Container.style.display = support_plugins() ? "block" : "none";
  844. return Container;
  845. };
  846. VueApp.use(ElementPlus).mount(start());
  847. _GM_registerMenuCommand(`${initObj().onlyUrls ? "仅在收藏题单页面生效" : "所有题单生效"}`, () => {
  848. const u = initObj();
  849. u.onlyUrls = !u.onlyUrls;
  850. Container.style.display = support_plugins() ? "block" : "none";
  851. _GM_setValue(__0x3f_problmes_solution__, u);
  852. });
  853. _GM_registerMenuCommand(`添加本页`, () => {
  854. const urls = initUrls();
  855. let ok = false;
  856. const url = window.location.href;
  857. for (let info of urls) {
  858. if (!info || !(info == null ? void 0 : info.link)) {
  859. continue;
  860. }
  861. if (info.link.indexOf(url) != -1) {
  862. ok = true;
  863. break;
  864. }
  865. }
  866. if (ok) {
  867. ElementPlus.ElMessage({
  868. message: "收藏失败,链接已经存在!",
  869. type: "error"
  870. });
  871. } else {
  872. urls.unshift({
  873. title: document.title,
  874. link: url
  875. });
  876. Container.style.display = "block";
  877. _GM_setValue(__0x3f_problmes_urls__, urls);
  878. _GM_setValue(__add_cur__, true);
  879. ElementPlus.ElMessage({
  880. message: "收藏成功!刷新生效",
  881. type: "success"
  882. });
  883. }
  884. });
  885. }
  886. }
  887. run();
  888.  
  889. })(Vue, ElementPlus);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址