Luogu Tasks

在洛谷侧边栏显示题单与自己存的题

As of 2021-04-02. See the latest version.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name 			Luogu Tasks
// @namespace 		http://tampermonkey.net/
// @version 		1.1
// @run-at			document-start
// @description 	在洛谷侧边栏显示题单与自己存的题
// @author 			__OwO__
// @match 			https://www.luogu.com.cn/*
// @grant       	GM_setValue
// @grant        	GM_getValue
// @grant			unsafeWindow
// @require 		https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js
// @require 		https://cdn.staticfile.org/sweetalert/2.1.2/sweetalert.min.js
// ==/UserScript==

window.onload = async () => {
	const inject_lantency = 500;

	let configs = {
		set train(v) {
			GM_setValue("problem-helper-local-train-list", v);
		},
		get train() {
			return GM_getValue("problem-helper-local-train-list");
		},
		set local(v) {
			GM_setValue("problem-helper-local-id", v);
		},
		get local() {
			return GM_getValue("problem-helper-local-id");
		},
		set hideac(v) {
			GM_setValue("problem-helper-hide-aced", v);
		},
		get hideac() {
			return GM_getValue("problem-helper-hide-aced");
		},
	};

	let local_problems;
	let geticon = (uid, pid, scr, fscr, stat = null) => {
		let res;
		let ua = (uid, pid) =>
			`<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512" class="icon svg-inline--fa fa-times fa-w-11" data-v-303bbf52="" style="transform: scale(1.2); color: rgb(231, 76, 60);"><path data-v-1b44b3e6="" fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" class=""></path></svg></a>`;
		let ac = (uid, pid) =>
			`<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="icon svg-inline--fa fa-check fa-w-16" data-v-303bbf52="" style="color: rgb(82, 196, 26);"><path data-v-1b44b3e6="" fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg></a>`;
		let nt = (uid, pid) =>
			`<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="minus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="icon svg-inline--fa fa-minus fa-w-14" data-v-303bbf52="" style="opacity: 0.7;"><path data-v-1b44b3e6="" fill="currentColor" d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z" class=""></path></svg></a>`;
		if (scr == fscr || stat) res = ac(uid, pid);
		else if (scr == null) res = nt(uid, pid);
		else res = ua(uid, pid);
		return (
			`<span data-v-3fb75f36="" style="font-weight: bold;">` + res + `</span>`
		);
	};
	let renderList = (title, content, float) =>
		`
			<div
				data-v-796309f8=""
				data-v-3fb75f36=""
				class="card padding-default"
				data-v-6febb0e8=""
				id="problem-helper-container"
			>
				${float}
				<h4 data-v-3fb75f36="" data-v-796309f8="" class="lfe-h4">${title}</h4>
				<div class="problem-helper-inner" style="display:none;">
				${content}
				</div>
				<div data-v-e4b7c2ca="" data-v-3fb75f36="" class="expand-tip lfe-caption" data-v-796309f8="" >
					<span class="problem-helper-fold-off" style="display:none;" data-v-e4b7c2ca=""><svg data-v-e4b7c2ca="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="chevron-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-chevron-up fa-w-14" ><path data-v-e4b7c2ca="" fill="currentColor" d="M4.465 366.475l7.07 7.071c4.686 4.686 12.284 4.686 16.971 0L224 178.053l195.494 195.493c4.686 4.686 12.284 4.686 16.971 0l7.07-7.071c4.686-4.686 4.686-12.284 0-16.97l-211.05-211.051c-4.686-4.686-12.284-4.686-16.971 0L4.465 349.505c-4.687 4.686-4.687 12.284 0 16.97z" class=""></path></svg> 隐藏列表</span>
					<span class="problem-helper-fold-on" data-v-e4b7c2ca=""><svg data-v-e4b7c2ca="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="chevron-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-chevron-down fa-w-14"><path data-v-e4b7c2ca="" fill="currentColor" d="M443.5 162.6l-7.1-7.1c-4.7-4.7-12.3-4.7-17 0L224 351 28.5 155.5c-4.7-4.7-12.3-4.7-17 0l-7.1 7.1c-4.7 4.7-4.7 12.3 0 17l211 211.1c4.7 4.7 12.3 4.7 17 0l211-211.1c4.8-4.7 4.8-12.3.1-17z" class=""></path></svg> 查看列表</span>
				</div>
			</div>
		`;
	let loadProblemList = async (id) => {
		return new Promise((res, rej) => {
			$.get(`https://www.luogu.com.cn/training/${id}?_contentOnly=any`).then(
				(task) => {
					task = task.currentData.training;
					let getList = (x, is_local) => {
						let id = task.problems[x].problem.pid;
						if (
							configs.hideac &&
							task.userScore.status[id] &&
							id != configs.local
						)
							return "";
						return `
							<div>
								<div>
									<span data-v-3a151854="">
										<a
											data-v-303bbf52=""
											data-v-3fb75f36=""
											href="/record/list?pid=${id}&amp;user=${task.userScore.user.uid}"
											class="color-default"
											style="text-decoration: none;"
										>
											${geticon(
												id,
												task.userScore.user.uid,
												task.userScore.score[id],
												task.problems[x].problem.fullScore,
												task.userScore.status[id]
											)}
										</a>
										${
											is_local
												? `
										<a
											data-v-3fb75f36=""
											style="float: right;font-weight: light;"
											class="problem-helper-delete-from-list"
											data="${id}"
										>
											<svg data-v-4121e124="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-times fa-w-10"><path data-v-4121e124="" fill="currentColor" d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z" class=""></path></svg>
										</a>
										`
												: ""
										}
									</span>
									<a
										class="colored problem-helper-text"
										style="padding-left: 3px"
										href="/problemnew/show/${id}"
										target="_blank"
									>
										<b>${id}</b> ${task.problems[x].problem.title}
									</a>
								</div>
							</div>`;
					};
					let content = "",
						float =
							'<a style="float:right;" data="${task.id}" data-v-303bbf52="" data-v-3fb75f36=""  href="#" class="problem-helper-train-remove color-default">删除</a>';
					if (id == configs.local)
						(float = ""),
							(local_problems = task.problems.map((u) => u.problem.pid));
					for (let i in task.problems)
						content += getList(i, id == configs.local);
					res(renderList(task.title, content, float));
				}
			);
		});
	};
	let saveTrain = async (problems) => {
		return new Promise((r) => {
			$.ajax({
				type: "POST",
				url: `https://www.luogu.com.cn/api/training/editProblems/${configs.local}`,
				beforeSend: function (request) {
					request.setRequestHeader(
						"x-csrf-token",
						$("meta[name='csrf-token']")[0].content
					);
				},
				contentType: "application/json;charset=UTF-8",
				data: JSON.stringify({ pids: problems }),
				success: () => r(),
			});
		});
	};
	let saveConfig = async (config) => {
		return new Promise((r) => {
			$.ajax({
				type: "POST",
				url: `https://www.luogu.com.cn/paste/new`,
				beforeSend: function (request) {
					request.setRequestHeader(
						"x-csrf-token",
						$("meta[name='csrf-token']")[0].content
					);
				},
				contentType: "application/json;charset=UTF-8",
				data: JSON.stringify({
					public: false,
					data: "#lgtsk" + JSON.stringify(config),
				}),
				success: () => r(),
			});
		});
	};
	let loadConfig = () => {
		return new Promise((r) => {
			$.get("https://www.luogu.com.cn/paste?_contentOnly").then((u) => {
				u = u.currentData.pastes.result;
				let nc = null;
				for (let i in u) {
					try {
						if (u[i].data.substr(0, 6) !== "#lgtsk") continue;
						let k = u[i].data;
						nc = JSON.parse(k.substr(6, k.lentgh));
						break;
					} catch (e) {}
				}
				if (!nc) return r(0);
				configs.train = nc.train;
				configs.local = nc.local;
				configs.hideac = nc.hideac;
				r(1);
			});
		});
	};
	let getScore = async (sett) => {
		if (sett.method == "train")
			return {
				uid: sett.task.userScore.user.uid,
				scr: sett.task.userScore.score[sett.id],
				fscr: sett.task.problems[sett.id].problem.fullScore,
			};
		else if (sett.method == "local")
			return new Promise((res, rej) => {
				$.get(`https://www.luogu.com.cn/problem/${sett.id}?_contentOnly`).then(
					(u) => {
						res({
							uid: u.currentUser.uid,
							scr: u.currentData.problem.score,
							fscr: u.currentData.problem.fullScore,
						});
					}
				);
			});
	};
	// let loadLocalProblem = async () => {
	// 	let local = GM_getValue("problem-helper-local-list");
	// 	let getList = async (id, opt = 1) => {
	// 		let h = "";
	// 		if (opt) {
	// 			let info = await getScore({ method: "local", id: id });
	// 			h = geticon(info.uid, id, info.scr, info.fscr);
	// 		}
	// 		return `
	// 			<div>
	// 				<div>
	// 					${h}
	// 					<span data-v-3a151854="">
	// 						<a
	// 							data-v-303bbf52=""
	// 							data-v-3fb75f36=""
	// 							href="#"
	// 							class="color-default"
	// 							style="text-decoration: none;"
	// 						>
	// 						<span
	// 							data-v-3fb75f36=""
	// 							style="float: right;font-weight: light;"
	// 							data="${id}"
	// 							class="problem-helper-delete-from-list"
	// 						>
	// 						删除
	// 						</span>
	// 						</a>
	// 					</span>
	// 					<a
	// 						class="colored problem-helper-text
	// 						style="padding-left: 3px"
	// 						href="/problemnew/show/${id}"
	// 						target="_blank"
	// 					>
	// 						<b>${id}</b> ${local[id]}
	// 					</a>
	// 				</div>
	// 			</div>`;
	// 	};
	// 	let content = "";
	// 	for (let i in local) content += await getList(i);
	// 	return renderList("本地列表", content, "");
	// };
	function renderItem(title, id) {
		return `
			<div>
				<div>
					<span data-v-3a151854="">
						<a
							data-v-303bbf52=""
							data-v-3fb75f36=""
							href="/record/list?pid=${id}&amp;user=${task.userScore.user.uid}"
							class="color-default"
							style="text-decoration: none;"
						>
							${geticon(
								id,
								task.userScore.user.uid,
								task.userScore.score[id],
								task.problems[x].problem.fullScore,
								task.userScore.status[id]
							)}
						</a>
					</span>
					<a
						class="colored problem-helper-text
						style="padding-left: 3px"
						href="/problemnew/show/${id}"
						target="_blank"
					>
						<b>${id}</b> ${task.problems[x].problem.title}
					</a>
				</div>
			</div>
		`;
	}
	async function loaderProblemEntry() {
		let lists = "";
		let urls = configs.train || [];
		// console.log(urls);
		if (configs.local && !urls[configs.local]) urls[configs.local] = "本地列表";
		for (let i in urls) lists += await loadProblemList(i);
		lists += renderList(
			"设置",
			`<div data-v-59a1d633="" data-v-83961efe="" class="row">
			<div data-v-72d91c56="" data-v-59a1d633="" class="checkbox" data-v-83961efe=""><input id="problem-helper-hide-aced" type="checkbox" value="65560" ${
				configs.hideac ? 'checked=""' : ""
			}">   <lable>
          	隐藏已通过题目
			</label> </div>
			<div> 
				<label>本地题单</label>
				<input data-v-a7f7c968="" type="text" placeholder="题单id" class="lfe-form-sz-middle" style+"width: 30%;" value="${
					configs.local || ""
				}" id="problem-helper-set-local-list">
			</div>
			<div>
				<a id="problem-helper-save">保存到洛谷云剪贴板</a>
				<a id="problem-helper-load">从洛谷云剪贴板加载</a>
			</div>
			</div>`,
			""
		);
		$("#problem-helper-entry").html(lists);
		$(".problem-helper-fold-on").click((u) => {
			u = $(u.target);
			u.parent().prev(".problem-helper-inner").removeAttr("style");
			u.attr("style", "display:none;");
			u.prev(".problem-helper-fold-off").removeAttr("style");
		});
		$(".problem-helper-fold-off").click((u) => {
			u = $(u.target);
			u.parent().prev(".problem-helper-inner").attr("style", "display:none;");
			u.attr("style", "display:none;");
			u.next(".problem-helper-fold-on").removeAttr("style");
		});
		$("#problem-helper-hide-aced").click((u) => {
			u = $(u.target);
			configs.hideac = u[0].checked;
			unsafeWindow._feInstance.$swalToastSuccess("修改成功");
			loaderProblemEntry();
		});
		$("#problem-helper-save").click((u) => {
			saveConfig(configs);
			unsafeWindow._feInstance.$swalToastSuccess("保存成功");
			loaderProblemEntry();
		});
		$("#problem-helper-load").click(async (u) => {
			if (await loadConfig())
				unsafeWindow._feInstance.$swalToastSuccess("加载成功");
			else unsafeWindow._feInstance.$swalToastError("加载失败");
			loaderProblemEntry();
		});
		$("#problem-helper-set-local-list").keydown(function (e) {
			if (e.keyCode == 13) {
				configs.local = $("#problem-helper-set-local-list").val();
				unsafeWindow._feInstance.$swalToastSuccess("修改成功");
				loaderProblemEntry();
			}
		});
		$("#problem-helper-add-to-list").click((u) => {
			let r = unsafeWindow.location.href.split("/");
			r = r[r.length - 1];
			while (r[r.length - 1] == "#") r = r.slice(0, r.length - 1);
			if (!unsafeWindow._feInjection.currentData.problem.title) return;
			if (local_problems.indexOf(r) == -1) local_problems.push(r);
			saveTrain(local_problems);
			unsafeWindow._feInstance.$swalToastSuccess("添加成功");
			loaderProblemEntry();
		});
		$(".problem-helper-delete-from-list").click((u) => {
			u = $(u.target).parents(".problem-helper-delete-from-list");
			let r = u.attr("data");
			let now = local_problems;
			let newone = [];
			for (let i in now) if (now[i] != r) newone[i] = now[i];
			saveTrain(newone);
			unsafeWindow._feInstance.$swalToastSuccess("删除成功");
			loaderProblemEntry();
		});
		$(".problem-helper-train-remove").click((u) => {
			u = $(u.target);
			let r = u.attr("data");
			let now = configs.train;
			let newone = {};
			for (let i in now) if (i != r) newone[i] = now[i];
			configs.train = now;
			unsafeWindow._feInstance.$swalToastSuccess("删除成功");
			loaderProblemEntry();
		});
	}
	let deferredInjectProblemPage = () => {
		$("#problem-helper-container").remove();
		$(".side").prepend(
			renderList(
				"做题助手",
				'<div id="problem-helper-entry"></div>',
				'<a style="float:right;" data-v-303bbf52="" data-v-3fb75f36=""  href="#" id="problem-helper-add-to-list" class="color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>添加至列表</a >'
			)
		);
		loaderProblemEntry();
	};
	let loadTrainList = (id) => {
		let local = configs.train;
		let getList = (id) => {
			return `
				<div>
					<div>
						<span data-v-3a151854="">
							<a
								style="text-decoration: none;float: right;font-weight: light;"
								data="${id}"
								class="color-default problem-helper-delete-from-list"
								data-v-303bbf52=""
								data-v-3fb75f36=""
								href="#"
							>
								<svg data-v-4121e124="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-times fa-w-10"><path data-v-4121e124="" fill="currentColor" d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z" class=""></path></svg>
							</a>
						</span>
						<a
							class="colored problem-helper-text"
							style="padding-left: 3px"
							href="https://www.luogu.com.cn/training/${id}#information"
							target="_blank"
						>
							<b>${id}</b> ${local[id]}
						</a>
					</div>
				</div>`;
		};
		let lists = "";
		for (let i in local) lists += getList(i);
		return lists;
	};
	let loaderTrainEntry = async () => {
		let lists = loadTrainList();
		$("#problem-helper-entry").html(lists);
		$(".problem-helper-fold-on").click((u) => {
			u = $(u.target);
			u.parent().prev(".problem-helper-inner").removeAttr("style");
			u.attr("style", "display:none;");
			u.prev(".problem-helper-fold-off").removeAttr("style");
		});
		$(".problem-helper-fold-off").click((u) => {
			u = $(u.target);
			u.parent().prev(".problem-helper-inner").attr("style", "display:none;");
			u.attr("style", "display:none;");
			u.next(".problem-helper-fold-on").removeAttr("style");
		});
		$("#problem-helper-add-to-list").click((u) => {
			let r = unsafeWindow.location.href.split("/");
			r = r[r.length - 1].split("#")[0];
			if (!unsafeWindow._feInjection.currentData.training.title) return;
			let now = configs.train;
			if (!now) now = {};
			now[r] = unsafeWindow._feInjection.currentData.training.title;
			configs.train = now;
			unsafeWindow._feInstance.$swalToastSuccess("添加成功");
			loaderTrainEntry();
		});
		$(".problem-helper-delete-from-list").click((u) => {
			u = $(u.target).parents(".problem-helper-delete-from-list");
			let r = u.attr("data");
			let now = configs.train;
			let newone = {};
			for (let i in now) if (i != r) newone[i] = now[i];
			configs.train = newone;
			unsafeWindow._feInstance.$swalToastSuccess("删除成功");
			loaderProblemEntry();
		});
	};
	let deferredInjectTrainPage = () => {
		$("#problem-helper-container").remove();
		$(".side").prepend(
			renderList(
				"做题助手",
				'<div id="problem-helper-entry"></div>',
				'<a style="float:right;" data-v-303bbf52="" data-v-3fb75f36=""  href="#" id="problem-helper-add-to-list" class="color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>添加至列表</a>'
			)
		);
		loaderTrainEntry();
	};
	let deferredInjectProblemlist = () => {
		$(".problem-helper-inlist-adder").remove();
		let pid = "",
			name = "";
		let h = (pid, name) => `
			<a style="float:right; padding-right: 2em;" data="${pid}" name="${name}" data-v-303bbf52="" data-v-3fb75f36=""  href="#" class="problem-helper-inlist-adder color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>
        		添加
     		</a>`;
		let rows = $(".row");
		let trim = (s) => {
			return s.replace(/(^\s*)|(\s*$)/g, "");
		};
		rows.each((u) => {
			u = $(rows[u]);
			pid = u.children(".pid").text();
			name = u.children(".title").children(".title").text();
			name = trim(name);
			u.children(".title").prepend(h(pid, name));
		});
		$(".problem-helper-inlist-adder").click((u) => {
			u = $(u.target);
			let r = u.attr("data"),
				s = u.attr("name");
			let now = GM_getValue("problem-helper-local-list");
			if (!now) now = {};
			now[r] = s;
			GM_setValue("problem-helper-local-list", now);
			unsafeWindow._feInstance.$swalToastSuccess("添加成功");
		});
	};

	/* main controller */
	let inject = () => {
		if (
			unsafeWindow.location.href.includes(
				"problem/list"
			) /*deferredInjectProblemlist();*/
		);
		else if (unsafeWindow.location.href.includes("training"))
			deferredInjectTrainPage(), deferredInjectProblemlist();
		else if (unsafeWindow.location.href.includes("problem"))
			deferredInjectProblemPage();
	};
	$(".entry").click(() => setTimeout(inject, inject_lantency));
	$("a").click(() => setTimeout(inject, inject_lantency));
	$("button").click(() => setTimeout(inject, inject_lantency));
	setTimeout(inject, 100);
	$(document.body).append(
		`<style>
		.problem-helper-text{
			-webkit-line-clamp: 1; overflow: hidden; display: -webkit-box;
			-webkit-box-orient: vertical; white-space: normal;
		}
		.expand-tip > span[data-v-e4b7c2ca] {
			-webkit-user-select: none;
			-moz-user-select: none;
			-ms-user-select: none;
			cuser-select: none;
			cursor: pointer;
			color: rgba(0, 0, 0, .3);
		}
		.expand-tip[data-v-e4b7c2ca] {
			text-align: center;
		}
		.expand-tip > span[data-v-e4b7c2ca]:hover {
			color: inherit;
		}
		</style>`
	);
};