Greasy Fork

Greasy Fork is available in English.

(改)百度网盘会员青春版

《也许同类型中最好用?》系列、LinkSwift 官方扩展 - 虚拟百度网盘身份信息为会员,支持隐藏云一朵、使用视频倍速、生成/查看/下载 AI字幕、修改头像、用户名、等级、SVIP 10 ID 等功能,自定义程度超高!

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

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

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         (改)百度网盘会员青春版
// @author       hmjz100、Gwen
// @namespace    github.com/hmjz100
// @version      1.2.7.3
// @description  《也许同类型中最好用?》系列、LinkSwift 官方扩展 - 虚拟百度网盘身份信息为会员,支持隐藏云一朵、使用视频倍速、生成/查看/下载 AI字幕、修改头像、用户名、等级、SVIP 10 ID 等功能,自定义程度超高!
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAA1bSURBVHgB7VoJcFXVGf5PgkISkhcIL2GRzAMrKBYFtCjEDjyjw4DRGrcEp0pSTShuvIB1EMEkMq2jtRiLLGoliYAQrICJyAygOJWkILZBR61IS56CAgkZHmRhaXJPz7689wJZO9NOfrjJXc6993z/8v3/f24AeqVXeqVX/ocEQScF1xTHA/SZChAR36EbHWO/tdXYb2tsq76mx/jR+OyPoRPSBzoh+Pu3Xz7w5Xe+I4dqoan5HNEa1RvW1+kuOYUQOYmB/iTnsNAuEvv8Nx+P1X1Y7Jj7dAC5A/FhGNyDXID/XuyHFkhHE7P3QwekwxamYMvX7/aVl1VyJPKnfBIOGg9YKMQWh86e3ORIsMCBs9/ANcWwIj5WX+M6cLtdUPjUvYHE2BgvSsltN+gI6IDgw+vzd1bs81UwsABg/pSzESAvBFbqRFrRBksBOmI/CKjcyCOP152CxS9sjG8437IZVxe3O6zaDZhY9s7Dh44XlL35kTKn4cTc6+RDlS8jBR4UGGwA1S7NroGtAMd4h7K4CA+6UdDLVm/zwL/xZuhOwISgPHXHThYvf36TOMGnISKX+ibRAeLGRPwyUta3X8FcVECl4xzLVbENnoIWY8hvanesgAM9h/Ge6n/C21sqp+I9xS9DO+SigCnY5jPOrqXPlsWfOB6gwCyrUUzqCId9ggCgQUqgkrDpbwdDqOuCYVmuX6SfhZhW6bV171XCF99858N//dMs6CpgiLxkS8mybZ662lMcLNZxKchYWFoFcBBcaTnlGMzKEoxjqMUEalk+6JokSsXk5HjJq5vhaG2gCFe+Pg46C5gycsWGqmur9x60qEdiMs+Z5CTD2cHCBSUI7oZBjIuhVZGUZmRQ43XqdvgDles7xjMaSHpc8NI78acbzm/Gu9omsTYBM0Yu3+cr31AZgk5nIK1zrOzAB4QwMW6DccUNPE45CKkYMEhPWlyPkTFONsQtfrT+FKx6Z5cH+rRs7hBgXLOGMPKxgrLVHxknVZrAEiCzKoqwSMp0OQdwG3FpTBaCiYvfz3K0SNIavH2/2nc0uW2v+hJKy6um4k/eyA+HDYWCLfbU1jbvWppf5qkncRtWIRAax/oamCwK0kqjr7kCrkuZAFdeeyXERPVlZSWmpSXZmk43gv9fh6G4tBwam87oZyADGDYITFjUMSo0B4zqjMjSeRkwbnRyFprycGmbgCnYJsLIS+aVKrDBgNpQALUxEqbXJENOR/WPghzfL2HCZMIlkaSSjYgEaGnhdbTcxPHGsu2w4d0dBptjAdqwqiBOFe9idqRY4eWnMEh/otTXFj4QGDbIPR55s/1yrrZLR15S/H5ZlaeeJHQdqLqgCBEkfyEkig8FVrrr00sehQk3jLXUo3expm4i0TH9wrg+tOnKsljn/yRYvp0mJLZ41XuExE7vMklMAaYkVb6haurOis+4lWRxgRAKmqYgJTLCMctBEJrWOTU9YxokjxgGoYoK9Zna2pNQsW23XU1Z4DUry3jVOV2PMfI2fHukDpa9+7EHWs8pEmPdEv5+XVb1ngMFFZSRZeODkVEkcxsq1JykkBVj6pJ25597r7O0VHe8HkpXlrF4dcSssEhJjY3N0EDiV8a8ZGExd8SPTWBynOYJ1XQY89i65yv4yTD3VLzjNR+6dXZRHzHLuaxGBlAuhpBNSnRetHg0CcvBWGnDSjtEiGXRoMSBwpp8fMmKMvi0qpoTPXmBsJIAhNX7FPnw5yL5HvpmR/SKsoRV97DU5mjwgsiovPF+JUyfeHU+2eWAD/vrxmmSskoIDpzNT2QhjBR5cKLCFlj2QjIyKibKNC7bCFjrHuUsQhzBetK6INiYTgJrMuR+p/gCWUwuTYKV5Uk8nzkL1QcPx+NtKz0RWkdiblZ4IZtjhHo1U2r3VbEswDQRF7UFwZhrRokpI5WHZfpSHCCeF5KfhSLAcGtZsEjXlvHN7xcbtTp5H2VtKszCCe44P2FIT3PT2eA52voglpNWUHkSQMcOnyibSY3/R6gjROQe4lYPevSph2Drpp3Q2NAIvP3h/c9xEtuHan4gMdwMDlZRBJLtzSkIYExrDqhSSDUV3PpGnIsbE12xfjR9jp8BJmCLbs+cXETjGCsf44gUGQkXUw9EYMUJBtXPKh8pfXMLPLkoR51JHJwA2Y9k2nnY2N/54aew9s870LG6k6IOF7ndsKTIgMhR6YySJ9YVGp2DOmaXIXfGZBg+yMUKkEj6o7Bo0963Vj0+jlj4yppvj1rmRRKsyYACsNY26BworEynduSHWvbCq0mVBRERfGNh4hj5y1G5ZeTwJJh03VVQ9dnXtBlAwalJAhdpEaylIAjN3XRgpncCPHbHlP1o+q9n0jO68Gg9n535q9T9Kam6SJAuZdK8GadCiUiPk2TGXJ/WPrhs3VZ4dekaqCVuq54qZ2WFDD9OSnBB/tyZwlIybLCKSxWnYHAHMo7FOPo/7cafwvy7U/fDmUu9YJlRvpcuvUb0rX5p8dueA18eDqlPzYW34DLPtLD6jWwGnXjTePCMHA5JJF3R+IVWh9XVI5MHE6Bx3L1buHsvX7MV3t2xl81QLwtpwIAMa5qkSfbpEtMVl7lhxeP3+V1R/bw0dsMC5qDXk3q6adfvF5d5vq85btexAKGbBRB09aNY1NEuj0Vvq0Gwa9HR/eDFwjlw+WWJAnALfP7VIfC9UBLktpxJ1KIB1op1SGslVihgCPGStQse9Mf162uBtV1aamDETH9MVIz3N89l+BPIUmgIWC4Qtr/FOgQAFNGhEAVhmTN58dHQfBbWbNxuaJ27tnRdXToi5GCtVEmUDvUWXorAELJmvfyJ+8KCDQtYgY6O8T5ZmOlPSHSpAoCTFUL4Qr0piAYejKbdHEutIUC0Oo567mmat636lVuUL9livVoir5jHopobMtAFK5/ICAwf6AoLtk3AEnRSUnz6gucyAgPdcWCTlaPBOI61GqHcTDK5MI8u+KVj8onKFY5p3p9ps5HzR+sDjMZw0PoVB6qtLs8OIRywYm4GaQf7twmW4YKLCK5ZN+5EXaD6aV8xac7Pqlc44chKgATDtaNjomHE5ZfZXiIZXfhmyvVj4K4ZN/H4pcTltMLvXtsEH+yutsEaFuV1M39XLOGAtQtnwdABrnQ0bfaWC+G5KGAO+q0s/6G64iWL1tMVCU4cqqC3QYulGXZ846Rr4Zlnc3njHxnJNxpvBhtbBYgAfLS2Hu7NW8rerTMFlks+SLI/5ajY6L6wypcBo4YnZaFbZpdeDEu7FuLRiAdLPB533vwF6crNQsEKyxs98h2/mALhet8QPauyCMPREwF44rerQaxmYpbMBWi2Dm0nUph398141FB3YXvAthswm+LlDxaNGZNc+MhjM1iq4USENDPzis9o0jF88cVBXWBI4FI7wUJOfbLva8he8Ef48cRJWYtQgEjHr0ZLc+28e1Ih7YYxz6FpcwqgvTigg4IPril4v2Jf/uriD0PzLyjXUwXKrbdOIjX0IMARcoWTFxzM/SlLk/0GwtDbPtrLFgBkuxfSCHALix8Ycm5Lgdzpkwo7Albe3WHBB0oLNmyszF+/4ROTRJgtRX7VpCbZNEzFpHI3YMvwjghQWkxgxFtxo4kiYCdDbtpNr6Bbcn3QQenUB3E0elYB/scaD5nZrHUbdwMvmRCyqi4FDIU5Z3qEzQHAj3l7iHSzL02Tk0Ysm5ZSglI7DrbTgBnoqx7Iwl+VuBoaz9255YN9YWprfexYYPRHcEeuURjhwMcwlCD/SkB+wKOdT+70yZ8TsNnQSenQB/EQOY+zc2bdvD91ylhFVA62P4vYQLBRfWGrsOCCwizv8Ctpk8bC/AzS+Vxy6VTognQJMBqfHSAfo73zHpnhHzsmWRYVGIzqSC6WYzBqbMOtrW9GogqTXymlX9DOJ+8ebw1EOOlkUT0AXZCuWRg06EV5d/pHehJZ3MmvfmIEr4ixKC8BrOLfrKDMhQbRVrPOZ0Vepj8uNu5m5G27ZGyvdBkwFQLaHxcd5X1xYaY/if6FjayMQH28touUoIZdub3RPNBn0Pp4uS/D74q91Gt+LumKdAtgKgx0fwGaNBtg97F6RcRoMMQinByHjacxsCvnzwwMT4rzdodlpXQbYCoU9LCEAel/eGZmIHFQrOW2PA/rY/3FgF9E4psOPR5Kwc7LJJ2Pq1vBiml0v+BPi8cdqw9UZy1cTaqnsxo06LUvDdaIW+DNwNpFWaTzGZCObnl4C3SzdKuFpdC/jhucEJe97Jn7ob/6IohDPpDrdVE6EdH5zM+EoQP7Z/cEWP6eHhI08aGSK5Ldvufn3gXB1ZX+mM7pGovvLnn3pcKoYYmFKHVOCfSQ9BhgKmjiw69MGJ1cuDgnTRFVEDuxnEs6H5SX4YXbJ19NwM4ugB6UHgVMBU16qOA2AiTv/lSWdhDiIM0/jMm5PQVmpl5fiLw9C5ZKp2vpjghKySnAlW9QkPnrt39GmvxTDChdmhFgX0He3AL4L0iPsHRbgv/yehbpifP/9s13nliyAD94QFyAFCzEsjlF8P8s9G8uyOaBXumVXumVXrmw/AdT224dpRDt7wAAAABJRU5ErkJggg==
// @license      AGPL-3.0-or-later
// @homepage     https://github.com/hmjz100/BaiduNetDiskYouthMember/
// @homepageURL  https://github.com/hmjz100/BaiduNetDiskYouthMember/
// @support      https://github.com/hmjz100/BaiduNetDiskYouthMember/issues
// @supportURL   https://github.com/hmjz100/BaiduNetDiskYouthMember/issues
// @require      https://unpkg.com/[email protected]/dist/jquery.min.js
// @require      https://unpkg.com/[email protected]/dist/sweetalert2.min.js
// @resource     SwalLigt https://unpkg.com/[email protected]/dist/sweetalert2.min.css
// @run-at       document-start
// @early-start
// @match        *://pan.baidu.com/*
// @match        *://yun.baidu.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_getResourceText
// @grant        GM_registerMenuCommand
// @grant        unsafeWindow
// @compatible	 Chrome
// @compatible	 Edge
// @compatible	 Firefox
// @compatible	 Safari
// @compatible	 Opera
// ==/UserScript==

(function $baidu() {
	// 严格模式,确保代码安全执行,不越界
	"use strict";
	// unsafeWindow 检测,适用于 Via 这类无 unsafeWindow 的浏览器
	if (typeof (unsafeWindow) === "undefined") window.unsafeWindow = window;

	let temp = {
		// 脚本已包含设置 UI,所以请不要修改此处的代码。
		defaults: {
			vip: true,
			svip: true,
			previous: false,
			name: "百湿不得其解",
			photo: "https://bkimg.cdn.bcebos.com/pic/cdbf6c81800a19d8bc3e5cfd95ab958ba61ea9d3e8b3",
			// desc: "What's your problem? | 业绩增长凌驾于用户体验,简单经营替代了简单可依赖,我们与用户渐行渐远,我们与创业初期坚守的使命和价值观渐行渐远。",
			level: 10,
			point: 100000,
			vip_id: "000001",
			endtime: 253402185600,
			unAnalytics: true,
			unAI_Yiduo: true,
			unPViewer: false,
			unVerSwitch: false,
			unTab_aiNote: true,
			unTab_aiStudy: false,
			unTab_aiCourseware: true,
			unTab_aiDraft: false,
			iLoveAD: false,
			debug: false,
		},
		swalDefault: {
			position: "center",
			heightAuto: false,
			scrollbarPadding: false,
			confirmButtonText: `确认`,
			denyButtonText: `拒绝`,
			cancelButtonText: `取消`
		},
		hooker: new WeakMap(),
		url: (url = location) => url.host + url.pathname + url.search + url.hash
	}

	/*
	防止代码因其他原因被执行多次
	代码出自 “Via 轻插件”,作者谷花泰
	*/
	let key = encodeURIComponent("(改)百度网盘会员青春版:主代码");
	if (window[key]) return;
	window[key] = true;

	let mount = idontknow("BaiduNetDiskYouthMember");
	let info = {
		author: GM_info.script?.author,
		name: GM_info.script?.name,
		version: (GM_info.script?.version || "1.2.7.3"),
		icon: (GM_info.script?.icon || "data:image/png;base64,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"),
		maction: GM_info.scriptaction,
		mversion: GM_info.version,
	};

	let base = {
		hooker: {
			toString: function () {
				if (temp.hooker.has(this)) return `function ${this.name}() { [native code] }`;
				return originalToString.call(this);
			},
			toLocaleString: function () {
				if (temp.hooker.has(this)) return `function ${this.name}() { [native code] }`;
				return originalToLocaleString.call(this);
			},
			attachShadow(options) {
				if (options?.mode === "closed") {
					options.mode = "open";
					console.log("【(改)百度网盘会员青春版】Hook Shadow\n新增:", this);
				};
				return originalAttachShadow.call(this, options);
			},
			async fetch(input, init = {}) {
				let url = typeof input === "string" ? input : input?.url || "";
				url = new URL(url, location.origin);
				if (rules.some(r => r.match(url) && r.condition() && r.runat === "url")) url = base.hooker.universal("fetch", url, url, "url");
				if (rules.some(r => r.match(url) && r.condition() && r.runat === "header")) {
					if (!init.headers) init.headers = {};

					let tempHeaders = {};
					if (init.headers instanceof Headers) {
						for (let [key, value] of init.headers.entries()) {
							tempHeaders[key] = value;
						}
					} else {
						tempHeaders = { ...init.headers };
					}

					init.headers = new Headers(base.hooker.universal("fetch", url, tempHeaders, "header"));
				}
				if (rules.some(r => r.match(url) && r.condition() && r.runat === "end")) {
					try {
						let response = await originalFetch.call(this, url, init);
						let responseText = await response.text();

						let res = base.hooker.universal("fetch", url, responseText, "end");

						return new Response(res, {
							status: response.status,
							statusText: response.statusText,
							headers: response.headers
						});
					} catch (e) {
						return originalFetch.call(this, url, init);
					}
				}
				if (rules.some(r => r.match(url) && r.condition() && r.runat === "start")) {
					try {
						let res = base.hooker.universal("fetch", url, null, "start");
						return new Response(res, {
							status: 200,
							statusText: "OK",
							headers: { "Content-Type": "plain/text" }
						});
					} catch (e) {
						return originalFetch.call(this, url, init);
					}
				}
				return originalFetch.call(this, url, init);
			},
			send(data) {
				let url = this[mount];
				if (this.headers) {
					for (let [name, value] of Object.entries(this.headers)) {
						originalSetRequestHeader.call(this, name, value);
					}
				}
				if (rules.find(rule => rule.match(url) && rule.condition() && rule.runat === "start")) {
					try {
						let res = base.hooker.universal("XHR", url, null, "start");
						Object.defineProperty(this, "responseText", {
							writable: true,
						});
						Object.defineProperty(this, "response", {
							writable: true,
						});
						this.response = res;
						this.responseText = res;
						["readystatechange", "load", "loadend"].forEach(prop => {
							this.dispatchEvent(new Event(prop));
							if (typeof this[prop] === "function") this[prop]();
							if (typeof this[`on${prop}`] === "function") this[`on${prop}`]();
						});
						return true; // 显式 return
					} catch (e) {
						return originalSend.apply(this, arguments);
					}
				}
				return originalSend.apply(this, arguments);
			},
			open(method, input) {
				let url = new URL(input, location.origin);
				if (rules.some(r => r.match(url) && r.condition() && r.runat === "url")) url = base.hooker.universal("XHR", url, url, "url");
				this[mount] = url;
				this.addEventListener("readystatechange", function () {
					if (this.readyState === 4) {
						if (rules.some(r => r.match(url) && r.condition() && r.runat === "end")) {
							let response = this.response;
							if (this.responseType === "" || this.responseType === "text") response = this.responseText;

							let res = base.hooker.universal("XHR", url, response, "end");
							Object.defineProperty(this, "responseText", {
								writable: true,
							});
							Object.defineProperty(this, "response", {
								writable: true,
							});
							this.response = res;
							this.responseText = res;
						}
					}
				});
				return originalOpen.call(this, method, url);
			},
			setRequestHeader(name, value) {
				let url = this[mount];
				if (url && rules.some(r => r.match(url) && r.condition() && r.runat === "header")) {
					if (!this.headers) this.headers = {};
					this.headers[name] = value;
					this.headers = base.hooker.universal("XHR", url, { ...this.headers }, "header");
					return true; // 显式 return
				}
				return originalSetRequestHeader.call(this, name, value);
			},
			sendBeacon(input, data) {
				let url = new URL(input, location.origin);
				if (rules.some(rule => rule.match(url) && rule.condition() && rule.runat === "start")) {
					data = base.hooker.universal("sendBeacon", url, data, "start");
					return true;
				}
				return originalSendBeacon.call(this, url, data);
			},
			Image: function Image(...args) {
				return new Proxy(new OriginalImage(...args), {
					set(target, prop, value) {
						if (prop === "src") {
							let url = new URL(value, location.origin);
							if (rules.some(r => r.match(url) && r.condition() && r.runat === "image")) {
								// if (user.debug) console.log(`${log_head} Image`, "\n请求地址:", url.href, "\n模拟回复: 成功");
								return true; // 显式 return
							}
						}
						return (target[prop] = value); // 未匹配,设置属性
					},
					get(target, prop) {
						return target[prop]; // 获取属性值
					}
				});
			},
			createElement(tagName) {
				let element = originalCreateElement.call(unsafeWindow.document, tagName)
				if (tagName.toLowerCase() === "img") {
					Object.defineProperty(element, "src", {
						set(value) {
							let url = new URL(value, location.origin);
							if (rules.some(r => r.match(url) && r.condition() && r.runat === "image")) {
								// if (user.debug) console.log(`${log_head} createElement img`, "\n请求地址:", url.href, "\n模拟回复: 成功");
								return true; // 显式 return
							}
							return element.setAttribute("src", value); // 未匹配,设置属性
						},
						get() {
							return element.getAttribute("src");
						}
					});
				}
				return element;
			},
			universal(from, url, data, type) {
				let res, oriRes;
				try {
					res = typeof data === "string" ? JSON.parse(data) : data;
					oriRes = typeof data === "string" ? JSON.parse(data) : base.deepClone(data);
				} catch (e) {
					res = data;
					oriRes = base.deepClone(data);
				}
				let rule = rules.find(r => r.match(url) && r.condition() && r.runat === type);
				if (rule && typeof rule.action === "function") {
					if (type === "variable") {
						var originalSet = res.set;
						if (originalSet) res.set = (...args) => { set("set", ...args) };
						var originalMSet = res.mset;
						if (originalMSet) res.mset = (...args) => { set("mset", ...args) };
						var originalSetData = res.setData;
						if (originalSetData) res.setData = (...args) => { set("setData", ...args) };
						function set(type, ...args) {
							let object;
							if (typeof args[0] === "object" && !Array.isArray(args[0]) && args[0] !== null) {
								object = args[0];
							} else if (args[1] && args[1] !== null) {
								object = { [args[0]]: args[1] };
							}

							for (let key in object) {
								if (Object.prototype.hasOwnProperty.call(object, key)) {
									if (["function", "symbol", "undefined"].includes((typeof object[key]).toLowerCase())) {
										delete object[key];
									}
								}
							}

							object = base.hooker.universal(from, url, object, "variable");

							if (type === "set") for (key in object) {
								originalSet.call(res, key, object[key]);
							}
							if (type === "mset") {
								if (originalSet) for (key in object) {
									originalSet.call(res, key, object[key]);
								} else {
									originalMSet.call(res, object);
								}
							}
							if (type === "setData") originalSetData.call(res, object);
						}
						if (!originalMSet && !originalMSet && !originalSetData) res = rule.action(res, url);
					}

					if (!["variable"].includes(type)) res = rule.action(res, url);

					if (type === "header" && res !== null && typeof res === "object") try {
						let tempHeaders = {};
						for (let key in res) tempHeaders[key.toLowerCase().split("-").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join("-")] = res[key];
						res = tempHeaders;
					} catch { }

					if (user.debug) {
						let log_head = `【(改)百度网盘会员青春版】Hook`
						if (!base.deepEqual(res, oriRes)) {
							let format = (data) => typeof data === "string" && data.startsWith("#EXTM3U") ? "(M3U8预览) " + data.split("\n").slice(0, 5).join("\\n") : data;
							type === "start" && console.log(`${log_head} ${from} Virt`, "\n请求地址:", url.href, "\n模拟回复:", format(res) || "空");
							type === "end" && console.log(`${log_head} ${from} Repl`, "\n请求地址:", url.href, "\n原始回复:", format(oriRes) || "空", "\n修改回复:", format(res) || "空");
							type === "header" && console.log(`${log_head} ${from} Head`, "\n请求地址:", url.href, "\n原始头部:", oriRes || "空", "\n修改头部:", res || "空");
							type === "variable" && console.log(`${log_head} ${from}`, "\n原始内容:", oriRes || "空", "\n修改内容:", res || "空");
						}
						type === "url" && console.log(`${log_head} ${from} URL`, "\n原始地址:", oriRes?.href || "空", "\n修改地址:", res?.href || "空");
					}

					if (typeof res === "object" && !["header", "variable", "url"].includes(type)) try { res = JSON.stringify(res); } catch { }
				}
				return res;
			},
		},
		deepClone(obj) {
			if (obj instanceof URL) return new URL(obj.href);
			if (obj === null || typeof obj !== "object") return obj;
			if (obj instanceof Date) return new Date(obj);
			if (obj instanceof RegExp) return new RegExp(obj);
			if (typeof obj === "function") return obj; // 函数直接引用(无法真正克隆)
			if (Array.isArray(obj)) {
				return obj.map(item => this.deepClone(item));
			}
			let cloned = {};
			for (let key in obj) {
				if (Object.prototype.hasOwnProperty.call(obj, key)) {
					cloned[key] = this.deepClone(obj[key]);
				}
			}
			return cloned;
		},
		deepEqual(a, b) {
			// 严格相等
			if (Object.is(a, b)) return true;

			// 类型不同直接返回 false
			if (typeof a !== typeof b) return false;

			// null 或 undefined(typeof null === "object",需提前处理)
			if (a === null || b === null || a === undefined || b === undefined) {
				return a === b;
			}

			// Date
			if (a instanceof Date && b instanceof Date) {
				return a.getTime() === b.getTime();
			}

			// RegExp
			if (a instanceof RegExp && b instanceof RegExp) {
				return a.toString() === b.toString();
			}

			// 函数:只有同一个引用才算相等
			if (typeof a === "function" && typeof b === "function") {
				return a === b;
			}

			// 非对象类型(string, number, boolean 等)已在 Object.is 处理,此处可跳过
			if (typeof a !== "object") {
				return false;
			}

			// 数组
			let aIsArray = Array.isArray(a);
			let bIsArray = Array.isArray(b);
			if (aIsArray !== bIsArray) return false;

			if (aIsArray) {
				if (a.length !== b.length) return false;
				for (let i = 0; i < a.length; i++) {
					if (!this.deepEqual(a[i], b[i])) return false;
				}
				return true;
			}

			// 普通对象
			let aKeys = Object.keys(a);
			let bKeys = Object.keys(b);
			if (aKeys.length !== bKeys.length) return false;

			for (let key of aKeys) {
				if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
				if (!this.deepEqual(a[key], b[key])) return false;
			}

			return true;
		},
		getSettings() {
			var now = GM_getValue("user_settings", {});
			return { ...temp.defaults, ...now };
		},
		async setSettings(settings) {
			await GM_setValue("user_settings", settings);
		},
		/**
		 * 显示脚本设置
		 * @author hmjz100
		 */
		async showSettings() {
			let settings = base.getSettings();

			function generateHTML(title, key, type, other = {}) {
				function escapeHtml(str) {
					if (typeof str !== "string") return str;
					return str.replace(/[&<>""]/g,
						tag => ({
							"&": "&amp;",
							"<": "<",
							">": ">",
							"\"": `&quot;`,
							"'": `&#39;`
						}[tag] || tag)
					);
				}

				// 将 other 对象转换为属性字符串
				function buildAttrs(obj = {}) {
					let attrs = "";
					for (let [k, v] of Object.entries(obj)) {
						// 跳过空值或 undefined
						if (v === undefined || v === null) continue;
						if (typeof v === "boolean") {
							if (v) attrs += ` ${k}`;
							continue;
						}
						// 其他值作为 k="value"
						attrs += ` ${k}="${escapeHtml(String(v))}"`;
					}
					return attrs;
				};

				let control = "";
				let attrs = buildAttrs(other);

				if (type === "boolean") {
					let checked = settings[key] == true ? " checked" : "";
					control = `<input class="swal2-input ym-input" type="checkbox" data-key="${key}"${checked}${attrs} />`
				} else if (type === "string") {
					let value = settings[key] || "";
					let inputType = other?.type ? `type="${escapeHtml(String(other.type))}"` : `type="text"`;
					if (key === "vip_id") value = parseInt(value) || "";
					control = `<input class="swal2-input ym-input" autocomplete="off" ${inputType} data-key="${key}" value="${escapeHtml(value)}"${attrs} />`
				}

				if (title.includes("|")) {
					let parts = title.split("|").map(part => `<span>${part}</span>`);
					title = parts.join("<br/>");
				} else {
					title = `<span>${title}</span>`;
				}

				return `<label class="ym-setting-item" data-key="${key}">
					<div>${title}</div>${control}
				</label>`;
			}

			let dialog = await Swal.fire({
				...temp.swalDefault,
				icon: "info",
				iconHtml: "⚙︎",
				title: "设置",
				html: `<div class="ym-settings">
					<div class="block">Tips: 设置自动保存,刷新页面后生效。<br/>Tips: 您也可通过脚本管理器菜单再次打开本窗口。</div>
					<div class="block">
						<blockquote>
							<div>风雨送春归,飞雪迎春到。已是悬崖百丈冰,犹有花枝俏。</div>
							<div>俏也不争春,只把春来报。待到山花烂漫时,她在丛中笑。</div>
						</blockquote>
					</div>
					${generateHTML("会员|<small>所有功能的总开关,显示为 VIP</small>", "vip", "boolean")}
					${generateHTML("超级会员|<small>显示为 SVIP</small>", "svip", "boolean")}
					${generateHTML("过期|<small>显示为会员过期</small>", "previous", "boolean")}
					${generateHTML("昵称|<small>对外展示信息</small>", "name", "string", { "type": "string", "placeholder": "留空将使用已登录账户信息" })}
					${generateHTML("头像|<small>对外展示信息</small>|<small>可以是 <code>http(s):</code> 或 <code>data:</code> 链接</small>", "photo", "string", { "type": "string", "placeholder": "留空将使用已登录账户信息" })}
					${generateHTML("等级|<small>会员等级</small>|<small>1 ~ 10</small>", "level", "string", { "type": "number", "min": "1", "max": "10", "placeholder": "留空将使用已登录账户信息" })}
					${generateHTML("成长值|<small>会员成长值</small>|<small>1 ~ 100000</small>", "point", "string", { "type": "number", "min": "1", "max": "100000", "placeholder": "留空将使用已登录账户信息" })}
					${generateHTML("SVIP 10 专属 ID|<small>显示时会自动补零</small>|<small>1 ~ 999999</small>", "vip_id", "string", { "type": "number", "min": "1", "max": "999999", "placeholder": "留空将使用已登录账户信息" })}
					${generateHTML("会员过期时间|<small>对外展示信息</small>|<small>Unix 时间戳</small>", "endtime", "string", { "type": "number", "min": "-2147483648", "max": "253402185600", "placeholder": temp.defaults.endtime })}
					${generateHTML("屏蔽网页数据分析", "unAnalytics", "boolean")}
					${generateHTML("禁用 “云一朵” 相关功能入口", "unAI_Yiduo", "boolean")}
					${generateHTML(`禁用新版在线文档查看器|<small>勾选后新版的 PDF 在线预览会变为 WPS</small>`, "unPViewer", "boolean")}
					${generateHTML("隐藏新旧版切换入口", "unVerSwitch", "boolean")}
					${generateHTML("隐藏视频页 “笔记” ", "unTab_aiNote", "boolean")}
					${generateHTML("隐藏视频页 “AI看” ", "unTab_aiStudy", "boolean")}
					${generateHTML("隐藏视频页 “课件” ", "unTab_aiCourseware", "boolean")}
					${generateHTML("隐藏视频页 “文稿” ", "unTab_aiDraft", "boolean")}
					${generateHTML("我爱看广告|<small>修改视频广告播放时间为 200 秒,SVIP 下无效</small>", "iLoveAD", "boolean")}
					${generateHTML("显示调试信息到控制台", "debug", "boolean")}
					<label class="ym-setting-item">
						<div>快捷操作</div>
						<span><a href="http://passport.baidu.com/accountbind" target="_blank" class="ym-a pl-a">百度授权管理</a></span>
					</label>
				</div>
				<style>
					div:where(.swal2-container) div:where(.swal2-popup) {
						width: 36em!important;
						padding: 0 0 1.25em;
					}

					.ym-settings .ym-setting-item{display:flex;align-items:center;justify-content:space-between;margin-top:1em}
					.ym-settings .ym-setting-item > *:nth-child(1){text-align:left}
					.ym-settings .ym-setting-item > *:nth-child(2){max-width:80%;display:flex;justify-content:space-between;align-items:center}
					.ym-settings .ym-setting-item .ym-setting-item{margin:0;gap:5px}
					.ym-settings .ym-input{padding:8px 10px!important;border:1px solid #c2c2c2;border-radius:5px;font-size:14px!important;margin:0;appearance:auto!important}
					.ym-settings .ym-setting-item > .ym-input{width:50%}
					.ym-settings .ym-input[type=checkbox]{height:20px;width:20px;padding:0!important;background-image:none!important}

					.ym-settings .block { margin-bottom:20px }
					.ym-settings .block blockquote{
						padding:0.7em;
						border-left:5px solid #bdbdbd;
						background-color:#f9f9f9;
						margin:0;
						text-align:left;
					}
					@media (prefers-color-scheme:dark){
						/* 适配 LinkSwift 的自适应深色模式 */
						html:has(#swal-pub-dark-style) .ym-settings .block blockquote{
							border-left:5px solid #7A7C84;
							background-color:#464851;
						}
					}

					.ym-a{position:relative;vertical-align:baseline;color:#574AB8;border-bottom:2px solid #574AB8;text-decoration:none!important;transition:color.3s,opacity.3s;will-change:color,opacity;overflow:hidden}
					.ym-a::before{content:"";position:absolute;left:0;bottom:0;width:100%;height:100%;background-color:#574AB8;transform:scaleY(0);transform-origin:bottom center;transition:transform.15s,opacity.3s;will-change:transform;z-index:-1}
					.ym-a:hover,.ym-a:focus{color:#fff}
					.ym-a:hover::before,.ym-a:focus::before{transform:scaleY(1)}
					.ym-a:active{color:#fff;opacity:0.8}

					.swal2-footer,div:where(.swal2-container) div:where(.swal2-footer){flex-direction:column;justify-content:center;align-items:center}
					.swal2-footer p,div:where(.swal2-container) div:where(.swal2-footer) p{margin:0;padding:0}
				</style>`,
				allowOutsideClick: false,
				showCloseButton: true,
				showDenyButton: true,
				confirmButtonText: "刷新",
				denyButtonText: "关闭",
				didOpen: (toast) => {
					let element = $(toast);
					element.find(".ym-settings input").each((index, tag) => {
						$(tag).on("change", async (event) => {
							let element = $(event.target);
							let key = element.data("key");
							if (element.attr("type") === "checkbox") {
								settings[key] = element.prop("checked");
							} else {
								let value = element.val() || "";
								if (element.attr("type") === "number") value = parseInt(value) || "";
								if (key === "vip_id") value = String(value).padStart(6, "0");
								settings[key] = value;
							}
							await base.setSettings(settings);
						})
					})
				},
				footer: `<p>感谢您选择会员青春版,喜欢的话就来给个 <a href="https://github.com/hmjz100/BaiduNetDiskYouthMember" target="_blank" class="ym-a pl-a">Star</a> 吧~</p>`,
			});

			if (dialog.isConfirmed) {
				location.reload(); // 刷新页面使设置生效
			}
		},
		/**
		 * 等待指定元素加载完成并执行回调
		 * @author hmjz100
		 * @description 监听 DOM 元素是否出现,若未出现则每隔一段时间重试,直到找到为止。
		 * 支持在 iframe 内部查找元素,适用于异步加载场景。
		 * @param {string} selectorElem - 要等待的目标元素选择器
		 * @param {Function} actionFunction - 找到元素后执行的回调函数,接收 jQuery 元素作为参数,返回 true 可以不再继续寻找
		 * @param {boolean} [bWaitOnce=false] - 是否只执行一次回调,默认为 false,如果不设置为 true 的话需要自行判断是否对元素进行操作
		 * @param {string} [iframeSelector] - 若目标元素位于 iframe 中,传入 iframe 的选择器
		 * @param {string} [controlKey] - 控制唯一性的键名,用于避免重复处理
		 */
		waitForKeyElements(selectorElem, actionFunction, bWaitOnce, iframeSelector, controlKey) {
			// 初始化管理器
			let manager = this.waitForKeyElements.manager;
			if (!manager) {
				manager = this.waitForKeyElements.manager = {
					observers: new WeakMap(),
					tasks: new Map(),
					instanceCounter: 0
				};
			}

			// 获取目标文档
			let targetDoc = iframeSelector ? $(iframeSelector).get(0)?.contentDocument : document;
			if (!targetDoc) return;

			// 生成唯一键
			controlKey = controlKey || `wkfe_${manager.instanceCounter++}`;

			// 清理重复任务
			let existingTask = manager.tasks.get(controlKey);
			if (existingTask) {
				existingTask.observer.disconnect();
				manager.tasks.delete(controlKey);
			}

			// 递归扫描shadowRoot
			function scanShadowDOM(root, selector) {
				let results = [];
				try {
					// 扫描当前根节点
					let currentMatches = root.querySelectorAll(selector);
					results.push(...Array.from(currentMatches));

					// 递归扫描shadowRoot
					let walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
					let node;
					while (node = walker.nextNode()) {
						if (node.shadowRoot && node.shadowRoot.mode === 'open') {
							results.push(...scanShadowDOM(node.shadowRoot, selector));
						}
					}
				} catch (e) {
					// 跨域shadowRoot静默跳过
				}
				return results;
			}

			// 元素扫描核心逻辑
			function scanElements() {
				// 全局扫描(含shadowRoot)
				let rawElements = scanShadowDOM(targetDoc.documentElement, selectorElem);
				let jElements = $(rawElements);

				let foundActive = false;
				jElements.each(function () {
					let jEl = $(this);
					if (jEl.data(controlKey)) return true; // 跳过已处理元素

					let cancel = actionFunction(jEl);
					if (cancel) {
						foundActive = true;
					} else if (bWaitOnce) {
						jEl.data(controlKey, true); // 标记已处理
					}
				});

				// 一次性任务清理
				if (bWaitOnce && foundActive) {
					observer.disconnect();
					manager.tasks.delete(controlKey);
				}
			}

			// 创建观察器
			let observer = new MutationObserver(scanElements);

			// 配置观察项(增强shadowRoot监听)
			observer.observe(targetDoc.documentElement, {
				childList: true,
				subtree: true,
				attributes: true,
				characterData: true
			});

			// 注册任务
			manager.tasks.set(controlKey, {
				observer: observer,
				targetDoc: targetDoc
			});

			// 首次扫描
			scanElements();
		},
	}

	function has(value) { return !["undefined", "null"].includes(typeof value) }
	let user = base.getSettings();

	let rules = [
		{
			// 综合变量
			runat: "variable",
			match: (url) => !url.pathname.includes("buy/checkoutcounter"),
			condition: () => user.vip == true,
			action: (res, url) => {
				if (/\/s\/.*?\?fid=.*?/.test(url.href)) res.self = 1
				if (res.userInfo) {
					if (has(res.userInfo?.username) && has(user.name)) res.userInfo.username = user.name;
					if (has(res.userInfo?.["photo_url"]) && has(user.photo)) res.userInfo["photo_url"] = user.photo;

					if (has(res.userInfo?.vip_level) && has(user.level)) res.userInfo.vip_level = user.level;
					if (has(res.userInfo?.svip10_id) && has(user.vip_id)) res.userInfo.svip10_id = user.vip_id;

					if (has(res.userInfo?.vip_identity) && user.previous == false) res.userInfo.vip_identity = Number(`${user.svip == true ? 2 : 1}1`);
				}

				if (has(user.name)) res.username = user.name;
				if (has(res.MYNAME) && has(user.name)) res.MYNAME = user.name;

				if (has(user.photo)) res.photo = user.photo;
				if (has(res.MYAVATAR) && has(user.photo)) res.MYAVATAR = user.photo;

				if (user.previous == false) res.is_vip = 1;
				if (has(res.ISVIP) && user.previous == false) res.ISVIP = 1;

				if (user.svip == true && user.previous == false) res.is_svip = 1;
				if (has(res.ISSVIP) && user.svip == true && user.previous == false) res.ISSVIP = 1;

				if (has(res.ISYEARVIP)) res.ISYEARVIP = 1;
				if (has(res.is_plus_buy)) res.is_plus_buy = 1;
				if (has(res.is_vip_v2) && has(user.level) && user.level >= 2) res.is_vip_v2 = 1;
				if (has(res.is_vip_v2_new) && has(user.level) && user.level >= 2) res.is_vip_v2_new = 1;

				if (has(res.is_evip) && user.previous == false) res.is_evip = 1;
				if (has(res.is_mvip) && user.previous == false) res.is_mvip = 1;

				if (has(res.vipsid) && has(user.vip_id)) {
					let idStr = String(user.vip_id);
					let six = idStr.match(/\d{6}/)?.[0];
					let all = idStr.replace(/\D/g, "");
					let finalId = six ? +six : (all ? +all : 1);
					res.vipsid = finalId;
				}
				if (has(user.vip_id)) res.v10_id = user.vip_id;
				if (has(user.level)) res.vip_level = user.level;

				if (has(res.show_vip_ad)) res.show_vip_ad = 0;

				return res;
			}
		},
		{
			// 用户信息 基本
			runat: "end",
			match: (url) => url.pathname.includes("api/user/getinfo"),
			condition: () => user.vip == true,
			action: (res, url) => {
				let key = localStorage.getItem("realNameVerify");
				if (key && res.records?.[0] && res.records.some(item => item.uk === Number(key))) {
					let info = res.records.find(item => item.uk === Number(key));
					if (has(info.uname) && has(user.name)) info.uname = user.name;
					if (has(info.priority_name) && has(user.name)) info.priority_name = user.name;
					if (has(info.avatar_url) && has(user.photo)) info.avatar_url = user.photo;
				}
				return res;
			}
		},
		{
			// 登录信息 基本
			runat: "end",
			match: (url) => url.pathname.includes("api/loginStatus"),
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.login_info?.username) && has(user.name)) res.login_info.username = user.name;
				if (has(res.login_info?.["photo_url"]) && has(user.photo)) res.login_info["photo_url"] = user.photo;

				if (has(res.login_info?.vip_level) && has(user.level)) res.login_info.vip_level = user.level;
				if (has(res.login_info?.vip_point) && has(user.point)) res.login_info.vip_point = user.point;
				if (has(res.login_info?.vip_type)) res.login_info.vip_type = user.svip == true ? "21" : "11";
				if (has(res.login_info?.vip_identity)) res.login_info.vip_identity = user.svip == true ? 21 : 11;

				return res;
			}
		},
		{
			// 会员信息 用户
			runat: "end",
			match: (url) => url.pathname.includes("rest/2.0/membership/user") && (!url.searchParams.get("method") || url.searchParams.get("method") == "query"),
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.current_product) && user.previous == false) res.current_product = res.current_product_v2 = {
					"cluster": "vip",
					"detail_cluster": user.svip == true ? "svip" : "vip", // 决定会员标签变化
					"product_type": user.svip == true ? `vip2_1m_auto` : `vip_1m_auto`,
					"product_id": "12187135090581539740"
				}

				// 决定会员等级变化
				if (has(res.level_info)) res.level_info = {
					...res.level_info,
					"current_value": has(user.point) && user.point != "" ? user.point : 0, // 决定所有会员标签
					"current_level": has(user.level) && user.level != "" ? user.level : 1, // 决定所有会员标签
					"history_value": has(user.point) && user.point != "" ? user.point : 0,
					"history_level": has(user.level) && user.level != "" ? user.level : 1,
					"v10_id": user.vip_id,
					"last_manual_collection_time": 0
				}

				if (has(res.privilege_list)) [...res.privilege_list].forEach(item => {
					item.free_count = 100
				})

				// 决定会员剩余时间变化
				if (has(res.reminder) && user.previous == false) res.reminder = {
					...res.reminder,
					[user.svip == true ? "svip" : "vip"]: {
						"leftseconds": ((has(user.endtime) && user.endtime != "" ? user.endtime : 2147483648) * 1000 - Date.now()) / 1000,
						"nextState": "normal"
					}
				}

				// 其它(已有套餐、之前套餐)
				if (has(res.product_infos) && user.previous == false) res.product_infos.unshift({
					"product_id": "12187135090581539740",
					"buy_time": "946656000",
					"start_time": 946656000,
					"end_time": has(user.endtime) && user.endtime != "" ? user.endtime : 2147483648,
					"cluster": "vip",
					"detail_cluster": user.svip == true ? "svip" : "vip",
					"product_name": user.svip == true ? "svip2_nd" : "vip1_nd",
					"cur_svip_type": "year",
					"function_num": 8,
					"status": 0,
					"buy_description": "超级SVIP套餐(永久)",
					"product_description": "自打百度一诞生我就买了!"
				})

				if (has(res.previous_product)) res.previous_product = {
					"cluster": "vip",
					"detail_cluster": user.svip == true ? "svip" : "vip", // 决定之前会员标签
					"product_type": user.svip == true ? `vip2_1m_auto` : `vip_1m_auto`,
					"expired_time": 946656000
				}

				if (has(res.previous_product_v2)) res.previous_product_v2 = {
					"cluster": "vip",
					"detail_cluster": user.svip == true ? "svip" : "vip", // 决定之前会员标签
					"product_type": user.svip == true ? `vip2_1m_auto` : `vip_1m_auto`,
					"expired_time": 946656000
				}

				return res;
			}
		},
		{
			// 会员信息 用户导览
			runat: "end",
			match: (url) => url.pathname.includes("rest/2.0/membership/user") && url.searchParams.get("method") == "guide",
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.status_data) && has(user.endtime)) res.status_data = `${user.svip == true ? "SVIP" : "VIP"}至:${new Date(user.endtime * 1000).toLocaleDateString()}`;
				if (has(res.status_data) && has(user.endtime)) res.status_data_arr = [`${user.svip == true ? "SVIP" : "VIP"}至:${new Date(user.endtime * 1000).toLocaleDateString()}`];
				return res;
			}
		},
		{
			// 会员信息 用户信息
			runat: "end",
			match: (url) => url.pathname.includes("rest/2.0/membership/user/info") && url.searchParams.get("method") == "query",
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.user_info?.username) && has(user.name)) res.user_info.username = user.name;
				if (has(res.user_info?.["photo_url"]) && has(user.photo)) res.user_info["photo_url"] = user.photo;
				if (has(res.user_info?.phone) && has(user.phone)) res.user_info.phone = Number(user.phone);
				if (has(res.user_info?.vipsid) && has(user.vip_id)) {
					let idStr = String(user.vip_id);
					let six = idStr.match(/\d{6}/)?.[0];
					let all = idStr.replace(/\D/g, "");
					let finalId = six ? +six : (all ? +all : 1);
					res.user_info.vipsid = finalId;
				}
				if (has(res.user_info?.is_vip) && user.previous == false) res.user_info.is_vip = 1;
				if (has(res.user_info?.is_svip) && user.svip == true && user.previous == false) res.user_info.is_svip = 1;
				if (has(res.user_info?.is_mvip) && user.previous == false) res.user_info.is_mvip = 1;

				if (has(res.user_info?.is_vip_v2) && has(user.level) && user.level >= 2) res.user_info.is_vip_v2 = 1;
				if (has(res.user_info?.is_vip_v2_new) && has(user.level) && user.level >= 2) res.user_info.is_vip_v2_new = 1;

				if (has(res.user_info?.is_first_charge)) res.user_info.is_first_charge = 1;
				if (has(res.user_info?.is_first_charge) && user.svip == true) res.user_info.is_first_charge_svip = 1;
				if (has(res.user_info?.is_plus_buy)) res.user_info.is_plus_buy = 1;
				if (has(res.user_info?.plus_buy_hit)) res.user_info.plus_buy_hit = 1;
				return res;
			}
		},
		{
			// 会员信息 手机
			runat: "end",
			match: (url) => url.pathname.includes("rest/2.0/membership/phone") && url.searchParams.get("method") == "query",
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.phone) && has(user.phone)) res.phone = user.phone;
				if (has(res.phone_enc) && has(user.phone)) res.phone_enc = user.phone;
				return res;
			}
		},
		{
			// 会员信息 等级
			runat: "end",
			match: (url) => url.pathname.includes("rest/2.0/membership/level") && url.searchParams.get("method", "") == "getv10info",
			condition: () => user.vip == true,
			action: (res, url) => {
				if (has(res.data.points) && has(user.point)) res.data.points = user.point;
				if (has(res.data.svip_expire_time) && has(user.endtime)) res.data.svip_expire_time = user.endtime;
				if (has(res.data.v10_expire_time) && has(user.endtime)) res.data.v10_expire_time = user.endtime;
				if (has(res.data.v10_id) && has(user.vip_id)) res.data.v10_id = user.vip_id;
				if (has(res.data.v10_rank) && has(user.vip_id)) {
					let idStr = String(user.vip_id);
					let six = idStr.match(/\d{6}/)?.[0];
					let all = idStr.replace(/\D/g, "");
					let finalId = six ? +six : (all ? +all : 1);
					res.data.v10_rank = finalId;
				}
				return res;
			}
		},
		{
			// 视频信息
			runat: "end",
			match: (url) => url.pathname.includes("api/filemetas"),
			condition: () => user.vip == true,
			action: (res, url) => {
				// 百度网盘不允许非会员用户在线观看 1080P 及以上分辨率,所以在此处将其移除。
				if (Array.isArray(res?.info) && res.info.length > 0) {
					for (let item of res.info) {
						if (!item || typeof item !== "object") continue;

						// 从 resolution 解析宽高
						let width = item.width || 0, height = item.height || 0;
						if (item.resolution) {
							let match = item.resolution.match(/width:(\d+).*?height:(\d+)/i);
							if (match) {
								width = parseInt(match[1], 10) || 0;
								height = parseInt(match[2], 10) || 0;
							}
						}

						// 判断是否高于 720P
						if (Math.min(width, height) >= 720 || Math.max(width, height) >= 1280) {
							if (width >= height) {
								width = 1280, height = 720; // 横屏
							} else {
								width = 720, height = 1280; // 竖屏
							}

							item.width = width;
							item.height = height;
							item.resolution = `width:${width},height:${height}`;
						}
					}
				}
				return res;
			}
		},
		{
			// 视频信息 视频流 M3U8
			runat: "url",
			match: (url) => url.pathname.includes("api/streaming") && has(url.searchParams.get("vip")) && url.searchParams.get("type"),
			condition: () => user.vip == true,
			action: (url) => {
				url.searchParams.set("vip", "0");
				if (temp.adToken) {
					url.searchParams.set("adToken", temp.adToken);
					delete temp.adToken;
				}
				return url;
			}
		},
		{
			// 视频信息 视频流 M3U8
			runat: "end",
			match: (url) => url.pathname.includes("api/streaming") && has(url.searchParams.get("vip")) && /^M3U8_(AUTO|FLV)/.test(url.searchParams.get("type")),
			condition: () => user.vip == true,
			action: (res, url) => {
				if (typeof res === "object") {
					temp.adToken = res.adToken;
					res.adTime = 2;
					res.ltime = 1;
					if (user.iLoveAD) {
						res.adTime = 200;
						res.ltime = 100;
					}
				}
				return res;
			}
		},
		{
			// 视频信息 字幕流 M3U8
			runat: "end",
			match: (url) => url.pathname.includes("api/streaming") && has(url.searchParams.get("vip")) && url.searchParams.get("type") == "M3U8_SUBTITLE_SRT",
			condition: () => user.vip == true,
			action: (res, url) => {
				if (typeof res === "string" && res.startsWith("#EXTM3U") && res.includes("#MEDIA:SUBTITLES")) {
					function getSubtitles(text) {
						let regex = /#EXT-X-MEDIA:TYPE=SUBTITLES,[^#]*\n\s*(https?:\/\/[^\s]+)/g;
						let subtitles = [];
						let match;
						while ((match = regex.exec(text)) !== null) {
							let line = text.substring(match.index, regex.lastIndex).split('\n')[0];
							let attrs = Object.fromEntries(
								line.replace('#EXT-X-MEDIA:', '').split(',').map(pair => {
									let [k, v = ''] = pair.split('=');
									return [k.trim(), v.replace(/"/g, '').trim()];
								})
							);
							subtitles.push({
								name: attrs.NAME || '',
								language: attrs.LANGUAGE || '',
								default: attrs.DEFAULT === 'YES',
								ai: attrs['AI-SUB'] === 'YES',
								url: match[1]
							});
						}
						return subtitles;
					};

					let subtitles = getSubtitles(res);
					console.log(subtitles);

					base.waitForKeyElements("div.vjs-subtitle-item", (element) => {
						if (!element.parent("style.ym").length) element.parent().append(`<style class="ym">
							button.downloadSubtitle{float:right;padding:0 8px;border-radius:50px;cursor:pointer;color:#fff!important;background-color:#418ceb!important;}
							button.downloadSubtitle:hover{background-color:#418cebD0!important;}
							button.downloadSubtitle:disabled{background-color:#418cebD0!important;}
							div.vjs-subtitle-item:has(button.downloadSubtitle:hover){color:#a2abbd!important;}
						</style>`);
						let subName = element.find(".vjs-subtitle-item-text").text()?.trim();
						let maybeAI = element.find(".vjs-subtitle-item-text").prev(".vjs-subtitle-item-icon").length;
						if (subName && subtitles.some(i => i.name === subName && i.ai == maybeAI)) {
							let subtitle = subtitles.find(i => i.name === subName && i.ai == maybeAI);
							let button = $(`<button class="downloadSubtitle" title="下载后别忘了重命名文件加上扩展名 “.srt”">下载</button>`);

							button.on('click', function (e) {
								e.preventDefault();
								e.stopPropagation();
								window.open(subtitle.url, '_blank', 'noopener,noreferrer');
							});
							element.append(button);
						}
					}, true)
					base.waitForKeyElements(".vp-video__control-bar--video-subtitles-select-item", (element) => {
						let subName = element.find(".vp-video__control-bar--video-subtitles-select-desc").text()?.trim();
						let maybeAI = element.find(".vp-video__control-bar--video-subtitles-select-desc").prev(".vp-img-container").length;

						if (subName && subtitles.some(i => i.name === subName && i.ai == maybeAI)) {
							let subtitle = subtitles.find(i => i.name === subName && i.ai == maybeAI);
							let button = $(`<button class="downloadSubtitle" title="下载后别忘了重命名文件加上扩展名 “.srt”">下载</button>`);

							button.on('click', function (e) {
								e.preventDefault();
								e.stopPropagation();
								window.open(subtitle.url, '_blank', 'noopener,noreferrer');
							});
							if (element.find(".downloadSubtitle").length) element.find(".downloadSubtitle").remove();
							element.append(button);
						}
					}, true)
				}
				return res;
			}
		},
		{
			// 界面信息
			runat: "end",
			match: (url) => url.pathname.includes("api/getsyscfg"),
			condition: () => user.vip == true,
			action: (res, url) => {
				// huge_upgrade
				if (res.huge_upgrade?.cfg_list && has(user.unVerSwitch)) {
					let hue_config = res.huge_upgrade.cfg_list.find(item => item.node_key === "huge_upgrade_entrance_config");
					if (hue_config) {
						if (has(hue_config.new_nav_show)) hue_config.new_nav_show = (user.unVerSwitch == true ? "0" : "1")
						if (has(hue_config.new_nav_href)) hue_config.new_nav_href = "https://pan.baidu.com/disk/main"

						if (has(hue_config.old_nav_show)) hue_config.old_nav_show = (user.unVerSwitch == true ? "0" : "1")
						if (has(hue_config.old_nav_href)) hue_config.old_nav_href = "https://pan.baidu.com/disk/home?stayAtHome=true"
					}
				}

				// netdisk_docchat_config
				if (res.netdisk_docchat_config?.cfg_list && user.unAI_Yiduo == true) {
					let ce_config = res.netdisk_docchat_config.cfg_list.find(item => item.node_key === "chat_enter_config");
					ce_config.is_chat_show = "0";
					ce_config.is_docview_chat_auto_show = "0";
					ce_config.is_docview_chat_show = "0";
					ce_config.is_home_need_out_sug = "0";
					ce_config.is_main_chat_show = "0";
					ce_config.is_videoview_chat_auto_show = "0";
					ce_config.is_videoview_chat_show = "0";
				}
				// ai_collect
				if (res.ai_collect?.cfg_list && user.unAI_Yiduo == true) {
					let ac_config = res.ai_collect.cfg_list.find(item => item.node_key === "ai_collect_config");
					ac_config.is_ai_collect_show = "0";
				}

				// netdisk_docview_config
				if (res.netdisk_docview_config?.cfg_list) {
					let dv_type = res.netdisk_docview_config.cfg_list.find(item => item.node_key === "docview_type");
					dv_type.auto_search_to_ai = (user.unAI_Yiduo == true ? "0" : "1");
					dv_type.use_pfile_for_doc = (user.unPViewer == true ? "0" : "1");
					dv_type.use_pfile_for_ppt = (user.unPViewer == true ? "0" : "1");
					dv_type.use_pfile_reader = (user.unPViewer == true ? "0" : "1");
					dv_type.use_wps_reader = (user.unPViewer == true ? "1" : "0");
				}

				return res;
			}
		},
		{
			// 界面信息 视频页 笔记 Tab 展示状态
			runat: "end",
			match: (url) => url.pathname.includes("learn/query/strategy"),
			condition: () => true,
			action: (res, url) => {
				if (Array.isArray(res.data?.module_info) && res.data.module_info.length > 0 && res.data.module_info.some(i => i.module_name === "ainote")) {
					res.data.module_info.find(i => i.module_name === "ainote").display_strategy.enable = (user.unTab_aiNote !== true);
				}
				return res;
			}
		},
		{
			// 界面信息 视频页 AI看 Tab 展示状态
			runat: "end",
			match: (url) => url.pathname.includes("learn/query/roiinfo"),
			condition: () => true,
			action: (res, url) => {
				if (Array.isArray(res.data?.file_infos) && res.data?.file_infos.length > 0 && res.data.file_infos.some(i => has(i.roi_status))) {
					res.data.file_infos.forEach(i => {
						i.roi_status = user.unTab_aiStudy ? 0 : 1;
					});
				}
				return res;
			}
		},
		{
			// AI看 功能
			runat: "end",
			match: (url) => url.pathname.includes("api/study/kpointinfo"),
			condition: () => user.vip == true,
			action: (res, url) => {
				if (res.data?.left_times != null && Array.isArray(res.data?.display_data) && res.data.display_data.length > 0) {
					for (const item of res.data.display_data) {
						if (!["ready", "fail"].includes(item.ai_status)) continue;
						// 仅当免费次数用完时才修改状态
						if (res.data.left_times === 0) {
							if (item.id === 1) {
								item.ai_status = "done";
								item.content = "您的 AI 看免费使用次数已用尽,此视频无法生成 AI 总结(百度云盘会员青春版)";
							} else {
								item.ai_status = "done_empty";
							}
						}
					}
				}
				return res;
			}
		},
		{
			// 界面信息 视频页 课件/文稿 Tab 展示状态
			runat: "end",
			match: (url) => url.pathname.includes("/common") && url.searchParams.get("method") === "status",
			condition: () => true,
			action: (res, url) => {
				// 课件 - aitrans/ppt
				if (url.pathname.includes("aitrans/ppt") && has(res.data?.roi_status)) {
					res.data.roi_status = (user.unTab_aiCourseware == true ? 0 : 1);
				}
				// 文稿 - richsearch/autosubtitle
				if (url.pathname.includes("richsearch/autosubtitle") && has(res.res?.roi_status)) {
					res.res.roi_status = (user.unTab_aiDraft == true ? 0 : 1)
				}
				return res;
			}
		},
		{
			runat: "start",
			match: (url) => url.pathname.includes("cloudapp/api/v1/isLocateRight"),
			condition: () => user.vip == true,
			action: (res, url) => {
				res = {
					"errno": 0,
					"msg": "success",
					"result": false,
					"requestId": ""
				}
				return res;
			}
		},
		{
			// 广告信息 弹窗
			runat: "start",
			match: (url) => url.pathname.includes("rest/2.0/pcs/adx"),
			condition: () => user.vip == true,
			action: (res, url) => {
				res = {
					"list": {
						"tab": {
							"web-popup": []
						},
						"version": 0,
						"home_banner_version": 0
					},
					"request_id": ""
				}
				return res;
			}
		},
		{
			// 分析信息 报告
			runat: "start",
			match: (url) => {
				if (url.pathname.includes("api/report/user")) return true;
				if (url.pathname.includes("mwb2.gif")) return true;
				return false
			},
			condition: () => user.unAnalytics == true,
			action: () => { }
		},
		{
			// 分析信息 报告
			runat: "image",
			match: (url) => {
				if (url.host == "mbd.baidu.com" && url.pathname.includes("ztbox")) return true;
				if (url.host == "hm.baidu.com" && url.pathname.includes("hm.gif")) return true;
				if (url.host == "update.pan.baidu.com" && url.pathname.includes("statistics")) return true;
				if (url.pathname.includes("api/analytics")) return true;
				return false
			},
			condition: () => user.unAnalytics == true,
			action: () => { }
		},
	];

	/**
	 * 控制台输出
	 * @author 油小猴
	 * @author hmjz100
	 * @description 来自【网盘智能识别助手】,有改动
	 */
	console.log(`%c %c (改)百度网盘会员青春版\n虚拟百度网盘身份信息为会员\n仓库:https://github.com/hmjz100/BaiduNetDiskYouthMember\n版本:${info.version}\n领域:${(window.self !== window.top ? "[iframe] " : "") + (document.title ? (document.title + " (" + location.origin + location.pathname + ")") : temp.url())}`, `background:url(${info.icon}) center center no-repeat;background-size:12px;padding:3px`, `padding:2px`);

	// 没有什么是 Hook 解决不了的。
	var originalFetch = fetch;
	unsafeWindow.fetch = base.hooker.fetch;
	temp.hooker.set(unsafeWindow.fetch);

	var originalSend = XMLHttpRequest.prototype.send;
	unsafeWindow.XMLHttpRequest.prototype.send = base.hooker.send;
	temp.hooker.set(unsafeWindow.XMLHttpRequest.prototype.send);

	var originalOpen = XMLHttpRequest.prototype.open;
	unsafeWindow.XMLHttpRequest.prototype.open = base.hooker.open;
	temp.hooker.set(unsafeWindow.XMLHttpRequest.prototype.open);

	var originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
	unsafeWindow.XMLHttpRequest.prototype.setRequestHeader = base.hooker.setRequestHeader;
	temp.hooker.set(unsafeWindow.XMLHttpRequest.prototype.setRequestHeader);

	var originalSendBeacon = navigator.sendBeacon;
	unsafeWindow.navigator.sendBeacon = base.hooker.sendBeacon;
	temp.hooker.set(unsafeWindow.navigator.sendBeacon);

	var OriginalImage = Image;
	unsafeWindow.Image = base.hooker.Image;
	temp.hooker.set(unsafeWindow.Image);

	var originalCreateElement = document.createElement;
	unsafeWindow.document.createElement = base.hooker.createElement;
	temp.hooker.set(unsafeWindow.document.createElement);

	var originalToString = Function.prototype.toString;
	unsafeWindow.Function.prototype.toString = base.hooker.toString;
	temp.hooker.set(unsafeWindow.Function.prototype.toString);

	var originalToLocaleString = Function.prototype.toLocaleString;
	unsafeWindow.Function.prototype.toLocaleString = base.hooker.toLocaleString;
	temp.hooker.set(unsafeWindow.Function.prototype.toLocaleString);

	var originalAttachShadow = Element.prototype.attachShadow;
	unsafeWindow.Element.prototype.attachShadow = base.hooker.attachShadow;
	temp.hooker.set(unsafeWindow.Element.prototype.attachShadow);

	let localsTimer = setInterval(() => {
		if (!unsafeWindow.locals) return;
		clearInterval(localsTimer);
		let url = new URL(location.href);
		if (rules.some(r => r.match(url) && r.condition() && r.runat === "variable")) {
			unsafeWindow.locals = base.hooker.universal("locals", url, unsafeWindow.locals, "variable");
		}
	}, 1)

	let yunDataTimer = setInterval(() => {
		if (!unsafeWindow.yunData) return;
		clearInterval(yunDataTimer);
		let url = new URL(location.href);
		if (rules.some(r => r.match(url) && r.condition() && r.runat === "variable")) {
			unsafeWindow.yunData = base.hooker.universal("yunData", url, unsafeWindow.yunData, "variable");
		}
	}, 1)

	let yunDataRequireTimer = setInterval(() => {
		if (!unsafeWindow.require) return;
		clearInterval(yunDataRequireTimer);
		var originalRequire = unsafeWindow.require;

		originalRequire.async("pan-center:widget/data/yunData", (yunData) => {
			let url = new URL(location.href);
			return base.hooker.universal("require yunData", url, yunData, "variable");
		})

		/*unsafeWindow.require = function (url) {
			Object.assign(unsafeWindow.require, originalRequire);

			if (url.includes("widget/data/yunData")) {
				let url = new URL(location.href);
				return base.hooker.universal("require yunData", url, originalRequire.apply(this, arguments), "variable");
			}

			return originalRequire.apply(this, arguments);
		}*/
	}, 1)

	GM_registerMenuCommand("⚙️ 设置", () => {
		base.showSettings();
	});

	base.waitForKeyElements("html:not(:has(#swal-pub-dark-style)) head:not(:has(style.swal-pub-style.ym))", (element) => {
		element.prepend(`<style class="swal-pub-style ym">${GM_getResourceText('SwalLigt')}</style>`);
	}, true)
	base.waitForKeyElements("html:has(#swal-pub-dark-style) head style.swal-pub-style.ym", (element) => {
		element.remove();
	}, true)
	base.waitForKeyElements("head:not(:has(.style.listener-ym))", (element) => {
		element.append(`<style class="listener-ym">
			button.downloadSubtitle{margin-left:auto;padding:0 8px;border-radius:3px;cursor:pointer;color:#fff;background-color:#418ceb;}
			button.downloadSubtitle:hover{background-color:#418cebD0;}
			button.downloadSubtitle:disabled{background-color:#418cebD0;}
			.vp-video__control-bar--video-subtitles-select-item:has(button.downloadSubtitle:hover){background:transparent!important;}
			.vjs-live .vjs-progress-control{display:flex!important}
		</style>`);
	}, true)

	// 这是啥?我不到啊
	function idontknow(input) {
		let charArray = input.split("");
		// 这是 Fisher-Yates 洗牌算法的实现
		for (let i = charArray.length - 1; i > 0; i--) {
			let j = Math.floor(Math.random() * (i + 1));
			[charArray[i], charArray[j]] = [charArray[j], charArray[i]];
		}
		return charArray.join("");
	}
})();