98T Picture Preview

[NOW]Click/Copy all magnet/torrent links that have not been viewed.

As of 2024-09-10. 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 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         98T Picture Preview
// @description  [NOW]Click/Copy all magnet/torrent links that have not been viewed.
// @version     1.9.0
// @icon data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABMLAAATCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAtLvcALW92gawt9w0u73lZb2+62vKzu8ryNDpC87S9gDI1dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArLPYAKuy1g6ts92Esbbj5rq66/u3tuv5x8jy4r3A56e7wOIhur/jAAAAAAAAAAAAAAAAAK6z3QCxt90FqKvbQ52f1XybotWZp67g+Ker5v+ipej/pKbr/7K17/+3uun/vcPpi////wDP1egAAAAAAAAAAAC4uucWuLjvfqmp6O2Xl97/kZfa/4uR3P96gNX/gYnb/46W5v+SmOv/o6js/7i97srDxvUiyc30CMOf/wDH19YAsrDpjraw8/ynovL/jY3l/3l/3P9eYtD/bXTT/5Sc5f+krO7/r7X0/5qg8P+ssvT5w8X818PF+LG0s+9cp6bnF6Ga3t6mnej/lZDo/3Z42/9vd9f/iI3g/6Op7/+ZoPX/k5z3/6mu+v+8wvr/tbz6/7i9+f+1tfL/sa7s+7y676qZktn/l4/h/4mI4P99gd7/q7Dt/5ed8P9weOz/S0/s/zg96/8+R+r/p6/8/7rC+P+nq/X/qafy/7Gu7v+0s+v3pJ/j/5eV4/+doOv/oKXx/6Op+P9OVub/T1nv/1Ra8P9ASOz/W2jz/4+Z/f+wtvj/oafv/6Cj8v+oqO7/ra7q/ael5MmjpOj/qq7x/6Cn9/+Yovv/dID3/1ll9/9kavj/XWj0/36L+P+NmP3/p6v8/7e69v+tr/T/sLPz/73C8r7AwPFBsrXr2auv7/+Ynfj/nqj8/4uW/f9sefz/XGT9/2Jp/f91gP3/eYX//6Om/P/BxPr+wcT45MXJ+Z7V3Psn////ALm+7Ty6u/Xnq6z9/6eu/P+ZoP7/bHb+/3yH/v+Sm/7/kZf+/6Wr/v+vs/v/ur7648rQ+z70/P8F2+L+AM7R+QDO0PgQy8v7w7+//f+ytv3/srf9/6Km/v+ipf//q6z//7a4//+1uv7/srL+/726/dTX2fob1df6AAAAAADCv/gAwLv4CNPQ/bfJyvv/wcP8/77C/f+5vPz/urr8/72//f+7vv7/sLD+/7Cr+//Bvfju1tf4NdTV+QAAAAAAxsj2AMfL9QnZ1fy30cz8/7689v+qpvb/tbT9/8DC/v+6u/7/t7b8/7Sx+P+3sPX/xMD2vNnc9xDV1vcAAAAAANDX9gDt4v8A3Nz8SczK98+wq+3fmZLwq6uo+47Fx/q/vb33+r279v/IxPn/xsH49MfF9Va3r/IA19z3AAAAAAAAAAAAwMz0AMbY/gG2vOsfr7PsKqus+gawtPAAzNHzF8PH8XDR0vi129v9qtPT+3DT1PgW09T4AAAAAAAAAAAA+B8AAPAPAACABwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAACAAwAAgAMAAIADAADABwAAwgcAAA==
// @author       UnforgetMemory
// @namespace    https://www.sehuatang.net/*
// @namespace    https://www.sehuatang.org/*
// @match        https://www.sehuatang.net/forum*
// @match        https://www.sehuatang.org/forum*
// @match        https://www.sehuatang.net/forum.php?mod=forumdisplay&fid=103&page=*
// @match        https://www.sehuatang.org/forum.php?mod=forumdisplay&fid=103&page=*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js
// @require      https://cdn.jsdelivr.net/npm/sweetalert2@11
// @require		 https://cdn.jsdelivr.net/npm/[email protected]/i18next.min.js
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @grant        GM_registerMenuCommand
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_setClipboard
// @license 	 GNU GPLv3
// ==/UserScript==

(function () {
	'use strict';
	// Default Config >> Start
	const REFERER = document.location.href;
	const USER_AGENT = window.navigator.userAgent;
	const ACCEPT =
		'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7';
	const COOKIE = document.cookie;
	const JAVDB_COM = 'javdb.com';
	const VIEWED_AVIDS_LOCAL_STORAGE_KEY = '68905cf391b2428572e6446042ab1029';
	const VIEWED_US_TITLES_LOCAL_STORAGE_KEY = 'abba24c58fc69bf0955bddc7a0eadee1';
	const HIDE_VIEWED_MODE_KEY = '780fbed5c332f7f96ca73e19e94a9749';
	const VIEWED_COLOR = 'gray';
	const JIANGUOYUN_KEY_MD5 = '97f6483755d45ad927caf3108b61be91';
	const JIANGUOYUN_DAV_URL_EL_ID = `${JIANGUOYUN_KEY_MD5}_dav_url`;
	const JIANGUOYUN_ACCOUNT_EL_ID = `${JIANGUOYUN_KEY_MD5}_account`;
	const JIANGUOYUN_PASSWORD_EL_ID = `${JIANGUOYUN_KEY_MD5}_password`;
	const AVIDS_CLOUD_FILE_NAME = '95551967d3da7c5af36b141f630683c4';
	const US_CLOUD_FILE_NAME = '53648e7622cfa657f1f6de856efd67c9';
	const LOCALE_KEY = 'ee2757153264e82a1c8f64db8ddcb3e2';
	const LOCALE_LIST = {
		enUS: 'en-US',
		zhCN: 'zh-CN',
		zhHK: 'zh-HK',
		zhTW: 'zh-TW',
	};
	// Default Config >> End

	// REGEX >> Start
	const AVID_REGEX = /[a-zA-Z]{2,6}[-\s]?\d{2,5}/gi;
	// REGEX >> End

	// Gobal Var >> Start
	var elArrayLength = 0;
	// Gobal Var >> End

	// i18nnext

	i18next.init({
		lng: currentLocale(),
		fallbackLng: LOCALE_LIST.enUS,
		resources: {
			'en-US': {
				translation: {
					Language: '🕮 Language',
					'Hide Viewed': 'Hide Viewed',
					Jianguoyun: '☁️ Jianguoyun',
					'Jianguoyun Config': '☁️ Jianguoyun Config',
					'Upload To Jianguoyun': '↑ Upload To ☁️ Jianguoyun',
					'Download from Jianguoyun': '↓ Download from ☁️ Jianguoyun',
					'Local and Jianguoyun merge': '🔄 Local and ☁️ Jianguoyun merge',
					'DAV URL': '☁️  DAV URL',
					Account: '👤 Account',
					Password: '🔑 Password',
					'Show Password': 'Show Password',
					Save: 'Save',
					'Save Successful!': 'Save Successful!',
					'Update Successful!': 'Update Successful!',
					'Update Bad': 'Update Bad',
					'Upload successful!': 'Upload successful!',
					'Sync successful!': 'Sync successful!',
					'Download successful!': 'Download successful!',
					'Hidden Password': 'Hidden Password',
					'Status ERROR': 'Webdav Status Error',
					'Check Config!': 'Check Config!',
					'No Data': 'Cloud No historical data exists!',
					'Bad Download': 'Bad Download Data',
					'Page to Refresh':
						'The page is about to refresh due to new data updates. Please wait...',
					'Viewed Total': 'Viewed Total',
					click_all_magnet: 'Click All Magnet',
					click_all_torrent: 'Click All Torrent',
				},
			},
			'zh-CN': {
				translation: {
					Language: '🕮 语言(简体)',
					'Hide Viewed': '隐藏已阅',
					Jianguoyun: '☁️ 坚果云',
					'Jianguoyun Config': '☁️ 坚果云配置',
					'Upload To Jianguoyun': '↑ 上传至 ☁️ 坚果云',
					'Download from Jianguoyun': '从 ☁️ 坚果云 ↓ 下载',
					'Local and Jianguoyun merge': '🔄 双端同步 ☁️ 坚果云 ',
					'DAV URL': '☁️  DAV URL',
					Account: '👤 账号',
					Password: '🔑 密码',
					'Show Password': '显示密码',
					Save: '保存',
					'Save Successful!': '保存成功!',
					'Update Successful!': '更新成功!',
					'Update Bad': '更新失败',
					'Upload successful!': '上传成功!',
					'Sync successful!': '同步成功!',
					'Download successful!': '下载完成!',
					'Hidden Password': '隐藏密码',
					'Status ERROR': 'Webdav 状态异常',
					'Check Config!': '检查配置!',
					'No Data': '云端没有历史数据!',
					'Bad Download': '下载数据出错',
					'Page to Refresh': '数据更新,页面即将刷新,请稍候...',
					'Viewed Total': '浏览量',
					click_all_magnet: '点击所有磁力链接',
					click_all_torrent: '点击所有种子链接',
				},
			},
			'zh-TW': {
				translation: {
					Language: '🕮 語言(台)',
					'Hide Viewed': '隱藏已讀',
					Jianguoyun: '☁️ 堅果雲',
					'Jianguoyun Config': '☁️ 堅果雲配置',
					'Upload To Jianguoyun': '⬆️ 上傳至 ☁️ 堅果雲',
					'Download from Jianguoyun': '從 ☁️ 堅果雲 ⬇️ 下載',
					'Local and Jianguoyun merge': '本地與 ☁️ 堅果雲同步',
					'DAV URL': '☁️ DAV 網址',
					Account: ' 帳戶',
					Password: ' 密碼',
					'Show Password': '顯示密碼',
					Save: '儲存',
					'Save Successful!': '儲存成功!',
					'Hidden Password': '隱藏密碼',
					'Update Bad': '更新失敗',
					'Upload successful!': '上傳成功!',
					'Sync successful!': '同步成功!',
					'Download successful!': '下載成功!',
					'Status ERROR': 'Webdav 狀態錯誤',
					'Check Config!': '檢查設定!',
					'No Data': '雲端沒有歷史資料!',
					'Bad Download': '下載數據錯誤',
					'Page to Refresh': '頁面即將重新整理,以更新資料。請稍候...',
					'Viewed Total': '瀏覽量',
					click_all_magnet: '點擊所有磁力連結',
					click_all_torrent: '點擊所有種子連結',
				},
			},
			'zh-HK': {
				translation: {
					Language: '🕮 語言(港)',
					'Hide Viewed': '收埋睇過',
					'Jianguoyun Config': '☁️ 堅果雲',
					'Jianguoyun Config': '☁️ 堅果雲設定',
					'Upload To Jianguoyun': '⬆️ 上載到 ☁️ 堅果雲',
					'Download from Jianguoyun': '由 ☁️ 堅果雲 ⬇️ 下載',
					'Local and Jianguoyun merge': '本地同 ☁️ 堅果雲同步',
					'DAV URL': '☁️ DAV 網址',
					Account: '帳戶',
					Password: '密碼',
					'Show Password': '睇密碼',
					Save: '儲存',
					'Save Successful!': '儲存成功喇!',
					'Hidden Password': '收埋密碼',
					'Update Bad': '更新搞唔掂',
					'Upload successful!': '上傳成功喇!',
					'Sync successful!': '同步成功喇!',
					'Download successful!': '下載掂咗喇!',
					'Status ERROR': 'Webdav 狀態搞唔掂',
					'Check Config!': '睇吓設定啱唔啱!',
					'No Data': '雲端咩資料都冇呀!',
					'Bad Download': '下載嘅資料壞咗',
					'Page to Refresh': '资料更新紧系,页面要更新喇!等阵先!',
					'Viewed Total': '瀏覽量',
					click_all_magnet: '點擊所有磁力連結',
					click_all_torrent: '點擊所有種子連結',
				},
			},
		},
	});

	// i18nnext

	// Style >> Start
	GM_addStyle(`
        .nep_um_main{
            display: flex;
            flex-flow: wrap;
            width: 2501px;
        }

        .nep_um_title {
            width: 100%;
            max-width: 100%;
            margin: 1rem;
            font-size: 1.7rem;
            font-weight: bold;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            flex-basis: 100%;
        }

		.nep_um_release_date {
            width: 100%;
            max-width: 100%;
            margin: 1rem;
            flex-basis: 100%;
        }

        .nep_um_cover {
            height: auto;
            margin: 1rem;
            flex-basis: 100%;
			aspect-ratio: 3 / 2;
        }

        .nep_um_cover > img {
            width: 100%;
            height: auto;
            max-width: 938.667px;
        }

        .nep_um_magent {
            flex-basis: 100%;
            width: 100%;
            margin: 1rem;
        }

       .nep_um_torrent {
            flex-basis: 100%;
            width: 100%;
            margin: 1rem;
            font-size: 1.2rem;
        }

        .nep_um_divider {
            flex-basis: 100%;
            width: 100%;
            margin: 1rem;
            font-size: 1.2rem;
            height: 0.4rem;
            background-color: black;
			filter: grayscale(0.5);
        }
    `);
	// Style >> End

	// Custom Config >> Start
	GM_registerMenuCommand(`${i18next.t('Language')}`, languageConfigDialog);
	GM_registerMenuCommand(hideViewedTitle(), viewedModeSwitch);
	GM_registerMenuCommand(
		`${i18next.t('Jianguoyun Config')}`,
		jianguoyunConfigDialog
	);
	GM_registerMenuCommand(
		`${i18next.t('Upload To Jianguoyun')}`,
		uploadToJianguoyun
	);
	GM_registerMenuCommand(
		`${i18next.t('Download from Jianguoyun')}`,
		downloadFromJianguoyun
	);
	GM_registerMenuCommand(
		`${i18next.t('Local and Jianguoyun merge')}`,
		mergeWithJianguoyun
	);
	GM_registerMenuCommand(
		`${i18next.t('Viewed Total')} ${getCurrentViewedAVIDList().length}`
	);
	GM_registerMenuCommand(`${i18next.t('click_all_magnet')}`, clickAllMagent);
	GM_registerMenuCommand(`${i18next.t('click_all_torrent')}`, clickAllTorrent);
	// Custom Config >> End
	function currentLocale() {
		let locale = GM_getValue(LOCALE_KEY);
		if (typeof locale == 'string') {
			return locale;
		}
		return LOCALE_LIST.enUS;
	}

	function languageConfigDialog() {
		Swal.fire({
			title: '🕮 Language',
			input: 'select',
			inputOptions: {
				'en-US': '🕮 Language',
				'zh-CN': '🕮 语言(简体)',
				'zh-HK': '🕮 語言(港)',
				'zh-TW': '🕮 語言(台)',
			},
			inputValue: currentLocale(),
			showCancelButton: true,
			confirmButtonText: `${i18next.t('Save')}`,
		}).then((result) => {
			if (result.isConfirmed) {
				console.log(result);
				GM_setValue(LOCALE_KEY, result.value);
				i18next.changeLanguage(result.value);
				Swal.fire({
					icon: 'success',
					title: `${i18next.t('Save Successful!')}`,
					text: `${i18next.t('Page to Refresh')}`,
				});
				setTimeout(() => {
					document.location.reload();
				}, 300);
			}
		});
	}
	function hideViewedTitle() {
		let enabled = GM_getValue(HIDE_VIEWED_MODE_KEY) ? '✅' : '❌';
		return `${enabled} ${i18next.t('Hide Viewed')}`;
	}
	function viewedModeSwitch() {
		var enabled = GM_getValue(HIDE_VIEWED_MODE_KEY);
		enabled = !enabled;
		GM_setValue(HIDE_VIEWED_MODE_KEY, enabled);
		location.reload();
	}

	class JianguoyunClient {
		generateConfig(davURL, account, password) {
			if (
				account == null ||
				typeof account != 'string' ||
				account.trim().length < 1
			) {
				return null;
			}
			if (
				password == null ||
				typeof password != 'string' ||
				password.trim().length < 1
			) {
				return null;
			}
			if (
				davURL == null ||
				typeof davURL != 'string' ||
				account.trim().length < 1
			) {
				return null;
			}
			return {
				auth: `Basic ${btoa(`${account}:${password}`)}`,
				davURL: davURL,
			};
		}

		getConfig() {
			let jianguoyunConfig = getJianguoyunConfig();
			if (jianguoyunConfig == null) {
				return null;
			}
			let account = jianguoyunConfig.account;
			let password = jianguoyunConfig.password;
			let davURL = jianguoyunConfig.url;
			return this.generateConfig(davURL, account, password);
		}

		download(fileName) {
			let config = this.getConfig();
			if (config == null) {
				return Promise.reject('Bad Config!');
			}
			let url = `${config.davURL}/${fileName}.json`.replace(/\/+/g, '/');
			return new Promise((res, error) => {
				GM_xmlhttpRequest({
					method: 'GET',
					timeout: 3000,
					headers: { Authorization: config.auth },
					url: url,
					onload: res,
					onerror: error,
					ontimeout: error,
				});
			});
		}

		upload(fileName, data) {
			let config = this.getConfig();
			if (config == null) {
				return Promise.reject('Bad Config!');
			}
			let url = `${config.davURL}/${fileName}.json`.replace(/\/+/g, '/');
			return new Promise((res, error) => {
				GM_xmlhttpRequest({
					method: 'PUT',
					timeout: 3000,
					data: data,
					headers: { Authorization: config.auth },
					url: url,
					dataType: 'json',
					onload: res,
					onerror: error,
					ontimeout: error,
				});
			});
		}
	}
	function saveJianguoyunConfig(url, account, password) {
		GM_setValue(
			JIANGUOYUN_KEY_MD5,
			JSON.stringify({ url: url, account: account, password: password })
		);
	}
	function getJianguoyunConfig() {
		let jsonStr = GM_getValue(JIANGUOYUN_KEY_MD5);
		if (jsonStr == null) {
			return null;
		}
		try {
			return JSON.parse(jsonStr);
		} catch (_) {
			return null;
		}
	}
	function jianguoyunConfigDialog() {
		let oldData = getJianguoyunConfig();
		let formHTML = `
           <label for="${JIANGUOYUN_DAV_URL_EL_ID}">${i18next.t(
			'DAV URL'
		)}</label>
           <input type="text" id="${JIANGUOYUN_DAV_URL_EL_ID}" name="${JIANGUOYUN_DAV_URL_EL_ID}" class="swal2-input"/>
           <br />
           <label for="${JIANGUOYUN_ACCOUNT_EL_ID}">${i18next.t(
			'Account'
		)}</label>
           <input type="text" id="${JIANGUOYUN_ACCOUNT_EL_ID}" name="${JIANGUOYUN_ACCOUNT_EL_ID}" class="swal2-input"/>
           <br />
           <label for="${JIANGUOYUN_PASSWORD_EL_ID}">${i18next.t(
			'Password'
		)}</label>
           <input type="password" id="${JIANGUOYUN_PASSWORD_EL_ID}" name="${JIANGUOYUN_PASSWORD_EL_ID}" class="swal2-input"/>
           <button id="${JIANGUOYUN_PASSWORD_EL_ID}_button" class="swal2-cancel">${i18next.t(
			'Show Password'
		)}</button>
           <br />
         `;
		Swal.fire({
			title: `${i18next.t('Jianguoyun Config')}`,
			html: formHTML,
			showCancelButton: true,
			confirmButtonText: `${i18next.t('Save')}`,
			preConfirm: () => {
				let url = document.getElementById(JIANGUOYUN_DAV_URL_EL_ID).value;
				let account = document.getElementById(JIANGUOYUN_ACCOUNT_EL_ID).value;
				let password = document.getElementById(JIANGUOYUN_PASSWORD_EL_ID).value;
				saveJianguoyunConfig(url, account, password);
			},
		}).then((result) => {
			if (result.isConfirmed) {
				Swal.fire({
					icon: 'success',
					title: `${i18next.t('Save Successful!')}`,
				});
			}
		});
		document.getElementById(JIANGUOYUN_DAV_URL_EL_ID).value = oldData.url;
		document.getElementById(JIANGUOYUN_ACCOUNT_EL_ID).value = oldData.account;
		document.getElementById(JIANGUOYUN_PASSWORD_EL_ID).value = oldData.password;
		const passwordInput = document.getElementById(JIANGUOYUN_PASSWORD_EL_ID);
		const togglePasswordButton = document.getElementById(
			`${JIANGUOYUN_PASSWORD_EL_ID}_button`
		);
		togglePasswordButton.addEventListener('click', () => {
			if (passwordInput.type === 'password') {
				passwordInput.type = 'text';
				togglePasswordButton.innerText = `${i18next.t('Hidden Password')}`;
			} else {
				passwordInput.type = 'password';
				togglePasswordButton.innerText = `${i18next.t('Show Password')}`;
			}
		});
	}
	function uploadToJianguoyun() {
		let avIds = getCurrentViewedAVIDList();
		let usTitles = getCurrentViewedUSTitleList();
		let jianguoyunClient = new JianguoyunClient();
		jianguoyunClient
			.upload(US_CLOUD_FILE_NAME, JSON.stringify(usTitles))
			.then(() => {})
			.catch(() => {});
		jianguoyunClient
			.upload(AVIDS_CLOUD_FILE_NAME, JSON.stringify(avIds))
			.then((res) => {
				if (res.status >= 200 && res.status < 300) {
					Swal.fire({
						icon: 'success',
						title: `${i18next.t('Upload successful!')}`,
					});
				} else {
					Swal.fire({
						icon: 'error',
						title: `${i18next.t('Jianguoyun')}`,
						text: `${i18next.t('Status Error')} >> ${res.status} >> ${i18next.t(
							'Check Config!'
						)}`,
					});
				}
			})
			.catch((error) => {
				Swal.fire({
					icon: 'error',
					title: `${i18next.t('Update Bad')}`,
					text: JSON.stringify(error),
				});
			});
	}
	function downloadFromJianguoyun() {
		let jianguoyunClient = new JianguoyunClient();
		jianguoyunClient
			.download(US_CLOUD_FILE_NAME)
			.then((res) => {
				if (res === 200) {
					if (res.responseText != null && res.responseText.length > 2) {
						let cloudUSTitles = JSON.parse(res.responseText);
						addListToViewedUSTitle(cloudUSTitles);
					}
				}
			})
			.catch(() => {});
		jianguoyunClient
			.download(AVIDS_CLOUD_FILE_NAME)
			.then((res) => {
				if (res.status === 200) {
					if (res.responseText != null && res.responseText.length > 2) {
						let cloudAvIds = JSON.parse(res.responseText);
						addListToViewedAVID(cloudAvIds);
					}
					Swal.fire({
						icon: 'success',
						title: `${i18next.t('Download successful!')}`,
					});
				} else if (res.status == 404) {
					Swal.fire({
						icon: 'error',
						title: `${i18next.t('Jianguoyun')} >> ${i18next.t('No Data')}`,
					});
				} else {
					Swal.fire({
						icon: 'error',
						title: `${i18next.t('Jianguoyun')}`,
						text: `${i18next.t('Status Error')} >> ${res.status} >> ${i18next.t(
							'Check Config!'
						)}`,
					});
				}
			})
			.catch((error) => {
				Swal.fire({
					icon: 'error',
					title: `${i18next.t('Upload Bad')}`,
					text: JSON.stringify(error),
				});
			});
	}
	async function mergeWithJianguoyunUSTitle() {
		let jianguoyunClient = new JianguoyunClient();
		let cloudUSTitles = [];
		let usBreakFnc = false;
		await jianguoyunClient
			.download(US_CLOUD_FILE_NAME)
			.then((res) => {
				if (res.status >= 200 && res.status < 300) {
					if (res.responseText != null && res.responseText.length > 2) {
						cloudUSTitles = JSON.parse(res.responseText);
					}
				} else if (res.status == 404) {
				} else {
					usBreakFnc = true;
				}
			})
			.catch(() => {
				usBreakFnc = false;
			});
		if (usBreakFnc) {
			return;
		}
		let localUSTitles = getCurrentViewedUSTitleList();
		let mergeUSTitles = _.union(cloudUSTitles, localUSTitles);
		resetViewedUSTitle(mergeUSTitles);
		jianguoyunClient
			.upload(US_CLOUD_FILE_NAME, JSON.stringify(mergeUSTitles))
			.then(() => {})
			.catch(() => {});
	}
	async function mergeWithJianguoyun() {
		mergeWithJianguoyunUSTitle();
		let jianguoyunClient = new JianguoyunClient();
		let cloudAvIds = [];
		let breakFnc = false;
		await jianguoyunClient
			.download(AVIDS_CLOUD_FILE_NAME)
			.then((res) => {
				if (res.status >= 200 && res.status < 300) {
					if (res.responseText != null && res.responseText.length > 2) {
						cloudAvIds = JSON.parse(res.responseText);
					}
				} else if (res.status == 404) {
				} else {
					Swal.fire({
						icon: 'error',
						title: `${i18next.t('Jianguoyun')} >> ${i18next.t(
							'Status Error'
						)} >> ${res.status} >> ${i18next.t('Check Config!')}`,
					});
					breakFnc = true;
				}
			})
			.catch(() => {
				breakFnc = false;
			});
		if (breakFnc) {
			Swal.fire({
				icon: 'error',
				title: `${i18next.t('Jianguoyun')} >> ${i18next.t('Bad Download')}`,
			});
			return;
		}
		let localAvIds = getCurrentViewedAVIDList();
		let mergeAvIds = _.union(cloudAvIds, localAvIds);
		resetViewedAVID(mergeAvIds);
		jianguoyunClient
			.upload(AVIDS_CLOUD_FILE_NAME, JSON.stringify(mergeAvIds))
			.then((res) => {
				if (res.status >= 200 && res.status < 300) {
					Swal.fire({
						icon: 'success',
						title: `${i18next.t('Sync successful!')}`,
					});
				} else {
					Swal.fire({
						icon: 'error',
						title: `${i18next.t('Jianguoyun')} >> ${i18next.t(
							'Status Error'
						)} >> ${res.status} >> ${i18next.t('Check Config!')}`,
					});
				}
			})
			.catch((error) => {
				Swal.fire({
					icon: 'error',
					title: `${i18next.t('Upload Bad')}`,
					text: JSON.stringify(error),
				});
			});
	}

	function getCurrentViewedAVIDList() {
		let localList = GM_getValue(VIEWED_AVIDS_LOCAL_STORAGE_KEY) || '[]';
		return JSON.parse(localList);
	}

	function getCurrentViewedUSTitleList() {
		let localList = GM_getValue(VIEWED_US_TITLES_LOCAL_STORAGE_KEY) || '[]';
		return JSON.parse(localList);
	}

	function exitsViewedAVID(avId) {
		return getCurrentViewedAVIDList().includes(avId);
	}

	function exitsViewedUSTitle(title) {
		return getCurrentViewedUSTitleList().includes(title);
	}

	function addToViewedAVID(avId) {
		let oldIdList = getCurrentViewedAVIDList();
		if (oldIdList.includes(avId)) {
			return;
		}
		oldIdList.push(avId);
		let newValue = JSON.stringify(oldIdList);
		GM_setValue(VIEWED_AVIDS_LOCAL_STORAGE_KEY, newValue);
	}

	function addToViewedUSTitle(title) {
		let oldIdList = getCurrentViewedUSTitleList();
		if (oldIdList.includes(title)) {
			return;
		}
		oldIdList.push(title);
		let newValue = JSON.stringify(oldIdList);
		GM_setValue(VIEWED_US_TITLES_LOCAL_STORAGE_KEY, newValue);
	}

	function addListToViewedAVID(avIds) {
		let oldList = getCurrentViewedAVIDList();
		let newList = _.union(oldList, avIds);
		let newValue = JSON.stringify(newList);
		GM_setValue(VIEWED_AVIDS_LOCAL_STORAGE_KEY, newValue);
	}

	function addListToViewedUSTitle(titles) {
		let oldList = getCurrentViewedUSTitleList();
		let newList = _.union(oldList, titles);
		let newValue = JSON.stringify(newList);
		GM_setValue(VIEWED_US_TITLES_LOCAL_STORAGE_KEY, newValue);
	}

	function resetViewedAVID(avIds) {
		if (avIds == null || avIds.length < 1) {
			return;
		}
		let newValue = JSON.stringify(avIds);
		GM_setValue(VIEWED_AVIDS_LOCAL_STORAGE_KEY, newValue);
	}

	function resetViewedUSTitle(titles) {
		if (titles == null || titles.length < 1) {
			return;
		}
		let newValue = JSON.stringify(titles);
		GM_setValue(VIEWED_US_TITLES_LOCAL_STORAGE_KEY, newValue);
	}

	function elOpenUrl(elBody) {
		let elUrl = null;
		if (elBody) {
			let subUrl = null;
			let subUrlEl = elBody.querySelector('td > td.icon > a');
			if (!subUrlEl) {
				subUrlEl = elBody.querySelector('tr > th.common > a.s.xst');
			}
			if (!subUrlEl) {
				subUrlEl = elBody.querySelector('tr > th.new > a.s.xst');
			}
			if (subUrlEl) {
				subUrl = subUrlEl.href;
			}
			if (subUrl) {
				elUrl = subUrl;
			}
		}
		return elUrl;
	}
	function elAllArray() {
		return Array.from(
			document.querySelectorAll('[id^="normalthread_"]')
		).filter(function (element) {
			if (/^normalthread_\d+$/.test(element.id)) {
				return element;
			}
		});
	}
	function elCutLastArray() {
		let allArray = elAllArray();
		let lastArray = null;
		if (allArray && allArray.length > 0) {
			let nowArrayLength = allArray.length;
			if (elArrayLength <= 0) {
				lastArray = allArray;
			} else {
				lastArray = allArray.slice(elArrayLength);
			}
			elArrayLength = nowArrayLength;
		}
		return lastArray;
	}
	function elSubPageImageEl(subPageHTML) {
		if (subPageHTML) {
			let _el = subPageHTML.querySelector('ignore_js_op > img');
			if (_el) {
				return `<img src="${_el.getAttribute(
					'zoomFile'
				)}" style="width:100%; max-with:300px; height: auto;"/>`;
			}
		}
		return null;
	}

	function elSubPageMagentEl(subPageHTML) {
		if (subPageHTML) {
			let magentEl = subPageHTML.querySelector('.blockcode > div > ol > li');
			if (magentEl) {
				return `<a href="${magentEl.innerText}" style="text-decoration:underline;">${magentEl.innerText}</a>`;
			}
		}
		return null;
	}

	function elSubPageTorrentEl(subPageHTML) {
		if (subPageHTML) {
			return subPageHTML.querySelector(
				'div.pattl > ignore_js_op > dl > dd > p.attnm '
			);
		}
		return null;
	}

	function elPostReleaseDate(elBody) {
		let releaseDate = 'Unknown';
		if (elBody) {
			let _el = elBody.querySelector('tr > td:nth-child(3) > em > span > span');
			if (_el) {
				releaseDate = _el.innerText;
			}
			if (_el == null || _el.innerText == '') {
				_el = elBody.querySelector('tr > td:nth-child(3) > em > span');
				releaseDate = _el.innerText;
			}
		}
		return releaseDate;
	}

	function generateJAVDBURLEl(avId, title) {
		return `<a href='https://${JAVDB_COM}/search?q=${avId}&f=all' target='_blank' referrerpolicy='same-origin'>${avId} ${title}</a>`;
	}
	function elTitleDiv(elBody) {
		let title = 'Unknown';
		if (elBody) {
			let titleEl = elBody.querySelector('tr > th.common > a.s.xst');
			if (!titleEl) {
				titleEl = elBody.querySelector('tr > th.new > a.s.xst');
			}
			if (titleEl) {
				title = titleEl.innerText.replace(/<savdiv[^>]*>.*?<\/savdiv>/g, '');
			}
		}
		let avIdArray = title.match(AVID_REGEX);
		let avId = null;
		if (avIdArray && avIdArray.length > 0) {
			avId = avIdArray[0];
			let _title = title.replace(AVID_REGEX, '');
			title = generateJAVDBURLEl(avId, _title);
		}
		let titleDiv = document.createElement('div');
		titleDiv.classList.add('nep_um_title');
		titleDiv.innerHTML = title;
		let isUS = false;
		let isUSViewed = false;
		if (avId) {
			if (exitsViewedAVID(avId)) {
				titleDiv.querySelector('a').style.color = VIEWED_COLOR;
				if (GM_getValue(HIDE_VIEWED_MODE_KEY)) {
					return avId;
				}
			} else {
				titleDiv.addEventListener('click', function () {
					addToViewedAVID(avId);
					titleDiv.querySelector('a').style.color = VIEWED_COLOR;
				});
			}
		} else {
			isUS = true;
			titleDiv.innerHTML = `<a>${title}</a> `;
			if (exitsViewedUSTitle(title)) {
				isUSViewed = true;
				titleDiv.querySelector('a').style.color = VIEWED_COLOR;
				if (GM_getValue(HIDE_VIEWED_MODE_KEY)) {
					titleDiv.innerHTML = `<a>${title} >> ${i18next.t(
						'Hide Viewed'
					)}</a> `;
				}
			}
		}

		return {
			div: titleDiv,
			id: avId,
			isUS: isUS,
			isUSViewed: isUSViewed,
			title: title,
		};
	}

	function elTranTitleDivStyle(div, avId) {
		if (avId) {
			addToViewedAVID(avId);
			div.querySelector('a').style.color = VIEWED_COLOR;
		}
	}
	function elTranTitleDivStyleForUSTitle(div, title) {
		if (title) {
			addToViewedUSTitle(title);
			div.querySelector('a').style.color = VIEWED_COLOR;
		}
	}

	/* toRequestSubURL */
	function elConvertElBody(elBody) {
		let openPageUrl = elOpenUrl(elBody);

		if (!openPageUrl) {
			return null;
		}

		// main
		let mainDiv = document.createElement('div');
		mainDiv.classList.add('nep_um_main');
		mainDiv.id = 'nep_um_main';

		// title
		let titleDivAndId = elTitleDiv(elBody);
		if (typeof titleDivAndId === 'string') {
			let hiddenDiv = createHiddenDiv(
				titleDivAndId,
				`>> ${i18next.t('Hide Viewed')}`
			);
			mainDiv.append(hiddenDiv);
			elBody.innerHTML = '';
			elBody.appendChild(mainDiv);
			return;
		}

		let isUS = titleDivAndId.isUS;
		let titleDiv = titleDivAndId.div;
		let avId = titleDivAndId.id;
		let title = titleDivAndId.title;
		let isUSViewed = titleDivAndId.isUSViewed;

		if (isUS && isUSViewed) {
			let hiddenDiv = createHiddenDiv(
				openPageUrl,
				title,
				`>> ${i18next.t('Hide Viewed')}`
			);
			mainDiv.append(hiddenDiv);
			elBody.innerHTML = '';
			elBody.appendChild(mainDiv);
			return;
		}

		if (isUS) {
			titleDiv.onclick = function () {
				elTranTitleDivStyleForUSTitle(titleDiv, title);
				window.open(openPageUrl, '_blank');
			};
		}

		mainDiv.appendChild(titleDiv);

		// releaseDate
		let releaseDate = elPostReleaseDate(elBody);
		let releaseDateDiv = document.createElement('div');
		releaseDateDiv.classList.add('nep_um_release_date');
		releaseDateDiv.innerText = releaseDate;
		mainDiv.appendChild(releaseDateDiv);

		GM_xmlhttpRequest({
			method: 'GET',
			url: openPageUrl,
			headers: {
				'User-agent': USER_AGENT,
				Accept: ACCEPT,
				cookie: COOKIE,
				referer: REFERER,
			},
			onerror: function (error) {
				console.error('Error fetching data:', error);
				elBody.innerHTML = '';
				elBody.appendChild(mainDiv);
			},
			onload: function (res) {
				let parser = new DOMParser();
				let subPageHTML = parser.parseFromString(res.responseText, 'text/html');
				let imgEl = elSubPageImageEl(subPageHTML);
				let magentEl = elSubPageMagentEl(subPageHTML);
				let torrentEl = elSubPageTorrentEl(subPageHTML);
				if (imgEl && (magentEl || torrentEl)) {
					// cover
					let imgDiv = document.createElement('div');
					imgDiv.onclick = function () {
						window.open(openPageUrl, '_blank');
						if (isUS) {
							elTranTitleDivStyleForUSTitle(titleDiv, title);
						} else {
							elTranTitleDivStyle(titleDiv, avId);
						}
					};
					imgDiv.classList.add('nep_um_cover');
					imgDiv.innerHTML = imgEl;
					mainDiv.appendChild(imgDiv);

					// magent
					let magentDiv = document.createElement('div');
					magentDiv.onclick = function () {
						if (isUS) {
							elTranTitleDivStyleForUSTitle(titleDiv, title);
						} else {
							elTranTitleDivStyle(titleDiv, avId);
						}
					};
					magentDiv.classList.add('nep_um_magent');
					if (magentEl != null) {
						magentDiv.innerHTML = magentEl;
						mainDiv.appendChild(magentDiv);
					}

					// torrent
					let torrentDiv = document.createElement('div');
					torrentDiv.onclick = function () {
						if (isUS) {
							elTranTitleDivStyleForUSTitle(titleDiv, title);
						} else {
							elTranTitleDivStyle(titleDiv, avId);
						}
					};
					torrentDiv.classList.add('nep_um_torrent');
					if (torrentEl?.outerHTML != null) {
						torrentDiv.innerHTML = torrentEl.outerHTML;
						mainDiv.appendChild(torrentDiv);
					}

					// divider
					let dividerDiv = document.createElement('div');
					dividerDiv.classList.add('nep_um_divider');
					mainDiv.appendChild(dividerDiv);

					elBody.innerHTML = '';
					elBody.appendChild(mainDiv);
				}
			},
		});
	}

	function createHiddenDiv(url, innerText, additionalText = '') {
		let hiddenDiv = document.createElement('div');
		hiddenDiv.innerHTML = `<a href='${url}'>${innerText} ${additionalText}</a>`;
		hiddenDiv.style.color = VIEWED_COLOR;
		hiddenDiv.style.fontSize = '0.5rem';
		hiddenDiv.style.textAlign = 'center';
		hiddenDiv.style.width = '100%';
		hiddenDiv.style.paddingBottom = '0.5rem';
		return hiddenDiv;
	}

	function clickAllMagent() {
		let allMagentDiv = document.querySelectorAll('.nep_um_magent');
		let allMagentText = '';
		for (let i = 0; i < allMagentDiv.length; i++) {
			allMagentText += `\r\n${allMagentDiv[i].innerText}`;
			allMagentDiv[i].click();
		}
		GM_setClipboard(allMagentText);
	}

	function clickAllTorrent() {
		let allTorrentDiv = document.querySelectorAll('.nep_um_torrent');
		let allTorrentText = '';
		for (let i = 0; i < allTorrentDiv.length; i++) {
			allTorrentText += `\r\n${allTorrentDiv[i].innerText}`;
			allTorrentDiv[i].click();
		}
		GM_setClipboard(allTorrentText);
	}

	function run() {
		let modifyElArray = elCutLastArray();
		if (modifyElArray && modifyElArray.length > 0) {
			modifyElArray.forEach((_el) => {
				try {
					elConvertElBody(_el);
				} catch (error) {
					console.error('Error in elConvertElBody:', error);
				}
			});
		}
	}

	const runDebounce = _.debounce(run, 3000, { maxWait: 8000 });

	const observer_list = new MutationObserver((mutations) => {
		mutations.forEach((mutation) => {
			if (mutation.type === 'childList') {
				runDebounce();
			}
		});
	});

	const observerConfig_list = { childList: true, subtree: true };
	observer_list.observe(document.body, observerConfig_list);

	const wpDiv = document.querySelector('#wp');

	const observer_width = new ResizeObserver((entries) => {
		entries.forEach((entry) => {
			if (entry.target === wpDiv) {
				const newWidth = wpDiv.clientWidth;
				const childDivs = wpDiv.querySelectorAll('#nep_um_main');
				childDivs.forEach((childDiv) => {
					childDiv.style.width = `${newWidth}px`;
				});
			}
		});
	});
	observer_width.observe(wpDiv);

	// init
	run();
	document.querySelector('#threadlisttableid').style.width = '100%';
})();