xmoj-script 1.1.13 → 1.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,5 @@
1
1
  version: 2
2
2
  updates:
3
- - package-ecosystem: "npm"
4
- directory: "/Server"
5
- target-branch: "dev"
6
- schedule:
7
- interval: "weekly"
8
3
  - package-ecosystem: "github-actions"
9
4
  directory: "/"
10
5
  target-branch: "dev"
@@ -1,5 +1,15 @@
1
1
  - [ ] 我已认真阅读贡献指南 (contributing guidelines) 和社区公约 (code of conduct),并遵循了如何参与页及格式手册页的相应规范。
2
2
 
3
+ By making a contribution to this project, I certify that:
4
+
5
+ The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or
6
+
7
+ The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or
8
+
9
+ The contribution was provided directly to me by some other person who certified 1., 2. or 3. and I have not modified it.
10
+
11
+ I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
12
+
3
13
  <!--
4
14
  这是 Pull Request 的描述页面,可拖动输入框右下角调节大小。尽管按下绿色按钮提交后,您仍可以对描述进行修改,但还请您先阅读以下注意事项。
5
15
  - 请不要删去本区域文字,或在此修改内容,因为本区域作为注释内容是不可见的。你应该点击 Preview 查看描述页效果。
@@ -0,0 +1,27 @@
1
+ Index: XMOJ.user.js
2
+ IDEA additional info:
3
+ Subsystem: com.intellij.openapi.diff.impl.patch.BaseRevisionTextPatchEP
4
+ <+>// ==UserScript==\n// @name XMOJ\n// @version 1.1.12\n// @description XMOJ增强脚本\n// @author @XMOJ-Script-dev, @langningchen and the community\n// @namespace https://github/langningchen\n// @match *://*.xmoj.tech/*\n// @match *://116.62.212.172/*\n// @require https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js\n// @require https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/codemirror.min.js\n// @require https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/mode/clike/clike.min.js\n// @require https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/addon/merge/merge.js\n// @require https://cdn.bootcdn.net/ajax/libs/diff_match_patch/20121119/diff_match_patch_uncompressed.js\n// @require https://cdn.bootcdn.net/ajax/libs/dompurify/3.0.2/purify.min.js\n// @require https://cdn.bootcdn.net/ajax/libs/marked/4.3.0/marked.min.js\n// @grant GM_registerMenuCommand\n// @grant GM_xmlhttpRequest\n// @grant GM_setClipboard\n// @grant unsafeWindow\n// @grant GM_setValue\n// @grant GM_getValue\n// @homepage https://www.xmoj-bbs.tech/\n// @supportURL https://github.com/XMOJ-Script-dev/XMOJ-Script\n// @connect api.xmoj-bbs.tech\n// @connect challenges.cloudflare.com\n// @connect cppinsights.io\n// @connect 127.0.0.1\n// @license GPL\n// @icon data:image/x-icon;base64,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\n// ==/UserScript==\n\n/**\n * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n * You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.\n */\n\nconst CaptchaSiteKey = \"0x4AAAAAAALBT58IhyDViNmv\";\nconst AdminUserList = [\"zhuchenrui2\", \"shanwenxiao\", \"admin\", \"shihongxi\"];\n\nlet PurifyHTML = (Input) => {\n return DOMPurify.sanitize(Input, {\n \"ALLOWED_TAGS\": [\"a\", \"b\", \"big\", \"blockquote\", \"br\", \"code\", \"dd\", \"del\", \"div\", \"dl\", \"dt\", \"em\", \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\", \"h7\", \"h8\", \"hr\", \"i\", \"img\", \"ins\", \"kbd\", \"li\", \"ol\", \"p\", \"pre\", \"q\", \"rp\", \"rt\", \"ruby\", \"s\", \"samp\", \"strike\", \"strong\", \"sub\", \"sup\", \"table\", \"tbody\", \"td\", \"tfoot\", \"th\", \"thead\", \"tr\", \"tt\", \"ul\", \"var\"],\n \"ALLOWED_ATTR\": [\"abbr\", \"accept\", \"accept-charset\", \"accesskey\", \"action\", \"align\", \"alt\", \"axis\", \"border\", \"cellpadding\", \"cellspacing\", \"char\", \"charoff\", \"charset\", \"checked\", \"cite\", \"clear\", \"color\", \"cols\", \"colspan\", \"compact\", \"coords\", \"datetime\", \"dir\", \"disabled\", \"enctype\", \"for\", \"frame\", \"headers\", \"height\", \"href\", \"hreflang\", \"hspace\", \"ismap\", \"itemprop\", \"label\", \"lang\", \"longdesc\", \"maxlength\", \"media\", \"method\", \"multiple\", \"name\", \"nohref\", \"noshade\", \"nowrap\", \"prompt\", \"readonly\", \"rel\", \"rev\", \"rows\", \"rowspan\", \"rules\", \"scope\", \"selected\", \"shape\", \"size\", \"span\", \"src\", \"start\", \"summary\", \"tabindex\", \"target\", \"title\", \"type\", \"usemap\", \"valign\", \"value\", \"vspace\", \"width\"]\n });\n}\n/**\n * Calculates the relative time based on the input date.\n * @param {string|Date} Input - The input date.\n * @returns {string} The relative time in a formatted string.\n */\nlet GetRelativeTime = (Input) => {\n Input = new Date(Input);\n let Now = new Date().getTime();\n let Delta = Now - Input.getTime();\n let RelativeName = \"\";\n if (Delta < 0) { RelativeName = \"未来\"; }\n else if (Delta <= 1000 * 60) { RelativeName = \"刚刚\"; }\n else if (Delta <= 1000 * 60 * 60) { RelativeName = Math.floor((Now - Input) / 1000 / 60) + \"分钟前\"; }\n else if (Delta <= 1000 * 60 * 60 * 24) { RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60) + \"小时前\"; }\n else if (Delta <= 1000 * 60 * 60 * 24 * 31) { RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24) + \"天前\"; }\n else if (Delta <= 1000 * 60 * 60 * 24 * 365) { RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 31) + \"个月前\"; }\n else { RelativeName = Math.floor((Now - Input) / 1000 / 60 / 60 / 24 / 365) + \"年前\"; }\n return \"<span title=\\\"\" + Input.toLocaleString() + \"\\\">\" + RelativeName + \"</span>\";\n};\nlet RenderMathJax = async () => {\n if (document.getElementById(\"MathJax-script\") === null) {\n var ScriptElement = document.createElement(\"script\");\n ScriptElement.id = \"MathJax-script\";\n ScriptElement.type = \"text/javascript\";\n ScriptElement.src = \"https://cdn.bootcdn.net/ajax/libs/mathjax/3.0.5/es5/tex-chtml.js\";\n document.body.appendChild(ScriptElement);\n await new Promise((Resolve) => {\n ScriptElement.onload = () => {\n Resolve();\n };\n });\n }\n MathJax.startup.input[0].findTeX.options.inlineMath.push([\"$\", \"$\"]);\n MathJax.startup.input[0].findTeX.getPatterns();\n MathJax.typeset();\n};\nlet GetUserInfo = async (Username) => {\n if (localStorage.getItem(\"UserScript-User-\" + Username + \"-UserRating\") != null &&\n new Date().getTime() - parseInt(localStorage.getItem(\"UserScript-User-\" + Username + \"-LastUpdateTime\")) < 1000 * 60 * 60 * 24) {\n return {\n \"Rating\": localStorage.getItem(\"UserScript-User-\" + Username + \"-UserRating\"),\n \"EmailHash\": localStorage.getItem(\"UserScript-User-\" + Username + \"-EmailHash\")\n }\n }\n return await fetch(\"https://www.xmoj.tech/userinfo.php?user=\" + Username).then((Response) => {\n return Response.text();\n }).then((Response) => {\n if (Response.indexOf(\"No such User!\") !== -1) {\n return null;\n }\n const ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let Rating = (parseInt(ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(4) > td:nth-child(2)\").innerText.trim()) /\n parseInt(ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(3) > td:nth-child(2)\").innerText.trim())).toFixed(3) * 1000;\n let Temp = ParsedDocument.querySelector(\"#statics > tbody\").children;\n let Email = Temp[Temp.length - 1].children[1].innerText.trim();\n let EmailHash = CryptoJS.MD5(Email).toString();\n localStorage.setItem(\"UserScript-User-\" + Username + \"-UserRating\", Rating);\n if (Email == \"\") {\n EmailHash = undefined;\n } else {\n localStorage.setItem(\"UserScript-User-\" + Username + \"-EmailHash\", EmailHash);\n }\n localStorage.setItem(\"UserScript-User-\" + Username + \"-LastUpdateTime\", new Date().getTime());\n return {\n \"Rating\": Rating,\n \"EmailHash\": EmailHash\n }\n });\n};\n/**\n * Retrieves the badge information for a given user.\n * \n * @param {string} Username - The username of the user.\n * @returns {Promise<Object>} - A promise that resolves to an object containing the badge information.\n * @property {string} BackgroundColor - The background color of the badge.\n * @property {string} Color - The color of the badge.\n * @property {string} Content - The content of the badge.\n */\nlet GetUserBadge = async (Username) => {\n if (localStorage.getItem(\"UserScript-User-\" + Username + \"-Badge-LastUpdateTime\") != null &&\n new Date().getTime() - parseInt(localStorage.getItem(\"UserScript-User-\" + Username + \"-Badge-LastUpdateTime\")) < 1000 * 60 * 60 * 24) {\n return {\n \"BackgroundColor\": localStorage.getItem(\"UserScript-User-\" + Username + \"-Badge-BackgroundColor\"),\n \"Color\": localStorage.getItem(\"UserScript-User-\" + Username + \"-Badge-Color\"),\n \"Content\": localStorage.getItem(\"UserScript-User-\" + Username + \"-Badge-Content\")\n }\n } else {\n let BackgroundColor = \"\";\n let Color = \"\";\n let Content = \"\";\n await new Promise((Resolve) => {\n RequestAPI(\"GetBadge\", {\n \"UserID\": String(Username)\n }, (Response) => {\n if (Response.Success) {\n BackgroundColor = Response.Data.BackgroundColor;\n Color = Response.Data.Color;\n Content = Response.Data.Content;\n }\n Resolve();\n });\n });\n localStorage.setItem(\"UserScript-User-\" + Username + \"-Badge-BackgroundColor\", BackgroundColor);\n localStorage.setItem(\"UserScript-User-\" + Username + \"-Badge-Color\", Color);\n localStorage.setItem(\"UserScript-User-\" + Username + \"-Badge-Content\", Content);\n localStorage.setItem(\"UserScript-User-\" + Username + \"-Badge-LastUpdateTime\", String(new Date().getTime()));\n return {\n \"BackgroundColor\": BackgroundColor,\n \"Color\": Color,\n \"Content\": Content\n }\n }\n};\n/**\n * Sets the HTML content of an element to display a username with optional additional information.\n * @param {HTMLElement} Element - The element to set the HTML content.\n * @param {string} Username - The username to display.\n * @param {boolean} [Simple=false] - Indicates whether to display additional information or not.\n * @param {string} [Href=\"https://www.xmoj.tech/userinfo.php?user=\"] - The URL to link the username to.\n * @returns {Promise<void>} - A promise that resolves when the HTML content is set.\n */\nlet GetUsernameHTML = async (Element, Username, Simple = false, Href = \"https://www.xmoj.tech/userinfo.php?user=\") => {\n Username = Username.replaceAll(/[^a-zA-Z0-9]/g, \"\");\n let ID = \"Username-\" + Username + \"-\" + Math.random();\n Element.id = ID;\n Element.innerHTML = `<div class=\"spinner-border spinner-border-sm me-2\" role=\"status\"></div>`;\n Element.appendChild(document.createTextNode(Username));\n let UserInfo = await GetUserInfo(Username);\n if (UserInfo === null) {\n document.getElementById(ID).innerHTML = \"\";\n document.getElementById(ID).appendChild(document.createTextNode(Username));\n return;\n }\n let HTMLData = \"\";\n if (!Simple) {\n HTMLData += `<img src=\"`;\n if (UserInfo.EmailHash == undefined) {\n HTMLData += `https://cravatar.cn/avatar/00000000000000000000000000000000?d=mp&f=y`;\n }\n else {\n HTMLData += `https://cravatar.cn/avatar/${UserInfo.EmailHash}?d=retro`;\n }\n HTMLData += `\" class=\"rounded me-2\" style=\"width: 20px; height: 20px; \">`;\n }\n HTMLData += `<a href=\"${Href}${Username}\" class=\"link-offset-2 link-underline-opacity-50 `\n if (UtilityEnabled(\"Rating\")) {\n let Rating = UserInfo.Rating;\n // if(AdminUserList.includes(Username)){\n // HTMLData += \"link-fuchsia\"\n // }\n // else\n if (Rating > 500) {\n HTMLData += \"link-danger\";\n } else if (Rating >= 400) {\n HTMLData += \"link-warning\";\n } else if (Rating >= 300) {\n HTMLData += \"link-success\";\n } else {\n HTMLData += \"link-info\";\n }\n }\n else {\n HTMLData += \"link-info\";\n }\n HTMLData += `\\\";\"></a>`;\n if (!Simple) {\n if (AdminUserList.includes(Username)) {\n HTMLData += `<span class=\"badge text-bg-danger ms-2\">管理员</span>`;\n }\n if (Username == \"chenlangning\") {\n HTMLData += `<span class=\"badge ms-2\" style=\"background-color: #6633cc; color: #ffffff\">吉祥物</span>`;\n }\n let BadgeInfo = await GetUserBadge(Username);\n if (BadgeInfo.Content != \"\") {\n HTMLData += `<span class=\"badge ms-2\" style=\"background-color: ${BadgeInfo.BackgroundColor}; color: ${BadgeInfo.Color}\">${BadgeInfo.Content}</span>`;\n }\n }\n document.getElementById(ID).innerHTML = HTMLData;\n document.getElementById(ID).getElementsByTagName(\"a\")[0].appendChild(document.createTextNode(Username));\n};\n/**\n * Converts the given number of seconds to a formatted string representation of hours, minutes, and seconds.\n * @param {number} InputSeconds - The number of seconds to convert.\n * @returns {string} The formatted string representation of the input seconds.\n */\nlet SecondsToString = (InputSeconds) => {\n let Hours = Math.floor(InputSeconds / 3600);\n let Minutes = Math.floor((InputSeconds % 3600) / 60);\n let Seconds = InputSeconds % 60;\n return (Hours < 10 ? \"0\" : \"\") + Hours + \":\" +\n (Minutes < 10 ? \"0\" : \"\") + Minutes + \":\" +\n (Seconds < 10 ? \"0\" : \"\") + Seconds;\n}\n/**\n * Converts a string in the format \"hh:mm:ss\" to the equivalent number of seconds.\n * @param {string} InputString - The input string to convert.\n * @returns {number} The number of seconds equivalent to the input string.\n */\nlet StringToSeconds = (InputString) => {\n let SplittedString = InputString.split(\":\");\n return parseInt(SplittedString[0]) * 60 * 60 +\n parseInt(SplittedString[1]) * 60 +\n parseInt(SplittedString[2]);\n}\n/**\n * Converts a memory size in bytes to a human-readable string representation.\n * @param {number} Memory - The memory size in bytes.\n * @returns {string} The human-readable string representation of the memory size.\n */\nlet SizeToStringSize = (Memory) => {\n if (UtilityEnabled(\"AddUnits\")) {\n if (Memory < 1024) {\n return Memory + \"B\";\n } else if (Memory < 1024 * 1024) {\n return (Memory / 1024).toFixed(2) + \"KB\";\n } else if (Memory < 1024 * 1024 * 1024) {\n return (Memory / 1024 / 1024).toFixed(2) + \"MB\";\n } else {\n return (Memory / 1024 / 1024 / 1024).toFixed(2) + \"GB\";\n }\n }\n else {\n return Memory;\n }\n};\n/**\n * Converts a time value to a string representation.\n * @param {number} Time - The time value to convert.\n * @returns {string|number} - The converted time value as a string, or the original value if UtilityEnabled(\"AddUnits\") is false.\n */\nlet TimeToStringTime = (Time) => {\n if (UtilityEnabled(\"AddUnits\")) {\n if (Time < 1000) {\n return Time + \"ms\";\n } else if (Time < 1000 * 60) {\n return (Time / 1000).toFixed(2) + \"s\";\n }\n }\n else {\n return Time;\n }\n};\n/**\n * Tidies up the given table by applying Bootstrap styling and removing unnecessary attributes.\n * \n * @param {HTMLElement} Table - The table element to be tidied up.\n */\nlet TidyTable = (Table) => {\n if (UtilityEnabled(\"NewBootstrap\") && Table != null) {\n Table.className = \"table table-hover\";\n Table.querySelector(\"thead > tr\").removeAttribute(\"class\");\n Table.querySelector(\"thead > tr\").removeAttribute(\"align\");\n Table.querySelector(\"thead > tr\").innerHTML = Table.querySelector(\"thead > tr\").innerHTML.replaceAll(\"td\", \"th\");\n let Temp = Table.querySelector(\"thead > tr\").children;\n for (let j = 0; j < Temp.length; j++) {\n let Width = Temp[j].style.width;\n Temp[j].removeAttribute(\"style\");\n Temp[j].style.width = Width;\n Temp[j].removeAttribute(\"onclick\");\n Temp[j].removeAttribute(\"align\");\n }\n Table.querySelector(\"tbody\").className = \"table-group-divider\";\n Temp = Table.querySelector(\"tbody\").children;\n for (let j = 0; j < Temp.length; j++) {\n Temp[j].removeAttribute(\"align\");\n let Temp2 = Temp[j].querySelectorAll(\"*\");\n for (let k = 0; k < Temp2.length; k++) {\n Temp2[k].classList.remove(\"left\");\n Temp2[k].classList.remove(\"center\");\n if (Temp2[k].className == \"\") {\n Temp2[k].removeAttribute(\"class\");\n }\n }\n }\n }\n};\nlet UtilityEnabled = (Name) => {\n if (localStorage.getItem(\"UserScript-Setting-\" + Name) == null) {\n //DebugMode is off by default\n localStorage.setItem(\"UserScript-Setting-\" + Name, (Name == \"DebugMode\" ? \"false\" : \"true\"));\n }\n return localStorage.getItem(\"UserScript-Setting-\" + Name) == \"true\";\n};\nlet RequestAPI = (Action, Data, CallBack) => {\n let Session = \"\";\n let Temp = document.cookie.split(\";\");\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].includes(\"PHPSESSID\")) {\n Session = Temp[i].split(\"=\")[1];\n }\n }\n let PostData = {\n \"Authentication\": {\n \"SessionID\": Session,\n \"Username\": CurrentUsername,\n },\n \"Data\": Data,\n \"Version\": GM_info.script.version,\n \"DebugMode\": UtilityEnabled(\"DebugMode\")\n };\n let DataString = JSON.stringify(PostData);\n GM_xmlhttpRequest({\n method: \"POST\",\n url: \"https://api.xmoj-bbs.tech/\" + Action,\n // url: \"http://127.0.0.1:8787/\" + Action,\n headers: {\n \"Content-Type\": \"application/json\"\n },\n data: DataString,\n onload: (Response) => {\n try {\n CallBack(JSON.parse(Response.responseText));\n } catch (Error) {\n console.log(Response.responseText);\n CallBack({\n \"Success\": false,\n \"Message\": \"JSON解析错误:\" + Error,\n \"Data\": null\n });\n }\n }\n });\n};\n\nGM_registerMenuCommand(\"清除缓存\", () => {\n let Temp = [];\n for (let i = 0; i < localStorage.length; i++) {\n if (localStorage.key(i).startsWith(\"UserScript-User-\")) {\n Temp.push(localStorage.key(i));\n }\n }\n for (let i = 0; i < Temp.length; i++) {\n localStorage.removeItem(Temp[i]);\n }\n location.reload();\n});\nGM_registerMenuCommand(\"重置数据\", () => {\n if (confirm(\"确定要重置数据吗?\")) {\n localStorage.clear();\n location.reload();\n }\n});\n\n//otherwise CurrentUsername might be undefined\nif (UtilityEnabled(\"AutoLogin\") && document.querySelector(\"body > a:nth-child(1)\") != null && document.querySelector(\"body > a:nth-child(1)\").innerText == \"请登录后继续操作\") {\n localStorage.setItem(\"UserScript-LastPage\", location.pathname + location.search);\n location.href = \"https://www.xmoj.tech/loginpage.php\";\n}\n\nlet SearchParams = new URLSearchParams(location.search);\nlet ServerURL = (UtilityEnabled(\"DebugMode\") ? \"https://ghpages.xmoj-bbs.tech/\" : \"https://web.xmoj-bbs.tech\")\nlet CurrentUsername = document.querySelector(\"#profile\").innerText;\nCurrentUsername = CurrentUsername.replaceAll(/[^a-zA-Z0-9]/g, \"\");\nlet IsAdmin = AdminUserList.indexOf(CurrentUsername) !== -1;\nif (location.href.startsWith('http://')){\n //use https\n location.href = location.href.replace('http://', 'https://');\n}\nif (location.host != \"www.xmoj.tech\") {\n location.host = \"www.xmoj.tech\";\n}\nelse {\n document.body.classList.add(\"placeholder-glow\");\n if (document.querySelector(\"#navbar\") != null) {\n if (document.querySelector(\"body > div > div.jumbotron\") != null) {\n document.querySelector(\"body > div > div.jumbotron\").className = \"mt-3\";\n }\n\n if (UtilityEnabled(\"AutoLogin\") &&\n document.querySelector(\"#profile\") != null &&\n document.querySelector(\"#profile\").innerHTML == \"登录\" &&\n location.pathname != \"/login.php\" &&\n location.pathname != \"/loginpage.php\" &&\n location.pathname != \"/lostpassword.php\") {\n localStorage.setItem(\"UserScript-LastPage\", location.pathname + location.search);\n location.href = \"https://www.xmoj.tech/loginpage.php\";\n }\n\n let Discussion = null;\n if (UtilityEnabled(\"Discussion\")) {\n Discussion = document.createElement(\"li\");\n document.querySelector(\"#navbar > ul:nth-child(1)\").appendChild(Discussion);\n Discussion.innerHTML = \"<a href=\\\"https://www.xmoj.tech/discuss3/discuss.php\\\">讨论</a>\";\n }\n\n if (document.querySelector(\"#navbar > ul:nth-child(1)\").childElementCount > 8 && UtilityEnabled(\"ACMRank\")) {\n let ACMRank = document.createElement(\"li\");\n document.querySelector(\"#navbar > ul:nth-child(1)\").insertBefore(ACMRank, document.querySelector(\"#navbar > ul:nth-child(1) > li:nth-child(9)\"));\n ACMRank.innerHTML = \"<a href=\\\"https://www.xmoj.tech/contestrank-oi.php?cid=\" + Number(SearchParams.get(\"cid\")) + \"&ByUserScript=1\\\">ACM 排名</a>\";\n ACMRank.classList.add(\"active\");\n }\n if (UtilityEnabled(\"Translate\")) {\n document.querySelector(\"#navbar > ul:nth-child(1) > li:nth-child(2) > a\").innerText = \"题库\";\n }\n //send analytics\n RequestAPI(\"SendData\", {}, (result) => {\n if (UtilityEnabled(\"DebugMode\")) {\n console.log(result);\n }\n });\n if (UtilityEnabled(\"ReplaceLinks\")) {\n document.body.innerHTML =\n String(document.body.innerHTML).replaceAll(\n /\\[<a href=\"([^\"]*)\">([^<]*)<\\/a>\\]/g,\n \"<button onclick=\\\"location.href='$1'\\\" class=\\\"btn btn-outline-secondary\\\">$2</button>\");\n }\n if (UtilityEnabled(\"ReplaceXM\")) {\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"我\", \"高老师\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"小明\", \"高老师\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"下海\", \"上海\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"海上\", \"上海\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"小红\", \"徐师娘\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"小粉\", \"彩虹\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"提交上节课的代码\", \"自动提交当年代码\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"高老师们\", \"我们\");\n document.body.innerHTML = String(document.body.innerHTML).replaceAll(\"自高老师\", \"自我\");\n document.title = String(document.title).replaceAll(\"小明\", \"高老师\");\n }\n\n if (UtilityEnabled(\"NewBootstrap\")) {\n let Temp = document.querySelectorAll(\"link\");\n for (var i = 0; i < Temp.length; i++) {\n if (Temp[i].href.indexOf(\"bootstrap.min.css\") != -1) {\n Temp[i].remove();\n }\n else if (Temp[i].href.indexOf(\"white.css\") != -1) {\n Temp[i].remove();\n }\n else if (Temp[i].href.indexOf(\"semantic.min.css\") != -1) {\n Temp[i].remove();\n }\n else if (Temp[i].href.indexOf(\"bootstrap-theme.min.css\") != -1) {\n Temp[i].remove();\n }\n else if (Temp[i].href.indexOf(\"problem.css\") != -1) {\n Temp[i].remove();\n }\n }\n if (UtilityEnabled(\"DarkMode\")) {\n document.querySelector(\"html\").setAttribute(\"data-bs-theme\", \"dark\");\n }\n else {\n document.querySelector(\"html\").setAttribute(\"data-bs-theme\", \"light\");\n }\n\n let PopperScriptElement = document.createElement(\"script\"); document.head.appendChild(PopperScriptElement);\n PopperScriptElement.type = \"module\";\n PopperScriptElement.src = \"https://cdn.bootcdn.net/ajax/libs/popper.js/2.11.7/umd/popper.min.js\";\n let CodeMirrorStyleElement = document.createElement(\"link\"); document.head.appendChild(CodeMirrorStyleElement);\n CodeMirrorStyleElement.rel = \"stylesheet\";\n CodeMirrorStyleElement.href = \"https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/codemirror.min.css\";\n let CodeMirrorThemeStyleElement = document.createElement(\"link\"); document.head.appendChild(CodeMirrorThemeStyleElement);\n CodeMirrorThemeStyleElement.rel = \"stylesheet\";\n CodeMirrorThemeStyleElement.href = \"https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/theme/darcula.min.css\";\n let CodeMirrorMergeStyleElement = document.createElement(\"link\"); document.head.appendChild(CodeMirrorMergeStyleElement);\n CodeMirrorMergeStyleElement.rel = \"stylesheet\";\n CodeMirrorMergeStyleElement.href = \"https://cdn.bootcdn.net/ajax/libs/codemirror/6.65.7/addon/merge/merge.min.css\";\n let BootstrapStyleElement = document.createElement(\"link\"); document.head.appendChild(BootstrapStyleElement);\n BootstrapStyleElement.rel = \"stylesheet\";\n BootstrapStyleElement.href = \"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/css/bootstrap.min.css\";\n await new Promise((Resolve) => {\n PopperScriptElement.onload = () => {\n Resolve();\n };\n });\n Temp = document.querySelectorAll(\"script\");\n for (var i = 0; i < Temp.length; i++) {\n if (Temp[i].src.indexOf(\"bootstrap.min.js\") != -1) {\n Temp[i].remove();\n let BootstrapScriptElement = document.createElement(\"script\"); document.head.appendChild(BootstrapScriptElement);\n BootstrapScriptElement.type = \"module\";\n BootstrapScriptElement.src = \"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0-alpha3/js/bootstrap.min.js\";\n await new Promise((Resolve) => {\n BootstrapScriptElement.onload = () => {\n Resolve();\n };\n });\n }\n }\n document.querySelector(\"nav\").className = \"navbar navbar-expand-lg bg-body-tertiary\";\n document.querySelector(\"#navbar > ul:nth-child(1)\").classList = \"navbar-nav me-auto mb-2 mb-lg-0\";\n document.querySelector(\"body > div > nav > div > div.navbar-header\").outerHTML = `<a class=\"navbar-brand\" href=\"https://www.xmoj.tech/\">${UtilityEnabled(\"ReplaceXM\") ? \"高老师\" : \"小明\"}的OJ</a><button type=\"button\" class=\"navbar-toggler\" data-bs-toggle=\"collapse\" data-bs-target=\"#navbar\"><span class=\"navbar-toggler-icon\"></span></button>`;\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li\").classList = \"nav-item dropdown\";\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > a\").className = \"nav-link dropdown-toggle\";\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > a > span.caret\").remove();\n Temp = document.querySelector(\"#navbar > ul:nth-child(1)\").children;\n for (var i = 0; i < Temp.length; i++) {\n if (Temp[i].classList.contains(\"active\")) {\n Temp[i].classList.remove(\"active\");\n Temp[i].children[0].classList.add(\"active\");\n }\n Temp[i].classList.add(\"nav-item\");\n Temp[i].children[0].classList.add(\"nav-link\");\n }\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > a\").setAttribute(\"data-bs-toggle\", \"dropdown\");\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > a\").removeAttribute(\"data-toggle\");\n }\n if (UtilityEnabled(\"RemoveUseless\") && document.getElementsByTagName(\"marquee\")[0] != undefined) {\n document.getElementsByTagName(\"marquee\")[0].remove();\n }\n\n let Style = document.createElement(\"style\");\n document.body.appendChild(Style);\n Style.innerHTML = `\n nav {\n border-bottom-left-radius: 5px;\n border-bottom-right-radius: 5px;\n }\n blockquote {\n border-left: 5px solid var(--bs-secondary-bg);\n padding: 0.5em 1em;\n }\n .status_y:hover {\n box-shadow: #52c41a 1px 1px 10px 0px !important;\n }\n .status_n:hover {\n box-shadow: #fe4c61 1px 1px 10px 0px !important;\n }\n .test-case {\n border-radius: 5px !important;\n }\n .test-case:hover {\n box-shadow: rgba(0, 0, 0, 0.3) 0px 10px 20px 3px !important;\n }\n .data[result-item] {\n border-bottom-left-radius: 5px;\n border-bottom-right-radius: 5px;\n }\n .software_list {\n width: unset !important;\n }\n .software_item {\n margin: 5px 10px !important;\n background-color: var(--bs-secondary-bg) !important;\n }\n .item-txt {\n color: var(--bs-emphasis-color) !important;\n }\n .cnt-row {\n justify-content: inherit;\n align-items: stretch;\n width: 100% !important;\n padding: 1rem 0;\n }\n .cnt-row-head {\n padding: 0.8em 1em;\n background-color: var(--bs-secondary-bg);\n border-radius: 0.3rem 0.3rem 0 0;\n width: 100%;\n }\n .cnt-row-body {\n padding: 1em;\n border: 1px solid var(--bs-secondary-bg);\n border-top: none;\n border-radius: 0 0 0.3rem 0.3rem;\n }`;\n if (UtilityEnabled(\"AddAnimation\")) {\n Style.innerHTML += `.status, .test-case {\n transition: 0.5s !important;\n }`;\n }\n if (UtilityEnabled(\"AddColorText\")) {\n Style.innerHTML += `.red {\n color: red !important;\n }\n .green {\n color: green !important;\n }\n .blue {\n color: blue !important;\n }`;\n }\n\n if (UtilityEnabled(\"RemoveUseless\")) {\n if (document.getElementsByClassName(\"footer\")[0] != null) {\n document.getElementsByClassName(\"footer\")[0].remove();\n }\n }\n\n if (UtilityEnabled(\"ReplaceYN\")) {\n Temp = document.getElementsByClassName(\"status_y\");\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].innerText = \"✓\";\n }\n Temp = document.getElementsByClassName(\"status_n\");\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].innerText = \"✗\";\n }\n }\n\n Temp = document.getElementsByClassName(\"page-item\");\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].children[0].className = \"page-link\";\n }\n if (document.getElementsByClassName(\"pagination\")[0] != null) {\n document.getElementsByClassName(\"pagination\")[0].classList.add(\"justify-content-center\");\n }\n\n Temp = document.getElementsByTagName(\"table\");\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].querySelector(\"thead\") != null) {\n TidyTable(Temp[i]);\n }\n }\n\n setInterval(() => {\n try {\n let CurrentDate = new Date(new Date().getTime() + diff);\n let Year = CurrentDate.getFullYear();\n if (Year > 3000) {\n Year -= 1900;\n }\n let Month = CurrentDate.getMonth() + 1;\n let _Date = CurrentDate.getDate();\n let Hours = CurrentDate.getHours();\n let Minutes = CurrentDate.getMinutes();\n let Seconds = CurrentDate.getSeconds();\n document.getElementById(\"nowdate\").innerHTML =\n Year + \"-\" +\n (Month < 10 ? \"0\" : \"\") + Month + \"-\" +\n (_Date < 10 ? \"0\" : \"\") + _Date + \" \" +\n (Hours < 10 ? \"0\" : \"\") + Hours + \":\" +\n (Minutes < 10 ? \"0\" : \"\") + Minutes + \":\" +\n (Seconds < 10 ? \"0\" : \"\") + Seconds;\n } catch (Error) { }\n\n if (UtilityEnabled(\"ResetType\")) {\n if (document.querySelector(\"#profile\") != undefined &&\n document.querySelector(\"#profile\").innerHTML == \"登录\") {\n if (document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > ul\").childNodes.length == 3) {\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > ul\").childNodes[3].remove();\n }\n }\n else if (document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > ul > li:nth-child(3) > a > span\") != undefined &&\n document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > ul > li:nth-child(3) > a > span\").innerText != \"个人中心\") {\n let PopupUL = document.querySelector(\"#navbar > ul.nav.navbar-nav.navbar-right > li > ul\");\n PopupUL.innerHTML = `<li class=\"dropdown-item\">修改帐号</li>\n <li class=\"dropdown-item\">个人中心</li>\n <li class=\"dropdown-item\">短消息</li>\n <li class=\"dropdown-item\">插件设置</li>\n <li class=\"dropdown-item\">注销</li>`\n PopupUL.children[0].addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/modifypage.php\";\n });\n PopupUL.children[1].addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/userinfo.php?user=\" + CurrentUsername;\n });\n PopupUL.children[2].addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/mail.php\";\n });\n PopupUL.children[3].addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/index.php?ByUserScript=1\";\n });\n PopupUL.children[4].addEventListener(\"click\", () => {\n localStorage.removeItem(\"UserScript-Username\");\n localStorage.removeItem(\"UserScript-Password\");\n location.href = \"https://www.xmoj.tech/logout.php\";\n });\n Style.innerHTML += \".dropdown-item {\";\n Style.innerHTML += \" cursor: pointer;\";\n Style.innerHTML += \"}\";\n }\n }\n if (UtilityEnabled(\"AutoCountdown\")) {\n let Temp = document.getElementsByClassName(\"UpdateByJS\");\n for (let i = 0; i < Temp.length; i++) {\n let EndTime = Temp[i].getAttribute(\"EndTime\");\n if (EndTime === null) {\n Temp[i].classList.remove(\"UpdateByJS\");\n continue;\n }\n let TimeStamp = parseInt(EndTime) - new Date().getTime();\n if (TimeStamp < 3000) {\n Temp[i].classList.remove(\"UpdateByJS\");\n location.reload();\n }\n let CurrentDate = new Date(TimeStamp);\n let Day = parseInt((TimeStamp / 1000 / 60 / 60 / 24).toFixed(0));\n let Hour = CurrentDate.getUTCHours();\n let Minute = CurrentDate.getUTCMinutes();\n let Second = CurrentDate.getUTCSeconds();\n Temp[i].innerHTML = (Day !== 0 ? Day + \"天\" : \"\") +\n (Hour !== 0 ? (Hour < 10 ? \"0\" : \"\") + Hour + \"小时\" : \"\") +\n (Minute !== 0 ? (Minute < 10 ? \"0\" : \"\") + Minute + \"分\" : \"\") +\n (Second !== 0 ? (Second < 10 ? \"0\" : \"\") + Second + \"秒\" : \"\");\n }\n }\n }, 100);\n\n fetch(ServerURL + \"/Update.json\", { cache: \"no-cache\" })\n .then((Response) => {\n return Response.json();\n })\n .then((Response) => {\n let CurrentVersion = GM_info.script.version;\n let LatestVersion;\n for (let i = Object.keys(Response.UpdateHistory).length - 1; i >= 0; i--) {\n let VersionInfo = Object.keys(Response.UpdateHistory)[i];\n if (UtilityEnabled(\"DebugMode\") || Response.UpdateHistory[VersionInfo].Prerelease == false) {\n LatestVersion = VersionInfo;\n break;\n }\n }\n if (CurrentVersion < LatestVersion) {\n let UpdateDiv = document.createElement(\"div\");\n UpdateDiv.innerHTML = `<div class=\"alert alert-warning alert-dismissible fade show mt-2\" role=\"alert\">\n <div>\n XMOJ用户脚本发现新版本${LatestVersion},当前版本${CurrentVersion},点击\n <a href=\"${ServerURL}/XMOJ.user.js\" target=\"_blank\" class=\"alert-link\">此处</a>\n 更新\n </div>\n <button type=\"button\" class=\"btn-close\" data-bs-dismiss=\"alert\" aria-label=\"Close\"></button>\n </div>`;\n document.querySelector(\"body > div\").insertBefore(UpdateDiv, document.querySelector(\"body > div > div.mt-3\"));\n }\n if (localStorage.getItem(\"UserScript-Update-LastVersion\") != GM_info.script.version) {\n localStorage.setItem(\"UserScript-Update-LastVersion\", GM_info.script.version);\n let UpdateDiv = document.createElement(\"div\"); document.querySelector(\"body\").appendChild(UpdateDiv);\n UpdateDiv.className = \"modal fade\";\n UpdateDiv.id = \"UpdateModal\";\n UpdateDiv.tabIndex = -1;\n let UpdateDialog = document.createElement(\"div\"); UpdateDiv.appendChild(UpdateDialog);\n UpdateDialog.className = \"modal-dialog\";\n let UpdateContent = document.createElement(\"div\"); UpdateDialog.appendChild(UpdateContent);\n UpdateContent.className = \"modal-content\";\n let UpdateHeader = document.createElement(\"div\"); UpdateContent.appendChild(UpdateHeader);\n UpdateHeader.className = \"modal-header\";\n let UpdateTitle = document.createElement(\"h5\"); UpdateHeader.appendChild(UpdateTitle);\n UpdateTitle.className = \"modal-title\";\n UpdateTitle.innerText = \"更新日志\";\n let UpdateCloseButton = document.createElement(\"button\"); UpdateHeader.appendChild(UpdateCloseButton);\n UpdateCloseButton.type = \"button\";\n UpdateCloseButton.className = \"btn-close\";\n UpdateCloseButton.setAttribute(\"data-bs-dismiss\", \"modal\");\n let UpdateBody = document.createElement(\"div\"); UpdateContent.appendChild(UpdateBody);\n UpdateBody.className = \"modal-body\";\n let UpdateFooter = document.createElement(\"div\"); UpdateContent.appendChild(UpdateFooter);\n UpdateFooter.className = \"modal-footer\";\n let UpdateButton = document.createElement(\"button\"); UpdateFooter.appendChild(UpdateButton);\n UpdateButton.type = \"button\";\n UpdateButton.className = \"btn btn-secondary\";\n UpdateButton.setAttribute(\"data-bs-dismiss\", \"modal\");\n UpdateButton.innerText = \"关闭\";\n let Version = Object.keys(Response.UpdateHistory)[Object.keys(Response.UpdateHistory).length - 1]\n let Data = Response.UpdateHistory[Version];\n let UpdateDataCard = document.createElement(\"div\"); UpdateBody.appendChild(UpdateDataCard);\n UpdateDataCard.className = \"card mb-3\";\n let UpdateDataCardBody = document.createElement(\"div\"); UpdateDataCard.appendChild(UpdateDataCardBody);\n UpdateDataCardBody.className = \"card-body\";\n let UpdateDataCardTitle = document.createElement(\"h5\"); UpdateDataCardBody.appendChild(UpdateDataCardTitle);\n UpdateDataCardTitle.className = \"card-title\";\n UpdateDataCardTitle.innerText = Version;\n let UpdateDataCardSubtitle = document.createElement(\"h6\"); UpdateDataCardBody.appendChild(UpdateDataCardSubtitle);\n UpdateDataCardSubtitle.className = \"card-subtitle mb-2 text-muted\";\n UpdateDataCardSubtitle.innerHTML = GetRelativeTime(Data.UpdateDate);\n let UpdateDataCardText = document.createElement(\"p\"); UpdateDataCardBody.appendChild(UpdateDataCardText);\n UpdateDataCardText.className = \"card-text\";\n //release notes\n if (Data.Notes != undefined){\n UpdateDataCardText.innerHTML = Data.Notes;\n }\n let UpdateDataCardList = document.createElement(\"ul\"); UpdateDataCardText.appendChild(UpdateDataCardList);\n UpdateDataCardList.className = \"list-group list-group-flush\";\n for (let j = 0; j < Data.UpdateContents.length; j++) {\n let UpdateDataCardListItem = document.createElement(\"li\"); UpdateDataCardList.appendChild(UpdateDataCardListItem);\n UpdateDataCardListItem.className = \"list-group-item\";\n UpdateDataCardListItem.innerHTML =\n \"(<a href=\\\"https://github.com/XMOJ-Script-dev/XMOJ-Script/pull/\" + Data.UpdateContents[j].PR + \"\\\" target=\\\"_blank\\\">\" +\n \"#\" + Data.UpdateContents[j].PR + \"</a>) \" +\n Data.UpdateContents[j].Description;\n }\n let UpdateDataCardLink = document.createElement(\"a\"); UpdateDataCardBody.appendChild(UpdateDataCardLink);\n UpdateDataCardLink.className = \"card-link\";\n UpdateDataCardLink.href = \"https://github.com/XMOJ-Script-dev/XMOJ-Script/releases/tag/\" + Version;\n UpdateDataCardLink.target = \"_blank\";\n UpdateDataCardLink.innerText = \"查看该版本\";\n new bootstrap.Modal(document.getElementById(\"UpdateModal\")).show();\n }\n });\n fetch(ServerURL + \"/AddonScript.js\", { cache: \"no-cache\" })\n .then((Response) => {\n return Response.text();\n })\n .then((Response) => {\n eval(Response);\n });\n\n let ToastContainer = document.createElement(\"div\");\n ToastContainer.classList.add(\"toast-container\", \"position-fixed\", \"bottom-0\", \"end-0\", \"p-3\");\n document.body.appendChild(ToastContainer);\n addEventListener(\"focus\", () => {\n if (UtilityEnabled(\"BBSPopup\")) {\n RequestAPI(\"GetBBSMentionList\", {}, (Response) => {\n if (Response.Success) {\n ToastContainer.innerHTML = \"\";\n let MentionList = Response.Data.MentionList;\n for (let i = 0; i < MentionList.length; i++) {\n let Toast = document.createElement(\"div\");\n Toast.classList.add(\"toast\");\n Toast.setAttribute(\"role\", \"alert\");\n let ToastHeader = document.createElement(\"div\");\n ToastHeader.classList.add(\"toast-header\");\n let ToastTitle = document.createElement(\"strong\");\n ToastTitle.classList.add(\"me-auto\");\n ToastTitle.innerHTML = \"提醒:有人@你\";\n ToastHeader.appendChild(ToastTitle);\n let ToastTime = document.createElement(\"small\");\n ToastTime.classList.add(\"text-body-secondary\");\n ToastTime.innerHTML = GetRelativeTime(MentionList[i].MentionTime);\n ToastHeader.appendChild(ToastTime);\n let ToastCloseButton = document.createElement(\"button\");\n ToastCloseButton.type = \"button\";\n ToastCloseButton.classList.add(\"btn-close\");\n ToastCloseButton.setAttribute(\"data-bs-dismiss\", \"toast\");\n ToastHeader.appendChild(ToastCloseButton);\n Toast.appendChild(ToastHeader);\n let ToastBody = document.createElement(\"div\");\n ToastBody.classList.add(\"toast-body\");\n ToastBody.innerHTML = \"讨论\" + MentionList[i].PostTitle + \"有新回复\";\n let ToastFooter = document.createElement(\"div\");\n ToastFooter.classList.add(\"mt-2\", \"pt-2\", \"border-top\");\n let ToastDismissButton = document.createElement(\"button\");\n ToastDismissButton.type = \"button\";\n ToastDismissButton.classList.add(\"btn\", \"btn-secondary\", \"btn-sm\", \"me-2\");\n ToastDismissButton.innerText = \"忽略\";\n ToastDismissButton.addEventListener(\"click\", () => {\n RequestAPI(\"ReadBBSMention\", {\n \"MentionID\": Number(MentionList[i].MentionID)\n }, () => { });\n Toast.remove();\n });\n ToastFooter.appendChild(ToastDismissButton);\n let ToastViewButton = document.createElement(\"button\");\n ToastViewButton.type = \"button\";\n ToastViewButton.classList.add(\"btn\", \"btn-primary\", \"btn-sm\");\n ToastViewButton.innerText = \"查看\";\n ToastViewButton.addEventListener(\"click\", () => {\n open(\"https://www.xmoj.tech/discuss3/thread.php?tid=\" + MentionList[i].PostID, \"_blank\");\n RequestAPI(\"ReadBBSMention\", {\n \"MentionID\": Number(MentionList[i].MentionID)\n }, () => { });\n });\n ToastFooter.appendChild(ToastViewButton);\n ToastBody.appendChild(ToastFooter);\n Toast.appendChild(ToastBody);\n ToastContainer.appendChild(Toast);\n new bootstrap.Toast(Toast).show();\n }\n }\n });\n }\n if (UtilityEnabled(\"MessagePopup\")) {\n RequestAPI(\"GetMailMentionList\", {}, async (Response) => {\n if (Response.Success) {\n if (!UtilityEnabled(\"BBSPopup\")) {\n ToastContainer.innerHTML = \"\";\n }\n let MentionList = Response.Data.MentionList;\n for (let i = 0; i < MentionList.length; i++) {\n let Toast = document.createElement(\"div\");\n Toast.classList.add(\"toast\");\n Toast.setAttribute(\"role\", \"alert\");\n let ToastHeader = document.createElement(\"div\");\n ToastHeader.classList.add(\"toast-header\");\n let ToastTitle = document.createElement(\"strong\");\n ToastTitle.classList.add(\"me-auto\");\n ToastTitle.innerHTML = \"提醒:有新消息\";\n ToastHeader.appendChild(ToastTitle);\n let ToastTime = document.createElement(\"small\");\n ToastTime.classList.add(\"text-body-secondary\");\n ToastTime.innerHTML = GetRelativeTime(MentionList[i].MentionTime);\n ToastHeader.appendChild(ToastTime);\n let ToastCloseButton = document.createElement(\"button\");\n ToastCloseButton.type = \"button\";\n ToastCloseButton.classList.add(\"btn-close\");\n ToastCloseButton.setAttribute(\"data-bs-dismiss\", \"toast\");\n ToastHeader.appendChild(ToastCloseButton);\n Toast.appendChild(ToastHeader);\n let ToastBody = document.createElement(\"div\");\n ToastBody.classList.add(\"toast-body\");\n let ToastUser = document.createElement(\"span\");\n GetUsernameHTML(ToastUser, MentionList[i].FromUserID);\n ToastBody.appendChild(ToastUser);\n ToastBody.innerHTML += \" 给你发了一封短消息\";\n let ToastFooter = document.createElement(\"div\");\n ToastFooter.classList.add(\"mt-2\", \"pt-2\", \"border-top\");\n let ToastDismissButton = document.createElement(\"button\");\n ToastDismissButton.type = \"button\";\n ToastDismissButton.classList.add(\"btn\", \"btn-secondary\", \"btn-sm\", \"me-2\");\n ToastDismissButton.innerText = \"忽略\";\n ToastDismissButton.addEventListener(\"click\", () => {\n RequestAPI(\"ReadMailMention\", {\n \"MentionID\": Number(MentionList[i].MentionID)\n }, () => { });\n });\n ToastFooter.appendChild(ToastDismissButton);\n let ToastViewButton = document.createElement(\"button\");\n ToastViewButton.type = \"button\";\n ToastViewButton.classList.add(\"btn\", \"btn-primary\", \"btn-sm\");\n ToastViewButton.innerText = \"查看\";\n ToastViewButton.addEventListener(\"click\", () => {\n open(\"https://www.xmoj.tech/mail.php?other=\" + MentionList[i].FromUserID, \"_blank\");\n RequestAPI(\"ReadMailMention\", {\n \"MentionID\": Number(MentionList[i].MentionID)\n }, () => { });\n });\n ToastFooter.appendChild(ToastViewButton);\n ToastBody.appendChild(ToastFooter);\n Toast.appendChild(ToastBody);\n ToastContainer.appendChild(Toast);\n new bootstrap.Toast(Toast).show();\n }\n }\n });\n }\n });\n dispatchEvent(new Event(\"focus\"));\n\n\n if (location.pathname == \"/index.php\" || location.pathname == \"/\") {\n if (new URL(location.href).searchParams.get(\"ByUserScript\") != null) {\n localStorage.setItem(\"UserScript-Opened\", \"true\");\n let Container = document.getElementsByClassName(\"mt-3\")[0];\n Container.innerHTML = \"\";\n let Alert = document.createElement(\"div\");\n Alert.classList.add(\"alert\");\n Alert.classList.add(\"alert-primary\");\n Alert.role = \"alert\";\n Alert.innerHTML = `欢迎您使用XMOJ增强脚本!点击\n <a class=\"alert-link\" href=\"https://www.xmoj.tech/modifypage.php?ByUserScript=1\" target=\"_blank\">此处</a>\n 查看更新日志。`;\n Container.appendChild(Alert);\n let UtilitiesCard = document.createElement(\"div\");\n UtilitiesCard.classList.add(\"card\");\n UtilitiesCard.classList.add(\"mb-3\");\n let UtilitiesCardHeader = document.createElement(\"div\");\n UtilitiesCardHeader.classList.add(\"card-header\");\n UtilitiesCardHeader.innerText = \"XMOJ增强脚本功能列表\";\n UtilitiesCard.appendChild(UtilitiesCardHeader);\n let UtilitiesCardBody = document.createElement(\"div\");\n UtilitiesCardBody.classList.add(\"card-body\");\n let CreateList = (Data) => {\n let List = document.createElement(\"ul\");\n List.classList.add(\"list-group\");\n for (let i = 0; i < Data.length; i++) {\n let Row = document.createElement(\"li\");\n Row.classList.add(\"list-group-item\");\n if (Data[i].Type == \"A\") {\n Row.classList.add(\"list-group-item-success\");\n }\n else if (Data[i].Type == \"F\") {\n Row.classList.add(\"list-group-item-warning\");\n }\n else if (Data[i].Type == \"D\") {\n Row.classList.add(\"list-group-item-danger\");\n }\n if (Data[i].Children == undefined) {\n let CheckBox = document.createElement(\"input\");\n CheckBox.classList.add(\"form-check-input\");\n CheckBox.classList.add(\"me-1\");\n CheckBox.type = \"checkbox\";\n CheckBox.id = Data[i].ID;\n if (localStorage.getItem(\"UserScript-Setting-\" + Data[i].ID) == null) {\n localStorage.setItem(\"UserScript-Setting-\" + Data[i].ID, \"true\");\n }\n if (localStorage.getItem(\"UserScript-Setting-\" + Data[i].ID) == \"false\") {\n CheckBox.checked = false;\n }\n else {\n CheckBox.checked = true;\n }\n CheckBox.addEventListener(\"change\", () => {\n return localStorage.setItem(\"UserScript-Setting-\" + Data[i].ID, CheckBox.checked);\n });\n\n Row.appendChild(CheckBox);\n let Label = document.createElement(\"label\");\n Label.classList.add(\"form-check-label\");\n Label.htmlFor = Data[i].ID;\n Label.innerText = Data[i].Name;\n Row.appendChild(Label);\n }\n else {\n let Label = document.createElement(\"label\");\n Label.innerText = Data[i].Name;\n Row.appendChild(Label);\n }\n if (Data[i].Children != undefined) {\n Row.appendChild(CreateList(Data[i].Children));\n }\n List.appendChild(Row);\n }\n return List;\n };\n UtilitiesCardBody.appendChild(CreateList([\n { \"ID\": \"ACMRank\", \"Type\": \"A\", \"Name\": \"比赛ACM排名,并且能下载ACM排名\" },\n { \"ID\": \"Discussion\", \"Type\": \"F\", \"Name\": \"恢复讨论与短消息功能\" },\n { \"ID\": \"MoreSTD\", \"Type\": \"F\", \"Name\": \"查看到更多标程\" },\n {\n \"ID\": \"StudyMode\", \"Type\": \"A\", \"Name\": \"学术模式\", \"Children\": [\n { \"ID\": \"ApplyData\", \"Type\": \"A\", \"Name\": \"获取数据功能\" },\n { \"ID\": \"AutoCheat\", \"Type\": \"A\", \"Name\": \"自动提交当年代码\" }\n ]\n },\n { \"ID\": \"Rating\", \"Type\": \"A\", \"Name\": \"添加用户评分和用户名颜色\" },\n { \"ID\": \"AutoRefresh\", \"Type\": \"A\", \"Name\": \"比赛列表、比赛排名界面自动刷新\" },\n { \"ID\": \"AutoCountdown\", \"Type\": \"A\", \"Name\": \"比赛列表等界面的时间自动倒计时\" },\n { \"ID\": \"DownloadPlayback\", \"Type\": \"A\", \"Name\": \"回放视频增加下载功能\" },\n { \"ID\": \"ImproveACRate\", \"Type\": \"A\", \"Name\": \"自动提交已AC题目以提高AC率\" },\n { \"ID\": \"AutoO2\", \"Type\": \"F\", \"Name\": \"代码提交界面自动选择O2优化\" },\n {\n \"ID\": \"Beautify\", \"Type\": \"F\", \"Name\": \"美化界面\", \"Children\": [\n { \"ID\": \"NewBootstrap\", \"Type\": \"F\", \"Name\": \"使用新版的Bootstrap样式库*\" },\n { \"ID\": \"ResetType\", \"Type\": \"F\", \"Name\": \"重新排版*\" },\n { \"ID\": \"AddColorText\", \"Type\": \"A\", \"Name\": \"增加彩色文字\" },\n { \"ID\": \"AddUnits\", \"Type\": \"A\", \"Name\": \"状态界面内存与耗时添加单位\" },\n { \"ID\": \"DarkMode\", \"Type\": \"A\", \"Name\": \"使用暗色模式\" },\n { \"ID\": \"AddAnimation\", \"Type\": \"A\", \"Name\": \"增加动画\" },\n { \"ID\": \"ReplaceYN\", \"Type\": \"F\", \"Name\": \"题目前对错的Y和N替换为勾和叉\" },\n { \"ID\": \"RemoveAlerts\", \"Type\": \"D\", \"Name\": \"去除多余反复的提示\" },\n { \"ID\": \"Translate\", \"Type\": \"F\", \"Name\": \"统一使用中文,翻译了部分英文*\" },\n { \"ID\": \"ReplaceLinks\", \"Type\": \"F\", \"Name\": \"将网站中所有以方括号包装的链接替换为按钮\" },\n { \"ID\": \"RemoveUseless\", \"Type\": \"D\", \"Name\": \"删去无法使用的功能*\" },\n { \"ID\": \"ReplaceXM\", \"Type\": \"F\", \"Name\": \"将网站中所有“小明”和“我”关键字替换为“高老师”,所有“小红”替换为“徐师娘”,所有“小粉”替换为“彩虹”,所有“下海”、“海上”替换为“上海”\" }\n ]\n },\n { \"ID\": \"AutoLogin\", \"Type\": \"A\", \"Name\": \"在需要登录的界面自动跳转到登陆界面\" },\n { \"ID\": \"SavePassword\", \"Type\": \"A\", \"Name\": \"自动保存用户名与密码,免去每次手动输入密码的繁琐\" },\n { \"ID\": \"CopySamples\", \"Type\": \"F\", \"Name\": \"题目界面测试样例有时复制无效\" },\n { \"ID\": \"RefreshSolution\", \"Type\": \"F\", \"Name\": \"状态页面结果自动刷新每次只能刷新一个\" },\n { \"ID\": \"CopyMD\", \"Type\": \"A\", \"Name\": \"复制题目或题解内容\" },\n { \"ID\": \"OpenAllProblem\", \"Type\": \"A\", \"Name\": \"比赛题目界面一键打开所有题目\" },\n {\n \"ID\": \"CheckCode\", \"Type\": \"A\", \"Name\": \"提交代码前对代码进行检查\", \"Children\": [\n { \"ID\": \"IOFile\", \"Type\": \"A\", \"Name\": \"是否使用了文件输入输出(如果需要使用)\" },\n { \"ID\": \"CompileError\", \"Type\": \"A\", \"Name\": \"是否有编译错误\" }\n ]\n },\n { \"ID\": \"ExportACCode\", \"Type\": \"F\", \"Name\": \"导出AC代码每一道题目一个文件\" },\n { \"ID\": \"LoginFailed\", \"Type\": \"F\", \"Name\": \"修复登录后跳转失败*\" },\n { \"ID\": \"NewDownload\", \"Type\": \"A\", \"Name\": \"下载页面增加下载内容\" },\n { \"ID\": \"CompareSource\", \"Type\": \"A\", \"Name\": \"比较代码\" },\n { \"ID\": \"BBSPopup\", \"Type\": \"A\", \"Name\": \"讨论提醒\" },\n { \"ID\": \"MessagePopup\", \"Type\": \"A\", \"Name\": \"短消息提醒\" },\n { \"ID\": \"DebugMode\", \"Type\": \"A\", \"Name\": \"调试模式(仅供开发者使用)\" }\n ]));\n let UtilitiesCardFooter = document.createElement(\"div\");\n UtilitiesCardFooter.className = \"card-footer text-muted\";\n UtilitiesCardFooter.innerText = \"* 不建议关闭,可能会导致系统不稳定、界面错乱、功能缺失等问题\\n绿色:增加功能 黄色:修改功能 红色:删除功能\";\n UtilitiesCardBody.appendChild(UtilitiesCardFooter);\n UtilitiesCard.appendChild(UtilitiesCardBody);\n Container.appendChild(UtilitiesCard);\n let FeedbackCard = document.createElement(\"div\");\n FeedbackCard.className = \"card mb-3\";\n let FeedbackCardHeader = document.createElement(\"div\");\n FeedbackCardHeader.className = \"card-header\";\n FeedbackCardHeader.innerText = \"反馈、源代码、联系作者\";\n FeedbackCard.appendChild(FeedbackCardHeader);\n let FeedbackCardBody = document.createElement(\"div\");\n FeedbackCardBody.className = \"card-body\";\n let FeedbackCardText = document.createElement(\"p\");\n FeedbackCardText.className = \"card-text\";\n FeedbackCardText.innerText = \"如果您有任何建议或者发现了bug,请前往本项目的GitHub页面并提交issue。提交issue前请先搜索是否有相同的issue,如果有请在该issue下留言。请在issue中尽可能详细地描述您的问题,并且附上您的浏览器版本、操作系统版本、脚本版本、复现步骤等信息。谢谢您支持本项目。\";\n FeedbackCardBody.appendChild(FeedbackCardText);\n let FeedbackCardLink = document.createElement(\"a\");\n FeedbackCardLink.className = \"card-link\";\n FeedbackCardLink.innerText = \"GitHub\";\n FeedbackCardLink.href = \"https://github.com/XMOJ-Script-dev/XMOJ-Script\";\n FeedbackCardBody.appendChild(FeedbackCardLink);\n FeedbackCard.appendChild(FeedbackCardBody);\n Container.appendChild(FeedbackCard);\n }\n else {\n let Temp = document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").children;\n let NewsData = [];\n for (let i = 0; i < Temp.length; i += 2) {\n let Title = Temp[i].children[0].innerText;\n let Time = 0;\n if (Temp[i].children[1] != null) {\n Time = Temp[i].children[1].innerText;\n }\n let Body = Temp[i + 1].innerHTML;\n NewsData.push({ \"Title\": Title, \"Time\": new Date(Time), \"Body\": Body });\n }\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").innerHTML = \"\";\n for (let i = 0; i < NewsData.length; i++) {\n let NewsRow = document.createElement(\"div\");\n NewsRow.className = \"cnt-row\";\n let NewsRowHead = document.createElement(\"div\");\n NewsRowHead.className = \"cnt-row-head title\";\n NewsRowHead.innerText = NewsData[i].Title;\n if (NewsData[i].Time != 0) {\n NewsRowHead.innerHTML += \"<small class=\\\"ms-3\\\">\" + NewsData[i].Time.toLocaleDateString() + \"</small>\";\n }\n NewsRow.appendChild(NewsRowHead);\n let NewsRowBody = document.createElement(\"div\");\n NewsRowBody.className = \"cnt-row-body\";\n NewsRowBody.innerHTML = NewsData[i].Body;\n NewsRow.appendChild(NewsRowBody);\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").appendChild(NewsRow);\n }\n let CountDownData = document.querySelector(\"#countdown_list\").innerHTML;\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-4\").innerHTML = `<div class=\"cnt-row\">\n <div class=\"cnt-row-head title\">倒计时</div>\n <div class=\"cnt-row-body\">${CountDownData}</div>\n </div>`;\n }\n } else if (location.pathname == \"/problemset.php\") {\n if (UtilityEnabled(\"Translate\")) {\n document.querySelector(\"body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > input\").placeholder = \"题目编号\";\n document.querySelector(\"body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(2) > form > button\").innerText = \"确认\";\n document.querySelector(\"body > div > div.mt-3 > center > table:nth-child(2) > tbody > tr > td:nth-child(3) > form > input\").placeholder = \"标题或内容\";\n document.querySelector(\"#problemset > thead > tr > th:nth-child(1)\").innerText = \"状态\";\n }\n if (UtilityEnabled(\"ResetType\")) {\n document.querySelector(\"#problemset > thead > tr > th:nth-child(1)\").style.width = \"5%\";\n document.querySelector(\"#problemset > thead > tr > th:nth-child(2)\").style.width = \"10%\";\n document.querySelector(\"#problemset > thead > tr > th:nth-child(3)\").style.width = \"75%\";\n document.querySelector(\"#problemset > thead > tr > th:nth-child(4)\").style.width = \"5%\";\n document.querySelector(\"#problemset > thead > tr > th:nth-child(5)\").style.width = \"5%\";\n }\n document.querySelector(\"body > div > div.mt-3 > center > table:nth-child(2)\").outerHTML = `\n <div class=\"row\">\n <div class=\"center col-md-3\"></div>\n <div class=\"col-md-2\">\n <form action=\"problem.php\" class=\"input-group\">\n <input class=\"form-control\" type=\"number\" name=\"id\" placeholder=\"题目编号\" min=\"0\">\n <button class=\"btn btn-outline-secondary\" type=\"submit\">跳转</button>\n </form>\n </div>\n <div class=\"col-md-4\">\n <form action=\"problemset.php\" class=\"input-group\">\n <input class=\"form-control\" type=\"text\" name=\"search\" placeholder=\"标题或内容\">\n <button class=\"btn btn-outline-secondary\" type=\"submit\">查找</button>\n </form>\n </div>\n </div>`;\n if (SearchParams.get(\"search\") != null) {\n document.querySelector(\"body > div > div.mt-3 > center > div > div:nth-child(3) > form > input\").value = SearchParams.get(\"search\");\n }\n\n let Temp = document.querySelector(\"#problemset\").rows;\n for (let i = 1; i < Temp.length; i++) {\n localStorage.setItem(\"UserScript-Problem-\" + Temp[i].children[1].innerText + \"-Name\",\n Temp[i].children[2].innerText);\n }\n } else if (location.pathname == \"/problem.php\") {\n if (SearchParams.get(\"cid\") != null) {\n document.getElementsByTagName(\"h2\")[0].innerHTML += \" (\" +\n localStorage.getItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") +\n \"-Problem-\" + SearchParams.get(\"pid\") + \"-PID\") +\n \")\";\n }\n if (document.querySelector(\"body > div > div.mt-3 > h2\") != null) {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"没有此题目或题目对你不可见\";\n setTimeout(() => {\n location.href = \"https://www.xmoj.tech/problemset.php\";\n }, 1000);\n }\n else {\n let PID = localStorage.getItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") +\n \"-Problem-\" + SearchParams.get(\"pid\") + \"-PID\");\n\n document.querySelector(\"body > div > div.mt-3 > center\").lastChild.style.marginLeft = \"10px\";\n //修复提交按钮\n let SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(12)');\n if (SubmitLink == null) { //如果是比赛题目\n SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(10)');\n }\n if (SubmitLink == null) {\n SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(11)');\n }\n if (SubmitLink == null) {\n SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(13)');\n }\n if (SubmitLink == null) {\n SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(9)');\n }\n let SubmitButton = document.createElement('button');\n SubmitButton.id = 'SubmitButton';\n SubmitButton.className = 'btn btn-outline-secondary';\n SubmitButton.textContent = '提交';\n SubmitButton.href = SubmitLink.href;\n SubmitButton.onclick = function () {\n window.location.href = SubmitLink.href;\n console.log(SubmitLink.href);\n };\n\n // Replace the <a> element with the button\n SubmitLink.parentNode.replaceChild(SubmitButton, SubmitLink);\n // Remove the button's outer []\n let str = document.querySelector('.mt-3 > center:nth-child(1)').innerHTML;\n let target = SubmitButton.outerHTML;\n let result = str.replace(new RegExp(`(.?)${target}(.?)`, 'g'), target);\n document.querySelector('.mt-3 > center:nth-child(1)').innerHTML = result;\n document.querySelector('html body.placeholder-glow div.container div.mt-3 center button#SubmitButton.btn.btn-outline-secondary').onclick = function () {\n window.location.href = SubmitLink.href;\n console.log(SubmitLink.href);\n };\n Temp = document.querySelectorAll(\".sampledata\");\n for (var i = 0; i < Temp.length; i++) {\n Temp[i].parentElement.className = \"card\";\n }\n if (UtilityEnabled(\"RemoveUseless\")) {\n document.querySelector(\"h2.lang_en\").remove();\n document.getElementsByTagName(\"center\")[1].remove();\n }\n if (UtilityEnabled(\"CopySamples\")) {\n $(\".copy-btn\").click((Event) => {\n let CurrentButton = $(Event.currentTarget);\n let span = CurrentButton.parent().last().find(\".sampledata\");\n if (!span.length) {\n CurrentButton.text(\"未找到代码块\").addClass(\"done\");\n setTimeout(() => {\n $(\".copy-btn\").text(\"复制\").removeClass(\"done\");\n }, 1000);\n return;\n }\n GM_setClipboard(span.text());\n CurrentButton.text(\"复制成功\").addClass(\"done\");\n setTimeout(() => {\n $(\".copy-btn\").text(\"复制\").removeClass(\"done\");\n }, 1000);\n //document.body.removeChild(textarea[0]);\n });\n }\n let IOFileElement = document.querySelector(\"body > div > div.mt-3 > center > h3\");\n if (IOFileElement != null) {\n while (IOFileElement.childNodes.length >= 1) {\n IOFileElement.parentNode.insertBefore(IOFileElement.childNodes[0], IOFileElement);\n }\n IOFileElement.parentNode.insertBefore(document.createElement(\"br\"), IOFileElement);\n IOFileElement.remove();\n let Temp = document.querySelector(\"body > div > div.mt-3 > center\").childNodes[2].data.trim();\n let IOFilename = Temp.substring(0, Temp.length - 3);\n localStorage.setItem(\"UserScript-Problem-\" + PID + \"-IOFilename\", IOFilename);\n }\n\n if (UtilityEnabled(\"CopyMD\")) {\n await fetch(location.href).then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let Temp = ParsedDocument.querySelectorAll(\".cnt-row\");\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].children[1].children[0].className == \"content\") {\n let CopyMDButton = document.createElement(\"button\");\n CopyMDButton.className = \"btn btn-sm btn-outline-secondary copy-btn\";\n CopyMDButton.innerText = \"复制\";\n CopyMDButton.style.marginLeft = \"10px\";\n CopyMDButton.type = \"button\";\n document.querySelectorAll(\".cnt-row\")[i].children[0].appendChild(CopyMDButton);\n CopyMDButton.addEventListener(\"click\", () => {\n GM_setClipboard(Temp[i].children[1].children[0].innerText.trim().replaceAll(\"\\n\\t\", \"\\n\").replaceAll(\"\\n\\n\", \"\\n\").replaceAll(\"\\n\\n\", \"\\n\"));\n CopyMDButton.innerText = \"复制成功\";\n setTimeout(() => {\n CopyMDButton.innerText = \"复制\";\n }, 1000);\n });\n }\n }\n });\n }\n\n if (UtilityEnabled(\"Discussion\")) {\n let DiscussButton = document.createElement(\"button\");\n DiscussButton.className = \"btn btn-outline-secondary position-relative\";\n DiscussButton.innerHTML = `讨论`;\n DiscussButton.style.marginLeft = \"10px\";\n DiscussButton.type = \"button\";\n DiscussButton.addEventListener(\"click\", () => {\n if (SearchParams.get(\"cid\") != null) {\n open(\"https://www.xmoj.tech/discuss3/discuss.php?pid=\" + PID, \"_blank\");\n }\n else {\n open(\"https://www.xmoj.tech/discuss3/discuss.php?pid=\" + SearchParams.get(\"id\"), \"_blank\");\n }\n });\n document.querySelector(\"body > div > div.mt-3 > center\").appendChild(DiscussButton);\n let UnreadBadge = document.createElement(\"span\");\n UnreadBadge.className = \"position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger\";\n UnreadBadge.style.display = \"none\";\n DiscussButton.appendChild(UnreadBadge);\n\n let RefreshCount = () => {\n RequestAPI(\"GetPostCount\", {\n \"ProblemID\": Number(PID)\n }, (Response) => {\n if (Response.Success) {\n if (Response.Data.DiscussCount != 0) {\n UnreadBadge.innerText = Response.Data.DiscussCount;\n UnreadBadge.style.display = \"\";\n }\n }\n });\n };\n RefreshCount();\n addEventListener(\"focus\", RefreshCount);\n }\n\n let Tables = document.getElementsByTagName(\"table\");\n for (let i = 0; i < Tables.length; i++) {\n TidyTable(Tables[i]);\n }\n }\n Style.innerHTML += \"code, kbd, pre, samp {\";\n Style.innerHTML += \" font-family: monospace, Consolas, 'Courier New';\";\n Style.innerHTML += \" font-size: 1rem;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \"pre {\";\n Style.innerHTML += \" padding: 0.3em 0.5em;\";\n Style.innerHTML += \" margin: 0.5em 0;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \".in-out {\";\n Style.innerHTML += \" overflow: hidden;\";\n Style.innerHTML += \" display: flex;\";\n Style.innerHTML += \" padding: 0.5em 0;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \".in-out .in-out-item {\";\n Style.innerHTML += \" flex: 1;\";\n Style.innerHTML += \" overflow: hidden;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \".cnt-row .title {\";\n Style.innerHTML += \" font-weight: bolder;\";\n Style.innerHTML += \" font-size: 1.1rem;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \".cnt-row .content {\";\n Style.innerHTML += \" overflow: hidden;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \"a.copy-btn {\";\n Style.innerHTML += \" float: right;\";\n Style.innerHTML += \" padding: 0 0.4em;\";\n Style.innerHTML += \" border: 1px solid var(--bs-primary);\";\n Style.innerHTML += \" border-radius: 3px;\";\n Style.innerHTML += \" color: var(--bs-primary);\";\n Style.innerHTML += \" cursor: pointer;\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \"a.copy-btn:hover {\";\n Style.innerHTML += \" background-color: var(--bs-secondary-bg);\";\n Style.innerHTML += \"}\";\n Style.innerHTML += \"a.done, a.done:hover {\";\n Style.innerHTML += \" background-color: var(--bs-primary);\";\n Style.innerHTML += \" color: white;\";\n Style.innerHTML += \"}\";\n } else if (location.pathname == \"/status.php\") {\n if (SearchParams.get(\"ByUserScript\") == null) {\n document.querySelector(\"body > script:nth-child(5)\").remove();\n if (UtilityEnabled(\"NewBootstrap\")) {\n document.querySelector(\"#simform\").outerHTML = `<form id=\"simform\" class=\"justify-content-center form-inline row g-2\" action=\"status.php\" method=\"get\" style=\"padding-bottom: 7px;\">\n <input class=\"form-control\" type=\"text\" size=\"4\" name=\"user_id\" value=\"${CurrentUsername} \"style=\"display: none;\">\n <div class=\"col-md-1\">\n <label for=\"problem_id\" class=\"form-label\">题目编号</label>\n <input type=\"text\" class=\"form-control\" id=\"problem_id\" name=\"problem_id\" size=\"4\">\n </div>\n <div class=\"col-md-1\">\n <label for=\"language\" class=\"form-label\">语言</label>\n <select id=\"language\" name=\"language\" class=\"form-select\">\n <option value=\"-1\" selected=\"\">全部</option>\n <option value=\"0\">C</option>\n <option value=\"1\">C++</option>\n <option value=\"2\">Pascal</option>\n </select>\n </div><div class=\"col-md-1\">\n <label for=\"jresult\" class=\"form-label\">结果</label>\n <select id=\"jresult\" name=\"jresult\" class=\"form-select\">\n <option value=\"-1\" selected=\"\">全部</option>\n <option value=\"4\">正确</option>\n <option value=\"5\">格式错误</option>\n <option value=\"6\">答案错误</option>\n <option value=\"7\">时间超限</option>\n <option value=\"8\">内存超限</option>\n <option value=\"9\">输出超限</option>\n <option value=\"10\">运行错误</option>\n <option value=\"11\">编译错误</option>\n <option value=\"0\">等待</option>\n <option value=\"1\">等待重判</option>\n <option value=\"2\">编译中</option>\n <option value=\"3\">运行并评判</option>\n </select>\n </div>\n <div class=\"col-md-1\">\n <button type=\"submit\" class=\"btn btn-primary\">查找</button>\n </div><div id=\"csrf\"></div></form>`;\n }\n\n if (UtilityEnabled(\"ImproveACRate\")) {\n let ImproveACRateButton = document.createElement(\"button\");\n document.querySelector(\"body > div.container > div > div.input-append\").appendChild(ImproveACRateButton);\n ImproveACRateButton.className = \"btn btn-outline-secondary\";\n ImproveACRateButton.innerText = \"提高正确率\";\n ImproveACRateButton.disabled = true;\n let ACProblems = [];\n await fetch(\"https://www.xmoj.tech/userinfo.php?user=\" + CurrentUsername)\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n ImproveACRateButton.innerText += \"(\" + (parseInt(ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(4) > td:nth-child(2)\").innerText) / parseInt(ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(3) > td:nth-child(2)\").innerText) * 100).toFixed(2) + \"%)\";\n let Temp = ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script\").innerText.split(\"\\n\")[5].split(\";\");\n for (let i = 0; i < Temp.length; i++) {\n ACProblems.push(Number(Temp[i].substring(2, Temp[i].indexOf(\",\"))));\n }\n ImproveACRateButton.disabled = false;\n });\n ImproveACRateButton.addEventListener(\"click\", async () => {\n ImproveACRateButton.disabled = true;\n let SubmitTimes = 3;\n let Count = 0;\n let SubmitInterval = setInterval(async () => {\n if (Count >= SubmitTimes) {\n clearInterval(SubmitInterval);\n location.reload();\n return;\n }\n ImproveACRateButton.innerText = \"正在提交 (\" + (Count + 1) + \"/\" + SubmitTimes + \")\";\n let PID = ACProblems[Math.floor(Math.random() * ACProblems.length)];\n let SID = 0;\n await fetch(\"https://www.xmoj.tech/status.php?problem_id=\" + PID + \"&jresult=4\")\n .then((Result) => {\n return Result.text();\n }).then((Result) => {\n let ParsedDocument = new DOMParser().parseFromString(Result, \"text/html\");\n SID = ParsedDocument.querySelector(\"#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)\").innerText;\n });\n let Code = \"\";\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SID)\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n Code = Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim();\n });\n await fetch(\"https://www.xmoj.tech/submit.php\", {\n \"headers\": {\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n \"referrer\": \"https://www.xmoj.tech/submitpage.php?id=\" + PID,\n \"method\": \"POST\",\n \"body\": \"id=\" + PID + \"&\" +\n \"language=1&\" +\n \"source=\" + encodeURIComponent(Code) + \"&\" +\n \"enable_O2=on\"\n });\n Count++;\n }, 1000);\n });\n ImproveACRateButton.style.marginBottom = ImproveACRateButton.style.marginRight = \"7px\";\n ImproveACRateButton.style.marginRight = \"7px\";\n }\n if (UtilityEnabled(\"CompareSource\")) {\n let CompareButton = document.createElement(\"button\");\n document.querySelector(\"body > div.container > div > div.input-append\").appendChild(CompareButton);\n CompareButton.className = \"btn btn-outline-secondary\";\n CompareButton.innerText = \"比较提交记录\";\n CompareButton.addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/comparesource.php\";\n });\n CompareButton.style.marginBottom = \"7px\";\n }\n if (UtilityEnabled(\"ResetType\")) {\n document.querySelector(\"#result-tab > thead > tr > th:nth-child(1)\").remove();\n document.querySelector(\"#result-tab > thead > tr > th:nth-child(2)\").remove();\n document.querySelector(\"#result-tab > thead > tr > th:nth-child(10)\").innerHTML = \"开启O2\";\n }\n let Temp = document.querySelector(\"#result-tab > tbody\").childNodes;\n let SolutionIDs = [];\n for (let i = 1; i < Temp.length; i += 2) {\n let SID = Number(Temp[i].childNodes[1].innerText);\n SolutionIDs.push(SID);\n if (UtilityEnabled(\"ResetType\")) {\n Temp[i].childNodes[0].remove();\n Temp[i].childNodes[0].innerHTML = \"<a href=\\\"https://www.xmoj.tech/showsource.php?id=\" + SID + \"\\\">\" + SID + \"</a> \" +\n \"<a href=\\\"\" + Temp[i].childNodes[6].children[1].href + \"\\\">重交</a>\";\n Temp[i].childNodes[1].remove();\n Temp[i].childNodes[1].children[0].removeAttribute(\"class\");\n Temp[i].childNodes[3].childNodes[0].innerText = SizeToStringSize(Temp[i].childNodes[3].childNodes[0].innerText);\n Temp[i].childNodes[4].childNodes[0].innerText = TimeToStringTime(Temp[i].childNodes[4].childNodes[0].innerText);\n Temp[i].childNodes[5].innerText = Temp[i].childNodes[5].childNodes[0].innerText;\n Temp[i].childNodes[6].innerText = SizeToStringSize(Temp[i].childNodes[6].innerText.substring(0, Temp[i].childNodes[6].innerText.length - 1));\n Temp[i].childNodes[9].innerText = (Temp[i].childNodes[9].innerText == \"\" ? \"否\" : \"是\");\n }\n if (SearchParams.get(\"cid\") === null) {\n localStorage.setItem(\"UserScript-Solution-\" + SID + \"-Problem\",\n Temp[i].childNodes[1].innerText);\n }\n else {\n localStorage.setItem(\"UserScript-Solution-\" + SID + \"-Contest\",\n SearchParams.get(\"cid\"));\n localStorage.setItem(\"UserScript-Solution-\" + SID + \"-PID-Contest\",\n Temp[i].childNodes[1].innerText.charAt(0));\n }\n }\n\n if (UtilityEnabled(\"RefreshSolution\")) {\n let StdList;\n await new Promise((Resolve) => {\n RequestAPI(\"GetStdList\", {}, async (Result) => {\n if (Result.Success) {\n StdList = Result.Data.StdList;\n Resolve();\n }\n })\n });\n\n let Rows = document.getElementById(\"result-tab\").rows;\n let Points = Array();\n for (let i = 1; i <= SolutionIDs.length; i++) {\n Rows[i].cells[2].className = \"td_result\";\n let SolutionID = SolutionIDs[i - 1];\n if (Rows[i].cells[2].children.length == 2) {\n Points[SolutionID] = Rows[i].cells[2].children[1].innerText;\n Rows[i].cells[2].children[1].remove();\n }\n Rows[i].cells[2].innerHTML += \"<img style=\\\"margin-left: 10px\\\" height=\\\"18\\\" width=\\\"18\\\" src=\\\"image/loader.gif\\\">\";\n setTimeout(() => {\n RefreshResult(SolutionID);\n }, 0);\n }\n\n let RefreshResult = async (SolutionID) => {\n let CurrentRow = null;\n let Rows = document.getElementById(\"result-tab\").rows;\n for (let i = 0; i < SolutionIDs.length; i++) {\n if (SolutionIDs[i] == SolutionID) {\n CurrentRow = Rows[i + 1];\n break;\n }\n }\n await fetch(\"status-ajax.php?solution_id=\" + SolutionID)\n .then((Response) => {\n return Response.text();\n })\n .then((Response) => {\n let PID = 0;\n if (SearchParams.get(\"cid\") === null) {\n PID = localStorage.getItem(\"UserScript-Solution-\" + SolutionID + \"-Problem\");\n } else {\n PID = localStorage.getItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") + \"-Problem-\" + (CurrentRow.cells[1].innerText.charCodeAt(0) - 65) + \"-PID\");\n }\n let ResponseData = Response.split(\",\");\n CurrentRow.cells[3].innerHTML = \"<div id=\\\"center\\\" class=\\\"red\\\">\" + SizeToStringSize(ResponseData[1]) + \"</div>\";\n CurrentRow.cells[4].innerHTML = \"<div id=\\\"center\\\" class=\\\"red\\\">\" + TimeToStringTime(ResponseData[2]) + \"</div>\";\n let TempHTML = \"<a href=\\\"\" + (ResponseData[0] == 11 ? \"ce\" : \"re\") + \"info.php?sid=\" + SolutionID + \"\\\" class=\\\"\" + judge_color[ResponseData[0]] + \"\\\">\";\n TempHTML += judge_result[ResponseData[0]];\n TempHTML += \"</a>\";\n if (Points[SolutionID] != undefined) {\n TempHTML += \"<span style=\\\"margin-left: 5px\\\" class=\\\"badge text-bg-info\\\">\" + Points[SolutionID] + \"</span>\";\n if (Points[SolutionID].substring(0, Points[SolutionID].length - 1) >= 50) {\n TempHTML += `<a href=\"https://www.xmoj.tech/showsource.php?pid=${PID}&ByUserScript=1\" class=\"ms-1 link-secondary\">查看标程</a>`;\n }\n }\n if (ResponseData[0] < 4) {\n setTimeout(() => {\n RefreshResult(SolutionID)\n }, 500);\n TempHTML += \"<img style=\\\"margin-left: 5px\\\" height=\\\"18\\\" width=\\\"18\\\" src=\\\"image/loader.gif\\\">\";\n }\n else if (ResponseData[0] == 4 && UtilityEnabled(\"UploadStd\")) {\n if (SearchParams.get(\"cid\") == null)\n CurrentRow.cells[1].innerText;\n let Std = StdList.find((Element) => {\n return Element == Number(PID);\n });\n if (Std != undefined) {\n TempHTML += \"✅\";\n }\n else {\n RequestAPI(\"UploadStd\", {\n \"ProblemID\": Number(PID),\n }, (Result) => {\n if (Result.Success) {\n CurrentRow.cells[2].innerHTML += \"\uD83C\uDD97\";\n }\n else {\n CurrentRow.cells[2].innerHTML += \"⚠\uFE0F\";\n }\n });\n }\n }\n CurrentRow.cells[2].innerHTML = TempHTML;\n });\n };\n }\n }\n } else if (location.pathname == \"/contest.php\") {\n if (UtilityEnabled(\"AutoCountdown\")) {\n clock = () => { }\n }\n if (location.href.indexOf(\"?cid=\") == -1) {\n if (UtilityEnabled(\"ResetType\")) {\n document.querySelector(\"body > div > div.mt-3 > center\").innerHTML =\n String(document.querySelector(\"body > div > div.mt-3 > center\").innerHTML).replaceAll(\"ServerTime:\", \"服务器时间:\");\n document.querySelector(\"body > div > div.mt-3 > center > table\").style.marginTop = \"10px\";\n\n document.querySelector(\"body > div > div.mt-3 > center > form\").outerHTML = `<div class=\"row\">\n <div class=\"col-md-4\"></div>\n <form method=\"post\" action=\"contest.php\" class=\"col-md-4\">\n <div class=\"input-group\">\n <input name=\"keyword\" type=\"text\" class=\"form-control\" spellcheck=\"false\" data-ms-editor=\"true\">\n <input type=\"submit\" value=\"搜索\" class=\"btn btn-outline-secondary\">\n </div>\n </form>\n </div>`;\n }\n if (UtilityEnabled(\"Translate\")) {\n document.querySelector(\"body > div > div.mt-3 > center > table > thead > tr\").childNodes[0].innerText = \"编号\";\n document.querySelector(\"body > div > div.mt-3 > center > table > thead > tr\").childNodes[1].innerText = \"标题\";\n document.querySelector(\"body > div > div.mt-3 > center > table > thead > tr\").childNodes[2].innerText = \"状态\";\n document.querySelector(\"body > div > div.mt-3 > center > table > thead > tr\").childNodes[3].remove();\n document.querySelector(\"body > div > div.mt-3 > center > table > thead > tr\").childNodes[3].innerText = \"创建者\";\n }\n let Temp = document.querySelector(\"body > div > div.mt-3 > center > table > tbody\").childNodes;\n for (let i = 1; i < Temp.length; i++) {\n let CurrentElement = Temp[i].childNodes[2].childNodes;\n if (CurrentElement[1].childNodes[0].data.indexOf(\"运行中\") != -1) {\n let Time = String(CurrentElement[1].childNodes[1].innerText).substring(4);\n let Day = parseInt(Time.substring(0, Time.indexOf(\"天\"))) || 0;\n let Hour = parseInt(Time.substring((Time.indexOf(\"天\") == -1 ? 0 : Time.indexOf(\"天\") + 1), Time.indexOf(\"小时\"))) || 0;\n let Minute = parseInt(Time.substring((Time.indexOf(\"小时\") == -1 ? 0 : Time.indexOf(\"小时\") + 2), Time.indexOf(\"分\"))) || 0;\n let Second = parseInt(Time.substring((Time.indexOf(\"分\") == -1 ? 0 : Time.indexOf(\"分\") + 1), Time.indexOf(\"秒\"))) || 0;\n let TimeStamp = new Date().getTime() + diff + ((((isNaN(Day) ? 0 : Day) * 24 + Hour) * 60 + Minute) * 60 + Second) * 1000;\n CurrentElement[1].childNodes[1].setAttribute(\"EndTime\", TimeStamp);\n CurrentElement[1].childNodes[1].classList.add(\"UpdateByJS\");\n } else if (CurrentElement[1].childNodes[0].data.indexOf(\"开始于\") != -1) {\n let TimeStamp = Date.parse(String(CurrentElement[1].childNodes[0].data).substring(4)) + diff;\n CurrentElement[1].setAttribute(\"EndTime\", TimeStamp);\n CurrentElement[1].classList.add(\"UpdateByJS\");\n } else if (CurrentElement[1].childNodes[0].data.indexOf(\"已结束\") != -1) {\n let TimeStamp = String(CurrentElement[1].childNodes[0].data).substring(4);\n CurrentElement[1].childNodes[0].data = \" 已结束 \";\n CurrentElement[1].className = \"red\";\n let Temp = document.createElement(\"span\");\n CurrentElement[1].appendChild(Temp);\n Temp.className = \"green\";\n Temp.innerHTML = TimeStamp;\n }\n Temp[i].childNodes[3].style.display = \"none\";\n Temp[i].childNodes[4].innerHTML = \"<a href=\\\"https://www.xmoj.tech/userinfo.php?user=\" + Temp[i].childNodes[4].innerHTML + \"\\\">\" + Temp[i].childNodes[4].innerHTML + \"</a>\";\n localStorage.setItem(\"UserScript-Contest-\" + Temp[i].childNodes[0].innerText + \"-Name\", Temp[i].childNodes[1].innerText);\n }\n } else {\n document.getElementsByTagName(\"h3\")[0].innerHTML =\n \"比赛\" + document.getElementsByTagName(\"h3\")[0].innerHTML.substring(7);\n if (document.querySelector(\"#time_left\") != null) {\n let EndTime = document.querySelector(\"body > div > div.mt-3 > center\").childNodes[3].data;\n EndTime = EndTime.substring(EndTime.indexOf(\"结束时间是:\") + 6, EndTime.lastIndexOf(\"。\"));\n EndTime = new Date(EndTime).getTime();\n if (new Date().getTime() < EndTime) {\n document.querySelector(\"#time_left\").classList.add(\"UpdateByJS\");\n document.querySelector(\"#time_left\").setAttribute(\"EndTime\", EndTime);\n }\n }\n let HTMLData = document.querySelector(\"body > div > div.mt-3 > center > div\").innerHTML;\n HTMLData = HTMLData.replaceAll(\"&nbsp;&nbsp;\\n&nbsp;&nbsp;\", \"&nbsp;\")\n HTMLData = HTMLData.replaceAll(\"<br>开始于: \", \"开始时间:\")\n HTMLData = HTMLData.replaceAll(\"\\n结束于: \", \"<br>结束时间:\")\n HTMLData = HTMLData.replaceAll(\"\\n订正截止日期: \", \"<br>订正截止日期:\")\n HTMLData = HTMLData.replaceAll(\"\\n现在时间: \", \"当前时间:\")\n HTMLData = HTMLData.replaceAll(\"\\n状态:\", \"<br>状态:\")\n document.querySelector(\"body > div > div.mt-3 > center > div\").innerHTML = HTMLData;\n if (UtilityEnabled(\"RemoveAlerts\") && document.querySelector(\"body > div > div.mt-3 > center\").innerHTML.indexOf(\"尚未开始比赛\") != -1) {\n document.querySelector(\"body > div > div.mt-3 > center > a\").setAttribute(\"href\",\n \"start_contest.php?cid=\" + SearchParams.get(\"cid\"));\n }\n else if (UtilityEnabled(\"AutoRefresh\")) {\n addEventListener(\"focus\", async () => {\n await fetch(location.href)\n .then((Response) => {\n return Response.text();\n })\n .then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let Temp = ParsedDocument.querySelector(\"#problemset > tbody\").children;\n if (UtilityEnabled(\"ReplaceYN\")) {\n for (let i = 0; i < Temp.length; i++) {\n let Status = Temp[i].children[0].innerText;\n if (Status.indexOf(\"Y\") != -1) {\n document.querySelector(\"#problemset > tbody\").children[i].children[0].children[0].className = \"status status_y\";\n document.querySelector(\"#problemset > tbody\").children[i].children[0].children[0].innerText = \"✓\";\n }\n else if (Status.indexOf(\"N\") != -1) {\n document.querySelector(\"#problemset > tbody\").children[i].children[0].children[0].className = \"status status_n\";\n document.querySelector(\"#problemset > tbody\").children[i].children[0].children[0].innerText = \"✗\";\n }\n }\n }\n });\n });\n document.querySelector(\"body > div > div.mt-3 > center > br:nth-child(2)\").remove();\n document.querySelector(\"body > div > div.mt-3 > center > br:nth-child(2)\").remove();\n document.querySelector(\"body > div > div.mt-3 > center > div > .red\").innerHTML =\n String(document.querySelector(\"body > div > div.mt-3 > center > div > .red\").innerHTML).replaceAll(\"<br>\", \"<br><br>\");\n let StaticButton = document.createElement(\"button\");\n document.querySelectorAll(\"body > div > div.mt-3 > center > div > .red\")[1].appendChild(StaticButton);\n StaticButton.className = \"btn btn-outline-secondary\";\n StaticButton.innerText = \"统计\";\n StaticButton.addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/conteststatistics.php?cid=\" + SearchParams.get(\"cid\");\n });\n\n document.querySelector(\"#problemset > tbody\").innerHTML =\n String(document.querySelector(\"#problemset > tbody\").innerHTML).replaceAll(\n /\\t&nbsp;([0-9]*) &nbsp;&nbsp;&nbsp;&nbsp; 问题 &nbsp;([^<]*)/g,\n \"$2. $1\");\n\n document.querySelector(\"#problemset > tbody\").innerHTML =\n String(document.querySelector(\"#problemset > tbody\").innerHTML).replaceAll(\n /\\t\\*([0-9]*) &nbsp;&nbsp;&nbsp;&nbsp; 问题 &nbsp;([^<]*)/g,\n \"拓展$2. $1\");\n\n if (UtilityEnabled(\"MoreSTD\") && document.querySelector(\"#problemset > thead > tr\").innerHTML.indexOf(\"标程\") != -1) {\n let Temp = document.querySelector(\"#problemset > thead > tr\").children;\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].innerText == \"标程\") {\n Temp[i].remove();\n let Temp2 = document.querySelector(\"#problemset > tbody\").children;\n for (let j = 0; j < Temp2.length; j++) {\n if (Temp2[j].children[i] != undefined) {\n Temp2[j].children[i].remove();\n }\n }\n }\n }\n document.querySelector(\"#problemset > thead > tr\").innerHTML += \"<td width=\\\"5%\\\">标程</td>\";\n Temp = document.querySelector(\"#problemset > tbody\").children;\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].innerHTML += \"<td><a href=\\\"https://www.xmoj.tech/problem_std.php?cid=\" + Number(SearchParams.get(\"cid\")) + \"&pid=\" + i + \"\\\" target=\\\"_blank\\\">打开</a></td>\";\n }\n }\n\n Temp = document.querySelector(\"#problemset > tbody\").rows;\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].childNodes[0].children.length == 0) {\n Temp[i].childNodes[0].innerHTML = \"<div class=\\\"status\\\"></div>\";\n }\n let PID = Temp[i].childNodes[1].innerHTML;\n if (PID.substring(0, 2) == \"拓展\") {\n PID = PID.substring(2);\n }\n Temp[i].children[2].children[0].target = \"_blank\";\n localStorage.setItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") + \"-Problem-\" + i + \"-PID\",\n PID.substring(3));\n localStorage.setItem(\"UserScript-Problem-\" + PID.substring(3) + \"-Name\",\n Temp[i].childNodes[2].innerText);\n }\n let CheatDiv = document.createElement(\"div\");\n CheatDiv.style.marginTop = \"20px\";\n CheatDiv.style.textAlign = \"left\";\n document.querySelector(\"body > div > div.mt-3 > center\").insertBefore(CheatDiv, document.querySelector(\"#problemset\"));\n if (UtilityEnabled(\"AutoCheat\")) {\n let AutoCheatButton = document.createElement(\"button\");\n CheatDiv.appendChild(AutoCheatButton);\n AutoCheatButton.className = \"btn btn-outline-secondary\";\n AutoCheatButton.innerText = \"自动提交当年代码\";\n AutoCheatButton.style.marginRight = \"5px\";\n AutoCheatButton.disabled = true;\n let ACProblems = [], ContestProblems = [];\n const UrlParams = new URLSearchParams(window.location.search);\n const CID = UrlParams.get(\"cid\");\n await fetch(\"https://www.xmoj.tech/userinfo.php?user=\" + CurrentUsername)\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let Temp = ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script\").innerText.split(\"\\n\")[5].split(\";\");\n for (let i = 0; i < Temp.length; i++) {\n ACProblems.push(Number(Temp[i].substring(2, Temp[i].indexOf(\",\"))));\n }\n AutoCheatButton.disabled = false;\n });\n let Rows = document.querySelector(\"#problemset > tbody\").rows;\n for (let i = 0; i < Rows.length; i++) {\n ContestProblems.push(Rows[i].children[1].innerText.substring(Rows[i].children[1].innerText.indexOf('.') + 2)).toFixed;\n }\n AutoCheatButton.addEventListener(\"click\", async () => {\n AutoCheatButton.disabled = true;\n let Submitted = false;\n for (let i = 0; i < ContestProblems.length; i++) {\n let PID = ContestProblems[i];\n if (ACProblems.indexOf(Number(PID)) == -1) {\n console.log(\"Ignoring problem \" + PID + \" as it has not been solved yet.\");\n continue;\n }\n if (Rows[i].children[0].children[0].classList.contains(\"status_y\")) {\n console.log(\"Ignoring problem \" + PID + \" as it has already been solved in this contest.\");\n continue;\n }\n console.log(\"Submitting problem \" + PID);\n Submitted = true;\n AutoCheatButton.innerHTML = \"正在提交 \" + PID;\n let SID = 0;\n await fetch(\"https://www.xmoj.tech/status.php?problem_id=\" + PID + \"&jresult=4\")\n .then((Result) => {\n return Result.text();\n }).then((Result) => {\n let ParsedDocument = new DOMParser().parseFromString(Result, \"text/html\");\n SID = ParsedDocument.querySelector(\"#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)\").innerText;\n });\n let Code = \"\";\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SID)\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n Code = Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim();\n });\n await fetch(\"https://www.xmoj.tech/submit.php\", {\n \"headers\": {\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n \"referrer\": \"https://www.xmoj.tech/submitpage.php?id=\" + PID,\n \"method\": \"POST\",\n \"body\": \"cid=\" + CID + \"&pid=\" + i + \"&\" +\n \"language=1&\" +\n \"source=\" + encodeURIComponent(Code) + \"&\" +\n \"enable_O2=on\"\n });\n }\n if (!Submitted) {\n AutoCheatButton.innerHTML = \"没有可以提交的题目!\";\n await new Promise(r => setTimeout(r, 1000));\n }\n AutoCheatButton.disabled = false;\n if (Submitted) location.reload();\n else AutoCheatButton.innerHTML = \"自动提交当年代码\";\n });\n }\n\n if (UtilityEnabled(\"OpenAllProblem\")) {\n let OpenAllButton = document.createElement(\"button\");\n OpenAllButton.className = \"btn btn-outline-secondary\";\n OpenAllButton.innerText = \"打开全部题目\";\n OpenAllButton.style.marginRight = \"5px\";\n CheatDiv.appendChild(OpenAllButton);\n OpenAllButton.addEventListener(\"click\", () => {\n let Rows = document.querySelector(\"#problemset > tbody\").rows;\n for (let i = 0; i < Rows.length; i++) {\n open(Rows[i].children[2].children[0].href, \"_blank\");\n }\n });\n let OpenUnsolvedButton = document.createElement(\"button\");\n OpenUnsolvedButton.className = \"btn btn-outline-secondary\";\n OpenUnsolvedButton.innerText = \"打开未解决题目\";\n CheatDiv.appendChild(OpenUnsolvedButton);\n OpenUnsolvedButton.addEventListener(\"click\", () => {\n let Rows = document.querySelector(\"#problemset > tbody\").rows;\n for (let i = 0; i < Rows.length; i++) {\n if (!Rows[i].children[0].children[0].classList.contains(\"status_y\")) {\n open(Rows[i].children[2].children[0].href, \"_blank\");\n }\n }\n });\n }\n\n if (UtilityEnabled(\"ResetType\")) {\n document.querySelector(\"#problemset > thead > tr > th:nth-child(1)\").style.width = \"5%\";\n }\n localStorage.setItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") + \"-ProblemCount\",\n document.querySelector(\"#problemset > tbody\").rows.length);\n }\n }\n } else if (location.pathname == \"/contestrank-oi.php\") {\n if (document.querySelector(\"#rank\") == null) {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"<center><h3>比赛排名</h3><a></a><table id=\\\"rank\\\"></table>\";\n }\n if (SearchParams.get(\"ByUserScript\") == null) {\n if (document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText == \"比赛排名\") {\n document.querySelector(\"#rank\").innerText = \"比赛暂时还没有排名\";\n }\n else {\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText =\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.substring(\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.indexOf(\" -- \") + 4)\n + \"(OI排名)\";\n document.querySelector(\"#rank > thead > tr > :nth-child(1)\").innerText = \"排名\";\n document.querySelector(\"#rank > thead > tr > :nth-child(2)\").innerText = \"用户\";\n document.querySelector(\"#rank > thead > tr > :nth-child(3)\").innerText = \"昵称\";\n document.querySelector(\"#rank > thead > tr > :nth-child(4)\").innerText = \"AC数\";\n document.querySelector(\"#rank > thead > tr > :nth-child(5)\").innerText = \"得分\";\n let RefreshOIRank = async () => {\n await fetch(location.href)\n .then((Response) => {\n return Response.text()\n })\n .then(async (Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n TidyTable(ParsedDocument.getElementById(\"rank\"));\n let Temp = ParsedDocument.getElementById(\"rank\").rows;\n for (var i = 1; i < Temp.length; i++) {\n let MetalCell = Temp[i].cells[0];\n let Metal = document.createElement(\"span\");\n Metal.innerText = MetalCell.innerText;\n Metal.className = \"badge text-bg-primary\";\n MetalCell.innerText = \"\";\n MetalCell.appendChild(Metal);\n GetUsernameHTML(Temp[i].cells[1], Temp[i].cells[1].innerText);\n Temp[i].cells[2].innerHTML = Temp[i].cells[2].innerText;\n Temp[i].cells[3].innerHTML = Temp[i].cells[3].innerText;\n for (let j = 5; j < Temp[i].cells.length; j++) {\n let InnerText = Temp[i].cells[j].innerText;\n let BackgroundColor = Temp[i].cells[j].style.backgroundColor;\n let Red = BackgroundColor.substring(4, BackgroundColor.indexOf(\",\"));\n let Green = BackgroundColor.substring(BackgroundColor.indexOf(\",\") + 2, BackgroundColor.lastIndexOf(\",\"));\n let Blue = BackgroundColor.substring(BackgroundColor.lastIndexOf(\",\") + 2, BackgroundColor.lastIndexOf(\")\"));\n let NoData = (Red == 238 && Green == 238 && Blue == 238);\n let FirstBlood = (Red == 170 && Green == 170 && Blue == 255);\n let Solved = (Green == 255);\n let ErrorCount = \"\";\n if (Solved) {\n ErrorCount = (Blue == 170 ? 5 : (Blue - 51) / 32);\n }\n else {\n ErrorCount = (Blue == 22 ? 15 : (170 - Blue) / 10);\n }\n if (NoData) {\n BackgroundColor = \"\";\n }\n else if (FirstBlood) {\n BackgroundColor = \"rgb(127, 127, 255)\";\n }\n else if (Solved) {\n BackgroundColor = \"rgb(0, 255, 0, \" + Math.max(1 / 10 * (10 - ErrorCount), 0.2) + \")\";\n if (ErrorCount != 0) {\n InnerText += \" (\" + (ErrorCount == 5 ? \"4+\" : ErrorCount) + \")\";\n }\n }\n else {\n BackgroundColor = \"rgba(255, 0, 0, \" + Math.min(ErrorCount / 10 + 0.2, 1) + \")\";\n if (ErrorCount != 0) {\n InnerText += \" (\" + (ErrorCount == 15 ? \"14+\" : ErrorCount) + \")\";\n }\n }\n Temp[i].cells[j].innerHTML = InnerText;\n Temp[i].cells[j].style.backgroundColor = BackgroundColor;\n Temp[i].cells[j].style.color = (UtilityEnabled(\"DarkMode\") ? \"white\" : \"black\");\n }\n }\n document.querySelector(\"#rank > tbody\").innerHTML = ParsedDocument.querySelector(\"#rank > tbody\").innerHTML;\n });\n };\n RefreshOIRank();\n if (UtilityEnabled(\"AutoRefresh\")) {\n addEventListener(\"focus\", RefreshOIRank);\n }\n }\n }\n else if (UtilityEnabled(\"ACMRank\")) {\n if (document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText != \"比赛排名\") {\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText =\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.substring(\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.indexOf(\" -- \") + 4)\n + \"(ACM排名)\";\n }\n let RankData = [];\n let RefreshACMRank = async (ProblemCount) => {\n let LastPositionX = scrollX;\n let LastPositionY = scrollY;\n let NewURL = new URL(location.href);\n NewURL.pathname = \"/contestrank2.php\";\n await fetch(NewURL.toString())\n .then((Response) => {\n return Response.text()\n })\n .then(async (Response) => {\n RankData = [];\n\n let Table = document.querySelector(\"#rank\"); Table.innerHTML = \"\";\n let StartPosition = Response.indexOf(\"var solutions=\") + 14;\n let EndPosition = Response.indexOf(\"}];\", StartPosition) + 2;\n if (EndPosition == 1) {\n Table.innerHTML = \"暂时还没有人提交呢\";\n }\n else {\n let SubmitRecord = JSON.parse(Response.substring(StartPosition, EndPosition));\n\n for (let i = 0; i < SubmitRecord.length; i++) {\n let CurrentSubmission = SubmitRecord[i];\n let CurrentRow = RankData.find((CurrentRow) => {\n if (CurrentRow.Username == CurrentSubmission.user_id) {\n return true;\n }\n });\n if (CurrentRow == null) {\n CurrentRow = {\n Username: CurrentSubmission.user_id,\n Nickname: CurrentSubmission.nick,\n Solved: 0,\n Penalty: 0,\n Problem: [],\n QuickSubmitCount: 0\n };\n RankData.push(CurrentRow);\n }\n let CurrentProblem = CurrentRow.Problem.find((CurrentRow) => {\n if (CurrentRow.Index == CurrentSubmission.num) {\n return true;\n }\n });\n if (CurrentProblem == null) {\n CurrentProblem = {\n Index: CurrentSubmission.num,\n Attempts: [],\n SolveTime: 0\n };\n CurrentRow.Problem.push(CurrentProblem);\n }\n if (CurrentSubmission.result == 4 && CurrentProblem.SolveTime == 0) {\n CurrentProblem.SolveTime = parseInt(CurrentSubmission.in_date);\n CurrentRow.Solved++;\n CurrentRow.Penalty += parseInt(CurrentSubmission.in_date) + CurrentProblem.Attempts.length * 20 * 60;\n }\n CurrentProblem.Attempts.push({\n Time: CurrentSubmission.in_date,\n Result: CurrentSubmission.result\n });\n }\n\n for (let i = 0; i < RankData.length; i++) {\n for (let j = 0; j < RankData[i].Problem.length; j++) {\n for (let k = 0; k < RankData[i].Problem.length; k++) {\n if (j != k && RankData[i].Problem[j].SolveTime != 0 && RankData[i].Problem[k].SolveTime != 0 &&\n Math.abs(RankData[i].Problem[j].SolveTime - RankData[i].Problem[k].SolveTime) < 60) {\n RankData[i].QuickSubmitCount++;\n }\n }\n }\n }\n\n RankData.sort((a, b) => {\n if (a.Solved != b.Solved) {\n return a.Solved < b.Solved ? 1 : -1;\n } else if (a.Penalty != b.Penalty) {\n return a.Penalty > b.Penalty ? 1 : -1;\n }\n return 0;\n });\n\n let Header = document.createElement(\"thead\"); Table.appendChild(Header);\n let RowHeader = document.createElement(\"tr\"); Header.appendChild(RowHeader);\n let MetalHeader = document.createElement(\"th\"); RowHeader.appendChild(MetalHeader); MetalHeader.innerText = \"排名\"; MetalHeader.style.width = \"5%\";\n let UsernameHeader = document.createElement(\"th\"); RowHeader.appendChild(UsernameHeader); UsernameHeader.innerText = \"用户\"; UsernameHeader.style.width = \"10%\";\n let NicknameHeader = document.createElement(\"th\"); RowHeader.appendChild(NicknameHeader); NicknameHeader.innerText = \"昵称\"; NicknameHeader.style.width = \"10%\";\n let NameHeader = document.createElement(\"th\"); RowHeader.appendChild(NameHeader); NameHeader.innerText = \"姓名\"; NameHeader.style.width = \"5%\";\n let SolvedHeader = document.createElement(\"th\"); RowHeader.appendChild(SolvedHeader); SolvedHeader.innerText = \"AC数\"; SolvedHeader.style.width = \"5%\";\n let PenaltyHeader = document.createElement(\"th\"); RowHeader.appendChild(PenaltyHeader); PenaltyHeader.innerText = \"罚时\"; PenaltyHeader.style.width = \"10%\";\n\n for (let i = 0; i < ProblemCount; i++) {\n let ProblemHeader = document.createElement(\"th\"); RowHeader.appendChild(ProblemHeader);\n let ProblemLink = document.createElement(\"a\"); ProblemHeader.appendChild(ProblemLink);\n ProblemLink.href = \"problem.php?cid=\" + SearchParams.get(\"cid\") + \"&pid=\" + i; ProblemLink.innerText = String.fromCharCode(65 + i);\n ProblemHeader.classList.add(\"header\"); ProblemHeader.style.width = (50 / ProblemCount) + \"%\";\n }\n\n let Body = document.createElement(\"tbody\"); Table.appendChild(Body);\n Body.className = \"table-group-divider\";\n for (let i = 0; i < RankData.length; i++) {\n let RowData = RankData[i];\n let Row = document.createElement(\"tr\"); Body.appendChild(Row);\n let MetalCell = document.createElement(\"td\"); Row.appendChild(MetalCell);\n let UsernameCell = document.createElement(\"td\"); Row.appendChild(UsernameCell);\n let NicknameCell = document.createElement(\"td\"); Row.appendChild(NicknameCell);\n let NameCell = document.createElement(\"td\"); Row.appendChild(NameCell);\n let SolvedCell = document.createElement(\"td\"); Row.appendChild(SolvedCell);\n let PenaltyCell = document.createElement(\"td\"); Row.appendChild(PenaltyCell);\n\n let Medal = document.createElement(\"span\"); MetalCell.appendChild(Medal);\n Medal.innerText = i + 1;\n Medal.classList.add(\"badge\");\n if (i <= RankData.length * 0.05) {\n Medal.classList.add(\"text-bg-danger\");\n }\n else if (i <= RankData.length * 0.15) {\n Medal.classList.add(\"text-bg-warning\");\n }\n else if (i <= RankData.length * 0.4) {\n Medal.classList.add(\"text-bg-primary\");\n }\n else {\n Medal.classList.add(\"text-bg-secondary\");\n }\n\n let UsernameSpan = document.createElement(\"span\"); UsernameCell.appendChild(UsernameSpan);\n GetUsernameHTML(UsernameSpan, RowData.Username);\n if (RowData.Username == CurrentUsername) {\n Row.classList.add(\"table-primary\");\n }\n if (RowData.QuickSubmitCount >= 2) {\n let QuickSubmitBadge = document.createElement(\"span\"); UsernameCell.appendChild(QuickSubmitBadge);\n QuickSubmitBadge.innerText = \"作弊者\";\n QuickSubmitBadge.className = \"badge text-bg-warning ms-2\";\n }\n\n NicknameCell.innerText = (RowData.Nickname.length < 16 ? RowData.Nickname : RowData.Nickname.substring(0, 15) + \"...\");\n\n let Names = {\n \"huangkai\": \"黄开\", \"chenlangning\": \"陈朗宁\", \"chensiru\": \"陈斯如\", \"chentianle\": \"陈天乐\", \"chenxuanhe\": \"陈宣合\", \"chenzecong\": \"陈泽聪\", \"chenzerui\": \"陈泽睿\", \"danwenxiao\": \"单文骁\", \"dongminghui\": \"董明辉\", \"gaochenming\": \"高晨茗\", \"guoqingtong\": \"郭庆桐\", \"guoruiqun\": \"郭睿群\", \"guyuchen\": \"顾毓辰\",\n \"hanshujian\": \"韩书简\", \"heshuhan\": \"贺书瀚\", \"hexinyi\": \"何昕弈\", \"huangmingxuan\": \"黄铭宣\", \"huangruina\": \"黄睿纳\", \"huangwei\": \"黄唯\", \"huyiyang\": \"胡以杨\", \"jiangxingyu\": \"姜星宇\", \"jingtaiyu\": \"荆泰宇\", \"jinweizhe\": \"金炜喆\", \"leijiahan\": \"雷家涵\",\n \"lianzhongzhe\": \"连中哲\", \"liaoyanxu\": \"廖彦旭\", \"lingzixiang\": \"凌梓翔\", \"linziyi\": \"林子懿\", \"liujianhao\": \"刘健豪\", \"liujiankun\": \"刘健坤\", \"liuxianyong\": \"刘先勇\", \"liuxixian\": \"刘希贤\", \"liyihan\": \"李亦涵\", \"luojinyang\": \"罗金阳\", \"lutianfeng\": \"陆天枫\",\n \"meitianyi\": \"梅天一\", \"panyinliang\": \"潘胤良\", \"pengyixuan\": \"彭议萱\", \"putong\": \"蒲通\", \"qianqingyuan\": \"钱清源\", \"qidekai\": \"戚得凯\", \"shanwenxiao\": \"单文骁\", \"shenxichen\": \"沈熙晨\", \"shihongxi\": \"施泓熙\", \"shimufan\": \"施慕梵\", \"shiyichen\": \"施奕辰\",\n \"shiyunhao\": \"施云浩\", \"shuxinmo\": \"舒馨墨\", \"suiruochen\": \"隋若宸\", \"sunyihan\": \"孙艺涵\", \"sunyimiao\": \"孙义淼\", \"tangchao\": \"唐潮\", \"tangyuhan\": \"唐钰涵\", \"tanhaoxuan\": \"谭皓轩\", \"taoxianyu\": \"陶羡榆\", \"wangkangming\": \"王康明\", \"wangminghao\": \"王明浩\",\n \"wangmingshuo\": \"王茗铄\", \"wangpengyu\": \"王芃雨\", \"wangsiyuan3\": \"王思源\", \"wangtianqi\": \"王天琦\", \"wangzetong\": \"王泽通\", \"wanxinlian\": \"万馨联\", \"wensiyi\": \"闻思奕\", \"wujinhong\": \"吴锦鸿\", \"wurunze\": \"吴润泽\", \"wuyukai\": \"巫昱恺\", \"xiangjicheng\": \"项际诚\",\n \"xiaoguanxun\": \"肖贯勋\", \"xiaojiasheng\": \"肖嘉盛\", \"xiaruicheng\": \"夏瑞成\", \"xiaweimin\": \"夏蔚民\", \"xiaxuran\": \"夏诩然\", \"xiebingxiu\": \"谢秉修\", \"xiebingxiu\": \"谢秉修\", \"xieliren\": \"谢立仁\", \"xinyihan\": \"辛轶涵\", \"xuconghan\": \"徐从瀚\", \"xukan\": \"徐衎\",\n \"xuweiyi\": \"徐维易\", \"yanghaochen\": \"杨皓宸\", \"yezijiong\": \"叶梓炅\", \"youzhouhang\": \"尤周杭\", \"yuanruiqing\": \"袁瑞擎\", \"yutingjun\": \"于庭郡\", \"zhangchenming\": \"张宸铭\", \"zhangqiuze\": \"张秋泽\", \"zhangshuxuan\": \"张澍萱\", \"zhangwenda\": \"张闻达\", \"zhangyifu\": \"张亦夫\",\n \"zhangyouheng\": \"张佑恒\", \"zhaochenshen\": \"赵晨神\", \"zhaochenwei\": \"赵晨伟\", \"zhengyinan\": \"郑逸楠\", \"zhonghongyi\": \"钟弘毅\", \"zhoujunyu\": \"周峻瑜\", \"zhouziyi\": \"周子逸\", \"zhouziyou\": \"周子游\", \"zhuchenrui2\": \"朱晨瑞\", \"zhuruichen\": \"朱睿宸\", \"zhuxule\": \"朱徐乐\",\n \"zhuyikun\": \"朱奕坤\", \"leiwenda\": \"雷文达\", \"wangyuancheng\": \"王源成\", \"zhuyiyang\": \"朱奕阳\", \"hanjialin\": \"韩佳霖\", \"zhaozichen\": \"赵紫辰\", \"zhuaiwei\": \"朱艾薇\", \"linlitong\": \"林立桐\", \"xuyan\": \"徐衍\", \"fenghaochen\": \"冯皓宸\", \"lutianlang\": \"陆天朗\", \"tangyuhan\": \"唐钰涵\",\n \"jiangbowen\": \"姜博文\", \"shangguanbocheng\": \"上官伯呈\", \"wangchengqi\": \"王呈齐\", \"yanpeitong\": \"颜培桐\", \"gongcheng\": \"龚橙\", \"weijiefu\": \"韦杰夫\", \"\": \"\"\n };\n NameCell.innerText = (Names[RowData.Username] == undefined ? \"\" : Names[RowData.Username]);\n\n SolvedCell.innerText = RowData.Solved;\n\n PenaltyCell.innerText = SecondsToString(RowData.Penalty);\n\n for (let j = 0; j < ProblemCount; j++) {\n let Problem = document.createElement(\"td\"); Row.appendChild(Problem);\n let ProblemData = RowData.Problem.find((CurrentRow) => {\n if (CurrentRow.Index == j) {\n return true;\n }\n });\n if (ProblemData == undefined) {\n Problem.style.backgroundColor = \"rgba(0, 0, 0, 0)\";\n }\n else if (ProblemData.SolveTime != 0) {\n Problem.innerText = SecondsToString(ProblemData.SolveTime) + \"(\" + ProblemData.Attempts.length + \")\";\n let Color = Math.max(1 / 10 * (10 - ProblemData.Attempts.length), 0.2);\n Problem.style.backgroundColor = \"rgba(0, 255, 0, \" + Color + \")\";\n }\n else {\n Problem.innerText = \"(\" + ProblemData.Attempts.length + \")\";\n let Color = Math.min(ProblemData.Attempts.length / 10 + 0.2, 1);\n Problem.style.backgroundColor = \"rgba(255, 0, 0, \" + Color + \")\";\n }\n Problem.style.color = (UtilityEnabled(\"DarkMode\") ? \"white\" : \"black\");\n }\n }\n\n TidyTable(Table);\n\n scrollTo({\n left: LastPositionX,\n top: LastPositionY,\n behavior: \"instant\"\n });\n }\n });\n }\n document.getElementById(\"rank\").style.width = \"100%\";\n let DownloadButton = document.createElement(\"button\");\n document.querySelector(\"body > div.container > div > center\").insertBefore(DownloadButton, document.querySelector(\"body > div.container > div > center > a\"));\n DownloadButton.className = \"btn btn-outline-secondary\";\n DownloadButton.innerText = \"下载ACM排名\";\n DownloadButton.style.marginBottom = \"20px\";\n DownloadButton.addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/contestrank.xls.php?cid=\" + SearchParams.get(\"cid\");\n });\n let ProblemCount = localStorage.getItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") + \"-ProblemCount\");\n RefreshACMRank(ProblemCount);\n if (UtilityEnabled(\"AutoRefresh\")) {\n addEventListener(\"focus\", () => {\n RefreshACMRank(ProblemCount);\n });\n }\n }\n Style.innerHTML += \"td {\";\n Style.innerHTML += \" white-space: nowrap;\";\n Style.innerHTML += \"}\";\n document.querySelector(\"body > div.container > div > center\").style.paddingBottom = \"10px\";\n document.querySelector(\"body > div.container > div > center > a\").style.display = \"none\";\n } else if (location.pathname == \"/contestrank-correct.php\") {\n if (document.querySelector(\"#rank\") == null) {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"<center><h3>比赛排名</h3><a></a><table id=\\\"rank\\\"></table>\";\n }\n if (document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText == \"比赛排名\") {\n document.querySelector(\"#rank\").innerText = \"比赛暂时还没有排名\";\n }\n else {\n if (UtilityEnabled(\"ResetType\")) {\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText =\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.substring(\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText.indexOf(\" -- \") + 4)\n + \"(订正排名)\";\n document.querySelector(\"body > div > div.mt-3 > center > a\").remove();\n }\n document.querySelector(\"#rank > thead > tr > :nth-child(1)\").innerText = \"排名\";\n document.querySelector(\"#rank > thead > tr > :nth-child(2)\").innerText = \"用户\";\n document.querySelector(\"#rank > thead > tr > :nth-child(3)\").innerText = \"昵称\";\n document.querySelector(\"#rank > thead > tr > :nth-child(4)\").innerText = \"AC数\";\n document.querySelector(\"#rank > thead > tr > :nth-child(5)\").innerText = \"得分\";\n let RefreshCorrectRank = async () => {\n await fetch(location.href)\n .then((Response) => {\n return Response.text()\n })\n .then(async (Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n TidyTable(ParsedDocument.getElementById(\"rank\"));\n let Temp = ParsedDocument.getElementById(\"rank\").rows;\n for (var i = 1; i < Temp.length; i++) {\n let MetalCell = Temp[i].cells[0];\n let Metal = document.createElement(\"span\");\n Metal.innerText = MetalCell.innerText;\n Metal.className = \"badge text-bg-primary\";\n MetalCell.innerText = \"\";\n MetalCell.appendChild(Metal);\n GetUsernameHTML(Temp[i].cells[1], Temp[i].cells[1].innerText);\n Temp[i].cells[2].innerHTML = Temp[i].cells[2].innerText;\n Temp[i].cells[3].innerHTML = Temp[i].cells[3].innerText;\n for (let j = 5; j < Temp[i].cells.length; j++) {\n let InnerText = Temp[i].cells[j].innerText;\n let BackgroundColor = Temp[i].cells[j].style.backgroundColor;\n let Red = BackgroundColor.substring(4, BackgroundColor.indexOf(\",\"));\n let Green = BackgroundColor.substring(BackgroundColor.indexOf(\",\") + 2, BackgroundColor.lastIndexOf(\",\"));\n let Blue = BackgroundColor.substring(BackgroundColor.lastIndexOf(\",\") + 2, BackgroundColor.lastIndexOf(\")\"));\n let NoData = (Red == 238 && Green == 238 && Blue == 238);\n let FirstBlood = (Red == 170 && Green == 170 && Blue == 255);\n let Solved = (Green == 255);\n let ErrorCount = \"\";\n if (Solved) {\n ErrorCount = (Blue == 170 ? \"4+\" : (Blue - 51) / 32);\n }\n else {\n ErrorCount = (Blue == 22 ? \"14+\" : (170 - Blue) / 10);\n }\n if (NoData) {\n BackgroundColor = \"\";\n }\n else if (FirstBlood) {\n BackgroundColor = \"rgba(127, 127, 255, 0.5)\";\n }\n else if (Solved) {\n BackgroundColor = \"rgba(0, 255, 0, 0.5)\";\n if (ErrorCount != 0) {\n InnerText += \" (\" + ErrorCount + \")\";\n }\n }\n else {\n BackgroundColor = \"rgba(255, 0, 0, 0.5)\";\n if (ErrorCount != 0) {\n InnerText += \" (\" + ErrorCount + \")\";\n }\n }\n Temp[i].cells[j].innerHTML = InnerText;\n Temp[i].cells[j].style.backgroundColor = BackgroundColor;\n }\n }\n document.querySelector(\"#rank > tbody\").innerHTML = ParsedDocument.querySelector(\"#rank > tbody\").innerHTML;\n });\n };\n RefreshCorrectRank();\n if (UtilityEnabled(\"AutoRefresh\")) {\n addEventListener(\"focus\", RefreshCorrectRank);\n }\n }\n } else if (location.pathname == \"/submitpage.php\") {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `<center class=\"mb-3\">` +\n `<h3>提交代码</h3>` +\n (SearchParams.get(\"id\") != null ?\n `题目<span class=\"blue\">${Number(SearchParams.get(\"id\"))}</span>` :\n `比赛<span class=\"blue\">${Number(SearchParams.get(\"cid\")) + `</span>&emsp;题目<span class=\"blue\">` + String.fromCharCode(65 + parseInt(SearchParams.get(\"pid\")))}</span>`) +\n `</center>\n <textarea id=\"CodeInput\"></textarea>\n <center class=\"mt-3\">\n <input id=\"enable_O2\" name=\"enable_O2\" type=\"checkbox\"><label for=\"enable_O2\">打开O2开关</label>\n <br>\n <input id=\"Submit\" class=\"btn btn-info mt-2\" type=\"button\" value=\"提交\">\n <div id=\"ErrorElement\" class=\"mt-2\" style=\"display: none; text-align: left; padding: 10px;\">\n <div id=\"ErrorMessage\" style=\"white-space: pre; background-color: rgba(0, 0, 0, 0.1); padding: 10px; border-radius: 5px;\"></div>\n <button id=\"PassCheck\" class=\"btn btn-outline-secondary mt-2\" style=\"display: none\">强制提交</button>\n </div>\n </center>`;\n if (UtilityEnabled(\"AutoO2\")) {\n document.querySelector(\"#enable_O2\").checked = true;\n }\n let CodeMirrorElement;\n (() => {\n CodeMirrorElement = CodeMirror.fromTextArea(document.querySelector(\"#CodeInput\"), {\n lineNumbers: true,\n matchBrackets: true,\n mode: \"text/x-c++src\",\n indentUnit: 4,\n indentWithTabs: true,\n enterMode: \"keep\",\n tabMode: \"shift\",\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\"),\n extraKeys: {\n \"Ctrl-Space\": \"autocomplete\",\n \"Ctrl-Enter\": function (instance) {\n Submit.click();\n }\n }\n })\n })();\n CodeMirrorElement.setSize(\"100%\", \"auto\");\n CodeMirrorElement.getWrapperElement().style.border = \"1px solid #ddd\";\n\n if (SearchParams.get(\"sid\") !== null) {\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SearchParams.get(\"sid\"))\n .then((Response) => {\n return Response.text()\n })\n .then((Response) => {\n CodeMirrorElement.setValue(Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim());\n });\n }\n\n PassCheck.addEventListener(\"click\", async () => {\n ErrorElement.style.display = \"none\";\n document.querySelector(\"#Submit\").disabled = true;\n document.querySelector(\"#Submit\").value = \"正在提交...\";\n await fetch(\"https://www.xmoj.tech/submit.php\", {\n \"headers\": {\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n \"referrer\": location.href,\n \"method\": \"POST\",\n \"body\":\n (SearchParams.get(\"id\") != null ?\n \"id=\" + SearchParams.get(\"id\") :\n \"cid=\" + SearchParams.get(\"cid\") + \"&pid=\" + SearchParams.get(\"pid\")) +\n \"&language=1&\" +\n \"source=\" + encodeURIComponent(CodeMirrorElement.getValue()) + \"&\" +\n \"enable_O2=on\"\n }).then((Response) => {\n if (Response.redirected) {\n location.href = Response.url;\n }\n else {\n ErrorElement.style.display = \"block\";\n ErrorMessage.style.color = \"red\";\n ErrorMessage.innerText = \"提交失败!请关闭脚本后重试!\";\n Submit.disabled = false;\n Submit.value = \"提交\";\n }\n })\n });\n\n Submit.addEventListener(\"click\", async () => {\n PassCheck.style.display = \"none\";\n ErrorElement.style.display = \"none\";\n document.querySelector(\"#Submit\").disabled = true;\n document.querySelector(\"#Submit\").value = \"正在检查...\";\n let Source = CodeMirrorElement.getValue();\n let PID = 0;\n let IOFilename = \"\";\n if (SearchParams.get(\"cid\") != null && SearchParams.get(\"pid\") != null) {\n PID = localStorage.getItem(\"UserScript-Contest-\" + SearchParams.get(\"cid\") + \"-Problem-\" + SearchParams.get(\"pid\") + \"-PID\")\n }\n else {\n PID = SearchParams.get(\"id\");\n }\n IOFilename = localStorage.getItem(\"UserScript-Problem-\" + PID + \"-IOFilename\");\n if (UtilityEnabled(\"IOFile\") && IOFilename != null) {\n if (Source.indexOf(IOFilename) == -1) {\n PassCheck.style.display = \"\";\n ErrorElement.style.display = \"block\";\n ErrorMessage.style.color = \"red\";\n ErrorMessage.innerText = \"此题输入输出文件名为\" + IOFilename + \",请检查是否填错\";\n document.querySelector(\"#Submit\").disabled = false;\n document.querySelector(\"#Submit\").value = \"提交\";\n return false;\n }\n else if (RegExp(\"//.*freopen\").test(Source)) {\n PassCheck.style.display = \"\";\n ErrorElement.style.display = \"block\";\n ErrorMessage.style.color = \"red\";\n ErrorMessage.innerText = \"请不要注释freopen语句\";\n document.querySelector(\"#Submit\").disabled = false;\n document.querySelector(\"#Submit\").value = \"提交\";\n return false;\n }\n }\n if (Source == \"\") {\n PassCheck.style.display = \"\";\n ErrorElement.style.display = \"block\";\n ErrorMessage.style.color = \"red\";\n ErrorMessage.innerText = \"源代码为空\";\n document.querySelector(\"#Submit\").disabled = false;\n document.querySelector(\"#Submit\").value = \"提交\";\n return false;\n }\n if (UtilityEnabled(\"CompileError\")) {\n let ResponseData = await new Promise((Resolve) => {\n GM_xmlhttpRequest({\n method: \"POST\",\n url: \"https://cppinsights.io/api/v1/transform\",\n headers: {\n \"content-type\": \"application/json;charset=UTF-8\"\n },\n referrer: \"https://cppinsights.io/\",\n data: JSON.stringify({\n \"insightsOptions\": [\n \"cpp14\"\n ],\n \"code\": Source\n }),\n onload: (Response) => {\n Resolve(Response);\n }\n });\n });\n let Response = JSON.parse(ResponseData.responseText);\n if (Response.returncode) {\n PassCheck.style.display = \"\";\n ErrorElement.style.display = \"block\";\n ErrorMessage.style.color = \"red\";\n ErrorMessage.innerText = \"编译错误:\\n\" + Response.stderr.trim();\n document.querySelector(\"#Submit\").disabled = false;\n document.querySelector(\"#Submit\").value = \"提交\";\n return false;\n }\n else {\n PassCheck.click();\n }\n }\n else {\n PassCheck.click();\n }\n });\n } else if (location.pathname == \"/modifypage.php\") {\n if (SearchParams.get(\"ByUserScript\") != null) {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"\";\n await fetch(ServerURL + \"/Update.json\", { cache: \"no-cache\" })\n .then((Response) => {\n return Response.json();\n })\n .then((Response) => {\n for (let i = Object.keys(Response.UpdateHistory).length - 1; i >= 0; i--) {\n let Version = Object.keys(Response.UpdateHistory)[i];\n let Data = Response.UpdateHistory[Version];\n let UpdateDataCard = document.createElement(\"div\"); document.querySelector(\"body > div > div.mt-3\").appendChild(UpdateDataCard);\n UpdateDataCard.className = \"card mb-3\";\n if (Data.Prerelease)\n UpdateDataCard.classList.add(\"text-secondary\");\n let UpdateDataCardBody = document.createElement(\"div\"); UpdateDataCard.appendChild(UpdateDataCardBody);\n UpdateDataCardBody.className = \"card-body\";\n let UpdateDataCardTitle = document.createElement(\"h5\"); UpdateDataCardBody.appendChild(UpdateDataCardTitle);\n UpdateDataCardTitle.className = \"card-title\";\n UpdateDataCardTitle.innerText = Version;\n if (Data.Prerelease) {\n UpdateDataCardTitle.innerHTML += \"(预览版)\";\n }\n let UpdateDataCardSubtitle = document.createElement(\"h6\"); UpdateDataCardBody.appendChild(UpdateDataCardSubtitle);\n UpdateDataCardSubtitle.className = \"card-subtitle mb-2 text-muted\";\n UpdateDataCardSubtitle.innerHTML = GetRelativeTime(Data.UpdateDate);\n let UpdateDataCardText = document.createElement(\"p\"); UpdateDataCardBody.appendChild(UpdateDataCardText);\n UpdateDataCardText.className = \"card-text\";\n //release notes\n if (Data.Notes != undefined) {\n UpdateDataCardText.innerHTML = Data.Notes;\n }\n let UpdateDataCardList = document.createElement(\"ul\"); UpdateDataCardText.appendChild(UpdateDataCardList);\n UpdateDataCardList.className = \"list-group list-group-flush\";\n for (let j = 0; j < Data.UpdateContents.length; j++) {\n let UpdateDataCardListItem = document.createElement(\"li\"); UpdateDataCardList.appendChild(UpdateDataCardListItem);\n UpdateDataCardListItem.className = \"list-group-item\";\n UpdateDataCardListItem.innerHTML =\n \"(<a href=\\\"https://github.com/XMOJ-Script-dev/XMOJ-Script/pull/\" + Data.UpdateContents[j].PR + \"\\\" target=\\\"_blank\\\">\" +\n \"#\" + Data.UpdateContents[j].PR + \"</a>) \" +\n Data.UpdateContents[j].Description;\n }\n let UpdateDataCardLink = document.createElement(\"a\"); UpdateDataCardBody.appendChild(UpdateDataCardLink);\n UpdateDataCardLink.className = \"card-link\";\n UpdateDataCardLink.href = \"https://github.com/XMOJ-Script-dev/XMOJ-Script/releases/tag/\" + Version;\n UpdateDataCardLink.target = \"_blank\";\n UpdateDataCardLink.innerText = \"查看该版本\";\n }\n });\n }\n else {\n let Nickname = document.getElementsByName(\"nick\")[0].value;\n let School = document.getElementsByName(\"school\")[0].value;\n let EmailAddress = document.getElementsByName(\"email\")[0].value;\n let CodeforcesAccount = document.getElementsByName(\"acc_cf\")[0].value;\n let AtcoderAccount = document.getElementsByName(\"acc_atc\")[0].value;\n let USACOAccount = document.getElementsByName(\"acc_usaco\")[0].value;\n let LuoguAccount = document.getElementsByName(\"acc_luogu\")[0].value;\n document.querySelector(\"body > div > div\").innerHTML = `<div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"UserID\" class=\"col-form-label\">用户ID</label></div>\n <div class=\"col-9\"><input id=\"UserID\" class=\"form-control\" disabled readonly value=\"${CurrentUsername}\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"Avatar\" class=\"col-form-label\">头像</label></div>\n <div class=\"col-9\">\n <img width=\"64\" height=\"64\" src=\"https://cravatar.cn/avatar/` + (await GetUserInfo(CurrentUsername)).EmailHash + `?d=retro\">\n <a href=\"https://cravatar.cn/avatars\" target=\"_blank\">修改头像</a>\n </div>\n </div>\n <div class=\"row g-2 align-items-center col-6 pb-1 ps-2 pe-2 mt-3 mb-3 border\" id=\"BadgeRow\" style=\"display: none\">\n <div class=\"col-3\">标签</div>\n <div class=\"col-9\">\n <div class=\"row g-2 align-items-center mb-1\">\n <div class=\"col-3\"><label for=\"BadgeContent\" class=\"col-form-label\">内容</label></div>\n <div class=\"col-9\"><input class=\"form-control\" id=\"BadgeContent\"></div>\n </div>\n <div class=\"row g-2 align-items-center mb-1\">\n <div class=\"col-3\"><label for=\"BadgeBackgroundColor\" class=\"col-form-label\">背景颜色</label></div>\n <div class=\"col-9\"><input class=\"form-control form-control-color\" type=\"color\" id=\"BadgeBackgroundColor\"></div>\n </div>\n <div class=\"row g-2 align-items-center mb-1\">\n <div class=\"col-3\"><label for=\"BadgeColor\" class=\"col-form-label\">文字颜色</label></div>\n <div class=\"col-9\"><input class=\"form-control form-control-color\" type=\"color\" id=\"BadgeColor\"></div>\n </div>\n </div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"Nickname\" class=\"col-form-label\">昵称</label></div>\n <div class=\"col-9\"><input id=\"Nickname\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"OldPassword\" class=\"col-form-label\">旧密码</label></div>\n <div class=\"col-9\"><input type=\"password\" id=\"OldPassword\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"NewPassword\" class=\"col-form-label\">新密码</label></div>\n <div class=\"col-9\"><input type=\"password\" id=\"NewPassword\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"NewPasswordAgain\" class=\"col-form-label\">请重复密码</label></div>\n <div class=\"col-9\"><input type=\"password\" id=\"NewPasswordAgain\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"School\" class=\"col-form-label\">学校</label></div>\n <div class=\"col-9\"><input id=\"School\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"EmailAddress\" class=\"col-form-label\">电子邮箱</label></div>\n <div class=\"col-9\"><input id=\"EmailAddress\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"CodeforcesAccount\" class=\"col-form-label\">Codeforces账号</label></div>\n <div class=\"col-9\"><input id=\"CodeforcesAccount\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"AtcoderAccount\" class=\"col-form-label\">Atcoder账号</label></div>\n <div class=\"col-9\"><input id=\"AtcoderAccount\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"USACOAccount\" class=\"col-form-label\">USACO账号</label></div>\n <div class=\"col-9\"><input id=\"USACOAccount\" class=\"form-control\"></div>\n </div>\n <div class=\"row g-2 align-items-center col-6 mb-1\">\n <div class=\"col-3\"><label for=\"LuoguAccount\" class=\"col-form-label\">洛谷账号</label></div>\n <div class=\"col-9\"><input id=\"LuoguAccount\" class=\"form-control\"></div>\n </div>\n <button type=\"submit\" class=\"btn btn-primary mb-2\" id=\"ModifyInfo\">\n 修改\n <span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" style=\"display: none\"></span>\n </button>\n <div class=\"alert alert-danger mb-3\" role=\"alert\" id=\"ErrorElement\" style=\"display: none;\"></div>\n <div class=\"alert alert-success mb-3\" role=\"alert\" id=\"SuccessElement\" style=\"display: none;\">修改成功</div>\n <br>`;\n document.getElementById(\"Nickname\").value = Nickname;\n document.getElementById(\"School\").value = School;\n document.getElementById(\"EmailAddress\").value = EmailAddress;\n document.getElementById(\"CodeforcesAccount\").value = CodeforcesAccount;\n document.getElementById(\"AtcoderAccount\").value = AtcoderAccount;\n document.getElementById(\"USACOAccount\").value = USACOAccount;\n document.getElementById(\"LuoguAccount\").value = LuoguAccount;\n RequestAPI(\"GetBadge\", {\n \"UserID\": String(CurrentUsername)\n }, (Response) => {\n if (Response.Success) {\n BadgeRow.style.display = \"\";\n BadgeContent.value = Response.Data.Content;\n BadgeBackgroundColor.value = Response.Data.BackgroundColor;\n BadgeColor.value = Response.Data.Color;\n SuccessElement.innerText += \",用户标签会在一天内生效\";\n }\n });\n ModifyInfo.addEventListener(\"click\", async () => {\n ModifyInfo.disabled = true;\n ModifyInfo.querySelector(\"span\").style.display = \"\";\n ErrorElement.style.display = \"none\";\n SuccessElement.style.display = \"none\";\n let BadgeContent = document.querySelector(\"#BadgeContent\").value;\n let BadgeBackgroundColor = document.querySelector(\"#BadgeBackgroundColor\").value;\n let BadgeColor = document.querySelector(\"#BadgeColor\").value;\n await new Promise((Resolve) => {\n RequestAPI(\"EditBadge\", {\n \"UserID\": String(CurrentUsername),\n \"Content\": String(BadgeContent),\n \"BackgroundColor\": String(BadgeBackgroundColor),\n \"Color\": String(BadgeColor)\n }, (Response) => {\n if (Response.Success) {\n Resolve();\n }\n else {\n ModifyInfo.disabled = false;\n ModifyInfo.querySelector(\"span\").style.display = \"none\";\n ErrorElement.style.display = \"block\";\n ErrorElement.innerText = Response.Message;\n }\n });\n });\n let Nickname = document.querySelector(\"#Nickname\").value;\n let OldPassword = document.querySelector(\"#OldPassword\").value;\n let NewPassword = document.querySelector(\"#NewPassword\").value;\n let NewPasswordAgain = document.querySelector(\"#NewPasswordAgain\").value;\n let School = document.querySelector(\"#School\").value;\n let EmailAddress = document.querySelector(\"#EmailAddress\").value;\n let CodeforcesAccount = document.querySelector(\"#CodeforcesAccount\").value;\n let AtcoderAccount = document.querySelector(\"#AtcoderAccount\").value;\n let USACOAccount = document.querySelector(\"#USACOAccount\").value;\n let LuoguAccount = document.querySelector(\"#LuoguAccount\").value;\n await fetch(\"https://www.xmoj.tech/modify.php\", {\n \"headers\": {\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n \"referrer\": location.href,\n \"method\": \"POST\",\n \"body\":\n \"nick=\" + encodeURIComponent(Nickname) + \"&\" +\n \"opassword=\" + encodeURIComponent(OldPassword) + \"&\" +\n \"npassword=\" + encodeURIComponent(NewPassword) + \"&\" +\n \"rptpassword=\" + encodeURIComponent(NewPasswordAgain) + \"&\" +\n \"school=\" + encodeURIComponent(School) + \"&\" +\n \"email=\" + encodeURIComponent(EmailAddress) + \"&\" +\n \"acc_cf=\" + encodeURIComponent(CodeforcesAccount) + \"&\" +\n \"acc_atc=\" + encodeURIComponent(AtcoderAccount) + \"&\" +\n \"acc_usaco=\" + encodeURIComponent(USACOAccount) + \"&\" +\n \"acc_luogu=\" + encodeURIComponent(LuoguAccount)\n });\n ModifyInfo.disabled = false;\n ModifyInfo.querySelector(\"span\").style.display = \"none\";\n SuccessElement.style.display = \"block\";\n });\n if (UtilityEnabled(\"ExportACCode\")) {\n let ExportACCode = document.createElement(\"button\");\n document.querySelector(\"body > div.container > div\").appendChild(ExportACCode);\n ExportACCode.innerText = \"导出AC代码\";\n ExportACCode.className = \"btn btn-outline-secondary\";\n ExportACCode.addEventListener(\"click\", () => {\n ExportACCode.disabled = true;\n let ExportProgressBar = document.getElementsByTagName(\"progress\")[0] || document.createElement(\"progress\");\n ExportProgressBar.removeAttribute(\"value\");\n ExportProgressBar.removeAttribute(\"max\");\n document.querySelector(\"body > div.container > div\").appendChild(ExportProgressBar);\n ExportACCode.innerText = \"正在导出...\";\n let Request = new XMLHttpRequest();\n Request.addEventListener(\"readystatechange\", () => {\n if (Request.readyState == 4) {\n if (Request.status == 200) {\n let Response = Request.responseText;\n let ACCode = Response.split(\"------------------------------------------------------\\r\\n\");\n ExportProgressBar.max = ACCode.length - 1;\n let DownloadCode = (i) => {\n if (i >= ACCode.length) {\n ExportACCode.innerText = \"AC代码导出成功\";\n ExportACCode.disabled = false;\n ExportProgressBar.remove();\n setTimeout(() => {\n ExportACCode.innerText = \"导出AC代码\";\n }, 1000);\n return;\n }\n let CurrentCode = ACCode[i];\n if (CurrentCode != \"\") {\n let CurrentQuestionID = CurrentCode.substring(7, 11);\n CurrentCode = CurrentCode.substring(14);\n ExportProgressBar.value = i + 1;\n let DownloadLink = document.createElement(\"a\");\n DownloadLink.href = window.URL.createObjectURL(new Blob([CurrentCode]));\n DownloadLink.download = CurrentQuestionID + \".cpp\";\n DownloadLink.click();\n }\n setTimeout(() => {\n DownloadCode(i + 1);\n }, 50);\n };\n DownloadCode(0);\n } else {\n ExportACCode.disabled = false;\n ExportACCode.innerText = \"AC代码导出失败\";\n setTimeout(() => {\n ExportACCode.innerText = \"导出AC代码\";\n }, 1000);\n }\n }\n });\n Request.open(\"GET\", \"https://www.xmoj.tech/export_ac_code.php\", true);\n Request.send();\n });\n }\n }\n } else if (location.pathname == \"/userinfo.php\") {\n if (SearchParams.get(\"ByUserScript\") === null) {\n if (UtilityEnabled(\"RemoveUseless\")) {\n let Temp = document.getElementById(\"submission\").childNodes;\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].remove();\n }\n }\n eval(document.querySelector(\"body > script:nth-child(5)\").innerHTML);\n document.querySelector(\"#statics > tbody > tr:nth-child(1)\").remove();\n\n let Temp = document.querySelector(\"#statics > tbody\").children;\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].children[0] != undefined) {\n if (Temp[i].children[0].innerText == \"Statistics\") {\n Temp[i].children[0].innerText = \"统计\";\n }\n else if (Temp[i].children[0].innerText == \"Email:\") {\n Temp[i].children[0].innerText = \"电子邮箱\";\n }\n else {\n Temp[i].children[1].innerText = Temp[i].children[1].innerText;\n }\n Temp[i].children[1].removeAttribute(\"align\");\n }\n }\n\n Temp = document.querySelector(\"#statics > tbody > tr:nth-child(1) > td:nth-child(3)\").childNodes;\n let ACProblems = [];\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].tagName == \"A\" && Temp[i].href.indexOf(\"problem.php?id=\") != -1) {\n ACProblems.push(Number(Temp[i].innerText.trim()));\n }\n }\n document.querySelector(\"#statics > tbody > tr:nth-child(1) > td:nth-child(3)\").remove();\n\n let UserID, UserNick;\n [UserID, UserNick] = document.querySelector(\"#statics > caption\").childNodes[0].data.trim().split(\"--\");\n document.querySelector(\"#statics > caption\").remove();\n\n let Row = document.createElement(\"div\"); Row.className = \"row\";\n let LeftDiv = document.createElement(\"div\"); LeftDiv.className = \"col-md-5\"; Row.appendChild(LeftDiv);\n\n let LeftTopDiv = document.createElement(\"div\"); LeftTopDiv.className = \"row mb-2\"; LeftDiv.appendChild(LeftTopDiv);\n let AvatarContainer = document.createElement(\"div\");\n AvatarContainer.classList.add(\"col-auto\");\n let AvatarElement = document.createElement(\"img\");\n let UserEmailHash = (await GetUserInfo(UserID)).EmailHash;\n if (UserEmailHash == undefined) {\n AvatarElement.src = `https://cravatar.cn/avatar/00000000000000000000000000000000?d=mp&f=y`;\n }\n else {\n AvatarElement.src = `https://cravatar.cn/avatar/${UserEmailHash}?d=retro`;\n }\n AvatarElement.classList.add(\"rounded\", \"me-2\");\n AvatarElement.style.height = \"120px\";\n AvatarContainer.appendChild(AvatarElement);\n LeftTopDiv.appendChild(AvatarContainer);\n\n let UserInfoElement = document.createElement(\"div\");\n UserInfoElement.classList.add(\"col-auto\");\n UserInfoElement.style.lineHeight = \"40px\";\n UserInfoElement.innerHTML += \"用户名:\" + UserID + \"<br>\";\n UserInfoElement.innerHTML += \"昵称:\" + UserNick + \"<br>\";\n if (UtilityEnabled(\"Rating\")) {\n UserInfoElement.innerHTML += \"评分:\" + ((await GetUserInfo(UserID)).Rating) + \"<br>\";\n }\n // Create a placeholder for the last online time\n let lastOnlineElement = document.createElement('div');\n lastOnlineElement.innerHTML = \"最后在线:加载中...<br>\";\n UserInfoElement.appendChild(lastOnlineElement);\n\n RequestAPI(\"LastOnline\", {\"Username\": UserID}, (result) => {\n if (result.Success) {\n if (UtilityEnabled(\"DebugMode\")) {\n console.log('lastOnline:' + result.Data.logintime);\n }\n lastOnlineElement.innerHTML = \"最后在线:\" + GetRelativeTime(result.Data.logintime) + \"<br>\";\n } else {\n lastOnlineElement.innerHTML = \"最后在线:近三个月内从未<br>\";\n }\n });\n LeftTopDiv.appendChild(UserInfoElement);\n LeftDiv.appendChild(LeftTopDiv);\n\n let LeftTable = document.querySelector(\"body > div > div > center > table\"); LeftDiv.appendChild(LeftTable);\n let RightDiv = document.createElement(\"div\"); RightDiv.className = \"col-md-7\"; Row.appendChild(RightDiv);\n RightDiv.innerHTML = \"<h5>已解决题目</h5>\";\n for (let i = 0; i < ACProblems.length; i++) {\n RightDiv.innerHTML += \"<a href=\\\"https://www.xmoj.tech/problem.php?id=\" + ACProblems[i] + \"\\\" target=\\\"_blank\\\">\" + ACProblems[i] + \"</a> \";\n }\n document.querySelector(\"body > div > div\").innerHTML = \"\";\n document.querySelector(\"body > div > div\").appendChild(Row);\n } else {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `<button id=\"UploadStd\" class=\"btn btn-primary mb-2\">上传标程</button>\n <div class=\"alert alert-danger mb-3\" role=\"alert\" id=\"ErrorElement\" style=\"display: none;\"></div>\n <div class=\"progress\" role=\"progressbar\">\n <div id=\"UploadProgress\" class=\"progress-bar progress-bar-striped\" style=\"width: 0%\">0%</div>\n </div>\n <p class=\"mt-2 text-muted\">\n 您必须要上传标程以后才能使用“查看标程”功能。点击“上传标程”按钮以后,系统会自动上传标程,请您耐心等待。<br>\n 首次上传标程可能会比较慢,请耐心等待。后续上传标程将会快很多。请不要直接抄袭或递交标程,否则会给予\"作弊者\"badge的惩罚!<br>\n 上传的内容不是您AC的程序,而是您AC的题目对应的用户std的程序。所以您可以放心上传,不会泄露您的代码。<br>\n 系统每过30天会自动提醒您上传标程,您必须要上传标程,否则将会被禁止使用“查看标程”功能。<br>\n </p>`;\n UploadStd.addEventListener(\"click\", async () => {\n UploadStd.disabled = true;\n ErrorElement.style.display = \"none\";\n ErrorElement.innerText = \"\";\n UploadProgress.classList.remove(\"bg-success\");\n UploadProgress.classList.remove(\"bg-warning\");\n UploadProgress.classList.remove(\"bg-danger\");\n UploadProgress.classList.add(\"progress-bar-animated\");\n UploadProgress.style.width = \"0%\";\n UploadProgress.innerText = \"0%\";\n let ACList = [];\n await fetch(\"https://www.xmoj.tech/userinfo.php?user=\" + CurrentUsername)\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let ScriptData = ParsedDocument.querySelector(\"#statics > tbody > tr:nth-child(2) > td:nth-child(3) > script\").innerText;\n ScriptData = ScriptData.substr(ScriptData.indexOf(\"}\") + 1).trim();\n ScriptData = ScriptData.split(\";\");\n for (let i = 0; i < ScriptData.length; i++) {\n ACList.push(Number(ScriptData[i].substring(2, ScriptData[i].indexOf(\",\"))));\n }\n });\n RequestAPI(\"GetStdList\", {}, async (Result) => {\n if (Result.Success) {\n let StdList = Result.Data.StdList;\n for (let i = 0; i < ACList.length; i++) {\n if (StdList.indexOf(ACList[i]) === -1) {\n await new Promise((Resolve) => {\n RequestAPI(\"UploadStd\", {\n \"ProblemID\": Number(ACList[i])\n }, (Result) => {\n if (!Result.Success) {\n ErrorElement.style.display = \"block\";\n ErrorElement.innerText += Result.Message + \"<br>\";\n UploadProgress.classList.add(\"bg-warning\");\n }\n UploadProgress.innerText = (i / ACList.length * 100).toFixed(1) + \"% (\" + ACList[i] + \")\";\n UploadProgress.style.width = (i / ACList.length * 100) + \"%\";\n Resolve();\n });\n });\n }\n }\n UploadProgress.classList.add(\"bg-success\");\n UploadProgress.classList.remove(\"progress-bar-animated\");\n UploadProgress.innerText = \"100%\";\n UploadProgress.style.width = \"100%\";\n UploadStd.disabled = false;\n localStorage.setItem(\"UserScript-LastUploadedStdTime\", new Date().getTime());\n }\n else {\n ErrorElement.style.display = \"block\";\n ErrorElement.innerText = Result.Message;\n UploadStd.disabled = false;\n }\n });\n });\n }\n } else if (location.pathname == \"/conteststatistics.php\") {\n document.querySelector(\"body > div > div.mt-3 > center > h3\").innerText = \"比赛统计\";\n if (UtilityEnabled(\"ResetType\")) {\n let Temp = document.getElementById(\"submission\").childNodes;\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].remove();\n }\n eval(document.querySelector(\"body > div.container > div > center > table:nth-child(4) > script:nth-child(6)\").innerHTML);\n document.querySelector(\"#cs > thead > tr > th:nth-child(1)\").innerText = \"题目编号\";\n document.querySelector(\"#cs > thead > tr > th:nth-child(10)\").remove();\n document.querySelector(\"#cs > thead > tr > th:nth-child(11)\").innerText = \"总和\";\n document.querySelector(\"#cs > thead > tr > th:nth-child(12)\").remove();\n document.querySelector(\"#cs > thead > tr > th:nth-child(12)\").remove();\n document.querySelector(\"#cs > thead > tr > th:nth-child(12)\").remove();\n document.querySelector(\"#cs > tbody > tr:last-child > td\").innerText = \"总和\";\n TidyTable(document.getElementById(\"cs\"));\n Temp = document.querySelector(\"#cs > tbody\").children;\n for (let i = 0; i < Temp.length; i++) {\n let CurrentRowChildren = Temp[i].children;\n CurrentRowChildren[9].remove();\n CurrentRowChildren[11].remove();\n CurrentRowChildren[11].remove();\n CurrentRowChildren[11].remove();\n for (let j = 0; j < CurrentRowChildren.length; j++) {\n if (CurrentRowChildren[j].innerText == \"\") {\n CurrentRowChildren[j].innerText = \"0\";\n }\n }\n }\n }\n } else if (location.pathname == \"/comparesource.php\") {\n if (UtilityEnabled(\"CompareSource\")) {\n if (location.search == \"\") {\n document.querySelector(\"body > div.container > div\").innerHTML = \"\";\n let LeftCodeText = document.createElement(\"span\");\n document.querySelector(\"body > div.container > div\").appendChild(LeftCodeText);\n LeftCodeText.innerText = \"左侧代码的运行编号:\";\n let LeftCode = document.createElement(\"input\");\n document.querySelector(\"body > div.container > div\").appendChild(LeftCode);\n LeftCode.classList.add(\"form-control\");\n LeftCode.style.width = \"40%\";\n LeftCode.style.marginBottom = \"5px\";\n let RightCodeText = document.createElement(\"span\");\n document.querySelector(\"body > div.container > div\").appendChild(RightCodeText);\n RightCodeText.innerText = \"右侧代码的运行编号:\";\n let RightCode = document.createElement(\"input\");\n document.querySelector(\"body > div.container > div\").appendChild(RightCode);\n RightCode.classList.add(\"form-control\");\n RightCode.style.width = \"40%\";\n RightCode.style.marginBottom = \"5px\";\n let CompareButton = document.createElement(\"button\");\n document.querySelector(\"body > div.container > div\").appendChild(CompareButton);\n CompareButton.innerText = \"比较\";\n CompareButton.className = \"btn btn-primary\";\n CompareButton.addEventListener(\"click\", () => {\n location.href = \"https://www.xmoj.tech/comparesource.php?left=\" + Number(LeftCode.value) + \"&right=\" + Number(RightCode.value);\n });\n }\n else {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `\n <div class=\"form-check\">\n <input class=\"form-check-input\" type=\"checkbox\" checked id=\"IgnoreWhitespace\">\n <label class=\"form-check-label\" for=\"IgnoreWhitespace\">忽略空白</label>\n </div>\n <div id=\"CompareElement\"></div>`;\n\n let LeftCode = \"\";\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SearchParams.get(\"left\"))\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n LeftCode = Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim();\n });\n let RightCode = \"\";\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SearchParams.get(\"right\"))\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n RightCode = Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim();\n });\n\n let MergeViewElement = CodeMirror.MergeView(CompareElement, {\n value: LeftCode,\n origLeft: null,\n orig: RightCode,\n lineNumbers: true,\n mode: \"text/x-c++src\",\n collapseIdentical: \"true\",\n readOnly: true,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\"),\n revertButtons: false,\n ignoreWhitespace: true\n });\n\n IgnoreWhitespace.addEventListener(\"change\", () => {\n MergeViewElement.ignoreWhitespace = ignorews.checked;\n });\n }\n }\n } else if (location.pathname == \"/loginpage.php\") {\n if (UtilityEnabled(\"NewBootstrap\")) {\n document.querySelector(\"#login\").innerHTML = `<form id=\"login\" action=\"login.php\" method=\"post\">\n <div class=\"row g-3 align-items-center mb-3\">\n <div class=\"col-auto\">\n <label for=\"user_id\" class=\"col-form-label\">用户名(学号)</label>\n </div>\n <div class=\"col-auto\">\n <input type=\"text\" id=\"user_id\" name=\"user_id\" class=\"form-control\">\n </div>\n </div>\n <div class=\"row g-3 align-items-center mb-3\">\n <div class=\"col-auto\">\n <label for=\"password\" class=\"col-form-label\">密码</label>\n </div>\n <div class=\"col-auto\">\n <input type=\"password\" id=\"password\" name=\"password\" class=\"form-control\">\n </div>\n </div>\n <div class=\"row g-3 align-items-center mb-3\">\n <div class=\"col-auto\">\n <button name=\"submit\" type=\"button\" class=\"btn btn-primary\">登录</button>\n </div>\n <div class=\"col-auto\">\n <a class=\"btn btn-warning\" href=\"https://www.xmoj.tech/lostpassword.php\">忘记密码</a>\n </div>\n </div>\n </form > `;\n }\n let ErrorText = document.createElement(\"div\");\n ErrorText.style.color = \"red\";\n ErrorText.style.marginBottom = \"5px\";\n document.querySelector(\"#login\").appendChild(ErrorText);\n let LoginButton = document.getElementsByName(\"submit\")[0];\n LoginButton.addEventListener(\"click\", async () => {\n let Username = document.getElementsByName(\"user_id\")[0].value;\n let Password = document.getElementsByName(\"password\")[0].value;\n if (Username == \"\" ||\n Password == \"\") {\n ErrorText.innerText = \"用户名或密码不能为空\";\n } else {\n await fetch(\"https://www.xmoj.tech/login.php\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n body: \"user_id=\" + encodeURIComponent(Username) +\n \"&password=\" + hex_md5(Password)\n })\n .then((Response) => {\n return Response.text();\n })\n .then((Response) => {\n if (UtilityEnabled(\"LoginFailed\")) {\n if (Response.indexOf(\"history.go(-2);\") != -1) {\n if (UtilityEnabled(\"SavePassword\")) {\n localStorage.setItem(\"UserScript-Username\", Username);\n localStorage.setItem(\"UserScript-Password\", Password);\n }\n let NewPage = localStorage.getItem(\"UserScript-LastPage\");\n if (NewPage == null) {\n NewPage = \"https://www.xmoj.tech/index.php\";\n }\n location.href = NewPage;\n } else {\n if (UtilityEnabled(\"SavePassword\")) {\n localStorage.removeItem(\"UserScript-Username\");\n localStorage.removeItem(\"UserScript-Password\");\n }\n Response = Response.substring(Response.indexOf(\"alert('\") + 7);\n Response = Response.substring(0, Response.indexOf(\"');\"));\n if (Response == \"UserName or Password Wrong!\") {\n ErrorText.innerText = \"用户名或密码错误!\";\n }\n else {\n ErrorText.innerText = Response;\n }\n }\n }\n else {\n document.innerHTML = Response;\n }\n });\n }\n });\n if (UtilityEnabled(\"SavePassword\") &&\n localStorage.getItem(\"UserScript-Username\") != null &&\n localStorage.getItem(\"UserScript-Password\") != null) {\n document.querySelector(\"#login > div:nth-child(1) > div > input\").value = localStorage.getItem(\"UserScript-Username\");\n document.querySelector(\"#login > div:nth-child(2) > div > input\").value = localStorage.getItem(\"UserScript-Password\");\n LoginButton.click();\n }\n } else if (location.pathname == \"/contest_video.php\" || location.pathname == \"/problem_video.php\") {\n let ScriptData = document.querySelector(\"body > div > div.mt-3 > center > script\").innerHTML;\n if (document.getElementById(\"J_prismPlayer0\").innerHTML != \"\") {\n document.getElementById(\"J_prismPlayer0\").innerHTML = \"\";\n if (player) {\n player.dispose();\n }\n eval(ScriptData);\n }\n if (UtilityEnabled(\"DownloadPlayback\")) {\n ScriptData = ScriptData.substring(ScriptData.indexOf(\"{\"));\n ScriptData = ScriptData.substring(0, ScriptData.indexOf(\"}\") + 1);\n ScriptData = ScriptData.replace(/([a-zA-Z0-9]+) ?:/g, \"\\\"$1\\\":\");\n ScriptData = ScriptData.replace(/'/g, \"\\\"\");\n let VideoData = JSON.parse(ScriptData);\n let RandomUUID = () => {\n let t = \"0123456789abcdef\";\n let e = [];\n for (let r = 0; r < 36; r++)\n e[r] = t.substr(Math.floor(16 * Math.random()), 1);\n e[14] = \"4\";\n e[19] = t.substr(3 & e[19] | 8, 1);\n e[8] = e[13] = e[18] = e[23] = \"-\";\n return e.join(\"\");\n };\n let URLParams = new URLSearchParams({\n \"AccessKeyId\": VideoData.accessKeyId,\n \"Action\": \"GetPlayInfo\",\n \"VideoId\": VideoData.vid,\n \"Formats\": \"\",\n \"AuthTimeout\": 7200,\n \"Rand\": RandomUUID(),\n \"SecurityToken\": VideoData.securityToken,\n \"StreamType\": \"video\",\n \"Format\": \"JSON\",\n \"Version\": \"2017-03-21\",\n \"SignatureMethod\": \"HMAC-SHA1\",\n \"SignatureVersion\": \"1.0\",\n \"SignatureNonce\": RandomUUID(),\n \"PlayerVersion\": \"2.9.3\",\n \"Channel\": \"HTML5\"\n });\n URLParams.sort();\n await fetch(\"https://vod.\" + VideoData.region + \".aliyuncs.com/?\" +\n URLParams.toString() +\n \"&Signature=\" +\n encodeURIComponent(CryptoJS.HmacSHA1(\"GET&%2F&\" + encodeURIComponent(URLParams.toString()),\n VideoData.accessKeySecret + \"&\").toString(CryptoJS.enc.Base64)))\n .then((Response) => {\n return Response.json();\n })\n .then((Response) => {\n let DownloadButton = document.createElement(\"a\");\n DownloadButton.className = \"btn btn-outline-secondary\";\n DownloadButton.innerText = \"下载\";\n DownloadButton.href = Response.PlayInfoList.PlayInfo[0].PlayURL;\n DownloadButton.download = Response.VideoBase.Title;\n document.querySelector(\"body > div > div.mt-3 > center\").appendChild(DownloadButton);\n });\n }\n } else if (location.pathname == \"/reinfo.php\") {\n if (document.querySelector(\"#results > div\") == undefined) {\n document.querySelector(\"#results\").parentElement.innerHTML = \"没有测试点信息\";\n }\n else {\n for (let i = 0; i < document.querySelector(\"#results > div\").children.length; i++) {\n let CurrentElement = document.querySelector(\"#results > div\").children[i].children[0].children[0].children[0];\n let Temp = CurrentElement.innerText.substring(0, CurrentElement.innerText.length - 2).split(\"/\");\n CurrentElement.innerText = TimeToStringTime(Temp[0]) + \"/\" + SizeToStringSize(Temp[1]);\n }\n if (document.getElementById(\"apply_data\")) {\n let ApplyDiv = document.getElementById(\"apply_data\").parentElement;\n console.log(\"启动!!!\");\n if (UtilityEnabled(\"ApplyData\")) {\n let GetDataButton = document.createElement(\"button\");\n GetDataButton.className = \"ms-2 btn btn-outline-secondary\";\n GetDataButton.innerText = \"获取数据\";\n console.log(\"按钮创建成功\");\n ApplyDiv.appendChild(GetDataButton);\n GetDataButton.addEventListener(\"click\", async () => {\n GetDataButton.disabled = true;\n GetDataButton.innerText = \"正在获取数据...\";\n let PID = localStorage.getItem(\"UserScript-Solution-\" + SearchParams.get(\"sid\") + \"-Problem\");\n let Code = \"\";\n if (localStorage.getItem(`UserScript-Problem-${PID}-IOFilename`) !== null) {\n Code = `#define IOFile \"${localStorage.getItem(`UserScript-Problem-${PID}-IOFilename`)}\"\\n`;\n }\n Code += `//XMOJ-Script 获取数据代码\n #include <bits/stdc++.h>\nusing namespace std;\nstring Base64Encode(string Input)\n{\n const string Base64Chars = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n string Output;\n for (int i = 0; i < Input.length(); i += 3)\n {\n Output.push_back(i + 0 > Input.length() ? '=' : Base64Chars[(Input[i + 0] & 0xfc) >> 2]);\n Output.push_back(i + 1 > Input.length() ? '=' : Base64Chars[((Input[i + 0] & 0x03) << 4) + ((Input[i + 1] & 0xf0) >> 4)]);\n Output.push_back(i + 2 > Input.length() ? '=' : Base64Chars[((Input[i + 1] & 0x0f) << 2) + ((Input[i + 2] & 0xc0) >> 6)]);\n Output.push_back(i + 3 > Input.length() ? '=' : Base64Chars[Input[i + 2] & 0x3f]);\n }\n return Output;\n}\nint main()\n{\n#ifdef IOFile\n freopen(IOFile \".in\", \"r\", stdin);\n freopen(IOFile \".out\", \"w\", stdout);\n#endif\n string Input;\n while (1)\n {\n char Data = getchar();\n if (Data == EOF)\n break;\n Input.push_back(Data);\n }\n throw runtime_error(\"[\" + Base64Encode(Input.c_str()) + \"]\");\n return 0;\n}`;\n\n await fetch(\"https://www.xmoj.tech/submit.php\", {\n \"headers\": {\n \"content-type\": \"application/x-www-form-urlencoded\"\n },\n \"referrer\": \"https://www.xmoj.tech/submitpage.php?id=\" + PID,\n \"method\": \"POST\",\n \"body\": \"id=\" + PID + \"&\" +\n \"language=1&\" +\n \"source=\" + encodeURIComponent(Code) + \"&\" +\n \"enable_O2=on\"\n });\n\n let SID = await fetch(\"https://www.xmoj.tech/status.php\").then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n return ParsedDocument.querySelector(\"#result-tab > tbody > tr:nth-child(1) > td:nth-child(2)\").innerText;\n });\n\n await new Promise((Resolve) => {\n let Interval = setInterval(async () => {\n await fetch(\"status-ajax.php?solution_id=\" + SID).then((Response) => {\n return Response.text();\n }).then((Response) => {\n if (Response.split(\",\")[0] >= 4) {\n clearInterval(Interval);\n Resolve();\n }\n });\n }, 500);\n });\n\n await fetch(`https://www.xmoj.tech/reinfo.php?sid=${SID}`).then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let ErrorData = ParsedDocument.getElementById(\"errtxt\").innerText;\n let MatchResult = ErrorData.match(/\\what\\(\\): \\[([A-Za-z0-9+\\/=]+)\\]/g);\n for (let i = 0; i < MatchResult.length; i++) {\n let Data = CryptoJS.enc.Base64.parse(MatchResult[i].substring(10, MatchResult[i].length - 1)).toString(CryptoJS.enc.Utf8);\n ApplyDiv.appendChild(document.createElement(\"hr\"));\n ApplyDiv.appendChild(document.createTextNode(\"数据\" + (i + 1) + \":\"));\n let CodeElement = document.createElement(\"div\");\n ApplyDiv.appendChild(CodeElement);\n CodeMirror(CodeElement, {\n value: Data,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\"),\n lineNumbers: true,\n readOnly: true\n }).setSize(\"100%\", \"auto\");\n }\n GetDataButton.innerText = \"获取数据成功\";\n GetDataButton.disabled = false;\n });\n });\n }\n document.getElementById(\"apply_data\").addEventListener(\"click\", () => {\n let ApplyElements = document.getElementsByClassName(\"data\");\n for (let i = 0; i < ApplyElements.length; i++) {\n ApplyElements[i].style.display = (ApplyElements[i].style.display == \"block\" ? \"\" : \"block\");\n }\n });\n }\n let ApplyElements = document.getElementsByClassName(\"data\");\n for (let i = 0; i < ApplyElements.length; i++) {\n ApplyElements[i].addEventListener(\"click\", async () => {\n await fetch(\"https://www.xmoj.tech/data_distribute_ajax_apply.php\", {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n body: \"user_id=\" + CurrentUsername + \"&\" +\n \"solution_id=\" + SearchParams.get(\"sid\") + \"&\" +\n \"name=\" + ApplyElements[i].getAttribute(\"name\")\n }).then((Response) => {\n return Response.json();\n }).then((Response) => {\n ApplyElements[i].innerText = Response.msg;\n setTimeout(() => {\n ApplyElements[i].innerText = \"申请数据\";\n }, 1000);\n });\n });\n }\n }\n } else if (location.pathname == \"/downloads.php\") {\n let SoftwareList = document.querySelector(\"body > div > ul\");\n SoftwareList.remove();\n SoftwareList = document.createElement(\"ul\");\n SoftwareList.className = \"software_list\";\n let Container = document.createElement(\"div\"); document.querySelector(\"body > div\").appendChild(Container);\n Container.className = \"mt-3\";\n Container.appendChild(SoftwareList);\n if (UtilityEnabled(\"NewDownload\")) {\n let Softwares = [{\n \"Name\": \"Bloodshed Dev-C++\",\n \"Image\": \"https://a.fsdn.com/allura/p/dev-cpp/icon\",\n \"URL\": \"https://sourceforge.net/projects/dev-cpp/\"\n }, {\n \"Name\": \"Orwell Dev-C++\",\n \"Image\": \"https://a.fsdn.com/allura/p/orwelldevcpp/icon\",\n \"URL\": \"https://sourceforge.net/projects/orwelldevcpp/\"\n }, {\n \"Name\": \"Embarcadero Dev-C++\",\n \"Image\": \"https://a.fsdn.com/allura/s/embarcadero-dev-cpp/icon\",\n \"URL\": \"https://sourceforge.net/software/product/Embarcadero-Dev-Cpp/\"\n }, {\n \"Name\": \"RedPanda C++\",\n \"Image\": \"https://a.fsdn.com/allura/p/redpanda-cpp/icon\",\n \"URL\": \"https://sourceforge.net/projects/redpanda-cpp/\"\n }, {\n \"Name\": \"CP Editor\",\n \"Image\": \"https://a.fsdn.com/allura/mirror/cp-editor/icon\",\n \"URL\": \"https://sourceforge.net/projects/cp-editor.mirror/\"\n }, {\n \"Name\": \"Code::Blocks\",\n \"Image\": \"https://a.fsdn.com/allura/p/codeblocks/icon\",\n \"URL\": \"https://sourceforge.net/projects/codeblocks/\"\n }, {\n \"Name\": \"Visual Studio Code\",\n \"Image\": \"https://code.visualstudio.com/favicon.ico\",\n \"URL\": \"https://code.visualstudio.com/Download\"\n }, {\n \"Name\": \"Lazarus\",\n \"Image\": \"https://a.fsdn.com/allura/p/lazarus/icon\",\n \"URL\": \"https://sourceforge.net/projects/lazarus/\"\n }, {\n \"Name\": \"Geany\",\n \"Image\": \"https://www.geany.org/static/img/geany.svg\",\n \"URL\": \"https://www.geany.org/download/releases/\"\n }, {\n \"Name\": \"NOI Linux\",\n \"Image\": \"https://www.noi.cn/upload/resources/image/2021/07/16/163780.jpg\",\n \"URL\": \"https://www.noi.cn/gynoi/jsgz/2021-07-16/732450.shtml\"\n }, {\n \"Name\": \"VirtualBox\",\n \"Image\": \"https://www.virtualbox.org/graphics/vbox_logo2_gradient.png\",\n \"URL\": \"https://www.virtualbox.org/wiki/Downloads\"\n }, {\n \"Name\": \"MinGW\",\n \"Image\": \"https://www.mingw-w64.org/logo.svg\",\n \"URL\": \"https://sourceforge.net/projects/mingw/\"\n }];\n for (let i = 0; i < Softwares.length; i++) {\n SoftwareList.innerHTML +=\n \"<li class=\\\"software_item\\\">\" +\n \"<a href=\\\"\" + Softwares[i].URL + \"\\\">\" +\n \"<div class=\\\"item-info\\\">\" +\n \"<div class=\\\"item-img\\\">\" +\n \"<img height=\\\"50\\\" src=\\\"\" + Softwares[i].Image + \"\\\" alt=\\\"点击下载\\\">\" +\n \"</div>\" +\n \"<div class=\\\"item-txt\\\">\" + Softwares[i].Name + \"</div>\" +\n \"</div>\" +\n \"</a>\" +\n \"</li>\";\n }\n }\n } else if (location.pathname == \"/problemstatus.php\") {\n document.querySelector(\"body > div > div.mt-3 > center\").insertBefore(document.querySelector(\"#statics\"), document.querySelector(\"body > div > div.mt-3 > center > table\"));\n document.querySelector(\"body > div > div.mt-3 > center\").insertBefore(document.querySelector(\"#problemstatus\"), document.querySelector(\"body > div > div.mt-3 > center > table\"));\n\n document.querySelector(\"body > div > div.mt-3 > center > table:nth-child(3)\").remove();\n let Temp = document.querySelector(\"#statics\").rows;\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].removeAttribute(\"class\");\n if (Temp[i].children.length == 2) {\n Temp[i].children[1].innerText = Temp[i].children[1].innerText;\n }\n }\n\n document.querySelector(\"#problemstatus > thead > tr\").innerHTML =\n document.querySelector(\"#problemstatus > thead > tr\").innerHTML.replaceAll(\"td\", \"th\");\n document.querySelector(\"#problemstatus > thead > tr > th:nth-child(2)\").innerText = \"运行编号\";\n document.querySelector(\"#problemstatus > thead > tr > th:nth-child(4)\").remove();\n document.querySelector(\"#problemstatus > thead > tr > th:nth-child(4)\").remove();\n document.querySelector(\"#problemstatus > thead > tr > th:nth-child(4)\").remove();\n document.querySelector(\"#problemstatus > thead > tr > th:nth-child(4)\").remove();\n Temp = document.querySelector(\"#problemstatus > thead > tr\").children;\n for (let i = 0; i < Temp.length; i++) {\n Temp[i].removeAttribute(\"class\");\n }\n Temp = document.querySelector(\"#problemstatus > tbody\").children;\n for (let i = 0; i < Temp.length; i++) {\n if (Temp[i].children[5].children[0] != null) {\n Temp[i].children[1].innerHTML = `<a href=\"${Temp[i].children[5].children[0].href}\">${Temp[i].children[1].innerText.trim()}</a>`;\n }\n GetUsernameHTML(Temp[i].children[2], Temp[i].children[2].innerText);\n Temp[i].children[3].remove();\n Temp[i].children[3].remove();\n Temp[i].children[3].remove();\n Temp[i].children[3].remove();\n }\n\n\n let CurrentPage = parseInt(SearchParams.get(\"page\") || 1);\n let PID = Number(SearchParams.get(\"id\"));\n let Pagination = `<nav class=\"center\"><ul class=\"pagination justify-content-center\">`;\n if (CurrentPage != 1) {\n Pagination += `<li class=\"page-item\"><a href=\"https://www.xmoj.tech/problemstatus.php?id=${PID + `&page=1\" class=\"page-link\">&laquo;</a></li><li class=\"page-item\"><a href=\"https://www.xmoj.tech/problemstatus.php?id=` + PID + `&page=` + (CurrentPage - 1) + `\" class=\"page-link\">` + (CurrentPage - 1)}</a></li>`;\n }\n Pagination += `<li class=\"active page-item\"><a href=\"https://www.xmoj.tech/problemstatus.php?id=${PID + `&page=` + CurrentPage + `\" class=\"page-link\">` + CurrentPage}</a></li>`;\n if (document.querySelector(\"#problemstatus > tbody\").children != null && document.querySelector(\"#problemstatus > tbody\").children.length == 20) {\n Pagination += `<li class=\"page-item\"><a href=\"https://www.xmoj.tech/problemstatus.php?id=${PID + `&page=` + (CurrentPage + 1) + `\" class=\"page-link\">` + (CurrentPage + 1) + `</a></li><li class=\"page-item\"><a href=\"https://www.xmoj.tech/problemstatus.php?id=` + PID + `&page=` + (CurrentPage + 1)}\" class=\"page-link\">&raquo;</a></li>`;\n }\n Pagination += `</ul></nav>`;\n document.querySelector(\"body > div > div.mt-3 > center\").innerHTML += Pagination;\n } else if (location.pathname == \"/problem_solution.php\") {\n if (UtilityEnabled(\"CopyMD\")) {\n await fetch(location.href).then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let CopyMDButton = document.createElement(\"button\");\n CopyMDButton.className = \"btn btn-sm btn-outline-secondary copy-btn\";\n CopyMDButton.innerText = \"复制\";\n CopyMDButton.style.marginLeft = \"10px\";\n CopyMDButton.type = \"button\";\n document.querySelector(\"body > div > div.mt-3 > center > h2\").appendChild(CopyMDButton);\n CopyMDButton.addEventListener(\"click\", () => {\n GM_setClipboard(ParsedDocument.querySelector(\"body > div > div > div\").innerText.trim().replaceAll(\"\\n\\t\", \"\\n\").replaceAll(\"\\n\\n\", \"\\n\").replaceAll(\"\\n\\n\", \"\\n\"));\n CopyMDButton.innerText = \"复制成功\";\n setTimeout(() => {\n CopyMDButton.innerText = \"复制\";\n }, 1000);\n });\n });\n }\n let Temp = document.getElementsByClassName(\"prettyprint\");\n for (let i = 0; i < Temp.length; i++) {\n let Code = Temp[i].innerText;\n Temp[i].outerHTML = `<textarea class=\"prettyprint\"></textarea>`;\n Temp[i].value = Code;\n }\n for (let i = 0; i < Temp.length; i++) {\n CodeMirror.fromTextArea(Temp[i], {\n lineNumbers: true,\n mode: \"text/x-c++src\",\n readOnly: true,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\")\n }).setSize(\"100%\", \"auto\");\n }\n } else if (location.pathname == \"/open_contest.php\") {\n let Temp = document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").children;\n let NewsData = [];\n for (let i = 0; i < Temp.length; i += 2) {\n let Title = Temp[i].children[0].innerText;\n let Time = 0;\n if (Temp[i].children[1] != null) {\n Time = Temp[i].children[1].innerText;\n }\n let Body = Temp[i + 1].innerHTML;\n NewsData.push({ \"Title\": Title, \"Time\": new Date(Time), \"Body\": Body });\n }\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").innerHTML = \"\";\n for (let i = 0; i < NewsData.length; i++) {\n let NewsRow = document.createElement(\"div\");\n NewsRow.className = \"cnt-row\";\n let NewsRowHead = document.createElement(\"div\");\n NewsRowHead.className = \"cnt-row-head title\";\n NewsRowHead.innerText = NewsData[i].Title;\n if (NewsData[i].Time.getTime() != 0) {\n NewsRowHead.innerHTML += \"<small class=\\\"ms-3\\\">\" + NewsData[i].Time.toLocaleDateString() + \"</small>\";\n }\n NewsRow.appendChild(NewsRowHead);\n let NewsRowBody = document.createElement(\"div\");\n NewsRowBody.className = \"cnt-row-body\";\n NewsRowBody.innerHTML = NewsData[i].Body;\n NewsRow.appendChild(NewsRowBody);\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-8\").appendChild(NewsRow);\n }\n let MyContestData = document.querySelector(\"body > div > div.mt-3 > div > div.col-md-4 > div:nth-child(2)\").innerHTML;\n let CountDownData = document.querySelector(\"#countdown_list\").innerHTML;\n document.querySelector(\"body > div > div.mt-3 > div > div.col-md-4\").innerHTML = `<div class=\"cnt-row\">\n <div class=\"cnt-row-head title\">我的月赛</div>\n <div class=\"cnt-row-body\">${MyContestData}</div>\n </div>\n <div class=\"cnt-row\">\n <div class=\"cnt-row-head title\">倒计时</div>\n <div class=\"cnt-row-body\">${CountDownData}</div>\n </div>`;\n } else if (location.pathname == \"/showsource.php\") {\n let Code = \"\";\n if (SearchParams.get(\"ByUserScript\") == null) {\n await fetch(\"https://www.xmoj.tech/getsource.php?id=\" + SearchParams.get(\"id\"))\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n Code = Response.substring(0, Response.indexOf(\"/**************************************************************\")).trim();\n });\n }\n else {\n if (localStorage.getItem(\"UserScript-LastUploadedStdTime\") === undefined ||\n new Date().getTime() - localStorage.getItem(\"UserScript-LastUploadedStdTime\") > 1000 * 60 * 60 * 24 * 30) {\n location.href = \"https://www.xmoj.tech/userinfo.php?ByUserScript=1\";\n }\n await new Promise((Resolve) => {\n RequestAPI(\"GetStd\", {\n \"ProblemID\": Number(SearchParams.get(\"pid\"))\n }, (Response) => {\n if (Response.Success) {\n Code = Response.Data.StdCode;\n }\n else {\n Code = Response.Message;\n }\n Resolve();\n });\n });\n }\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `<textarea>${Code}</textarea>`;\n CodeMirror.fromTextArea(document.querySelector(\"body > div > div.mt-3 > textarea\"), {\n lineNumbers: true,\n mode: \"text/x-c++src\",\n readOnly: true,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\")\n }).setSize(\"100%\", \"auto\");\n } else if (location.pathname == \"/ceinfo.php\") {\n await fetch(location.href)\n .then((Result) => {\n return Result.text();\n }).then((Result) => {\n let ParsedDocument = new DOMParser().parseFromString(Result, \"text/html\");\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"\";\n let CodeElement = document.createElement(\"div\");\n CodeElement.className = \"mb-3\";\n document.querySelector(\"body > div > div.mt-3\").appendChild(CodeElement);\n CodeMirror(CodeElement, {\n value: ParsedDocument.getElementById(\"errtxt\").innerHTML.replaceAll(\"&lt;\", \"<\").replaceAll(\"&gt;\", \">\"),\n lineNumbers: true,\n mode: \"text/x-c++src\",\n readOnly: true,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\")\n }).setSize(\"100%\", \"auto\");\n });\n } else if (location.pathname == \"/problem_std.php\") {\n await fetch(\"https://www.xmoj.tech/problem_std.php?cid=\" + SearchParams.get(\"cid\") + \"&pid=\" + SearchParams.get(\"pid\"))\n .then((Response) => {\n return Response.text();\n }).then((Response) => {\n let ParsedDocument = new DOMParser().parseFromString(Response, \"text/html\");\n let Temp = ParsedDocument.getElementsByTagName(\"pre\");\n document.querySelector(\"body > div > div.mt-3\").innerHTML = \"\";\n for (let i = 0; i < Temp.length; i++) {\n let CodeElement = document.createElement(\"div\");\n CodeElement.className = \"mb-3\";\n document.querySelector(\"body > div > div.mt-3\").appendChild(CodeElement);\n CodeMirror(CodeElement, {\n value: Temp[i].innerText,\n lineNumbers: true,\n mode: \"text/x-c++src\",\n readOnly: true,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\")\n }).setSize(\"100%\", \"auto\");\n }\n });\n } else if (location.pathname == \"/mail.php\") {\n if (SearchParams.get(\"other\") == null) {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `<div class=\"row g-2 align-items-center\">\n <div class=\"col-auto form-floating\">\n <input class=\"form-control\" id=\"Username\" placeholder=\" \" spellcheck=\"false\" data-ms-editor=\"true\">\n <label for=\"Username\">搜索新用户</label>\n </div>\n <div class=\"col-auto form-floating\">\n <button class=\"btn btn-outline-secondary\" id=\"AddUser\">\n 添加\n <div class=\"spinner-border spinner-border-sm\" role=\"status\" style=\"display: none;\">\n </button>\n </div>\n </div>\n <table class=\"table mb-3\" id=\"ReceiveTable\">\n <thead>\n <tr>\n <td class=\"col-3\">接收者</td>\n <td class=\"col-7\">最新消息</td>\n <td class=\"col-2\">最后联系时间</td>\n </tr>\n </thead>\n <tbody></tbody>\n </table>\n <div class=\"alert alert-danger mb-3\" role=\"alert\" id=\"ErrorElement\" style=\"display: none;\"></div>`;\n let RefreshMessageList = (Silent = true) => {\n if (!Silent) {\n ReceiveTable.children[1].innerHTML = \"\";\n for (let i = 0; i < 10; i++) {\n let Row = document.createElement(\"tr\"); ReceiveTable.children[1].appendChild(Row);\n for (let j = 0; j < 3; j++) {\n let Cell = document.createElement(\"td\"); Row.appendChild(Cell);\n Cell.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>`;\n }\n }\n }\n RequestAPI(\"GetMailList\", {}, async (ResponseData) => {\n if (ResponseData.Success) {\n ErrorElement.style.display = \"none\";\n let Data = ResponseData.Data.MailList;\n ReceiveTable.children[1].innerHTML = \"\";\n for (let i = 0; i < Data.length; i++) {\n let Row = document.createElement(\"tr\"); ReceiveTable.children[1].appendChild(Row);\n let UsernameCell = document.createElement(\"td\"); Row.appendChild(UsernameCell);\n let UsernameSpan = document.createElement(\"span\"); UsernameCell.appendChild(UsernameSpan);\n GetUsernameHTML(UsernameSpan, Data[i].OtherUser, false, \"https://www.xmoj.tech/mail.php?other=\");\n if (Data[i].UnreadCount != 0) {\n let UnreadCountSpan = document.createElement(\"span\"); UsernameCell.appendChild(UnreadCountSpan);\n UnreadCountSpan.className = \"ms-1 badge text-bg-danger\";\n UnreadCountSpan.innerText = Data[i].UnreadCount;\n }\n let LastsMessageCell = document.createElement(\"td\"); Row.appendChild(LastsMessageCell);\n LastsMessageCell.innerText = Data[i].LastsMessage;\n let SendTimeCell = document.createElement(\"td\"); Row.appendChild(SendTimeCell);\n SendTimeCell.innerHTML = GetRelativeTime(Data[i].SendTime);\n }\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n };\n Username.addEventListener(\"input\", () => {\n Username.classList.remove(\"is-invalid\");\n });\n AddUser.addEventListener(\"click\", () => {\n let UsernameData = Username.value;\n if (UsernameData == \"\") {\n Username.classList.add(\"is-invalid\");\n return;\n }\n AddUser.children[0].style.display = \"\";\n AddUser.disabled = true;\n RequestAPI(\"SendMail\", {\n \"ToUser\": String(UsernameData),\n \"Content\": String(\"您好,我是\" + localStorage.getItem(\"UserScript-Username\"))\n }, (ResponseData) => {\n AddUser.children[0].style.display = \"none\";\n AddUser.disabled = false;\n if (ResponseData.Success) {\n ErrorElement.style.display = \"none\";\n RefreshMessageList();\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n });\n RefreshMessageList(false);\n addEventListener(\"focus\", RefreshMessageList);\n }\n else {\n document.querySelector(\"body > div > div.mt-3\").innerHTML = `<div class=\"row g-2 mb-3\">\n <div class=\"col-md form-floating\">\n <div class=\"form-control\" id=\"ToUser\"></div>\n <label for=\"ToUser\">接收用户</label>\n </div>\n <div class=\"col-md form-floating\">\n <input class=\"form-control\" id=\"Content\" placeholder=\" \">\n <label for=\"Content\">内容</label>\n </div>\n </div>\n <button id=\"Send\" type=\"submit\" class=\"btn btn-primary mb-1\">\n 发送\n <div class=\"spinner-border spinner-border-sm\" role=\"status\" style=\"display: none;\">\n </button>\n <div id=\"ErrorElement\" class=\"alert alert-danger mb-3\" role=\"alert\" style=\"display: none;\"></div>\n <table class=\"table mb-3\" id=\"MessageTable\">\n <thead>\n <tr>\n <td class=\"col-3\">发送者</td>\n <td class=\"col-7\">内容</td>\n <td class=\"col-1\">发送时间</td>\n <td class=\"col-1\">阅读状态</td>\n </tr>\n </thead>\n <tbody></tbody>\n </table>`;\n GetUsernameHTML(ToUser, SearchParams.get(\"other\"));\n let RefreshMessage = (Silent = true) => {\n if (!Silent) {\n MessageTable.children[1].innerHTML = \"\";\n for (let i = 0; i < 10; i++) {\n let Row = document.createElement(\"tr\"); MessageTable.children[1].appendChild(Row);\n for (let j = 0; j < 4; j++) {\n let Cell = document.createElement(\"td\"); Row.appendChild(Cell);\n Cell.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>`;\n }\n }\n }\n RequestAPI(\"GetMail\", {\n \"OtherUser\": String(SearchParams.get(\"other\"))\n }, async (ResponseData) => {\n if (ResponseData.Success) {\n ErrorElement.style.display = \"none\";\n let Data = ResponseData.Data.Mail;\n MessageTable.children[1].innerHTML = \"\";\n for (let i = 0; i < Data.length; i++) {\n let Row = document.createElement(\"tr\"); MessageTable.children[1].appendChild(Row);\n if (!Data[i].IsRead && Data[i].FromUser != CurrentUsername) {\n Row.className = \"table-info\";\n }\n let UsernameCell = document.createElement(\"td\"); Row.appendChild(UsernameCell);\n GetUsernameHTML(UsernameCell, Data[i].FromUser);\n let ContentCell = document.createElement(\"td\"); Row.appendChild(ContentCell);\n ContentCell.innerHTML = PurifyHTML(Data[i].Content);\n let SendTimeCell = document.createElement(\"td\"); Row.appendChild(SendTimeCell);\n SendTimeCell.innerHTML = GetRelativeTime(Data[i].SendTime);\n let IsReadCell = document.createElement(\"td\"); Row.appendChild(IsReadCell);\n IsReadCell.innerHTML = (Data[i].IsRead ? \"已读\" : \"未读\");\n }\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n };\n Content.addEventListener(\"input\", () => {\n Content.classList.remove(\"is-invalid\");\n });\n Content.addEventListener(\"keydown\", (Event) => {\n if (Event.keyCode == 13) {\n Send.click();\n }\n });\n Send.addEventListener(\"click\", () => {\n if (Content.value == \"\") {\n Content.classList.add(\"is-invalid\");\n return;\n }\n Send.disabled = true;\n Send.children[0].style.display = \"\";\n let ContentData = Content.value;\n RequestAPI(\"SendMail\", {\n \"ToUser\": String(SearchParams.get(\"other\")),\n \"Content\": String(ContentData)\n }, (ResponseData) => {\n Send.disabled = false;\n Send.children[0].style.display = \"none\";\n if (ResponseData.Success) {\n ErrorElement.style.display = \"none\";\n Content.value = \"\";\n RefreshMessage();\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n });\n RefreshMessage(false);\n addEventListener(\"focus\", RefreshMessage);\n }\n } else if (location.pathname.indexOf(\"/discuss3\") != -1) {\n if (UtilityEnabled(\"Discussion\")) {\n Discussion.classList.add(\"active\");\n if (location.pathname == \"/discuss3/discuss.php\") {\n let ProblemID = parseInt(SearchParams.get(\"pid\"));\n let Page = Number(SearchParams.get(\"page\")) || 1;\n document.querySelector(\"body > div > div\").innerHTML = `<h3>讨论列表${(isNaN(ProblemID) ? \"\" : ` - 题目` + ProblemID)}</h3>\n <button id=\"NewPost\" type=\"button\" class=\"btn btn-primary\">发布新讨论</button>\n <nav>\n <ul class=\"pagination justify-content-center\" id=\"DiscussPagination\">\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\"><span>&laquo;</span></a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\">${Page - 1}</a></li>\n <li class=\"page-item\"><a class=\"page-link active\" href=\"#\">${Page}</a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\">${Page + 1}</a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\"><span>&raquo;</span></a></li>\n </ul>\n </nav>\n <div id=\"GotoBoard\"></div>\n <div id=\"ErrorElement\" class=\"alert alert-danger\" role=\"alert\" style=\"display: none;\"></div>\n <table id=\"PostList\" class=\"table table-hover\">\n <thead>\n <tr>\n <th class=\"col-1\">编号</th>\n <th class=\"col-3\">标题</th>\n <th class=\"col-3\">作者</th>\n <th class=\"col-1\">题目编号</th>\n <th class=\"col-1\">发布时间</th>\n <th class=\"col-1\">回复数</th>\n <th class=\"col-1\">最后回复</th>\n </tr>\n </thead>\n <tbody>\n </tbody>\n </table>`;\n NewPost.addEventListener(\"click\", () => {\n if (!isNaN(ProblemID)) {\n location.href = \"https://www.xmoj.tech/discuss3/newpost.php?pid=\" + ProblemID;\n }\n else if (SearchParams.get(\"bid\") != null) {\n location.href = \"https://www.xmoj.tech/discuss3/newpost.php?bid=\" + SearchParams.get(\"bid\");\n }\n else {\n location.href = \"https://www.xmoj.tech/discuss3/newpost.php\";\n }\n });\n const RefreshPostList = (Silent = true) => {\n if (!Silent) {\n PostList.children[1].innerHTML = \"\";\n for (let i = 0; i < 10; i++) {\n let Row = document.createElement(\"tr\"); PostList.children[1].appendChild(Row);\n for (let j = 0; j < 7; j++) {\n let Cell = document.createElement(\"td\"); Row.appendChild(Cell);\n Cell.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>`;\n }\n }\n }\n RequestAPI(\"GetPosts\", {\n \"ProblemID\": Number(ProblemID || 0),\n \"Page\": Number(Page),\n \"BoardID\": Number(SearchParams.get(\"bid\") || -1)\n }, async (ResponseData) => {\n if (ResponseData.Success == true) {\n ErrorElement.style.display = \"none\";\n if (!Silent) {\n DiscussPagination.children[0].children[0].href = \"https://www.xmoj.tech/discuss3/discuss.php?\" + (isNaN(ProblemID) ? \"\" : \"pid=\" + ProblemID + \"&\") + \"page=1\";\n DiscussPagination.children[1].children[0].href = \"https://www.xmoj.tech/discuss3/discuss.php?\" + (isNaN(ProblemID) ? \"\" : \"pid=\" + ProblemID + \"&\") + \"page=\" + (Page - 1);\n DiscussPagination.children[2].children[0].href = \"https://www.xmoj.tech/discuss3/discuss.php?\" + (isNaN(ProblemID) ? \"\" : \"pid=\" + ProblemID + \"&\") + \"page=\" + Page;\n DiscussPagination.children[3].children[0].href = \"https://www.xmoj.tech/discuss3/discuss.php?\" + (isNaN(ProblemID) ? \"\" : \"pid=\" + ProblemID + \"&\") + \"page=\" + (Page + 1);\n DiscussPagination.children[4].children[0].href = \"https://www.xmoj.tech/discuss3/discuss.php?\" + (isNaN(ProblemID) ? \"\" : \"pid=\" + ProblemID + \"&\") + \"page=\" + ResponseData.Data.PageCount;\n if (Page <= 1) {\n DiscussPagination.children[0].classList.add(\"disabled\");\n DiscussPagination.children[1].remove();\n }\n if (Page >= ResponseData.Data.PageCount) {\n DiscussPagination.children[DiscussPagination.children.length - 1].classList.add(\"disabled\");\n DiscussPagination.children[DiscussPagination.children.length - 2].remove();\n }\n }\n let Posts = ResponseData.Data.Posts;\n PostList.children[1].innerHTML = \"\";\n if (Posts.length == 0) {\n PostList.children[1].innerHTML = `<tr><td colspan=\"7\">暂无数据</td></tr>`;\n }\n for (let i = 0; i < Posts.length; i++) {\n let Row = document.createElement(\"tr\"); PostList.children[1].appendChild(Row);\n let IDCell = document.createElement(\"td\"); Row.appendChild(IDCell);\n IDCell.innerText = Posts[i].PostID + \" \" + Posts[i].BoardName;\n let TitleCell = document.createElement(\"td\"); Row.appendChild(TitleCell);\n let TitleLink = document.createElement(\"a\"); TitleCell.appendChild(TitleLink);\n TitleLink.href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + Posts[i].PostID;\n if (Posts[i].Lock.Locked) {\n TitleLink.classList.add(\"link-secondary\");\n TitleLink.innerHTML = \"\uD83D\uDD12 \";\n }\n TitleLink.innerHTML += Posts[i].Title;\n let AuthorCell = document.createElement(\"td\"); Row.appendChild(AuthorCell);\n GetUsernameHTML(AuthorCell, Posts[i].UserID);\n let ProblemIDCell = document.createElement(\"td\"); Row.appendChild(ProblemIDCell);\n if (Posts[i].ProblemID != 0) {\n let ProblemIDLink = document.createElement(\"a\"); ProblemIDCell.appendChild(ProblemIDLink);\n ProblemIDLink.href = \"https://www.xmoj.tech/problem.php?id=\" + Posts[i].ProblemID;\n ProblemIDLink.innerText = Posts[i].ProblemID;\n }\n let PostTimeCell = document.createElement(\"td\"); Row.appendChild(PostTimeCell);\n PostTimeCell.innerHTML = GetRelativeTime(Posts[i].PostTime);\n let ReplyCountCell = document.createElement(\"td\"); Row.appendChild(ReplyCountCell);\n ReplyCountCell.innerText = Posts[i].ReplyCount;\n let LastReplyTimeCell = document.createElement(\"td\"); Row.appendChild(LastReplyTimeCell);\n LastReplyTimeCell.innerHTML = GetRelativeTime(Posts[i].LastReplyTime);\n }\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"block\";\n }\n });\n };\n RefreshPostList(false);\n addEventListener(\"focus\", RefreshPostList);\n RequestAPI(\"GetBoards\", {}, (ResponseData) => {\n if (ResponseData.Success === true) {\n let LinkElement = document.createElement(\"a\");\n LinkElement.href = \"https://www.xmoj.tech/discuss3/discuss.php\";\n LinkElement.classList.add(\"me-2\");\n LinkElement.innerText = \"全部\";\n GotoBoard.appendChild(LinkElement);\n for (let i = 0; i < ResponseData.Data.Boards.length; i++) {\n let LinkElement = document.createElement(\"a\");\n LinkElement.href = \"https://www.xmoj.tech/discuss3/discuss.php?bid=\" + ResponseData.Data.Boards[i].BoardID;\n LinkElement.classList.add(\"me-2\");\n LinkElement.innerText = ResponseData.Data.Boards[i].BoardName;\n GotoBoard.appendChild(LinkElement);\n }\n }\n });\n } else if (location.pathname == \"/discuss3/newpost.php\") {\n let ProblemID = parseInt(SearchParams.get(\"pid\"));\n document.querySelector(\"body > div > div\").innerHTML = `<h3>发布新讨论` + (!isNaN(ProblemID) ? ` - 题目` + ProblemID : ``) + `</h3>\n <div class=\"form-group mb-3\" id=\"BoardSelect\">\n <label for=\"Board\" class=\"mb-1\">请选择要发布的板块</label>\n <div class=\"row ps-3\" id=\"Board\">\n </div>\n </div>\n <div class=\"form-group mb-3\">\n <label for=\"Title\" class=\"mb-1\">标题</label>\n <input type=\"text\" class=\"form-control\" id=\"TitleElement\" placeholder=\"请输入标题\">\n </div>\n <div>\n <label for=\"ContentElement\" class=\"mb-1\">回复</label>\n <div class=\"input-group\">\n <textarea class=\"col-6 form-control\" id=\"ContentElement\" rows=\"3\" placeholder=\"请输入内容\"></textarea>\n <div class=\"col-6 form-control\" id=\"PreviewTab\"></div>\n </div>\n <div class=\"cf-turnstile mt-2\" id=\"CaptchaContainer\"></div>\n <button id=\"SubmitElement\" type=\"button\" class=\"btn btn-primary mb-2\" disabled>\n 发布\n <div class=\"spinner-border spinner-border-sm\" role=\"status\" style=\"display: none;\">\n </button>\n </div>\n <div id=\"ErrorElement\" class=\"alert alert-danger\" role=\"alert\" style=\"display: none;\"></div>`;\n let CaptchaSecretKey = \"\";\n unsafeWindow.CaptchaLoadedCallback = () => {\n turnstile.render(\"#CaptchaContainer\", {\n sitekey: CaptchaSiteKey,\n callback: function (CaptchaSecretKeyValue) {\n CaptchaSecretKey = CaptchaSecretKeyValue;\n SubmitElement.disabled = false;\n },\n });\n };\n let TurnstileScript = document.createElement(\"script\");\n TurnstileScript.src = \"https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=CaptchaLoadedCallback\";\n document.body.appendChild(TurnstileScript);\n ContentElement.addEventListener(\"keydown\", (Event) => {\n if (Event.ctrlKey && Event.keyCode == 13) {\n SubmitElement.click();\n }\n });\n ContentElement.addEventListener(\"input\", () => {\n ContentElement.classList.remove(\"is-invalid\");\n PreviewTab.innerHTML = PurifyHTML(marked.parse(ContentElement.value));\n RenderMathJax();\n });\n TitleElement.addEventListener(\"input\", () => {\n TitleElement.classList.remove(\"is-invalid\");\n });\n ContentElement.addEventListener(\"paste\", (EventData) => {\n let Items = EventData.clipboardData.items;\n if (Items.length !== 0) {\n for (let i = 0; i < Items.length; i++) {\n if (Items[i].type.indexOf(\"image\") != -1) {\n let Reader = new FileReader();\n Reader.readAsDataURL(Items[i].getAsFile());\n Reader.onload = () => {\n let Before = ContentElement.value.substring(0, ContentElement.selectionStart);\n let After = ContentElement.value.substring(ContentElement.selectionEnd, ContentElement.value.length);\n const UploadMessage = \"![正在上传图片...]()\";\n ContentElement.value = Before + UploadMessage + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n RequestAPI(\"UploadImage\", {\n \"Image\": Reader.result\n }, (ResponseData) => {\n if (ResponseData.Success) {\n ContentElement.value = Before + `![](https://assets.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})` + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n }\n else {\n ContentElement.value = Before + `![上传失败!]()` + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n }\n });\n };\n }\n }\n }\n });\n SubmitElement.addEventListener(\"click\", async () => {\n ErrorElement.style.display = \"none\";\n let Title = TitleElement.value;\n let Content = ContentElement.value;\n let ProblemID = parseInt(SearchParams.get(\"pid\"));\n if (Title === \"\") {\n TitleElement.classList.add(\"is-invalid\");\n return;\n }\n if (Content === \"\") {\n ContentElement.classList.add(\"is-invalid\");\n return;\n }\n if (document.querySelector(\"#Board input:checked\") === null) {\n ErrorElement.innerText = \"请选择要发布的板块\";\n ErrorElement.style.display = \"block\";\n return;\n }\n SubmitElement.disabled = true;\n SubmitElement.children[0].style.display = \"inline-block\";\n RequestAPI(\"NewPost\", {\n \"Title\": String(Title),\n \"Content\": String(Content),\n \"ProblemID\": Number(isNaN(ProblemID) ? 0 : ProblemID),\n \"CaptchaSecretKey\": String(CaptchaSecretKey),\n \"BoardID\": Number(document.querySelector(\"#Board input:checked\").value)\n }, (ResponseData) => {\n SubmitElement.disabled = false;\n SubmitElement.children[0].style.display = \"none\";\n if (ResponseData.Success == true) {\n location.href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ResponseData.Data.PostID;\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"block\";\n }\n });\n });\n RequestAPI(\"GetBoards\", {}, (ResponseData) => {\n if (ResponseData.Success === true) {\n let Data = ResponseData.Data.Boards;\n for (let i = 0; i < Data.length; i++) {\n let RadioElement = document.createElement(\"div\");\n RadioElement.className = \"col-auto form-check form-check-inline\";\n let RadioInput = document.createElement(\"input\");\n RadioInput.className = \"form-check-input\";\n RadioInput.type = \"radio\";\n RadioInput.name = \"Board\";\n RadioInput.id = \"Board\" + Data[i].BoardID;\n RadioInput.value = Data[i].BoardID;\n RadioElement.appendChild(RadioInput);\n if (SearchParams.get(\"bid\") !== null && SearchParams.get(\"bid\") == Data[i].BoardID) {\n RadioInput.checked = true;\n }\n if (!isNaN(ProblemID)) {\n RadioInput.disabled = true;\n }\n if (Data[i].BoardID == 4) {\n if (!isNaN(ProblemID))\n RadioInput.checked = true;\n RadioInput.disabled = true;\n }\n let RadioLabel = document.createElement(\"label\");\n RadioLabel.className = \"form-check-label\";\n RadioLabel.htmlFor = \"Board\" + Data[i].BoardID;\n RadioLabel.innerText = Data[i].BoardName;\n RadioElement.appendChild(RadioLabel);\n Board.appendChild(RadioElement);\n }\n }\n });\n } else if (location.pathname == \"/discuss3/thread.php\") {\n if (SearchParams.get(\"tid\") == null) {\n location.href = \"https://www.xmoj.tech/discuss3/discuss.php\";\n }\n else {\n let ThreadID = SearchParams.get(\"tid\");\n let Page = Number(SearchParams.get(\"page\")) || 1;\n document.querySelector(\"body > div > div\").innerHTML = `<h3 id=\"PostTitle\"></h3>\n <div class=\"row mb-3\">\n <span class=\"col-5 text-muted\">作者:<div style=\"display: inline-block;\" id=\"PostAuthor\"></div></span>\n <span class=\"col-3 text-muted\">发布时间:<span id=\"PostTime\"></span></span>\n <span class=\"col-2 text-muted\">板块:<span id=\"PostBoard\"></span></span>\n <span class=\"col-2\">\n <button id=\"Delete\" type=\"button\" class=\"btn btn-sm btn-danger\" style=\"display: none;\">\n 删除\n <div class=\"spinner-border spinner-border-sm\" role=\"status\" style=\"display: none;\">\n </button>\n </span>\n </div>\n <div id=\"PostReplies\"></div>\n <nav>\n <ul class=\"pagination justify-content-center\" id=\"DiscussPagination\">\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\"><span>&laquo;</span></a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\">${(Page - 1)}</a></li>\n <li class=\"page-item\"><a class=\"page-link active\" href=\"#\">${Page}</a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\">${(Page + 1)}</a></li>\n <li class=\"page-item\"><a class=\"page-link\" href=\"#\"><span>&raquo;</span></a></li>\n </ul>\n </nav>\n <div>\n <div class=\"container p-0 m-0\">\n <div class=\"row\">\n <div class=\"col\">\n <label for=\"ContentElement\" class=\"mb-1\">回复</label>\n </div>\n <div class=\"col\">\n <div class=\"form-check form-switch\" id=\"ToggleLock\" style=\"display: none\">\n <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"ToggleLockButton\">\n <label class=\"form-check-label\" for=\"ToggleLockButton\">锁定本讨论</label>\n </div>\n </div>\n </div>\n </div>\n <div class=\"input-group\">\n <textarea class=\"col-6 form-control\" id=\"ContentElement\" rows=\"3\" placeholder=\"请输入内容\"></textarea>\n <div class=\"col-6 form-control\" id=\"PreviewTab\"></div>\n </div>\n <div class=\"cf-turnstile mt-2\" id=\"CaptchaContainer\"></div>\n <button id=\"SubmitElement\" type=\"button\" class=\"btn btn-primary mb-2\" disabled>\n 发布\n <div class=\"spinner-border spinner-border-sm\" role=\"status\" style=\"display: none;\">\n </button>\n </div>\n <div id=\"ErrorElement\" class=\"alert alert-danger\" role=\"alert\" style=\"display: none;\"></div>`;\n let CaptchaSecretKey = \"\";\n unsafeWindow.CaptchaLoadedCallback = () => {\n turnstile.render(\"#CaptchaContainer\", {\n sitekey: CaptchaSiteKey,\n callback: function (CaptchaSecretKeyValue) {\n CaptchaSecretKey = CaptchaSecretKeyValue;\n SubmitElement.disabled = false;\n },\n });\n };\n let TurnstileScript = document.createElement(\"script\");\n TurnstileScript.src = \"https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit&onload=CaptchaLoadedCallback\";\n document.body.appendChild(TurnstileScript);\n ContentElement.addEventListener(\"keydown\", (Event) => {\n if (Event.ctrlKey && Event.keyCode == 13) {\n SubmitElement.click();\n }\n });\n ContentElement.addEventListener(\"input\", () => {\n PreviewTab.innerHTML = PurifyHTML(marked.parse(ContentElement.value));\n RenderMathJax();\n });\n ContentElement.addEventListener(\"paste\", (EventData) => {\n let Items = EventData.clipboardData.items;\n if (Items.length !== 0) {\n for (let i = 0; i < Items.length; i++) {\n if (Items[i].type.indexOf(\"image\") != -1) {\n let Reader = new FileReader();\n Reader.readAsDataURL(Items[i].getAsFile());\n Reader.onload = () => {\n let Before = ContentElement.value.substring(0, ContentElement.selectionStart);\n let After = ContentElement.value.substring(ContentElement.selectionEnd, ContentElement.value.length);\n const UploadMessage = \"![正在上传图片...]()\";\n ContentElement.value = Before + UploadMessage + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n RequestAPI(\"UploadImage\", {\n \"Image\": Reader.result\n }, (ResponseData) => {\n if (ResponseData.Success) {\n ContentElement.value = Before + `![](https://assets.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})` + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n }\n else {\n ContentElement.value = Before + `![上传失败!]()` + After;\n ContentElement.dispatchEvent(new Event(\"input\"));\n }\n });\n };\n }\n }\n }\n });\n let RefreshReply = (Silent = true) => {\n if (!Silent) {\n PostTitle.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span>`;\n PostAuthor.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span>`;\n PostTime.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span>`;\n PostBoard.innerHTML = `<span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span>`;\n PostReplies.innerHTML = \"\";\n for (let i = 0; i < 10; i++) {\n PostReplies.innerHTML += `<div class=\"card mb-3\">\n <div class=\"card-body\">\n <div class=\"row mb-3\">\n <span class=\"col-6\"><span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span></span>\n <span class=\"col-6\"><span class=\"placeholder col-${Math.ceil(Math.random() * 6)}\"></span></span>\n </div>\n <hr>\n <span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>\n <span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>\n <span class=\"placeholder col-${Math.ceil(Math.random() * 12)}\"></span>\n </div>\n </div>`;\n }\n }\n RequestAPI(\"GetPost\", {\n \"PostID\": Number(ThreadID),\n \"Page\": Number(Page)\n }, async (ResponseData) => {\n if (ResponseData.Success == true) {\n let OldScrollTop = document.documentElement.scrollTop;\n let LockButtons = !IsAdmin && ResponseData.Data.Lock.Locked;\n if (!Silent) {\n DiscussPagination.children[0].children[0].href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ThreadID + \"&page=1\";\n DiscussPagination.children[1].children[0].href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ThreadID + \"&page=\" + (Page - 1);\n DiscussPagination.children[2].children[0].href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ThreadID + \"&page=\" + Page;\n DiscussPagination.children[3].children[0].href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ThreadID + \"&page=\" + (Page + 1);\n DiscussPagination.children[4].children[0].href = \"https://www.xmoj.tech/discuss3/thread.php?tid=\" + ThreadID + \"&page=\" + ResponseData.Data.PageCount;\n if (Page <= 1) {\n DiscussPagination.children[0].classList.add(\"disabled\");\n DiscussPagination.children[1].remove();\n }\n if (Page >= ResponseData.Data.PageCount) {\n DiscussPagination.children[DiscussPagination.children.length - 1].classList.add(\"disabled\");\n DiscussPagination.children[DiscussPagination.children.length - 2].remove();\n }\n if (IsAdmin || ResponseData.Data.UserID == CurrentUsername) {\n Delete.style.display = \"\";\n }\n }\n PostTitle.innerText = ResponseData.Data.Title + (ResponseData.Data.ProblemID == 0 ? \"\" : ` - 题目` + ResponseData.Data.ProblemID);\n PostAuthor.innerHTML = \"<span></span>\";\n GetUsernameHTML(PostAuthor.children[0], ResponseData.Data.UserID);\n PostTime.innerHTML = GetRelativeTime(ResponseData.Data.PostTime);\n PostBoard.innerHTML = ResponseData.Data.BoardName;\n let Replies = ResponseData.Data.Reply;\n PostReplies.innerHTML = \"\";\n for (let i = 0; i < Replies.length; i++) {\n let CardElement = document.createElement(\"div\"); PostReplies.appendChild(CardElement);\n CardElement.className = \"card mb-3\";\n let CardBodyElement = document.createElement(\"div\"); CardElement.appendChild(CardBodyElement);\n CardBodyElement.className = \"card-body row\";\n let CardBodyRowElement = document.createElement(\"div\"); CardBodyElement.appendChild(CardBodyRowElement);\n CardBodyRowElement.className = \"row mb-3\";\n let AuthorElement = document.createElement(\"span\"); CardBodyRowElement.appendChild(AuthorElement);\n AuthorElement.className = \"col-4 text-muted\";\n let AuthorSpanElement = document.createElement(\"span\"); AuthorElement.appendChild(AuthorSpanElement);\n AuthorSpanElement.innerText = \"作者:\";\n let AuthorUsernameElement = document.createElement(\"span\"); AuthorElement.appendChild(AuthorUsernameElement);\n GetUsernameHTML(AuthorUsernameElement, Replies[i].UserID);\n let SendTimeElement = document.createElement(\"span\"); CardBodyRowElement.appendChild(SendTimeElement);\n SendTimeElement.className = \"col-4 text-muted\";\n SendTimeElement.innerHTML = \"发布时间:\" + GetRelativeTime(Replies[i].ReplyTime);\n\n let OKButton;\n if (!LockButtons) {\n let ButtonsElement = document.createElement(\"span\"); CardBodyRowElement.appendChild(ButtonsElement);\n ButtonsElement.className = \"col-4\";\n let ReplyButton = document.createElement(\"button\"); ButtonsElement.appendChild(ReplyButton);\n ReplyButton.type = \"button\";\n ReplyButton.className = \"btn btn-sm btn-info\";\n ReplyButton.innerText = \"回复\";\n ReplyButton.addEventListener(\"click\", () => {\n let Content = Replies[i].Content;\n while (Content.startsWith(\">\")) {\n Content = Content.substring(Content.indexOf(\"\\n\") + 1);\n }\n Content = Content.trim();\n Content = Content.split(\"\\n\").map((Line) => {\n return \"> \" + Line;\n }).join(\"\\n\");\n ContentElement.value += Content + `\\n\\n@${Replies[i].UserID} `;\n ContentElement.focus();\n });\n let DeleteButton = document.createElement(\"button\"); ButtonsElement.appendChild(DeleteButton);\n DeleteButton.type = \"button\";\n DeleteButton.className = \"btn btn-sm btn-danger ms-1\";\n DeleteButton.innerText = \"删除\";\n DeleteButton.style.display = (IsAdmin || Replies[i].UserID == CurrentUsername ? \"\" : \"none\");\n DeleteButton.addEventListener(\"click\", () => {\n DeleteButton.disabled = true;\n DeleteButton.lastChild.style.display = \"\";\n RequestAPI(\"DeleteReply\", {\n \"ReplyID\": Number(Replies[i].ReplyID)\n }, (ResponseData) => {\n if (ResponseData.Success == true) {\n RefreshReply();\n }\n else {\n DeleteButton.disabled = false;\n DeleteButton.lastChild.style.display = \"none\";\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n });\n let DeleteSpin = document.createElement(\"div\"); DeleteButton.appendChild(DeleteSpin);\n DeleteSpin.className = \"spinner-border spinner-border-sm\";\n DeleteSpin.role = \"status\";\n DeleteSpin.style.display = \"none\";\n OKButton = document.createElement(\"button\"); ButtonsElement.appendChild(OKButton);\n OKButton.type = \"button\";\n OKButton.style.display = \"none\";\n OKButton.className = \"btn btn-sm btn-success ms-1\";\n OKButton.innerText = \"确认\";\n let OKSpin = document.createElement(\"div\"); OKButton.appendChild(OKSpin);\n OKSpin.className = \"spinner-border spinner-border-sm\";\n OKSpin.role = \"status\";\n OKSpin.style.display = \"none\";\n OKButton.addEventListener(\"click\", () => {\n OKButton.disabled = true;\n OKButton.lastChild.style.display = \"\";\n RequestAPI(\"EditReply\", {\n ReplyID: Number(Replies[i].ReplyID),\n Content: String(ContentEditor.value)\n }, (ResponseData) => {\n if (ResponseData.Success == true) {\n RefreshReply();\n }\n else {\n OKButton.disabled = false;\n OKButton.lastChild.style.display = \"none\";\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"\";\n }\n });\n });\n let CancelButton = document.createElement(\"button\"); ButtonsElement.appendChild(CancelButton);\n CancelButton.type = \"button\";\n CancelButton.style.display = \"none\";\n CancelButton.className = \"btn btn-sm btn-secondary ms-1\";\n CancelButton.innerText = \"取消\";\n CancelButton.addEventListener(\"click\", () => {\n CardBodyElement.children[2].style.display = \"\";\n CardBodyElement.children[3].style.display = \"none\";\n EditButton.style.display = \"\";\n OKButton.style.display = \"none\";\n CancelButton.style.display = \"none\";\n });\n let EditButton = document.createElement(\"button\"); ButtonsElement.appendChild(EditButton);\n EditButton.type = \"button\";\n EditButton.className = \"btn btn-sm btn-warning ms-1\";\n EditButton.innerText = \"编辑\";\n EditButton.style.display = (IsAdmin || Replies[i].UserID == CurrentUsername ? \"\" : \"none\");\n EditButton.addEventListener(\"click\", () => {\n CardBodyElement.children[2].style.display = \"none\";\n CardBodyElement.children[3].style.display = \"\";\n EditButton.style.display = \"none\";\n OKButton.style.display = \"\";\n CancelButton.style.display = \"\";\n });\n }\n\n let CardBodyHRElement = document.createElement(\"hr\"); CardBodyElement.appendChild(CardBodyHRElement);\n\n let ReplyContentElement = document.createElement(\"div\"); CardBodyElement.appendChild(ReplyContentElement);\n ReplyContentElement.innerHTML = PurifyHTML(marked.parse(Replies[i].Content)).replaceAll(/@([a-zA-Z0-9]+)/g, `<b>@</b><span class=\"ms-1 Usernames\">$1</span>`);\n if (Replies[i].EditTime != null) {\n if (Replies[i].EditPerson == Replies[i].UserID) {\n ReplyContentElement.innerHTML += `<span class=\"text-muted\" style=\"font-size: 12px\">最后编辑于${GetRelativeTime(Replies[i].EditTime)}</span>`;\n }\n else {\n ReplyContentElement.innerHTML += `<span class=\"text-muted\" style=\"font-size: 12px\">最后被<span class=\"Usernames\">${Replies[i].EditPerson}</span>编辑于${GetRelativeTime(Replies[i].EditTime)}</span>`;\n }\n }\n let ContentEditElement = document.createElement(\"div\"); CardBodyElement.appendChild(ContentEditElement);\n ContentEditElement.classList.add(\"input-group\");\n ContentEditElement.style.display = \"none\";\n let ContentEditor = document.createElement(\"textarea\"); ContentEditElement.appendChild(ContentEditor);\n ContentEditor.className = \"form-control col-6\";\n ContentEditor.rows = 3;\n ContentEditor.value = Replies[i].Content;\n if (ContentEditor.value.indexOf(\"<br>\") != -1) {\n ContentEditor.value = ContentEditor.value.substring(0, ContentEditor.value.indexOf(\"<br>\"));\n }\n ContentEditor.addEventListener(\"keydown\", (Event) => {\n if (Event.ctrlKey && Event.keyCode == 13) {\n OKButton.click();\n }\n });\n let PreviewTab = document.createElement(\"div\"); ContentEditElement.appendChild(PreviewTab);\n PreviewTab.className = \"form-control col-6\";\n PreviewTab.innerHTML = PurifyHTML(marked.parse(ContentEditor.value));\n ContentEditor.addEventListener(\"input\", () => {\n PreviewTab.innerHTML = PurifyHTML(marked.parse(ContentEditor.value));\n RenderMathJax();\n });\n ContentEditor.addEventListener(\"paste\", (EventData) => {\n let Items = EventData.clipboardData.items;\n if (Items.length !== 0) {\n for (let i = 0; i < Items.length; i++) {\n if (Items[i].type.indexOf(\"image\") != -1) {\n let Reader = new FileReader();\n Reader.readAsDataURL(Items[i].getAsFile());\n Reader.onload = () => {\n let Before = ContentEditor.value.substring(0, ContentEditor.selectionStart);\n let After = ContentEditor.value.substring(ContentEditor.selectionEnd, ContentEditor.value.length);\n const UploadMessage = \"![正在上传图片...]()\";\n ContentEditor.value = Before + UploadMessage + After;\n ContentEditor.dispatchEvent(new Event(\"input\"));\n RequestAPI(\"UploadImage\", {\n \"Image\": Reader.result\n }, (ResponseData) => {\n if (ResponseData.Success) {\n ContentEditor.value = Before + `![](https://assets.xmoj-bbs.tech/GetImage?ImageID=${ResponseData.Data.ImageID})` + After;\n ContentEditor.dispatchEvent(new Event(\"input\"));\n }\n else {\n ContentEditor.value = Before + `![上传失败!]()` + After;\n ContentEditor.dispatchEvent(new Event(\"input\"));\n }\n });\n };\n }\n }\n }\n });\n }\n\n let UsernameElements = document.getElementsByClassName(\"Usernames\");\n for (let i = 0; i < UsernameElements.length; i++) {\n GetUsernameHTML(UsernameElements[i], UsernameElements[i].innerText, true);\n }\n\n let CodeElements = document.querySelectorAll(\"#PostReplies > div > div > div:nth-child(3) > pre > code\");\n for (let i = 0; i < CodeElements.length; i++) {\n let ModeName = \"text/x-c++src\";\n if (CodeElements[i].className == \"language-c\") {\n ModeName = \"text/x-csrc\";\n }\n else if (CodeElements[i].className == \"language-cpp\") {\n ModeName = \"text/x-c++src\";\n }\n CodeMirror(CodeElements[i].parentElement, {\n value: CodeElements[i].innerText,\n mode: ModeName,\n theme: (UtilityEnabled(\"DarkMode\") ? \"darcula\" : \"default\"),\n lineNumbers: true,\n readOnly: true\n }).setSize(\"100%\", \"auto\");\n CodeElements[i].remove();\n }\n\n if (LockButtons) {\n let LockElement = ContentElement.parentElement.parentElement;\n LockElement.innerHTML = \"讨论已于 \" + await GetRelativeTime(ResponseData.Data.Lock.LockTime) + \" 被 \";\n let LockUsernameSpan = document.createElement(\"span\"); LockElement.appendChild(LockUsernameSpan);\n GetUsernameHTML(LockUsernameSpan, ResponseData.Data.Lock.LockPerson);\n LockElement.innerHTML += \" 锁定\";\n LockElement.classList.add(\"mb-5\");\n }\n\n if (IsAdmin) {\n ToggleLock.style.display = \"inline-block\";\n ToggleLockButton.checked = ResponseData.Data.Lock.Locked;\n ToggleLockButton.onclick = () => {\n ToggleLockButton.disabled = true;\n ErrorElement.style.display = \"none\";\n RequestAPI((ToggleLockButton.checked ? \"LockPost\" : \"UnlockPost\"), {\n \"PostID\": Number(ThreadID)\n }, (LockResponseData) => {\n ToggleLockButton.disabled = false;\n if (LockResponseData.Success) {\n RefreshReply();\n } else {\n ErrorElement.style.display = \"\";\n ErrorElement.innerText = \"错误:\" + LockResponseData.Message;\n ToggleLockButton.checked = !ToggleLockButton.checked;\n }\n });\n };\n }\n\n Style.innerHTML += \"img {\";\n Style.innerHTML += \" width: 50%;\";\n Style.innerHTML += \"}\";\n\n RenderMathJax();\n\n if (Silent) {\n scrollTo({\n top: OldScrollTop,\n behavior: \"instant\"\n });\n }\n }\n else {\n PostTitle.innerText = \"错误:\" + ResponseData.Message;\n }\n });\n };\n Delete.addEventListener(\"click\", () => {\n Delete.disabled = true;\n Delete.children[0].style.display = \"inline-block\";\n RequestAPI(\"DeletePost\", {\n \"PostID\": Number(SearchParams.get(\"tid\"))\n }, (ResponseData) => {\n Delete.disabled = false;\n Delete.children[0].style.display = \"none\";\n if (ResponseData.Success == true) {\n location.href = \"https://www.xmoj.tech/discuss3/discuss.php\";\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"block\";\n }\n });\n });\n SubmitElement.addEventListener(\"click\", async () => {\n ErrorElement.style.display = \"none\";\n SubmitElement.disabled = true;\n SubmitElement.children[0].style.display = \"inline-block\";\n RequestAPI(\"NewReply\", {\n \"PostID\": Number(SearchParams.get(\"tid\")),\n \"Content\": String(ContentElement.value),\n \"CaptchaSecretKey\": String(CaptchaSecretKey)\n }, async (ResponseData) => {\n SubmitElement.disabled = false;\n SubmitElement.children[0].style.display = \"none\";\n if (ResponseData.Success == true) {\n RefreshReply();\n ContentElement.value = \"\";\n PreviewTab.innerHTML = \"\";\n while (PostReplies.innerHTML.indexOf(\"placeholder\") != -1) {\n await new Promise((resolve) => {\n setTimeout(resolve, 100);\n });\n }\n ContentElement.focus();\n ContentElement.scrollIntoView();\n turnstile.reset();\n }\n else {\n ErrorElement.innerText = ResponseData.Message;\n ErrorElement.style.display = \"block\";\n }\n });\n });\n RefreshReply(false);\n addEventListener(\"focus\", RefreshReply);\n }\n }\n }\n }\n }\n}\n
5
+ Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
6
+ <+>UTF-8
7
+ ===================================================================
8
+ diff --git a/XMOJ.user.js b/XMOJ.user.js
9
+ --- a/XMOJ.user.js (revision ef12ff509740c221a55a522732d342ec9be71c0f)
10
+ +++ b/XMOJ.user.js (date 1705754433337)
11
+ @@ -1210,7 +1210,7 @@
12
+ document.querySelector("body > div > div.mt-3 > center").lastChild.style.marginLeft = "10px";
13
+ //修复提交按钮
14
+ let SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(12)');
15
+ - if (SubmitLink == null) { //如果是比赛题目
16
+ + if (SubmitLink == null) { //a special type of problem
17
+ SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(10)');
18
+ }
19
+ if (SubmitLink == null) {
20
+ @@ -3411,6 +3411,7 @@
21
+ Pagination += `</ul></nav>`;
22
+ document.querySelector("body > div > div.mt-3 > center").innerHTML += Pagination;
23
+ } else if (location.pathname == "/problem_solution.php") {
24
+ + document.querySelector("h2.lang_en").remove(); //fixes #332
25
+ if (UtilityEnabled("CopyMD")) {
26
+ await fetch(location.href).then((Response) => {
27
+ return Response.text();
@@ -0,0 +1,4 @@
1
+ <changelist name="Uncommitted_changes_before_Checkout_at_2024_1_20,_20_40_[Changes]" date="1705754441726" recycled="true" deleted="true">
2
+ <option name="PATH" value="$PROJECT_DIR$/.idea/shelf/Uncommitted_changes_before_Checkout_at_2024_1_20,_20_40_[Changes]/shelved.patch" />
3
+ <option name="DESCRIPTION" value="Uncommitted changes before Checkout at 2024/1/20, 20:40 [Changes]" />
4
+ </changelist>
package/.idea/vcs.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="VcsDirectoryMappings">
4
+ <mapping directory="" vcs="Git" />
5
+ </component>
6
+ </project>
@@ -0,0 +1,87 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="AutoImportSettings">
4
+ <option name="autoReloadType" value="SELECTIVE" />
5
+ </component>
6
+ <component name="ChangeListManager">
7
+ <list default="true" id="5e980562-396b-40f1-9d8f-058ee50050b2" name="Changes" comment="fix #332">
8
+ <change beforePath="$PROJECT_DIR$/XMOJ.user.js" beforeDir="false" afterPath="$PROJECT_DIR$/XMOJ.user.js" afterDir="false" />
9
+ </list>
10
+ <option name="SHOW_DIALOG" value="false" />
11
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
12
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
13
+ <option name="LAST_RESOLUTION" value="IGNORE" />
14
+ </component>
15
+ <component name="Git.Settings">
16
+ <option name="RECENT_BRANCH_BY_REPOSITORY">
17
+ <map>
18
+ <entry key="$PROJECT_DIR$" value="9a1884976b31cc96a04fd2e6e5ba983a269c0087" />
19
+ </map>
20
+ </option>
21
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
22
+ </component>
23
+ <component name="MarkdownSettingsMigration">
24
+ <option name="stateVersion" value="1" />
25
+ </component>
26
+ <component name="ProjectColorInfo">{
27
+ &quot;associatedIndex&quot;: 8
28
+ }</component>
29
+ <component name="ProjectId" id="2bDel13UW5QC5DaJyPIfOCjNLw2" />
30
+ <component name="ProjectViewState">
31
+ <option name="hideEmptyMiddlePackages" value="true" />
32
+ <option name="showLibraryContents" value="true" />
33
+ </component>
34
+ <component name="PropertiesComponent"><![CDATA[{
35
+ "keyToString": {
36
+ "RunOnceActivity.OpenProjectViewOnStart": "true",
37
+ "RunOnceActivity.ShowReadmeOnStart": "true",
38
+ "git-widget-placeholder": "dev",
39
+ "node.js.detected.package.eslint": "true",
40
+ "node.js.detected.package.tslint": "true",
41
+ "node.js.selected.package.eslint": "(autodetect)",
42
+ "node.js.selected.package.tslint": "(autodetect)",
43
+ "nodejs_package_manager_path": "npm",
44
+ "vue.rearranger.settings.migration": "true"
45
+ }
46
+ }]]></component>
47
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
48
+ <component name="TaskManager">
49
+ <task active="true" id="Default" summary="Default task">
50
+ <changelist id="5e980562-396b-40f1-9d8f-058ee50050b2" name="Changes" comment="" />
51
+ <created>1705754225086</created>
52
+ <option name="number" value="Default" />
53
+ <option name="presentableId" value="Default" />
54
+ <updated>1705754225086</updated>
55
+ <workItem from="1705754231968" duration="364000" />
56
+ <workItem from="1705754620181" duration="179000" />
57
+ </task>
58
+ <task id="LOCAL-00001" summary="fix #332">
59
+ <option name="closed" value="true" />
60
+ <created>1705754532454</created>
61
+ <option name="number" value="00001" />
62
+ <option name="presentableId" value="LOCAL-00001" />
63
+ <option name="project" value="LOCAL" />
64
+ <updated>1705754532454</updated>
65
+ </task>
66
+ <option name="localTasksCounter" value="2" />
67
+ <servers />
68
+ </component>
69
+ <component name="TypeScriptGeneratedFilesManager">
70
+ <option name="version" value="3" />
71
+ </component>
72
+ <component name="Vcs.Log.Tabs.Properties">
73
+ <option name="TAB_STATES">
74
+ <map>
75
+ <entry key="MAIN">
76
+ <value>
77
+ <State />
78
+ </value>
79
+ </entry>
80
+ </map>
81
+ </option>
82
+ </component>
83
+ <component name="VcsManagerConfiguration">
84
+ <MESSAGE value="fix #332" />
85
+ <option name="LAST_COMMIT_MESSAGE" value="fix #332" />
86
+ </component>
87
+ </project>
@@ -0,0 +1,8 @@
1
+ Hi, there! Welcome to XMOJ-Script!
2
+
3
+ We are happy to have you here with us!
4
+
5
+ We believe that you must be excited to contribute to our repo, but first, please read the contribution guidelines!
6
+
7
+ > [!IMPORTANT]
8
+ > 请注意, 外部开发者应向`extern-contrib`提交 pull requests。
package/README.md CHANGED
@@ -67,6 +67,7 @@
67
67
 
68
68
  ### 安装
69
69
  请参考 [官网介绍](https://www.xmoj-bbs.tech) 。
70
+ 如果您无法打开该网站,请前往[这里](https://scriptcat.org/zh-CN/script-show-page/1500/)安装。
70
71
 
71
72
  ### 贡献
72
73
  您想为我们的脚本添砖加瓦吗?快加入我们,为小明的OJ用户创造更美好的环境!(具体要求参见Code Of Conduct)
package/Update.json CHANGED
@@ -911,6 +911,33 @@
911
911
  }
912
912
  ],
913
913
  "Notes": "No release notes were provided for this release."
914
+ },
915
+ "1.1.14": {
916
+ "UpdateDate": 1705756153752,
917
+ "Prerelease": true,
918
+ "UpdateContents": [
919
+ {
920
+ "PR": 355,
921
+ "Description": "fix #332"
922
+ },
923
+ {
924
+ "PR": 356,
925
+ "Description": "增加script-cat统计模块"
926
+ }
927
+ ],
928
+ "Notes": "收集用户的版本信息,设备型号等非敏感数据 + 修复题解标题"
929
+ },
930
+ "1.1.15": {
931
+ "UpdateDate": 1705807807990,
932
+ "Prerelease": true,
933
+ "UpdateContents": [
934
+ {
935
+ "PR": 357,
936
+ "Description": "cleanup"
937
+ }
938
+ ],
939
+ "Notes": "This release fixes a lot of things"
940
+
914
941
  }
915
942
  }
916
943
  }
package/XMOJ.user.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // ==UserScript==
2
2
  // @name XMOJ
3
- // @version 1.1.13
3
+ // @version 1.1.15
4
4
  // @description XMOJ增强脚本
5
5
  // @author @XMOJ-Script-dev, @langningchen and the community
6
6
  // @namespace https://github/langningchen
@@ -29,6 +29,7 @@
29
29
  // @icon data:image/x-icon;base64,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
30
30
  // ==/UserScript==
31
31
 
32
+
32
33
  /**
33
34
  * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
34
35
  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
@@ -1210,7 +1211,7 @@ else {
1210
1211
  document.querySelector("body > div > div.mt-3 > center").lastChild.style.marginLeft = "10px";
1211
1212
  //修复提交按钮
1212
1213
  let SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(12)');
1213
- if (SubmitLink == null) { //如果是比赛题目
1214
+ if (SubmitLink == null) { //a special type of problem
1214
1215
  SubmitLink = document.querySelector('.mt-3 > center:nth-child(1) > a:nth-child(10)');
1215
1216
  }
1216
1217
  if (SubmitLink == null) {
@@ -3415,6 +3416,9 @@ int main()
3415
3416
  Pagination += `</ul></nav>`;
3416
3417
  document.querySelector("body > div > div.mt-3 > center").innerHTML += Pagination;
3417
3418
  } else if (location.pathname == "/problem_solution.php") {
3419
+ if (UtilityEnabled("RemoveUseless")) {
3420
+ document.querySelector("h2.lang_en").remove(); //fixes #332
3421
+ }
3418
3422
  if (UtilityEnabled("CopyMD")) {
3419
3423
  await fetch(location.href).then((Response) => {
3420
3424
  return Response.text();
package/eula.md CHANGED
@@ -1,3 +1,6 @@
1
+ > [!NOTE]
2
+ > This eula only applies to our instance of xmoj-bbs, not xmoj-bbs itself. (xmoj-bbs is licenced under AGPL)
3
+
1
4
  ### XMOJ讨论区用户服务协议
2
5
 
3
6
  欢迎阅读《XMOJ讨论区用户服务协议》(以下简称“本协议”)。本协议阐述之条款和条件适用于您(以下简称“用户”)使用XMOJ讨论区的各种产品和服务。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xmoj-script",
3
- "version": "1.1.13",
3
+ "version": "1.1.15",
4
4
  "description": "an improvement script for xmoj.tech",
5
5
  "main": "AddonScript.js",
6
6
  "scripts": {