圖片全載Next

支持寫真、H漫、漫畫的網站1000+,樸實無華直觀操作的UI,圖片全量載入,簡易的看圖功能,漫畫無限滾動閱讀模式,下載壓縮打包,如有下一頁元素可自動化下載。

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey, το Greasemonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

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

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Violentmonkey για να εγκαταστήσετε αυτόν τον κώδικα.

θα χρειαστεί να εγκαταστήσετε μια επέκταση όπως το Tampermonkey ή το Userscripts για να εγκαταστήσετε αυτόν τον κώδικα.

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

Θα χρειαστεί να εγκαταστήσετε μια επέκταση διαχείρισης κώδικα χρήστη για να εγκαταστήσετε αυτόν τον κώδικα.

(Έχω ήδη έναν διαχειριστή κώδικα χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

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.

(Έχω ήδη έναν διαχειριστή στυλ χρήστη, επιτρέψτε μου να τον εγκαταστήσω!)

// ==UserScript==
// @name               圖片全載Next
// @name:en            Full Picture Load
// @name:zh-CN         图片全载Next
// @name:zh-TW         圖片全載Next
// @version            2025.12.19
// @description        支持寫真、H漫、漫畫的網站1000+,樸實無華直觀操作的UI,圖片全量載入,簡易的看圖功能,漫畫無限滾動閱讀模式,下載壓縮打包,如有下一頁元素可自動化下載。
// @description:en     supports 1,000+ websites for photos, h-comics, and comics, fully load all images, simple image viewing function, comic infinite scroll read mode, and compressed and packaged downloads.
// @description:zh-CN  支持写真、H漫、漫画的网站1000+,朴实无华直观操作的UI,图片全量加载,简易的看图功能,漫画无限滚动阅读模式,下载压缩打包,如有下一页元素可自动化下载。
// @description:zh-TW  支持寫真、H漫、漫畫的網站1000+,樸實無華直觀操作的UI,圖片全量載入,簡易的看圖功能,漫畫無限滾動閱讀模式,下載壓縮打包,如有下一頁元素可自動化下載。
// @author             德克斯DEX
// @match              *://*/*
// @connect            *
// @exclude            *.youtube.com*
// @exclude            *docs.google.com*
// @exclude            *google*/maps/*
// @exclude            *mail.google.com*
// @exclude            *accounts.google.com*
// @icon               data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAtFBMVEVEREAAAABEREBEREAuuaIzqpkvr58yiHgzhnY6kYM7mYI4kog4s6A2tpo0r544ooo2nY40sJw0sp00rZg1sJw0sZ0zsp01sZw0sZw0rZk1sJw1sZw1rZk0sp00rpk1sp01sZs1rpk1rpk0sp01spw1sJ00rZo1rZk1rpo0r5k0sJw0sZ01r5o0sZw0rpk0sp01sZ01sJw1spw1r5k1sp01sZw0sZ01sZw1rpk1sp01sZw1r5pUzpTcAAAAOXRSTlMAAAUGCw8QERIUFxgbHB0hIieqq6yvtLa3vb/AwMHCxMXFxsfIyc3Oz+zt7vDx8fL4+Pn5+vr7/v7AEFI4AAABR0lEQVR42qWT11bDMAxApbhsmm5KKVD2KiUQwpD1///FkZcSmh4e8FOsex3LsgymPy6ISkRyA4FlWMRXomIyQOg/SbyKAmSOE2Ip02UOYxf/DILNjOOEWLnAEAqio0MMAzJjTAZh1p0SrYCIuu0cMZc9JbENXLa1NWGdI1nWeQuXGPzBTdzC8ws52UI5MwchrA/VTOuTEP9fFyTG7E+R9q8JLsbW1UHzU8HHrCuU1fyToDlB43xRqMUgfc+/KA77fZrWSH/47zPlzOcpJxG8u32r/OEg5SRCqO/WTeT3+5oTuP4LxrXnd5F7waZ+wM5c+NVeujMRrDYMYueE+VK5E5r3uzOb7TbvHH7f/1pP/L8nU9u38Nwyy8OZdjfwY+ZnmPinp28y3mglNeERDJYy/9A3GYVS+GMPMB+uyL67/qO68Mb8MurBD7foVTtvIbtnAAAAAElFTkSuQmCC
// @license            MIT
// @namespace          https://greasyfork.org/users/20361
// @grant              GM_xmlhttpRequest
// @grant              GM.xmlHttpRequest
// @grant              GM_registerMenuCommand
// @grant              GM.registerMenuCommand
// @grant              GM_unregisterMenuCommand
// @grant              GM.unregisterMenuCommand
// @grant              GM_openInTab
// @grant              GM.openInTab
// @grant              GM_getValue
// @grant              GM.getValue
// @grant              GM_setValue
// @grant              GM.setValue
// @grant              GM_listValues
// @grant              GM.listValues
// @grant              GM_deleteValue
// @grant              GM.deleteValue
// @grant              GM_getResourceText
// @grant              GM.getResourceText
// @grant              GM_addElement
// @grant              GM.addElement
// @grant              unsafeWindow
// @grant              window.close
// @grant              window.onurlchange
// @run-at             document-end
// @noframes
// @require            https://update.greasyfork.org/scripts/473358/1237031/JSZip.js
// @require            https://unpkg.com/[email protected]/dist/axios.min.js
// @resource           JSZip_code https://unpkg.com/[email protected]/dist/jszip.min.js
// @resource           ajaxHookerJS https://scriptcat.org/lib/637/1.4.8/ajaxHooker.js#sha256=dTF50feumqJW36kBpbf6+LguSLAtLr7CEs3oPmyfbiM=
// @resource           CryptoJS_code https://unpkg.com/[email protected]/crypto-js.js
// @resource           JqueryJS https://unpkg.com/[email protected]/dist/jquery.min.js
// @resource           FancyboxV6JS https://unpkg.com/@fancyapps/[email protected]/dist/fancybox/fancybox.umd.js
// @resource           FancyboxV6Css https://unpkg.com/@fancyapps/[email protected]/dist/fancybox/fancybox.css
// @resource           FancyboxV5JS https://unpkg.com/@fancyapps/[email protected]/dist/fancybox/fancybox.umd.js
// @resource           FancyboxV5Css https://unpkg.com/@fancyapps/[email protected]/dist/fancybox/fancybox.css
// @resource           FancyboxV3JS https://unpkg.com/@fancyapps/[email protected]/dist/jquery.fancybox.min.js
// @resource           FancyboxV3Css https://unpkg.com/@fancyapps/[email protected]/dist/jquery.fancybox.min.css
// @resource           ViewerJs https://unpkg.com/[email protected]/dist/viewer.min.js
// @resource           ViewerJsCss https://unpkg.com/[email protected]/dist/viewer.min.css
// ==/UserScript==

(async (axios) => {
	"use strict";

	//await wait(() => !!document.body && document.readyState !== "loading");
	//await wait(() => !!document.body && document?.body?.childNodes?.length > 0);

	//限制在最上層頁框執行
	if (window.self !== window.top) {
		console.error("Full Picture Load 檢測到在非最上層頁框執行");
		return;
	}

	if ((ge("body.no-js:not(.has-preloader,.single-post,.archive)") && !ge("#layout-default")) || ge(".captcha-area") && !ge("#layout-default")) {
		debug("Cloudflare驗證中不執行腳本。");
		return;
	}

	if (document.title.startsWith("DDoS-Guard")) {
		debug("DDoS-Guard驗證中不執行腳本。");
		return;
	}

	//火狐Firefox使用open("about:blank", "_blank")打開空白頁,空白頁的location.href會變成父視窗的location.href,導致載入腳本,必須排除。
	if (["分頁畫廊:", "标签画廊:", "TabView:"].some(t => document.title.startsWith(t))) {
		return;
	}

	//await delay(600);

	const defaultOptions = {
		icon: 1, //是否顯示左下圖示,1:顯示、0:不顯示
		threading: 8, //最大下載線程數
		singleThreadInterval: 0, //1線程下載時的要求間隔秒數
		retry: 3, //下載錯誤重試次數
		interval: 3, //下載錯誤重試間隔秒數
		combineLimit: 10, //長圖拼接下載限制最大高度n*1000 ~ 65535
		zip: 1, //1:圖片下載後壓縮打包,0:批量下載圖片,無法全自動下載
		autoInsert: 1, //頁面容器自動聚圖,1:自動、0:手動
		autoDownload: 0, //!!!維持0不要改!!!建議透過UI選項設定來開啟,需要customData也有autoDownload
		autoDownloadCountdown: 5, //有NEXT時自動下載的倒數秒數
		comic: 0, //1,忽視漫畫站點開關選項,啟用漫畫規則
		zoom: 0, //1 ~ 10 腳本插入的圖片縮放比例,10 = 100%,9 = 90%,0 = auto
		column: 4, //圖片並排顯示的數量 2 ~ 6
		//viewMode: 0, //0:置中、1:並排
		fancybox: 1, //Fancybox圖片燈箱展示功能,1:開啟、0:關閉
		shadowGallery: 0, //自動進入影子畫廊,1:自動、0:手動
		mobileGallery: 0, //自動進入手機畫廊,1:自動、0:手動
		autoExport: 0, //自動匯出網址,1:自動、0:手動
		cdn: "-1"
	};
	const FullPictureLoadShowEye = localStorage.getItem("FullPictureLoadShowEye") ?? 1;
	const FullPictureLoadCustomDownloadVideo = localStorage.getItem("FullPictureLoadCustomDownloadVideo") ?? 1;
	let options = defaultOptions;

	const _unsafeWindow = unsafeWindow ?? window;
	let language = GM_getValue("language", null) || _unsafeWindow.navigator.language;
	if (language == "UI") {
		language = _unsafeWindow.navigator.language;
	}
	let siteUrl = _unsafeWindow.location.href.replace(_unsafeWindow.location.hash, "");
	let currentURL = document.URL;
	let lastValidPageURL = document.URL;
	let frameWindow = _unsafeWindow;
	let siteData = {};
	let _this = {};
	let tempData = {};
	let siteJson = {};
	let DL = {};
	let globalImgArray = [];
	let captureSrcArray = [];
	let captureTotal = 0;
	let isCaptureMode = false;
	let thumbnailSrcArray = [];
	let videoSrcArray = [];
	let fileUrlArray = [];
	let promiseBlobArray = [];
	let captureLinksArray = [];
	let setArray = new Set();
	let setVideoArray = new Set();
	let customTitle = null;
	let apiCustomTitle = null;
	let isEsc = false;
	let isDownloading = false;
	let isStopDownload = false;
	let isCountdowning = false;
	let isFetching = false;
	let isGetAll = false;
	let isAutoScrolling = false;
	let isValidPage = true;
	let isSimpleMode = false;
	let isAddKeyEvent = false;
	let isAddFullPictureLoadButton = false;
	let isAddFullPictureLoadFixedMenu = false;
	let isAddNewTabViewButton = false;
	let isAddAjaxHooker = false;
	let isOpenOptionsUI = false;
	let isOpenMenu = false;
	let isOpenGallery = false;
	let isOpenFilter = false;
	let isGoToNext = false;
	let isGoToPrev = false;
	let isChangeNum = false;
	let isRemove = false;
	let fetchErrorArray = [];
	let fastDownloadSwitch = false;
	let combineDownloadSwitch = false;
	let downloadNum = 0;
	let getImgFnProcessRecord = "";
	let doc = document;
	const fragment = new DocumentFragment();
	let autoPagerSwitch = true;
	let httpFetchError = false;
	let currentPageNum = 0;
	let nextLink = null;
	let prevLink = null;
	let nextElement = null;
	let tempNextLink = null;
	let tempEles = [];
	const PC_UA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36 Edg/142.0.0.0";
	const Mobile_UA = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Mobile Safari/537.36 EdgA/142.0.0.0";
	const MutationObserverConfig = {
		childList: true,
		subtree: true
	};
	const smoothOptions = {
		behavior: "smooth",
		block: "center",
		inline: "center"
	};
	const instantOptions = {
		behavior: "instant",
		block: "center",
		inline: "center"
	};
	//自定義站點規則開始
	const customData = [{
		name: "BEAUTYLEG 腿模",
		link: "http://www.beautyleg.com/photo/show.php?no=1",
		url: {
			h: "beautyleg.com",
			p: "/photo/show",
			s: "no="
		},
		box: [".table_all", 2, 1054],
		imgs: "a[href*='/album/']",
		thumbs: "a[href*='/album/'] img",
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".table_all"),
		next: () => `?no=${Number(fn.getUSP("no")) + 1}`,
		prev: () => `?no=${Number(fn.getUSP("no")) - 1}`,
		customTitle: () => {
			let [no, date] = fn.gat("tr span");
			no = no.padStart(3, "0");
			date = date.replace(/\d+$/, "").trim();
			return `BEAUTYLEG 腿模(免費下載) No.${no} ${date}`;
		},
		category: "photo"
	}, {
		name: "KAI-YOU(カイユウ)",
		url: {
			h: "kai-you.net",
			p: "/article/",
			e: ".m-article-eyecatch-content-link,.m-article-images-main"
		},
		imgs: () => fn.clp("/images/") ? fn.gae(".m-article-images-main-swiper-slide-img") : fn.getImgA(".m-article-images-main-swiper-slide-img", [fn.gu(".m-article-eyecatch-content-link")]),
		capture: () => _this.imgs(),
		videos: () => fn.gae("div.youtube[data-video]").map(e => e.dataset.video),
		customTitle: ".m-article-header-title,.m-article-image-title",
		category: "photo"
	}, {
		name: "cureco beta",
		url: {
			h: ["cureco.jp"],
			p: "/view/"
		},
		imgs: () => fn.getNP(".article_tweet:has(.triangle-border)", "#pager_box .next a", null, "#pager_box").then(() => fn.gae(".attach_image")),
		capture: () => _this.imgs(),
		customTitle: ".article_title",
		category: "photo"
	}, {
		name: "豆瓣相册",
		url: {
			h: ["www.douban.com", "douban.com"],
			p: "/album/",
			d: "pc"
		},
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr(".photolst a img");
			let pages = fn.ge(".paginator .next");
			if (pages) {
				let max = fn.gt(".paginator .next", 2);
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `?m_start=${i * 18}`);
				await fn.getEle(links, ".photolst a").then(eles => (thumbnailSrcArray = eles.map(a => fn.src("img", a))));
			}
			return thumbnailSrcArray.map(e => e.replace("/s/", "/l/"));
		},
		category: "photo"
	}, {
		name: "豆瓣相册M",
		url: {
			h: ["www.douban.com", "douban.com"],
			p: "/album/",
			d: "m"
		},
		init: () => fn.wait(() => {
			let button = fn.ge(".getmore-btn");
			if (!!button) {
				EClick(button);
			}
			return !button;
		}),
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("ul.grid a img");
			return thumbnailSrcArray.map(e => e.replace("/s/", "/l/"));
		},
		customTitle: ".photo-info>h1",
		category: "photo"
	}, {
		name: "百度 NewsPage",
		reg: [
			/^https?:\/\/baijiahao\.baidu\.com\/s\?id=\d+$/,
			/^https?:\/\/mbd\.baidu\.com\/newspage\/data\/landingsuper\?context=/
		],
		init: () => fn.waitEle(["div[data-testid=article] img", "#header div"]),
		imgs: "div[data-testid=article] img",
		customTitle: "#header div",
		category: "photo"
	}, {
		name: "交通部觀光署 桌布下載",
		url: {
			h: "www.taiwan.net.tw",
			p: "m1.aspx",
			s: "sNo=0012076"
		},
		imgs: ".media-download>a:last-child",
		category: "photo"
	}, {
		name: "免費圖庫相片",
		url: {
			h: "www.pexels.com"
		},
		SPA: true,
		init: () => fn.capture({
			s: "article[class^=MediaCard_card] img[srcset]:not(.get)",
			vs: "video[class^=VideoTag_video]:not(.get)",
			scb: src => {
				if (!src.includes("/free") && !src.includes("/lib/avatars/")) {
					src = src.replace(/\?.+$/, "");
					setArray.add(src);
				}
			}
		}),
		imgs: () => setArray,
		capture: () => _this.imgs(),
		infiniteCapture: 1,
		downloadVideo: true,
		category: "photo"
	}, {
		name: "wallhaven",
		url: {
			h: ["wallhaven.cc"],
			e: "figure[data-wallpaper-id]"
		},
		SPA: true,
		init: () => fn.capture({
			s: "figure[data-wallpaper-id]:not(.get)",
			ecb: figure => {
				figure.classList.add("get");
				const id = figure.dataset.wallpaperId;
				const isPng = !!fn.ge(".thumb-info .png", figure);
				const ex = isPng ? "png" : "jpg";
				const src = `https://w.wallhaven.cc/full/${id.substring(0, 2)}/wallhaven-${id}.${ex}`;
				setArray.add(src);
			}
		}),
		imgs: () => setArray,
		capture: () => _this.imgs(),
		infiniteCapture: 1,
		category: "photo"
	}, {
		name: "Behance",
		url: {
			h: "www.behance.net"
		},
		page: () => fn.clp("/gallery/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.waitEle([
			"div[class^='UniversalPopup-navigationLayer'],#primary-project-content",
			"h1[class^='Project-title']",
			".grid__item-image[srcset],picture source[srcset],.ImageElement-image-SRv"
		]) : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			videoSrcArray = fn.gae(".Preview__project--topMargin iframe[src*='.vimeo.']").map(e => e.src);
			return fn.getImgSrcset(".grid__item-image[srcset],#primary-project-content source[data-ut='project-module-source-original'],.ImageElement-image-SRv");
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.waitEle("h1[class^='Project-title']").then(e => fn.gt(e)) : null,
		category: "photo"
	}, {
		name: "kpopping",
		url: {
			h: "kpopping.com",
			p: "/kpics/"
		},
		box: [".justified-gallery", 2],
		imgs: ".justified-gallery a[data-fancybox]",
		thums: ".justified-gallery a[data-fancybox] img",
		button: [4],
		insertImg: [
			["box", 0, ".justified-gallery"], 2
		],
		customTitle: ".container h1",
		category: "photo"
	}, {
		name: "Irancartoon",
		url: {
			h: "www.irancartoon.com",
			p: "/gallery/"
		},
		imgs: "#galls a",
		thums: "#galls a img",
		customTitle: ".post_title",
		category: "photo"
	}, {
		name: "小黄书 xChina/8色人體攝影",
		url: {
			h: [
				/xchina/,
				/^(tw\.)?8se\.me$/
			],
			p: /^\/(photo|amateur)\/id-\w+\.html$/,
			e: ".photo-detail .item:has(>.icon>.fa-image)"
		},
		init: () => {
			setTimeout(() => {
				fn.rjk();
				let model = fn.gae(".model-avatar-container a,.model-container a.model-item");
				if (model.length) {
					const r = (a) => {
						if (["videos", "photos"].some(k => a.href.includes(k))) {
							a.href = fn.rt(a.href, [
								["model", "id"],
								[/videos|photos/, "model"]
							]);
						}
					};
					model.forEach(r);
				}
			}, 1000);
		},
		loop: () => {
			document.body.removeAttribute("class");
			document.body.removeAttribute("style");
		},
		imgs: async () => {
			const {
				videos,
				domain
			} = _unsafeWindow;
			if (videos && domain) {
				videoSrcArray = videos.map(e => domain + e.url);
			}
			const [, album_id] = /id-([^.]+)/.exec(fn.lp);
			let [numP] = fn.gt(".photo-detail .item:has(>.icon>.fa-image)").match(/\d+/);
			numP = Number(numP);
			const [thumb_src] = fn.getImgSrcArr(".photo-items div.img,.amateur-items div.img");
			const srcArrFn = (total, photoUrl = "https://img.xchina.io/photos/", mode = 1) => {
				let suffix = ".jpg";
				if (fn.lp.includes("/amateur/")) {
					suffix = ".webp";
				} else if (mode === 2) {
					suffix = "_600x0.webp";
				}
				return fn.arr(total, (v, i) => photoUrl + album_id + "/" + String(i + 1).padStart(4, "0") + suffix);
			};
			if (!!thumb_src) {
				const OOOI = thumb_src.endsWith("/0001_600x0.webp") || thumb_src.endsWith("/0001.webp");
				const [photoUrl] = /^https?:\/\/[^\/]+\/[^\/]+\//.exec(thumb_src);
				if (OOOI) {
					thumbnailSrcArray = srcArrFn(numP, photoUrl, 2);
					return srcArrFn(numP, photoUrl);
				} else {
					let max;
					try {
						let pageUrls = fn.gau(".pager a[href]");
						let lastUrl = pageUrls.at(-1);
						let [, lastNum] = lastUrl.match(/\/(\d+)\.html$/);
						max = Number(lastNum);
					} catch {
						max = 1;
					}
					if (max > 1) {
						await fn.getNP(".photo-items .item", ".pager a.current+a:not(.pager-next)", null, ".pager", 1500);
					}
					thumbnailSrcArray = fn.getImgSrcArr(".photo-items div.img");
					if (numP != thumbnailSrcArray.length) {
						setTimeout(() => {
							fn.hm();
							fn.showMsg(DL.xchina_picnum_error, 5000);
						}, 1500)
					}
					if (fn.lp.includes("amateur")) {
						return thumbnailSrcArray;
					}
					return thumbnailSrcArray.map(e => e.replace("_600x0", "").replace(".webp", ".jpg"));
				}
			} else {
				const srcArr = srcArrFn(numP);
				const [first] = srcArr;
				const check1 = await fn.checkImgStatus(first);
				if (check1.ok) {
					return srcArr;
				} else {
					const test_src = first.replace("/photos/", "/photos2/");
					const check2 = await fn.checkImgStatus(test_src);
					if (check2.ok) {
						return srcArr.map(src => src.replace("/photos/", "/photos2/"));
					}
					return [];
				}
			}
		},
		button: [4],
		insertImg: [".content-box:has([class*=items])", 3],
		insertImgAF: () => fn.hideEle(".btn-group:has(.nav-prev,.nav-next)"),
		customTitle: () => {
			try {
				let text = "";
				let texts = [
					".photo-detail .item:has(.fa-video-camera) a",
					".photo-detail .item:has(.fa-video-camera) .joiner+a",
					".photo-detail .item:has(.fa-calendar-days)",
					".photo-detail .item:has(.fa-file)",
					".photo-detail .model-avatar-container,.photo-detail .item:has(.fa-circle-user)",
					".photo-detail .item:has(.fa-address-card)"
				].map(s => fn.gt(s));

				// 大分類、小分類、日期、編號、模特名、寫真名
				let [sort_a, sort_b, days, serial, model, album_title] = texts;

				texts.forEach((t, i, a) => {
					if (a.length - 1 == i && !!model) {
						if (t.includes(model)) {
							// 寫真名含模特名則刪掉模特名
							text = fn.rt(text, model, "");
						}
					}
					if (!!t && t?.length > 0) {
						text += " " + t;
					}
					if (i == 0 && !!sort_a) {
						text += " -";
					}
				});
				if (location.pathname.includes("/amateur/")) {
					// 補上業餘自拍
					text = fn.gt(".fa-angles-right+a") + " -" + text;
				}
				if (text.includes("秀人")) {
					text = fn.rt(text, "Vol. ", "NO.");
				}
				text = fn.rt(text, [
					[/(\d+)-(\d+)-(\d+)/, "$1.$2.$3"],
					[" 秀人网 ", " [Xiuren秀人网] "],
					[" 秀人網 ", " [Xiuren秀人網] "]
				]);
				text = fn.dt({
					t: text,
					d: [
						"各国其他套图 -",
						"各國其他套圖 -",
						"其他地区套图",
						"其他地區套圖",
						"其他套图 -",
						"其他套圖 -"
					]
				});
				if (text.includes("其他中国工作室") || text.includes("其他中國工作室")) {
					let t = fn.gt(".photo-detail .item:has(.fa-filter)");
					if (!!t && t?.length > 0) {
						// 換成工作室名稱
						text = fn.rt(text, /其他中国工作室|其他中國工作室/, t);
					}
				}
				if (text.includes("Graphis")) {
					let t = fn.gt(".photo-detail .item:has(.fa-filter)");
					if (!!t && t?.length > 0) {
						// 加上Graphis的子機構
						text = fn.rt(text, "Graphis", "Graphis " + t);
					}
				}
				return fn.dt({
					t: text
				});
			} catch (e) {
				return fn.dt({
					t: document.title
				});
			}
		},
		hide: ".block-overlay,.push-top-container,div[class*='backdrop-show'],.modal-overlay,.content-box:has([class^='static-container']),div[clickmode],.item:has([clickmode],[class*=exoclick],.a-media,iframe)",
		downloadVideo: true,
		preload: 0,
		category: "nsfw2"
	}, {
		name: "小黄书 xChina/8色人體攝影 AD",
		url: {
			h: [
				/xchina\./,
				/^(tw\.)?8se\.me$/
			]
		},
		init: () => fn.addMutationObserver(() => fn.remove("[class*='exoclick']")),
		loop: () => {
			document.body.removeAttribute("class");
			document.body.removeAttribute("style");
		},
		hide: ".block-overlay,.push-top-container,div[class*='backdrop-show'],.modal-overlay,.content-box:has([class^='static-container']),div[clickmode],.item:has([clickmode],[class*=exoclick],.a-media,iframe)",
		category: "ad"
	}, {
		name: "绅士会所/雪月映画",
		host: ["www.hentaiclub.net", "taoo.xyz"],
		url: {
			t: ["绅士会所", "雪月映画"],
			p: "/r"
		},
		imgs: "div[data-fancybox]",
		button: [4],
		insertImg: [
			["#masonry", 2, "#masonry"], 2
		],
		customTitle: ".post-info-text",
		hide: ".banner-top",
		category: "nsfw2"
	}, {
		name: "NLegs/HoneyLeg/Lady Lap/Nuyet/LegBabe", //需搭配專用腳本 https://greasyfork.org/scripts/463123
		host: ["www.nlegs.com", "www.honeyleg.com", "www.ladylap.com", "www.nuyet.com", "www.legbabe.com"],
		reg: [
			/^https?:\/\/www\.nlegs\.com\/girls\/\d+\/\d+\/\d+\/\d+\.html$/,
			/^https?:\/\/www\.honeyleg\.com\/article\/\d+\/\d+\/\d+\/\d+\.html$/,
			/^https?:\/\/www\.ladylap\.com\/show\//,
			/^https?:\/\/www\.nuyet\.com\/gallery\//,
			/^https?:\/\/www\.legbabe\.com\/hot\/[^\.]+\.html$/
		],
		imgs: ".col-md-12.col-xs-12 img[src^=blob],.col-md-12.col-lg-12 img[src^=blob]",
		repeat: 1,
		button: [4],
		insertImg: ["//div[img[starts-with(@src,'blob')]]", 0],
		customTitle: "[class^=container] p",
		category: "nsfw2"
	}, {
		name: "雅拉伊", //免VIP僅支援PC版和圖片命名是簡單數字遞增的。
		url: {
			h: ["www.yalayi.com"],
			p: "/gallery/"
		},
		imgs: async () => {
			await fn.waitEle(".bigimg>img");
			let [max] = fn.gt(".tishiwenzi-box").match(/\d+/);
			let img = fn.ge(".bigimg>img");
			let dir = fn.dir(img.dataset.original);
			let testArr = [dir + "1.jpg", dir + "01.jpg", dir + "001.jpg", dir + "0001.jpg"];
			let ok = false;
			let pad = 1;
			for (let [i, test] of testArr.entries()) {
				let obj = await fn.checkImgStatus(test);
				console.log(`確認圖片[${i}]`, obj);
				if (obj.ok) {
					ok = true;
					pad = i + 1;
					break;
				}
			}
			return ok ? [img.src, ...fn.arr(max, (v, i) => dir + String(i + 1).padStart(pad, "0") + ".jpg")] : [];
		},
		button: [4, 4],
		insertImg: [".bigimg", 2],
		customTitle: () => fn.title(" - ", 3),
		category: "nsfw1"
	}, {
		name: "24FA",
		host: ["www.24fa.com"],
		link: "https://www.24fa.com/c49.aspx",
		url: {
			t: "24FA",
			p: ".aspx",
			e: ["#content img", ".pager"]
		},
		init: "document.onkeydown=null",
		imgs: () => fn.getImgA("#content img", ".pager a:not([title])"),
		button: [4],
		insertImg: ["#content", 2],
		autoDownload: [0],
		next: ".prevNews>a",
		prev: ".nextNews>a",
		customTitle: "h1",
		hide: "body>ins",
		category: "nsfw2"
	}, {
		name: "Depvailon格式",
		url: {
			h: ["www.depvailon.com", "nungvl.net", "www.kaizty.com", "lootiu.com", "redseats.org", /dongojyousan\.com$/, "thismore.fun"],
			p: ["/gallery", "/articles/", "/photos/", "/view/", ".html"]
		},
		clearEvent: true,
		init: async () => {
			await fn.waitVar("jQuery");
			fn.run("jQuery(document).off() && jQuery('body').off()");
			fn.remove(".mobiletop,.ooo-icon-container");
		},
		box: [".contentme,.contentme2,.video-description", 2],
		imgs: async (s = ".contentme img,.contentme2 img,.video-description img") => {
			let srcs = fn.getImgSrcArr(s);
			let pages = document.title.includes("| Page");
			if (pages) {
				let max = document.title.match(/\d+/g).at(-1);
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}?page=${i + 1}`);
				//srcs = await fn.getImgA(s, links);
				return fn.getImgA(s, links);
			}
			//return fn.removeImageCDN(srcs);
			return srcs;
		},
		button: [4],
		insertImg: [
			["box", 0, ".video-description,.contentme,.contentme2"], 2
		],
		customTitle: () => fn.dt({
			d: [
				/^[a-z-\s\.]+:/i,
				/\s\|\sPage[\s\/\d]+/,
				"NứngVL.net:",
				/Nude Chinese Model Uncensored Gallery[\s\d–]+/,
				" – Chinese Beauties",
				" – DVL",
				"| E-CUP"
			]
		}),
		category: "nsfw2"
	}, {
		name: "Hit-x-Hot/Chinese in beauty",
		url: {
			h: ["www.hitxhot.org", "cn.looives.com"],
			p: ["/gallerys/", "/view/"]
		},
		clearEvent: true,
		imgs: () => {
			let links = [];
			if (fn.lh == "www.hitxhot.org") {
				links = [fn.lp, ...fn.gau("div[id^=post] a")];
			} else {
				let max = Number(document.title.match(/【(\d+)P】/)?.at(1));
				max > 1 ? links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}?page=${i + 1}`) : links = [];
			}
			if (!links.length) return [];
			return fn.getImgA(".VKSUBTSWA img", links) /*.then(srcs => fn.removeImageCDN(srcs))*/ ;
		},
		button: [4],
		insertImg: [".VKSUBTSWA", 2],
		insertImgAF: () => fn.remove(".pagination,h3+.HCRIN"),
		customTitle: () => fn.dt({
			t: fn.title(/^[a-z-\s\.I]+:/i).split("|")[0].trim(),
			d: " - 1.jpg"
		}),
		category: "nsfw2"
	}, {
		name: "Telegram Web",
		url: {
			h: ["telegra.ph"]
		},
		init: () => fn.rd(),
		imgs: () => fn.gae(".tl_article img", doc),
		capture: () => _this.imgs(),
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Rentry.co",
		url: {
			h: ["rentry.co"]
		},
		imgs: "img",
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "新闻吧/新闻屋/新娱乐在线/新娱乐网/福建热线/山东热线/广西热线/武汉热线/天津热线/云南热线/甘肃热线",
		link: "https://www.xinwenba.net/web/meinv/",
		url: {
			h: [
				/\.xinwenba\.net$/,
				/\.xwbar\.com$/,
				/\.dv67\.com$/,
				/\.xinent\.net$/,
				/\.fjrx\.org$/,
				/\.sdrx\.org$/,
				/\.gxrx\.org$/,
				/\.whrx\.org$/,
				/\.tjrx\.org$/,
				/\.ynrx\.org$/,
				/\.gsrx\.org$/,
				/\.xwwu\.net$/
			],
			p: /^\/web\/info\/\d+-\d+\.html$/,
			e: ".main img"
		},
		box: [".main", 1],
		imgs: () => {
			let [max] = fn.gt(".page-link").match(/\d+/);
			return fn.getImg(".main img", max, "5");
		},
		button: [4],
		insertImg: [
			["box", 0, ".view_img .main"], 2
		],
		insertImgAF: (p, b) => {
			let text = fn.ge(".main .txt,.info_imgs>.txt");
			if (text) {
				insertBefore(b, text);
			}
			fn.remove(".info_imgs>.main,.info_imgs>.page-item");
		},
		autoDownload: [0],
		next: "//li[text()='上篇:']/a",
		prev: "//li[text()='下篇:']/a",
		customTitle: ".title>h1",
		hide: "div.web",
		category: "nsfw1"
	}, {
		name: "四海资讯/娱乐吧/娱乐屋/娱乐宝/新闻宝",
		link: "https://www.shzx.org/b/12-0.html",
		url: {
			h: [
				/\.shzx\.org$/,
				/\.yuleba\.org$/,
				/\.entba\.net$/,
				/\.entwu\.com$/,
				/\.xwbzx\.com$/,
				/\.entbao\.com$/
			],
			p: [/\/web\/info\/[\d-]+\.html$/, /\/a\/[\d-]+\.html$/],
			e: ".main img"
		},
		imgs: () => {
			let [max] = fn.gt(".paging>a").match(/\d+/);
			let url = fn.lp.replace(/-\d+\.html$/, "");
			let links = fn.arr(max, (v, i) => url + `-${i}.html`);
			return fn.getImgA(".main img", links);
		},
		button: [4],
		insertImg: [".main", 2],
		insertImgAF: (p, b) => {
			let text = fn.ge(".info_imgs>.txt");
			if (text) {
				insertBefore(b, text);
			}
			fn.remove(".paging");
		},
		autoDownload: [0],
		next: "//li[text()='上一篇:']/a",
		prev: "//li[text()='下一篇:']/a",
		customTitle: ".title>h1",
		hide: "div.web",
		category: "nsfw1"
	}, {
		name: "JKF",
		host: ["www.jkforum.net"],
		reg: /^https?:\/\/www\.jkforum\.net\/(p\/)?thread/,
		init: () => fn.waitEle("img[id^=aimg]"),
		imgs: () => isM ? fn.gae("img[id^=aimg]:not([style])") : fn.gae("img[id^=aimg][zoomfile]"),
		capture: () => _this.imgs(),
		customTitle: ".title-hd h1,.post-title",
		category: "nsfw2"
	}, {
		name: "草榴社區",
		host: ["www.t66y.com", "cl.6962x.xyz"],
		url: {
			t: "草榴社區",
			p: /^\/(htm_data|htm_mob)\/\d+\/\d+\/\d+\.html$/,
			e: "img[ess-data]"
		},
		init: () => fn.rd(),
		box: [".t:has(.h),.f18", 2],
		button: [4],
		insertImg: ["box", 2],
		imgs: () => fn.gae("img[ess-data]", doc),
		capture: () => _this.imgs(),
		customTitle: "h4.f16,div.f18",
		hide: "div:has(>.ftad-ct)",
		category: "nsfw2"
	}, {
		name: "留园酷",
		host: ["www.cool18.com", "wap.cool18.com"],
		reg: [
			/^https?:\/\/www\.cool18\.com\/bbs\d*\/index\.php\?app=forum&act=threadview&tid=\d+/,
			/^https?:\/\/wap\.cool18\.com\/index\.php\?app=index&act=view&cid=\d+/
		],
		include: "img[mydatasrc],#shownewsc img,.show_content img,img[data-fancybox]",
		box: [".title-section,.article-head", 2],
		button: [4],
		insertImg: ["box", 2],
		imgs: () => fn.gae(_this.include),
		capture: () => _this.imgs(),
		customTitle: ".main-title,.show_content b,h1.article-tit",
		gallery: 1,
		hide: ".img_ad_list",
		category: "nsfw2"
	}, {
		name: "我为人人",
		host: ["2048.info", "2048.cc"],
		url: {
			t: "人人",
			p: "/read.php",
			s: "tid=",
			e: "#read_tpc img"
		},
		imgs: () => fn.gae("#read_tpc img"),
		capture: () => _this.imgs(),
		box: ["div:not([id]):has(>form[name=delatc]),form[name=delatc]", 1],
		button: [4],
		insertImg: ["box", 2],
		next: ".pages .fn",
		prev: ".pages a:not(.fn)",
		customTitle: "#subject_tpc",
		hide: ".recs-wrapper,.nav-container",
		category: "nsfw2"
	}, {
		name: "4096社区/色花堂",
		host: ["www.4096bbs.com", "4096bbs.com", "sehuatang.org"],
		url: (e = "img[zoomfile],img[id^='aimg'],.message img") => fn.checkUrl({
			t: ["4096", "98堂", "色花堂"],
			p: "/thread",
			e
		}) || fn.checkUrl({
			t: ["4096", "98堂", "色花堂"],
			s: "viewthread",
			e
		}),
		imgs: () => fn.gae("img[zoomfile],img[id^='aimg'],.message img"),
		capture: () => _this.imgs(),
		box: ["#postlist,.viewthread,div[id^=post],.n5_bbsnrbt+.plc", 1],
		button: [4],
		insertImg: ["box", 2],
		customTitle: "#thread_subject,.view_tit,.n5_bbsnrbt",
		category: "nsfw2"
	}, {
		name: "梦想岛",
		host: ["www.mmxxdd.com", "www.mmdd.cc"],
		link: "https://www.mmxxdd.com/website.html",
		url: () => {
			let ca = fn.checkUrl({
				e: [".logo img[alt=梦想岛],.logo img[alt=夢想島]", ".gallerypic img"],
				p: "/gallery/"
			});
			let cb = fn.checkUrl({
				t: ["梦想岛", "夢想島"],
				p: "/gallery/"
			});
			let cc = false;
			if (fn.clp(/^\/gallery\/\d+\.html$/)) {
				cc = !!document?.documentElement?.innerHTML?.includes("梦想岛");
			}
			return ca || cb || cc;
		},
		init: () => fn.waitEle(".gallerypic img"),
		test: async (max) => {
			let [src] = fn.getImgSrcArr(".gallerypic img").sort();
			let dir = fn.dir(src);
			let f = src.split("/").at(-1);
			let ex = f.split(".").at(-1);
			ex = "." + ex;
			let [num] = f.match(/\d+/);
			num = Number(num);
			let srcs = [];
			let successNum = 0;
			let testNum = 0;
			let testSrc;
			let loop = true;
			while (loop) {
				fn.showMsg(`test:${num} | success:${successNum}/${max}`, 0);
				testSrc = dir + num + ex;
				let status = await fn.xhrHEAD(testSrc).then(res => res.status);
				if (status == 200) {
					srcs.push(testSrc);
					successNum += 1;
					if (testNum > 500 || successNum >= max) {
						loop = false;
					}
				}
				testNum += 1;
				num += 1;
			}
			return srcs;
		},
		imgs: async () => {
			let src = fn.src(".gallerypic img");
			if (!src) return [];
			let dir = fn.dir(src);
			let f = src.split("/").at(-1);
			let [num] = f.match(/\d+/);
			let ex = ".jpg";
			let [max] = fn.gt(".gallery_img label").match(/\d+/);
			if (num?.length == 1 && num == 0) {
				return fn.arr(max, (v, i) => dir + i + ex);
			} else if (num?.length == 3 && Number(num) == 1) {
				return fn.arr(max, (v, i) => dir + String(i + 1).padStart(3, "0") + ex);
			} else if (isNumber(Number(num))) {
				let tfs = fn.getImgSrcArr(".gallerypic img").map(e => e.split("/").at(-1));
				let mode = prompt("thums:" + String(tfs) + "\nMode:\n1. [0.jpg]\n2. [1.jpg]\n3. [001.jpg]\n4. [test()]", 1);
				if (mode == 1) {
					return fn.arr(max, (v, i) => dir + i + ex);
				} else if (mode == 2) {
					return fn.arr(max, (v, i) => dir + (i + 1) + ex);
				} else if (mode == 3) {
					return fn.arr(max, (v, i) => dir + String(i + 1).padStart(3, "0") + ex);
				} else if (mode == 4) {
					return _this.test(max);
				} else {
					return fn.gae(".gallerypic img");
				}
			}
			return fn.gae(".gallerypic img");
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.title(" - 梦想岛"),
		category: "nsfw1"
	}, {
		name: "魅影画廊",
		host: ["www.wc1.es", "wc1.es", "www.jb9.es", "jb9.es"],
		url: {
			t: "魅影画廊"
		},
		box: [".gallery", 2],
		imgs: () => {
			videoSrcArray = fn.gae(".ckplayer-video[data-key]").map(e => atob(e.dataset.key));
			return fn.gau(".gallery .gallery-item a").map(u => u.replace("-scaled", ""));
		},
		thums: ".gallery .gallery-item img",
		button: [4],
		insertImg: [
			["box", 0, ".gallery"], 2
		],
		customTitle: () => {
			let text = fn.gt(".article-title");
			let m = text.match(/(\d+)/);
			if (m) {
				text = fn.dt({
					t: text
				});
				let [num] = m[0].match(/\d+/);
				return text + " No." + num;
			}
			return text;
		},
		hide: ".modown-ad",
		downloadVideo: true,
		category: "nsfw1"
	}, {
		name: "MOMO图库",
		host: ["mo8.org"],
		url: {
			t: "MOMO图库"
		},
		srcset: ".entry-content img[srcset],.entry-content .wp-block-image img",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-previous a",
		prev: ".nav-next a",
		customTitle: ".entry-title",
		hide: "a.show,a.show~*:not([id^=Full],[class^=fancybox],.viewer-container)",
		category: "nsfw1"
	}, {
		name: "写真门",
		host: ["xzm2048.com"],
		url: {
			t: "写真门",
			e: [".logo a[title$=写真门]", ".article-content img[src*='/cover.jpg'],.article-content img[src*='/0001.jpg']"]
		},
		imgs: () => {
			let g_num = prompt("请输入图片总数", 100);
			let src = fn.src(".article-content img");
			let dir = fn.dir(src);
			let srcs = src.includes("/cover.jpg") ? [src] : [];
			for (let i = 1, n = Number(g_num); i <= n; i++) {
				src = dir + String(i).padStart(4, "0") + ".jpg";
				srcs.push(src);
			}
			return srcs;
		},
		repeat: 1,
		customTitle: "h1.article-title",
		category: "nsfw1"
	}, {
		name: "秀人集",
		host: ["25.xy09.my"],
		url: {
			e: "//div[@class='item_info']//a[text()='秀人集']",
			p: /\/\w+\/\d+\.html$/
		},
		init: () => {
			let pag = fn.gae(".page");
			if (pag.length > 0) pag[0].remove();
		},
		imgs: () => fn.getImg(".content>p img[alt]", fn.gt(".page a:last-child", 2), 3, null, 100),
		button: [4],
		insertImg: ["//div[p[img[@alt]]]", 2],
		autoDownload: [0],
		next: "//span[contains(text(),'下一篇')]/a[contains(@href,'html')]",
		prev: "//span[contains(text(),'上一篇')]/a[contains(@href,'html')]",
		customTitle: ".item_title>h1",
		hide: ".content br",
		category: "nsfw1"
	}, {
		name: "秀人美女網",
		host: ["www.xiu01.top"],
		url: {
			e: "//div[@class='single-cat']/a[text()='秀人美女网']",
			p: /\/\w+\/\d+\/\d+\.html$/
		},
		imgs: () => fn.getImg(".content p img[alt]", fn.gt(".page a:last-child", 2), 3, null, 100),
		button: [4],
		insertImg: ["//div[p[img[@alt]]]", 2],
		autoDownload: [0],
		next: "//span[contains(text(),'下一篇')]/a[contains(@href,'html')]",
		prev: "//span[contains(text(),'上一篇')]/a[contains(@href,'html')]",
		customTitle: ".item_title>h1",
		hide: ".item_info>a,p[align='center']:has(>img),.item_title>div[id],.item_title>a,.content br,.bottom_fixed,.update_area_lists>div[id]",
		category: "nsfw1"
	}, {
		name: "极品性感美女",
		host: ["www.xinggan5.top", "尤物网.Com"],
		url: {
			e: "//div[@class='toptip']/a[text()='极品性感美女']",
			p: /\/\w+\/\w+\.html$/
		},
		init: () => {
			let pag = fn.gae(".pagination");
			if (pag.length > 0) pag[0].remove();
			let p = fn.gae("//article/p[not(img)]");
			if (p.length > 0) {
				let te = fn.ge(".article-content");
				for (let e of p) insertBefore(te, e);
			}
		},
		imgs: () => fn.getImg(".article-content img[alt]", fn.gt("a.current~*:last-child", 2), 3, null, 100),
		button: [4],
		insertImg: [
			["//div[@class='pagination'][last()]", 1, "//p[img[@alt]]"], 2
		],
		autoDownload: [0],
		next: ".article-nav-next>a[href$=html]",
		prev: ".article-nav-prev>a[href$=html]",
		customTitle: ".article-title",
		hide: ".article-header>div[id],.article-header>a,.article-content br,img[src*='zz1.gif'],.bottom_fixed,.article-content~a,#bottom-banner,.content>div[id]",
		category: "nsfw1"
	}, {
		name: "性感美女",
		host: ["www.5201025.xyz"],
		url: {
			e: "//h1[@class='logo']/a[@title='性感美女尤物']",
			p: /\/\w+\/\w+\.html$/
		},
		init: () => {
			let pag = fn.gae(".pagination");
			if (pag.length > 0) pag[0].remove();
			let p = fn.gae("//article/p[not(img)]");
			if (p.length > 0) {
				let te = fn.ge(".article-content");
				for (let e of p) insertBefore(te, e);
			}
		},
		imgs: () => fn.getImg(".article-content img[alt]", fn.gt("a.current~*:last-child", 2), 6),
		button: [4],
		insertImg: [
			["//div[@class='pagination'][last()]", 1, "//p[img[@alt]]"], 2
		],
		autoDownload: [0],
		next: ".article-nav-next>a[href$=html]",
		prev: ".article-nav-prev>a[href$=html]",
		customTitle: ".article-title",
		hide: "center.x-abc",
		category: "nsfw1"
	}, {
		name: "爱美女网",
		host: ["a1.imn1.vip"],
		url: {
			e: "//section[@class='container']//a[text()='爱美女网']",
			p: /\/\w+\/\w+\.html$/
		},
		imgs: () => fn.getImg(".imgwebp p img[alt]", fn.gt(".page a:last-child", 2), 3, null, 100),
		button: [4],
		insertImg: ["//div[p[img[@alt]]]", 2],
		autoDownload: [0],
		next: "//span/b[contains(text(),'下一篇')]/a[contains(@href,'html')]",
		prev: "//span/b[contains(text(),'上一篇')]/a[contains(@href,'html')]",
		customTitle: ".focusbox h1+div",
		hide: ".imgwebp br,img[src*='zz2.gif'],p:has(>a[title][alt]>img)",
		category: "nsfw1"
	}, {
		name: "爱看美女网",
		host: ["www.ik009.top"],
		url: {
			e: ["//i[@class='iconfont icon-shouye']/following-sibling::a[text()='爱看美女网']", ".info-pagebar>a"],
			p: /^\/\w+\/\d+\.html$/
		},
		init: () => {
			let pag = fn.gae(".pagebar");
			if (pag.length > 0) pag[0].remove();
		},
		imgs: () => fn.getImg(".info-imtg-box img[alt]", fn.gt(".pagebar>*:last-child", 2), 3, null, 100),
		button: [4],
		insertImg: ["//p[img[@alt]]", 2],
		autoDownload: [0],
		next: ".info-next li:last-child a",
		prev: ".info-next li:first-child a",
		customTitle: "h1",
		category: "nsfw1"
	}, {
		name: "美人图",
		url: {
			h: "meirentu",
			p: /\/pic\/\d+\.html$/
		},
		imgs: () => fn.getImg(".content_left img[alt]", fn.gt(".page a:last-child", 2), 5),
		button: [4],
		insertImg: [".content_left", 2],
		autoDownload: [0],
		next: "//span[contains(text(),'下一篇')]/a[contains(@href,'html')]",
		prev: "//span[contains(text(),'上一篇')]/a[contains(@href,'html')]",
		customTitle: ".item_title>h1",
		hide: "img[alt]~br",
		category: "nsfw1"
	}, {
		name: "卡卡美女网",
		host: ["www.kaka234.cc"],
		url: {
			h: "kaka234",
			p: /^\/HTM\/\w+\/(\w+\/)?\d+\/\d+\/\d+\.html$/
		},
		init: () => {
			let ele = fn.ge(".PsBox");
			if (ele) {
				let te = ele.parentNode;
				insertBefore(te, ele);
			}
		},
		imgs: () => {
			let max = Number(fn.gt(".dede_pages li>a,.article_page li>a")?.match(/\d+/)) || 1;
			return fn.getImg(".content img,.ArticleImageBox img", max, 9);
		},
		button: [4],
		insertImg: ["//div[@class='content'] | //div[div[@class='ArticleImageBox']]", 2],
		autoDownload: [0],
		next: () => fn.gu("//li[contains(text(),'上一篇')]/a"),
		prev: () => fn.gu("//li[contains(text(),'下一篇')]/a"),
		customTitle: ".Title>h1,.PsBox",
		hide: ".m_adv",
		category: "nsfw1"
	}, {
		name: "高清图片吧",
		host: ["www.pic881.cc"],
		reg: /^https?:\/\/www\.pic\d+\.cc\/\w+\/\d+\/\d+\.html$/,
		imgs: () => {
			let max = fn.gt(".page>*:last-child");
			return fn.getImg(".content img,.ArticleImageBox img", max, 9);
		},
		button: [4],
		insertImg: [".content", 2],
		customTitle: "//div[@class='Title111']/h3[not(a)]",
		hide: ".center:has(>.dibu1),.center:has(>.dibu2)",
		category: "nsfw1"
	}, {
		name: "高清图片吧M/美女写真网M/美女图片网M/聚图美女网M",
		host: ["m.pic881.cc", "m.ku138.cc", "m.tu99663.cc", "m.jutu1232.cc"],
		reg: [
			/^https?:\/\/m\.pic\d+\.cc\/\w+\/\d+\/\d+\.html$/,
			/^https?:\/\/m\.ku\d+\.cc\/\w+\/\d+\/\d+\.html$/,
			/^https?:\/\/m\.tu\d+\.cc\/\w+\/\d+\/\d+\.html$/,
			/^https?:\/\/m\.jutu\d+\.cc\/\w+\/\w+\/\d+\.html$/
		],
		box: [".PsBox", 2],
		imgs: ".ArticleImageBox>img",
		button: [4],
		insertImg: [
			["box", 0, ".ArticleImageBox,.m_adv,.m_kanp"], 2
		],
		customTitle: ".PsBox",
		hide: ".m_adv,.m_kanp",
		category: "nsfw1"
	}, {
		name: "美女图片网",
		host: ["www.tu99663.cc"],
		url: {
			t: "tu963.com",
			p: "/y/"
		},
		imgs: () => {
			let max = Number(fn.gt(".articleV4Page a")?.match(/\d+/)) || 1;
			return fn.getImg(".content img", max, 9);
		},
		button: [4],
		insertImg: [".content", 2],
		customTitle: ".articleV4Tit",
		hide: ".dibu1,.dibu2",
		category: "nsfw1"
	}, {
		name: "美女目录网 列表模式",
		url: {
			h: ["www.girldir.com"],
			p: "_list/"
		},
		imgs: () => fn.getNP(".list-page-box>.item", ".pagination a.active+a", null, ".pagination", 2000).then(() => {
			thumbnailSrcArray = fn.getImgSrcArr(".list-page-box img");
			return thumbnailSrcArray.map(e => e.replace(".medium.", ".big."));
		}),
		button: [4],
		insertImg: [".list-page-box", 2],
		customTitle: () => fn.dt({
			d: " - 美女目录网"
		}),
		category: "nsfw1"
	}, {
		name: "ROSI写真",
		host: ["www.52rosi.com", "v2.52rosi.com"],
		url: {
			h: "52rosi.com",
			p: "/rosi-"
		},
		imgs: ".phzoom",
		thums: ".phzoom img",
		customTitle: "#post-title",
		category: "nsfw1"
	}, {
		name: "ROSI写真",
		host: ["www.rosipic.com", "rosipic.com"],
		reg: /^https?:\/\/(www\.)?rosipic\.com\/rosi\/\d+\.html$/i,
		imgs: () => fn.gau("a.spotlight").map(u => u.replace("https://wsrv.nl/?url=", "").replace(/&blur=\d+/, "")),
		button: [4],
		insertImg: [
			["#waterfall-container", 2], 2
		],
		category: "nsfw1"
	}, {
		name: "ROSI美女写真",
		url: {
			h: "www.2meinv.cc",
			p: /^\/\w+\/\w+\.html$/,
			ee: "//span/a[text()='ROSI视频']"
		},
		init: () => {
			let pag = fn.gae(".pagination2");
			if (pag.length > 0) pag[0].remove();
			fn.remove(".content>b,.content>br,.asst");
		},
		imgs: () => {
			let max = Number(fn.gt("//a[contains(text(),'共')]")?.match(/\d+/)) || 1;
			return fn.getImg(".article-content img", max, 9);
		},
		button: [4],
		insertImg: [".article-content", 2],
		autoDownload: [0],
		next: ".article-nav-prev>a",
		prev: ".article-nav-next>.a",
		customTitle: ".article-title",
		category: "nsfw1"
	}, {
		name: "ROSI小莉最新写真",
		host: ["www.rosimm.top"],
		url: {
			t: "ROSI小莉写真官网",
			p: /^\/html\/\d+$/
		},
		imgs: () => fn.getImgA("article img", ".page-links a"),
		button: [4],
		insertImg: ["article.post", 2],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "闺秀网",
		url: {
			h: ["www.guixiu.org", "guixiu.org"],
			p: "/post/"
		},
		imgs: () => fn.getImgA("#lightgallery img", "#ipage a[href*=ipage]"),
		button: [4],
		insertImg: ["#lightgallery", 2],
		customTitle: ".focusbox-title",
		category: "nsfw1"
	}, {
		name: "甜猫猫",
		host: ["tianmaomao.cc", "a.tmm1.cfd"],
		url: {
			t: "甜猫猫",
			p: "/s"
		},
		imgs: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: "main h2",
		category: "nsfw2"
	}, {
		name: "悄悄的看2019",
		url: {
			h: ["qqdk2019.net"]
		},
		box: [".blog-details-text>p:has(>img)", 1],
		imgs: ".blog-details-text>p>img",
		button: [4],
		insertImg: [
			["box", 0, ".blog-details-text>p:has(>img)"], 2
		],
		customTitle: "h2.blog-details-headline",
		category: "nsfw1"
	}, {
		name: "爱图门",
		url: {
			h: ["aitu.men"],
			p: ".html",
			e: ".context img"
		},
		imgs: () => fn.getNP(".context img", ".pagelist span+a", null, ".pagelist", 0, null).then(() => fn.gae(".context img")),
		button: [4],
		insertImg: [".context", 1],
		autoDownload: [0],
		next: ".post-previous a",
		prev: ".post-next a",
		customTitle: "#content h1",
		category: "nsfw1"
	}, {
		name: "K55",
		link: "https://k55.net/arttype/2.html",
		url: {
			h: ["k55.net"],
			p: "/artdetail-",
			e: ".photo_box",
		},
		imgs: () => fn.gae(".photo_box img").map(e => e.src).sort((a, b) => a.match(/(\d+)\.\w+$/)[1] - b.match(/(\d+)\.\w+$/)[1]),
		button: [4],
		insertImg: [".photo_box", 2],
		autoDownload: [0],
		next: ".item_prev_next>.item_right>a",
		prev: ".item_prev_next>.item_left>a",
		customTitle: () => fn.dt({
			s: ".title-box>.h3-md.mb-1",
			d: /\[\d+P\].+$/i
		}),
		category: "nsfw1"
	}, {
		name: "Hotgirl.biz",
		url: {
			h: ["hotgirl.biz"]
		},
		imgs: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "XLUST.ORG",
		url: {
			h: ["xlust.org"]
		},
		imgs: ".rl-gallery-item a",
		button: [4],
		insertImg: [
			[".entry-content", 0, ".rl-gallery-container"], 2
		],
		customTitle: ".entry-title",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw1"
	}, {
		name: "秀人图",
		host: ["www.xiurentu.com", "www.xiurenst.com", "aituxiuren.com", "www.aixiurentus.com", "www.xiurentuo.com"],
		url: {
			e: ".site .logo-wrapper img.logo.tap-logo[alt^='秀人']",
			p: /^\/\d+\.html/,
			ee: "//button[contains(text(),'登录购买')]"
		},
		imgs: () => fn.getImgA("a[data-fancybox],.entry-content img", ".fenye a"),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: ".entry-title",
		observerClick: [".swal2-close", ".ht-n-close-toggle"],
		css: ".navbar .nav-list>.menu-item>a{line-height:20px;margin:0 6px}",
		category: "nsfw1"
	}, {
		name: "秀人网图集",
		url: {
			e: ".site .logo-wrapper img.logo.tap-logo[alt^='秀人']",
		},
		observerClick: [".swal2-close", ".ht-n-close-toggle"],
		css: ".navbar .nav-list>.menu-item>a{line-height:20px;margin:0 6px}",
		category: "ad"
	}, {
		name: "牛C網",
		url: {
			//h: ["rulel.com"],
			t: "NIUC.NET",
			p: /^\/\d+\.html$/,
			e: "//i[@class='czs-folder-l']/following-sibling::a[1][text()='美女写真' or text()='美女寫真' or text()='Beauty photo' or text()='뷰티포토' or text()='美容写真' or text()='Cosplay' or text()='JAV.PHOTO' or text()='JAV 的。相片']"
		},
		imgs: () => fn.gae(".content-warp img").filter(e => !e.closest("a[href*=android],a[href*=mypikpak],a[href$='app.html'],a[href*='/t.me/']")).map(e => e.src).filter(src => !src.includes("/svg")),
		button: [4],
		insertImgBF: () => fn.sm4().then(() => fn.waitEle("a.core-next-img").then(() => fn.hm())),
		insertImg: [".content-warp", 2],
		autoDownload: [0],
		next: "//a[div[text()='<<上一篇']]",
		prev: "//a[div[text()='下一篇>>']]",
		customTitle: ".post-title",
		mcss: ".post-warp .content-warp{padding:0px}",
		category: "nsfw2"
	}, {
		name: "牛C網 自動翻頁",
		url: {
			//h: ["rulel.com"],
			t: "NIUC.NET",
			e: [".post-list", ".list-footer"]
		},
		init: () => fn.waitEle(".el-pager .active").then(e => (currentPageNum = Number(fn.gt(e)))),
		autoPager: {
			ele: ".post-list",
			observer: ".post-list>.post-item",
			next: () => {
				let lastNum = _unsafeWindow.core_next.total_page;
				lastNum = Number(lastNum);
				if (currentPageNum < lastNum) {
					let url = fn.dlp().replace(/\/page\/\d+/, "");
					if (url === "/") {
						url = "";
					}
					if (fn.dls() !== "") {
						return url + "/page/" + (currentPageNum += 1) + fn.dls();
					}
					return url + "/page/" + (currentPageNum += 1);
				}
				return null;
			},
			pageNum: () => currentPageNum,
			lazySrc: "img[data-src]"
		},
		category: "autoPager"
	}, {
		name: "8E资源站",
		host: ["8ezy.com"],
		url: {
			e: [".logo>a[title='8EZY']", "h1.article-title"]
		},
		imgs: ".article-content p>img",
		videos: "video>source",
		button: [4],
		insertImg: [".article-content", 2],
		customTitle: () => fn.dt({
			s: "h1.article-title",
			d: [
				"【在线观看】-",
				/\d+p(\d+v)?$|\(\d+[\w\s\.\+-]+\)|\[\d+[\w\s\.\+-]+\]|“\d+ photos.*/i
			]
		}),
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "魅枝",
		host: ["meizhi.art"],
		url: {
			t: "魅枝",
			e: "article.single-article"
		},
		imgs: "#image-content>img",
		button: [4],
		insertImg: ["#image-content", 2],
		autoDownload: [0],
		next: ".post-pre-next-info>.next-jt>a:has(.b2-arrow-left-s-line)",
		prev: ".post-pre-next-info>.next-jt>a:has(.b2-arrow-right-s-line)",
		customTitle: ".entry-header>h1",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		name: "6图",
		url: {
			h: ["www.6tu.com"],
			p: "/t/"
		},
		box: [".container .box", 2],
		imgs: ".swiper-box img",
		button: [4],
		insertImg: ["box", 2],
		autoDownload: [0],
		next: "//a[text()='下一篇']",
		prev: "//a[text()='下一篇']",
		customTitle: ".box h1",
		category: "nsfw1"
	}, {
		name: "优美图录",
		url: {
			h: ["www.umei.net", "umei.net"],
			p: ".html",
			e: ".image_div img"
		},
		imgs: () => fn.getImgO(".image_div img", fn.gt(".item_info span"), 9, null, 200, ".nav-links"),
		button: [4],
		insertImg: [".image_div", 2],
		customTitle: ".item_title>h1",
		css: ".content_left img,.image_div a img{cursor:unset}",
		hide: ".affs,.xg_content>li:nth-child(n+1):nth-child(-n+2)",
		category: "nsfw1"
	}, {
		name: "Xiutaku/Kiutaku",
		url: {
			h: ["xiutaku.com", "kiutaku.com"],
			p: /^\/\d+$/
		},
		init: () => fn.remove(".search-form~*,.blog~*:not([class]),.pagination~*:not([class]):not(hr),.article.content~*:not([class]):not(hr),.bottom-articles~*"),
		imgs: () => fn.getImg(".article-fulltext img", fn.gt(".pagination-list>span:last-child")),
		button: [4],
		insertImg: [".article-fulltext", 2],
		customTitle: () => fn.dt({
			s: ".article-header>h1",
			d: /([\s-]+)?.Mitaku.*/i
		}),
		category: "nsfw1"
	}, {
		name: "MissBby.cc",
		url: {
			h: ["missbby.cc", "missneko.com"]
		},
		page: () => fn.clp("-photos") || fn.clp("-pictures") || fn.clp("/gallery/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => {
			if (_this.page()) {
				let links = [fn.clp()];
				let page_s = "a[class*=bg-pink-500][href*='page=']";
				if (fn.ge(page_s, doc)) {
					links = [...links, ...fn.gau(page_s, doc)];
				}
				return fn.getEle(links, ".items-center.min-h-screen img").then(eles => fn.getImgSrcset(eles));
			}
			return [];
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.dt({
			s: "//div[strong[contains(text(),'Album Name')]]",
			d: "Album Name: "
		}, doc) : null,
		css: ".md\:px-16,.xl\:px-20{padding:unset!important}.max-w-3xl{max-width:100%!important}",
		category: "nsfw2"
	}, {
		name: "BingMM",
		url: {
			h: ["bingmm.com"]
		},
		page: () => fn.clp(/^\/\w+\/\d+\.html$/),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => _this.page() ? fn.gae(".entry-content img", doc) : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let a = fn.ge({
				s: "a[href]:has(.puock-text>span)",
				t: key
			}, doc);
			return a ? a.pathname : null;
		},
		next: () => _this.np("Previous"),
		prev: () => _this.np("Next"),
		customTitle: () => _this.page() ? fn.gt("#post-title", 1, doc) : null,
		category: "nsfw1"
	}, {
		name: "图库库/套图吧/9b图库/cosck",
		host: ["tukuku.cc", "taotu8.biz", "8881134.xyz", "cosck.cc"],
		url: {
			t: ["图库库", "套图吧", "9b图库", "cosck"],
			p: [".html", /^\/\d+$/]
		},
		box: [".entry-content p:has(img)", 1],
		imgs: ".entry-content img[decoding]",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content p:has(img)"], 2
		],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: ".entry-header .entry-title",
		hide: "[id].widget_text,.gridmode-post-thumbnail-single,.gridbit-thumbnail-alignwide",
		category: "nsfw1"
	}, {
		name: "Cup2D",
		url: {
			h: ["cup2d.com"],
			p: /^\/[^\/]+\/$/
		},
		init: () => fn.rd(true),
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".entry-content>div:not(.separator,.c)>a img[data-lazy-src],.entry-content>a>img[data-lazy-src]", doc);
			return fn.gae(".entry-content>div:not(.separator,.c)>a,.entry-content>a:has(>img[data-lazy-src])", doc);
		},
		button: [4],
		insertImg: [".entry-content>div", 2],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: ".post-title.entry-title",
		category: "nsfw2"
	}, {
		name: "COSERMM",
		url: {
			h: ["cosermm.blog.2nt.com"],
			p: "/blog-entry-"
		},
		imgs: "#inner-contents img",
		button: [4],
		insertImg: ["#inner-contents", 2],
		autoDownload: [0],
		next: "a.next-a",
		prev: "a.prev-a",
		customTitle: "#entry-title",
		category: "nsfw1"
	}, {
		name: "COSERMM 自動翻頁",
		reg: /^https?:\/\/cosermm\.blog\.2nt\.com\/(page-\d+\.html)?$/i,
		autoPager: {
			mode: 1,
			waitEle: "#pagination>li",
			ele: "#grid-container",
			observer: "#grid-container>.grid-items",
			next: "li:has(>span#current)+li>a",
			re: "#pagination",
			pageNum: "li:has(>span#current)"
		},
		openInNewTab: ".grid-items a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "美图社/花瓣美女",
		host: ["www.928r.com", "www.060k.com"],
		url: {
			t: ["美图社", "花瓣美女"],
			p: /^\/post\/\d+\.html$/
		},
		imgs: () => {
			fn.sm5();
			let url = fn.gu("//a[text()='显示全文']");
			return fn.fetchDoc(url).then(dom => fn.gae("#lightgallery img", dom));
		},
		button: [4],
		insertImg: ["#lightgallery", 2],
		autoDownload: [0],
		next: ".prev>a",
		prev: ".next>a",
		customTitle: ".focusbox-title",
		category: "nsfw1"
	}, {
		name: "美女写真馆",
		host: ["www.photo13.com"],
		url: {
			t: "美女写真馆",
			p: "/m/"
		},
		init: () => {
			if ("detectDevTools" in _unsafeWindow) {
				_unsafeWindow.showWarning = null;
				_unsafeWindow.detectDevTools = null;
				_unsafeWindow.onresize = null;
			}
			tempEles = fn.gae(".post-content>blockquote");
		},
		imgs: ".post-content img",
		button: [4],
		insertImg: [".post-content", 2],
		insertImgAF: (_, bar) => bar.before(...tempEles),
		customTitle: "h1.post-title",
		category: "nsfw1"
	}, {
		name: "MMM333美女写真图片",
		url: {
			h: "mmm333.top",
			p: ".html"
		},
		box: ["#lightgallery", 1],
		imgs: "#lightgallery .boximg",
		button: [4],
		insertImg: [
			["box", 0, "#lightgallery"], 2
		],
		autoDownload: [0],
		next: "//a[text()='上一篇']",
		prev: "//a[text()='下一篇']",
		customTitle: "h1.focusbox-title",
		category: "nsfw1"
	}, {
		name: "桃花社",
		host: ["www.iiblog.live"],
		url: {
			t: "桃花社",
			p: "/thread/"
		},
		box: ["div:has(>p>img)", 1],
		imgs: ".entry-title~div img",
		button: [4],
		insertImg: [
			["box", 0, "div:has(>p>img)"], 2
		],
		customTitle: () => fn.dt({
			s: ".entry-title",
			r: [
				["|", " - "]
			]
		}),
		category: "nsfw1"
	}, {
		name: "找套图/Xiuno BBS",
		host: ["www.zhaotaotu.cc", "kantaotu.cc", "taotu.uk"],
		url: {
			t: "Xiuno BBS",
			u: ["/thread", "/?thread"],
			e: ".card-user-info"
		},
		imgs: ".message>img:not(:first-of-type)",
		button: [4],
		insertImg: [".message", 2],
		customTitle: ".media-body>h4",
		category: "nsfw1"
	}, {
		name: "尤美图库/M5MM",
		host: ["www.umeitu.com", "www.m5mm.com"],
		url: {
			h: /umeitu\.com$|m5mm\.com$/,
			p: ["/img/", "/photo/"]
		},
		imgs: () => fn.getImg(".vipimglist img", fn.gt(".stitle>h1>span").match(/\d+/)[0], 9),
		button: [4],
		insertImg: [".vipimglist", 2],
		customTitle: () => fn.dt({
			d: [
				" - 尤美图库",
				" - M5MM"
			]
		}),
		css: ".vipimglist img{min-height:unset!important;}",
		hide: "union[id],.sb.list2>li:nth-child(n+2):nth-child(-n+3)",
		category: "nsfw1"
	}, {
		name: "91性感美女",
		url: {
			h: ["www.913wen.com", "913wen.com"],
			p: ["/mm/", "/p/"]
		},
		imgs: () => fn.getImg(".sg_img img", Number(fn.gu(".page_navi a:last-child")?.split("_")?.at(1)?.match(/\d+/)) || 1, 9),
		button: [4],
		insertImg: [".sg_img", 2],
		customTitle: "h1",
		css: ".sg_img img{min-height:unset!important}",
		hide: "#divpsg,.tujia",
		category: "nsfw1"
	}, {
		name: "Xiuren 秀人网",
		url: {
			h: ["www.xiuren.org", "www6.imgxr.com"]
		},
		imgs: "a[rel='gallery']:not([href*='html']",
		button: [4],
		insertImg: [
			[".post p>a:not([title])", 2, ".post p>a[title],.post p>span"], 2
		],
		customTitle: "#title>h1",
		css: "#post .post img{max-width:100% !important}",
		category: "nsfw2"
	}, {
		name: "Xiuren 秀人网",
		url: {
			h: "xiuren.download",
			s: "token"
		},
		box: [".photo-show"],
		imgs: ".photo-show a:has(img)",
		button: [4],
		insertImg: [
			["box", 0, ".photo-show>a"], 2
		],
		customTitle: ".photo-show blockquote",
		category: "nsfw2"
	}, {
		name: "微密猫",
		host: [
			"www.",
			"wemecat.com",
			"wemecat[24789,10,11,12,13,14].com",
			"wemimao1.vip",
			"wemao.xyz",
			"weiminew.com",
			"maobao.xyz",
			"maobao.vip",
			"mvxzsp.com",
			"stxlmt.com",
			"amstt.com",
			"xiuren-wang.com",
			"xiurentaotu.com",
			"xiuren-tu.com",
			"xiurenmote.com",
			"xiurenxiezhen.com",
			"xiurenwxz.cc",
			"hywsg.com",
			"jvidmtpj.com",
			"panssphw.com",
			"pansspzp.com",
			"yuhuajie.net",
			"rtxzw.net",
			"www.xiuren-wang.com",
			"qnxz.top",
			"wmqxz.net",
			"fenseqingrenr.net",
			"net-weimi.com",
			"laohucaicai.net",
			"tik.oumeisetut.com",
			"oumeitp.cc",
			"taotuw.cc",
			"setu.bar"
		],
		url: {
			//t: ["微密猫", "秀人"],
			e: [
				".scrollbar-thumb-match-color.scrollbar-track-sub-color",
				"#nuxt-ui-colors",
				".van-back-top",
				"#__nuxt",
				"#teleports"
			]
		},
		page: () => fn.clp("/archives/"),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: async () => {
			if (!_this.page()) return [];
			fn.sm4();
			await fn.waitEle("h1~div .grid .fetch-image img:not([src*='default.png']),main .text-lg img:not([src*='default.png'])");
			let more = fn.ge("//div[span[starts-with(text(),'点击展开')]]");
			if (more) {
				EClick(more);
			}
			await fn.aotoScrollEles({
				ele: ".grid>div>div>div.fetch-image",
				cb: (ele) => isEle(fn.ge("img[src]:not([src*='default.png'])", ele)),
				top: "#page-main"
			});
			return fn.getImgSrcset(".grid>div>div>div.fetch-image img,main .text-lg img");
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.dt({
			s: "main h1"
		}) : null,
		loopClick: {
			s: ".van-icon-close",
			t: 60000
		},
		hide: ".my-2.grid.grid-cols-1,.lg\\:grid-cols-10,div:not([id],[class]):has(>div img[alt^='约炮首选']),div:has(>div.block span.text-match-color),.lg\\:grid-cols-2:has(.overflow-hidden img.inline-block)",
		category: "nsfw2"
	}, {
		name: "微密猫",
		host: [
			"www.me-quan.com",
			"www.weme-quan.com",
			"www.tie-fen.com",
			"www.wemmao.com"
		],
		url: {
			t: "微密猫",
			e: ".wp-singular",
			p: "/archives/"
		},
		box: [".article-copyright", 1],
		imgs: ".article-content img",
		button: [4],
		insertImg: [
			["box", 0, ".wp-block-image"], 2
		],
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: ".article-title",
		hide: ".modown-ad,.modown-ad-mobile-hide,.sitetips",
		category: "nsfw2"
	}, {
		name: "微密猫",
		host: [
			"se.9yjnqg.cc",
			"sat.dzyqs2.cc"
		],
		url: {
			e: ["a[data-id='weimimao']", "#gallery"],
			p: "/archives/"
		},
		init: () => fn.rd(),
		box: ["#gallery", 1],
		imgs: () => fn.gae("#gallery img", doc).map(img => "https://d2m11qmjo5lnoa.cloudfront.net" + img.dataset.src),
		button: [4],
		insertImg: [
			["box", 0, "#gallery,#toggle-more"], 2
		],
		insertImgAF: (p, b) => {
			let e = fn.ge(".post-content .post-content");
			if (e) {
				b.before(e);
			}
		},
		customTitle: ".post-title",
		hide: ".font-button-grid-1,#drawer-container,.image-grid,.image-card-grid",
		category: "nsfw2"
	}, {
		name: "微圖坊",
		url: () => fn.checkUrl({
			h: ["www.v2ph.com", "www.v2ph.net", "www.v2ph.ru", "www.v2ph.ovh"],
			p: "/album/",
			e: ".photos-list"
		}) && !fn.cls("page="),
		imgs: async () => {
			let [picTotalNum] = fn.gt("dd:last-child").match(/\d+/);
			let pagePicNum = fn.gae(".album-photo img[alt]").length;
			let max = Math.ceil(picTotalNum / pagePicNum);
			let links = fn.arr(max, (v, i) => siteUrl.replace(/\?hl=.+|\?page=\d+/, "") + `?page=${(i + 1)}`);
			let srcArr = [];
			let status = 200;
			let vip = false;
			let fetchNum = 0;
			fn.sm1();
			for (let [page, link] of links.entries()) {
				await fetch(link).then(res => {
					if (res.status == 403) status = 403;
					fn.showMsg(`${DL.str_02}${fetchNum+=1}/${links.length}`, 0);
					return res.arrayBuffer();
				}).then(buffer => {
					const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
					const htmlText = decoder.decode(buffer);
					const dom = fn.doc(htmlText);
					debug(`\n${link}\n`, dom);
					let vipEle = fn.ge(".lead", dom);
					if (vipEle) vip = true;
					let imgs = fn.gae(".album-photo img[alt]", dom);
					imgs.length == 0 ? debug(`\n${link}\n沒有任何圖片`) : debug(`\n${link}\n此頁圖片`, imgs);
					let tE = fn.gae("div.album-photo").at(-1);
					for (let img of imgs) {
						img.dataset.src ? srcArr.push(img.dataset.src) : srcArr.push(img.src);
						if (page != 0) insertAfter(tE, img.parentNode.cloneNode(true));
					}
					if (page != 0 && !vipEle && fn.ge(".pagination", dom)) fn.ge(".pagination").outerHTML = fn.ge(".pagination", dom).outerHTML;
				});
				if (status == 403) {
					setTimeout(() => {
						fn.showMsg("403請先登錄網站!", 0);
					}, 1200);
					return srcArr;
				}
				if (vip) {
					setTimeout(() => {
						fn.showMsg("VIP限定專輯圖片!", 5000);
					}, 1200);
					return srcArr;
				}
				await delay(600);
			}
			if (picTotalNum != srcArr.length && !vip) {
				setTimeout(() => {
					fn.hm();
					fn.showMsg("圖片有缺,請看主控台訊息", 5000);
				}, 1300)
			}
			return srcArr;
		},
		button: [4],
		insertImg: [".photos-list", 2],
		customTitle: "h1",
		css: ".albums-list img,.photos-list img{opacity:1!important}",
		category: "nsfw2"
	}, {
		name: "柠檬皮",
		url: {
			h: "www.emonl.com",
			p: ".html"
		},
		imgs: () => fn.getNP(".single-content>*", ".page-links span.current+a:has(.next-page)", null, ".page-links").then(() => fn.hideEle(".page-links")).then(() => fn.gae(".single-content img")),
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			d: " | 檸檬皮"
		}),
		category: "nsfw1"
	}, {
		name: "美图乐",
		host: ["www.meitule.net", "www.meitule.com", "www.meitulu.cc", "www.meitu001.cc"],
		url: {
			t: "美图乐",
			p: "/photo/",
			e: ".content img"
		},
		imgs: () => fn.getImgO(".content img", Number(fn.gu(".page>li:last-child>a")?.split("_")?.at(1)?.match(/\d+/)) || 1, 9),
		button: [4],
		insertImg: [".content", 2],
		customTitle: "h1.h5",
		hide: "#dtag>center,#divpsg,.tujia,.list-album>li:nth-child(n+1):nth-child(-n+2)",
		category: "nsfw1"
	}, {
		name: "绝美网",
		link: "https://www.juemei.com/mm/l.html",
		url: {
			h: "juemei.com",
			p: ".html"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".album_wrap img");
			return thumbnailSrcArray.map(e => e.replace("_s.", "."));
		},
		button: [4],
		insertImg: [".album .wrap", 2],
		autoDownload: [0],
		np: (key) => {
			let eles = fn.gae("//div[@class='wrapper']//a[text()='上一篇']");
			let [n, p] = eles;
			if (key == "next") {
				return n.href;
			} else if (eles.length > 1 && key == "prev") {
				return p.href;
			}
			return null;
		},
		next: () => _this.np("next"),
		prev: () => _this.np("prev"),
		customTitle: ".album h1",
		hide: ".asd,.album_list,.page>em,.page>.next,.page>.num,.page>.end,.page>.current",
		category: "nsfw1"
	}, {
		name: "美女私房菜",
		host: ["ozv.me"],
		url: {
			t: "美女私房菜",
			p: ".html"
		},
		init: () => fn.clearAllTimer(3),
		imgs: "img.swiper-lazy",
		customTitle: () => fn.title(" - 美女私房菜"),
		category: "nsfw1"
	}, {
		name: "Elysium",
		url: {
			h: "www.elysium.pro",
			p: "/albums/",
			e: "a[data-thumbnail]:not([data-video])"
		},
		box: [".list-group", 1],
		imgs: async () => {
			let eles = fn.gae(_this.url.e);
			let pages = fn.ge(".pagination.flex-wrap li.page-item.active+li>a:not([aria-label=Next])");
			if (pages) {
				let links = fn.gau(".pagination.flex-wrap>.page-item:not(.disabled)>a");
				eles = await fn.getEle(links, _this.url.e);
			}
			thumbnailSrcArray = eles.map(e => e.dataset.thumbnail);
			return eles;
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: () => fn.gt(".text-muted+a") + " - " + fn.gt(".btn-toolbar>h4"),
		category: "nsfw1"
	}, {
		name: "美桌",
		link: "http://www.win4000.com/meitu.html",
		url: {
			h: "www.win4000.com",
			p: /^\/meinv\d+\.html$/
		},
		imgs: () => fn.getImgA(".pic-large", "#scroll>li:not(.current)>a", 200),
		button: [4],
		insertImg: ["#pic-meinv,.pic-meinv", 2],
		autoDownload: [0],
		next: ".group-next>a",
		prev: ".group-prev>a",
		customTitle: ".ptitle>h1",
		category: "nsfw1"
	}, {
		name: "MM1311",
		url: {
			h: ["www.mm1311.net", "m.mm1311.net"],
			p: /^\/\w+\/\d+\.html$/
		},
		imgs: () => {
			let max;
			fn.ge(".page-ch") ? [max] = fn.gt(".page-ch").match(/\d+/) : [, max] = fn.gt(".fenye>.rw").match(/\d+\/(\d+)/);
			return fn.getImg(".content-pic img,.post-content img", max, 9);
		},
		button: [4],
		insertImg: [".content-pic,.post-content", 2],
		autoDownload: [0],
		next: ".updown_r",
		prev: ".updown_l",
		customTitle: ".content>h5,.mm-title",
		hide: "union",
		category: "nsfw1"
	}, {
		name: "656G精品套图/秀人妹子图",
		url: {
			h: ["www.656g.com", "m.656g.com", "www.mmww.cc"],
			p: "/tid/"
		},
		imgs: () => fn.getImgO(".imgg img", Number(fn.gt(".i1").match(/\d+/)), 9),
		button: [4],
		insertImg: [".imgg", 2],
		customTitle: ".c-tt>h1",
		category: "nsfw1"
	}, {
		name: "青年美圖",
		host: ["jrants.com"],
		reg: [
			/^https?:\/\/(\w+\.)?jrants\.com\/\d+\.html$/,
			/^https:\/\/\w+\.jrants\.com\/[^\/]+\/$/
		],
		imgs: () => fn.ge(".page-links") ? fn.getImg(".entry-content img", fn.gt(".page-links>a:last-child"), 7) : fn.gae(".entry-content img"),
		button: [4],
		insertImg: [".entry-content", 1],
		autoDownload: [0],
		next: "span.prev>a",
		prev: "span.next>a",
		customTitle: ".entry-title",
		hide: ".code-block",
		category: "nsfw2"
	}, {
		name: "CosBlay/風流雜誌/虹圖",
		host: ["cosblay.com", "trendszine.com", "www.hongimg.com"],
		reg: [
			/^https?:\/\/(cosblay\.com|trendszine\.com|www\.tiplogo\.com)\/\d+\.html/i,
			/^https?:\/\/[a-z]{2}\.cosblay\.com\/\d+\/[^\.]+\.html$/,
			/^https?:\/\/[a-z]{2,3}\.hongimg.com\/\d+\/[^\.]+\.html$/
		],
		imgs: () => fn.getImg(".entry-content img", fn.gt(".pgntn-page-pagination-block>*:last-child", 2) || 1, 7),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "span.prev>a",
		prev: "span.next>a",
		customTitle: ".entry-title",
		mcss: ".separate-containers .inside-article,.separate-containers .comments-area,.separate-containers .page-header,.separate-containers .paging-navigation,.one-container .site-content,.inside-page-header{padding:2px}.entry-content:not(:first-child),.entry-summary:not(:first-child),.page-content:not(:first-child){margin-top:2px}",
		hide: ".code-block",
		category: "nsfw2"
	}, {
		name: "888美女网",
		url: {
			h: "www.888meinv.com",
			e: [".suoyou", ".pannel img"]
		},
		imgs: () => {
			let [, max] = fn.gt(".suoyou").match(/\/(\d+)/);
			let links = fn.arr(max, (v, i) => siteUrl + "/" + (i + 1));
			return fn.getImgA(".pannel img", links);
		},
		button: [4],
		insertImg: [".pannel", 2],
		autoDownload: [0],
		next: ".pre_pageload>a",
		prev: ".next_pageload>a",
		customTitle: "h1",
		css: ".nr .tupianqu img{margin-top:0px !important}",
		mcss: ".nr .tupianqu,.nr .tupianqu .pannel{padding:0px !important}",
		hide: "union",
		category: "nsfw1"
	}, {
		name: "淑女爱",
		host: ["www.shunvi.com", "www.shunvai.com"],
		url: {
			h: /^www\.shunva?i\.com$/,
			e: "#allnum",
		},
		imgs: async () => {
			let max = fn.gt("#allnum");
			let links = fn.arr(max, (v, i) => i == 0 ? siteUrl : siteUrl.replace(".html", "") + "_" + (i + 1) + ".html");
			let all = fn.ge("//a[text()='多图显示']");
			if (all) {
				let ok = await fetch(all).then(res => res.ok);
				if (ok) {
					links = [all.href];
				}
			}
			return fn.getImgA(".picsbox img", links, 2).then(srcs => srcs.filter(e => fn.isImage(e) && !e.includes("/logo/") && !e.includes("onerror")));
		},
		button: [4],
		insertImg: [".picsbox>center", 2],
		customTitle: ".picmainer>h1",
		hide: ".picpege",
		category: "nsfw1"
	}, {
		name: "淑女爱M",
		host: ["m.shunvi.com", "m.shunvai.com"],
		url: {
			h: /^m\.shunva?i\.com$/,
			p: "/photo/",
			e: ["#thenum", ".swiper-slide img"]
		},
		imgs: () => {
			let [max] = fn.gt("//span[b[@id='thenum']]").match(/\d+$/);
			let links = fn.arr(max, (v, i) => i == 0 ? siteUrl : siteUrl.replace(".html", "") + "_" + (i + 1) + ".html");
			return fn.getImgA(".swiper-slide img", links, 200).then(srcs => srcs.filter(e => fn.isImage(e) && !e.includes("/logo/") && !e.includes("onerror")));
		},
		button: [4],
		insertImg: ["#slider", 2],
		customTitle: () => fn.dt({
			s: ".infoline",
			d: /\d+\s\/\s\d+\n/
		}),
		hide: "union,#pic_list li:has(img:not([src*=shunvi]))",
		category: "nsfw1"
	}, {
		name: "TWOIMG",
		link: "https://www.twoimgs.com/people",
		url: {
			h: [/twoimg/, /lovemmtu/],
			p: /^\/\d+\.html$/
		},
		imgs: ".gallery a",
		thums: ".gallery img",
		button: [4],
		insertImg: [
			[".article-content", 0, ".gallery"], 2
		],
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: ".article-title,.focusbox-title",
		category: "nsfw1"
	}, {
		name: "三千图片网",
		link: "https://www.win3000.com/tags/xingganmeinv/",
		url: {
			h: "www.win3000.com",
			p: ".html",
			e: ".pic-cont img"
		},
		imgs: () => {
			let [max] = fn.gt(".title>span").match(/\d+$/);
			let links = fn.arr(max, (v, i) => siteUrl.replace(".html", "") + "_" + (i + 1) + ".html");
			return fn.getImgA(".pic-cont img", links, 2);
		},
		button: [4],
		insertImg: [".pic-cont", 2],
		autoDownload: [0],
		next: "a.other-group.fr",
		prev: "a.other-group.fl",
		customTitle: ".title>h1",
		category: "nsfw1"
	}, {
		name: "三千图片网M",
		link: "https://m.win3000.com/tags/xingganmeinv/",
		url: {
			h: "m.win3000.com",
			p: ".html",
			e: [".show-page>i", ".pic-showbox .imgbox img"]
		},
		imgs: () => {
			let max = fn.gt(".show-page>i");
			let links = fn.arr(max, (v, i) => siteUrl.replace(".html", "") + "_" + (i + 1) + ".html");
			return fn.getImgA(".pic-showbox .imgbox img", links, 2);
		},
		button: [4],
		insertImg: [".pic-showbox", 2],
		autoDownload: [0],
		next: "a.page-next",
		prev: "a.page-prev",
		customTitle: ".pic-infobox h1",
		css: "#app{font-size:14px!important}",
		category: "nsfw1"
	}, {
		name: "3G 壁纸",
		host: ["www.3gbizhi.com", "m.3gbizhi.com"],
		link: "https://www.3gbizhi.com/meinv",
		reg: /^https?:\/\/(www|m|desk)\.3gbizhi\.com\/meinv\/(\w+\/)?\w+\.html$/,
		imgs: () => {
			let links = fn.gae(".showImglistw a").map(a => a.pathname);
			return fn.getImgA("#contpic,#mobile_c_img>img", links);
		},
		thums: ".showImglistw img",
		button: [4],
		insertImg: ["#showimg", 1],
		endColor: "white",
		autoDownload: [0],
		next: "a.next-page[href$=html]",
		prev: "a.prev-page[href$=html]",
		customTitle: "h2.title,.titlew>h2",
		hide: "[class^=ad_id]",
		category: "nsfw1"
	}, {
		name: "亿图全景图库",
		host: ["www.yeitu.com", "m.yeitu.com"],
		link: "https://www.yeitu.com/meinv/",
		reg: /^https?:\/\/(www|m)\.yeitu\.com\/\w+\/\w+\/\w+\.html$/,
		init: () => {
			let a = fn.ge(".article-body>a,.gallery-item>a");
			if (a) a.outerHTML = a.innerHTML;
		},
		imgs: () => {
			let [, max] = fn.gt(".imageset-sum,span.num").match(/\/\s?(\d+)/);
			let links = fn.arr(max, (v, i) => i == 0 ? siteUrl : siteUrl.replace(".html", "") + "_" + (i + 1) + ".html");
			return fn.getImgA(".img_box img[alt],.gallery-item img[alt],.article-show img", links, 2);
		},
		button: [4],
		insertImg: [".img_box,.gallery-item,.article-show", 2],
		customTitle: "#title>h1,h1.article-title,.article-info>h1",
		hide: ".appbox,.uk-page~section,.yt-pages+.mssp",
		category: "nsfw1"
	}, {
		name: "MEITU131",
		host: ["www.meitu131.com", "m.meitu131.com"],
		link: "https://www.meitu131.com/nvshen/,https://www.meitu131.com/jigou/",
		reg: /^https?:\/\/(www|m)\.meitu131\.(com|net)\/(\w+\/)?meinv\/\d+\//,
		imgs: () => {
			let [, max] = fn.gt("a[title],.uk-page>span").match(/\/(\d+)/);
			return fn.getImgO(".work-content img,.uk-article-bd img", max, 15);
		},
		button: [4],
		insertImg: [".work-content>p,.uk-article-bd", 1],
		customTitle: ".contitle-box>h1,h1.uk-article-title",
		css: ".work-content img{max-width:100%!important}",
		hide: ".appbox,.uk-page~section",
		category: "nsfw1"
	}, {
		name: "爱套图",
		url: {
			h: ["www.aitaotu.cc", "aitaotu.cc", "www.2taotu.cc", "2taotu.cc"],
			p: "/photo/"
		},
		box: [".uk-inline", 2],
		imgs: () => {
			let [, max] = fn.gu("//a[text()='尾页']").match(/_(\d+).htm/);
			return fn.getImg(".uk-article img", max, 9);
		},
		button: [4],
		insertImg: [
			["box", 0, "figure.uk-inline"], 2
		],
		next: ".m-prevnext a",
		customTitle: ".uk-article-title",
		hide: "union[id]",
		category: "nsfw1"
	}, {
		name: "和邪社",
		url: {
			h: "www.hexieshe.com",
			p: /^\/\d+\/$/
		},
		init: () => fn.getNP("#content-innerText>p", "span.current+a", null, ".post-links"),
		imgs: "#content-innerText img",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: "为您朗读"
		}),
		setFancybox: true,
		category: "nsfw1"
	}, {
		name: "天极图片",
		url: {
			h: "pic.yesky.com",
			p: ".shtml"
		},
		box: [".bigPic", 1],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".previewPic img");
			return thumbnailSrcArray.map(e => e.replace(/d-|\/180x320/g, ""));
		},
		button: [4],
		insertImg: [
			["box", 0, ".bigPic"], 2
		],
		customTitle: "h1",
		css: ".atlasSwiper .floatR,.atlasSwiper .floatR .previewPic{width:unset!important}",
		category: "nsfw1"
	}, {
		name: "天极图片M",
		link: "https://wap.yesky.com/pic/",
		url: {
			h: "wap.yesky.com",
			p: ".shtml"
		},
		box: [".swiper-container", 1],
		imgs: "[data-imgid] img",
		button: [4],
		insertImg: [
			["box", 0, ".swiper-container"], 2
		],
		customTitle: ".atlas_introduce h1",
		hide: ".swiper-sum,[class^=ad]",
		category: "nsfw1"
	}, {
		name: "爱美女",
		url: {
			h: "www.92meinv.com",
			p: "/article-",
			e: ".pp.hh img[alt],#image_div img"
		},
		imgs: () => {
			let [, max] = fn.gt(".des>h1,.post_title_topimg").match(/\/\s?(\d+)/);
			let links = fn.arr(max, (v, i) => siteUrl.replace(/\.html$/, "") + "-" + (i + 1) + ".html");
			return fn.getImgA(".pp.hh img[alt],#image_div img", links, 200);
		},
		button: [4],
		insertImg: [".pp.hh,.content", 2],
		autoDownload: [0],
		next: "//a[@class='active' and contains(text(),'下一篇')] | //a[@class='active' and contains(text(),'下一组')]",
		prev: "//a[@class='active' and contains(text(),'上一篇')] | //a[@class='active' and contains(text(),'上一组')]",
		css: ".pp img{max-width:100%!important}",
		customTitle: () => fn.title("_", 1),
		category: "nsfw1"
	}, {
		name: "爱美女M",
		url: {
			h: "m.92meinv.com",
			p: "/article-",
			e: ".arcmain img,#image_div img"
		},
		imgs: () => {
			let max = fn.gt(".article-page>*:last-child", 2);
			let links = fn.arr(max, (v, i) => siteUrl.replace(/\.html$/, "") + "-" + (i + 1) + ".html");
			return fn.getImgA(".arcmain img,#image_div img", links, 200);
		},
		button: [4],
		insertImg: [".clearfix.arcmain,.content", 1],
		autoDownload: [0],
		next: "a.f-r.l3",
		prev: "a.f-l.l2",
		hide: "body>a",
		customTitle: () => fn.title("_", 1),
		category: "nsfw1"
	}, {
		name: "52XiuRen",
		url: {
			h: "52xiuren.cc"
		},
		imgs: ".entry-content a[data-fancybox]",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		customTitle: ".jeg_post_title",
		category: "nsfw2"
	}, {
		name: "XiuRenBox",
		url: {
			h: "www.xiurenbox.com",
			p: /\/\d+\/$/
		},
		box: [".entry-content .wp-block-image", 1],
		imgs: () => fn.getImgA(".entry-content .wp-block-image img", [fn.lp + "?showall=1"]),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".wp-block-image,.simple-page-nav"),
		autoDownload: [0],
		next: "a[href][rel=prev]",
		prev: "a[href][rel=next]",
		customTitle: "#post-title",
		category: "nsfw1"
	}, {
		name: "男人之家",
		host: ["nanrenhome.cc", "nanrenhome.com"],
		url: {
			h: /nanrenhome\./,
			p: ".html",
			e: "//a[@rel='category tag'][text()='福利美图']"
		},
		imgs: () => {
			let pages = fn.ge(".article-paging a[href]");
			return pages ? fn.getImgA(".article-content img", ".article-paging a[href]") : fn.gae(".article-content img");
		},
		button: [4],
		insertImg: [
			["//article/p[img]", 2, "//article/p[img] | //div[@class='article-paging']"], 2
		],
		customTitle: ".article-title",
		category: "nsfw1"
	}, {
		name: "网红跟我俩",
		host: "www.2wh.net",
		reg: /^https?:\/\/www\.2wh\.net\/\d+\.html$/,
		include: "//div[@class='breadcrumbs']/a[2][text()='美女写真机构']",
		init: () => {
			for (let p of fn.gae(".article-content>p")) {
				if (!fn.ge("img", p)) {
					tempEles.push(p);
				}
			}
		},
		imgs: () => {
			let pag = fn.ge(".article-paging a[href]");
			return pag ? fn.getImgA(".article-content img", ".article-paging a[href]") : fn.gae(".article-content img");
		},
		button: [4],
		insertImg: [".article-content", 2],
		insertImgAF: (_, bar) => bar.before(...tempEles),
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: () => fn.dt({
			s: ".article-title",
			d: "无删减私房写真流出"
		}),
		category: "nsfw1"
	}, {
		name: "网红跟我俩",
		reg: /^https?:\/\/www\.2wh\.net\/\d+\.html$/,
		imgs: ".article-content img",
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: () => fn.dt({
			s: ".article-title",
			d: "无删减私房写真流出"
		}),
		setFancybox: true,
		category: "nsfw1"
	}, {
		name: "PixiBB",
		url: {
			h: "sexy.pixibb.com",
			e: [".entry-content img", ".post h2"]
		},
		imgs: () => fn.getImgA(".entry-content img", ".page-links a"),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".left-post a",
		prev: ".right-post a",
		customTitle: () => fn.dt({
			s: ".post h2",
			d: [
				/Sexy Cosplay.*$/,
				/Maid Raiden Cosplay.*$/
			]
		}),
		hide: ".row:has(>a>img[alt^=Watch]),#custom_html-3",
		category: "nsfw1"
	}, {
		name: "PutMega 分類自動翻頁",
		reg: /^https?:\/\/(www\.)?putmega\.com\/explore\//,
		autoPager: {
			ele: "#list-recent-albums>.pad-content-listing,#list-recent-images>.pad-content-listing",
			observer: "#list-recent-albums>.pad-content-listing>div,#list-recent-images>.pad-content-listing>div",
			next: ".pagination-next>a[href]",
			re: ".content-listing-pagination"
		},
		category: "autoPager"
	}, {
		name: "PutMega/ImgBB/JPG6/NF Host",
		links: [
			"https://www.putmega.com/explore/recent/?list=albums&sort=date_desc&page=1",
			"https://shiki17chen.imgbb.com/albums",
			"https://2920215920.imgbb.com/albums",
			"https://ozpin.imgbb.com/albums",
			"https://afc123.imgbb.com/albums",
			"https://jpg6.su/xelszy/albums",
			"https://jpg6.su/rainbowsmile/albums",
			"https://nfhost.me/insta_girls/albums"
		],
		url: {
			h: [/putmega\.com$/, "ibb.co", /jpg\d\.\w+$/, "nfhost.me"],
			p: ["/album/", "/a/"],
			st: "PF.obj.config.auth_token"
		},
		imgs: () => {
			fn.sm5();
			let id;
			if (fn.lh === "ibb.co") {
				[, , id] = fn.lp.split("/");
			} else {
				id = fn.lp.split(".").at(-1);
			}
			let code = fn.gst("PF.obj.config.auth_token");
			let [, auth_token] = code.match(/PF\.obj\.config\.auth_token[\s="]+(\w+)/);
			let params = fn.cp({
				auth_token,
				pathname: fn.lp,
				action: "get-album-contents",
				albumid: id
			});
			return fn.j("/json", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": params,
				"method": "POST"
			}).then(json => {
				customTitle = fn.dt({
					t: json.album.name
				});
				thumbnailSrcArray = json.contents.map(e => e.thumb.url);
				return json.contents.map(e => e.url);
			});
		},
		capture: () => _this.imgs(),
		button: [4],
		insertImg: ["#content-listing-tabs", 3],
		category: "nsfw2"
	}, {
		name: "anh.im/Lensdump",
		links: [
			"https://anh.im/bigradish/albums",
			"https://lensdump.com/marcusagrippa777",
			"https://lensdump.com/saucyspazgurl"
		],
		url: {
			h: ["anh.im", "lensdump.com"],
			p: ["/album/", "/a/"],
			e: "#content-listing-tabs"
		},
		imgs: () => fn.getNP("#list-most-recent>.pad-content-listing", ".pagination-next>a[href]").then(() => {
			thumbnailSrcArray = fn.getImgSrcArr(".list-item-image img").reverse();
			return thumbnailSrcArray.map(e => e.replace(".md.", "."));
		}),
		button: [4],
		insertImg: ["#content-listing-tabs", 3],
		customTitle: () => fn.dt({
			d: ["— anh.im"]
		}),
		hide: ".ad-banner",
		category: "nsfw2"
	}, {
		name: "Luscious",
		url: {
			h: "luscious.net"
		},
		page: () => fn.clp(/^\/albums\/[\w-]+_\d+\/$/),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: async () => {
			if (!_this.page()) return [];
			const getApiUrl = (id, page) => "https://www.luscious.net/graphql/nobatch/?" + new URLSearchParams({
				operationName: "PictureListInsideAlbum",
				query: "query PictureListInsideAlbum($input:PictureListInput!){picture{list(input:$input){info{total_pages}items{url_to_original url_to_video thumbnails{url}}}}}",
				variables: JSON.stringify({
					input: {
						filters: [{
							name: "album_id",
							value: String(id)
						}],
						display: "date_newest",
						items_per_page: 50,
						page
					}
				})
			}).toString();
			let id = fn.clp().match(/\d+/g).at(-1);
			let max = await fn.j(getApiUrl(id, 1)).then(json => json.data.picture.list.info.total_pages);
			let fetchNum = 0;
			let resArr = fn.arr(max, (v, i) => {
				let url = getApiUrl(id, (i + 1));
				return fn.j(url).then(json => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
					return json.data.picture.list.items.map(e => (e.url_to_video ? {
						video: e.url_to_video
					} : {
						original: e.url_to_original,
						thumbnail: e.thumbnails.at(-1).url
					}));
				});
			});
			return Promise.all(resArr).then(data => {
				videoSrcArray = data.flat().filter(item => item.video).map(e => e.video);
				thumbnailSrcArray = data.flat().filter(item => item.thumbnail).map(e => e.thumbnail);
				return data.flat().filter(item => item.original).map(e => e.original);
			});
		},
		capture: () => _this.imgs(),
		downloadVideo: true,
		customTitle: () => _this.page() ? fn.gt(".album-heading:not(.o-padding-sides),.album-heading.o-padding-sides a") : null,
		css: "body.o-modal-no-scroll{overflow:unset!important}",
		hide: "#modal-root,ul[role=toolbar]",
		category: "hcomic"
	}, {
		name: "次元岛",
		url: {
			h: ["ciyuandao.com"],
			p: "/photo/show/"
		},
		imgs: ".talk_pic img",
		button: [4],
		insertImg: [".talk_pic", 2],
		customTitle: "h1",
		category: "nsfw1"
	}, {
		name: "萌次元",
		host: ["www.mtutuu.com"],
		reg: /^https?:\/\/www\.mtutuu\.com\/\d+\.html$/,
		exclude: ".content-cap",
		imgs: ".entry-content img",
		button: [4],
		insertImg: [
			["//div[@class='entry-content']/p[img]", 2, "//div[@class='entry-content']/p[img]"], 2
		],
		customTitle: ".post-style-3-title",
		category: "nsfw1"
	}, {
		name: "次元小镇",
		host: ["dimtown.com"],
		reg: /^https?:\/\/dimtown\.com\/\d+\.html$/,
		exclude: ".down-login",
		imgs: "#content img",
		button: [4],
		insertImg: [
			["p:has(>img),p:has(a>img)", 2, "p:has(>img),p:has(a>img)"], 2
		],
		autoDownload: [0],
		next: ".post-pre a",
		prev: ".post-next a",
		customTitle: "h1",
		category: "nsfw1"
	}, {
		name: "米卡插画",
		host: ["mikagogo.com"],
		reg: /^https?:\/\/mikagogo\.com\/\d+/,
		imgs: "#content img",
		autoDownload: [0],
		next: ".post-pre a",
		prev: ".post-next a",
		customTitle: "h1:not([class])",
		setFancybox: true,
		category: "nsfw1"
	}, {
		name: "LA站",
		url: {
			h: "cosplayla.com",
			p: "/picture-"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".pic_list img,.picturelist img");
			return thumbnailSrcArray.map(e => e.replace("_750.", "."));
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.lh.startsWith("cos.") ? getTitle([".top_border a", ".picture_info .title"]) : fn.dt({
			r: [
				["之", " - "]
			]
		}),
		category: "nsfw1"
	}, {
		name: "C站CosZ",
		url: {
			h: ["cosz.com"],
			p: /\/\d+\.html$/
		},
		imgs: ".entry-content img",
		autoDownload: [0],
		next: ".post-pre .next-jt a",
		prev: ".post-next .next-jt a",
		customTitle: "#content h1",
		category: "nsfw1"
	}, {
		name: "推次元",
		host: ["www.a2cy.com", "a2cy.com"],
		url: {
			h: "a2cy.com",
			p: ".html"
		},
		imgs: () => fn.gae(".imgBox img,.w:not(.box-shadow) img").filter(e => !e.closest(".cy_tyoum,.cy_ranking,.yalayi_box")),
		capture: () => _this.imgs(),
		customTitle: "h1",
		category: "nsfw1"
	}, {
		name: "Cosplay Porn",
		link: "https://cosplayporn.online/category/cosplay/",
		url: {
			h: ["cosplayporn.online"],
			p: /^\/\w+\/[^\/]+\/$/,
			ee: ".responsive-player"
		},
		imgs: ".video-description img",
		button: [4],
		insertImg: [".video-description", 2],
		customTitle: ".entry-title",
		observerClick: "#wpdp-close",
		category: "nsfw1"
	}, {
		name: "Cosplay Porn",
		reg: /^https?:\/\/cosplayporn\.online\//,
		observerClick: "#wpdp-close",
		category: "ad"
	}, {
		name: "小丁 (Fantasy Factory) Patreon Cosplay Leaks",
		url: {
			h: "www.fantasyfactory.xyz"
		},
		page: () => fn.clp().split("/").length > 2,
		SPA: () => _this.page(),
		observeURL: "nav",
		json: () => fn.sm5().then(() => fn.j(fn.clp() + "?", {
			"body": JSON.stringify({
				"action": "get",
				"items": {
					"href": fn.clp(),
					"what": 1
				}
			}),
			"method": "POST"
		}).then(json => (siteJson = json) && fn.hm())),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (_this.page()) {
				videoSrcArray = siteJson.items.filter(e => fn.isVideo(e.href)).map(e => e.href);
				return siteJson.items.filter(e => fn.isImage(e.href)).map(e => e.href);
			}
			return [];
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? "小丁 (Fantasy Factory) - " + fn.clp().split("/").filter(Boolean).map(e => decodeURIComponent(e)).join(" ") : null,
		category: "nsfw2"
	}, {
		name: "Tokar浵卡 Cosplay",
		url: {
			h: "tokar.fantasyfactory.xyz"
		},
		box: [".container", 2],
		button: [4],
		imgs: async () => {
			fn.sm5();
			let video = fn.ge("a[href^='/video/']");
			if (video) {
				let url = fn.gu("a[href^='/video/']");
				videoSrcArray = await fn.fetchDoc(url).then(dom => fn.gae("video>source", dom).map(e => e.src));
			}
			let viewUrl = fn.gu("//a[text()='View Photos']");
			return fn.iframeVar(viewUrl, "list").then(w => w.list.flat());
		},
		insertImg: ["box", 2],
		customTitle: "h2.text-center",
		downloadVideo: true,
		category: "nsfw1"
	}, {
		name: "蠢沫沫",
		link: "https://yanxiangrong.github.io/chunmomo/",
		reg: /^https?:\/\/yanxiangrong\.github\.io\/chunmomo\/[^\/]+\//,
		imgs: "p img[alt]",
		customTitle: "h1[id]",
		setFancybox: true,
		category: "nsfw1"
	}, {
		name: "HaneAme",
		url: {
			h: "haneame.net",
			p: "/album-"
		},
		imgs: () => fn.getImgA(".entry-content img", ".pagelinks a"),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "a.g1-teaser-prev",
		prev: "a.g1-teaser-next",
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: "Album –"
		}),
		category: "nsfw1"
	}, {
		name: "蠢沫沫",
		url: {
			h: "chunmomo.net",
			p: "/album-"
		},
		imgs: async () => {
			let srcs = fn.getImgSrcArr(".s-post-content img");
			let pages = fn.ge(".all-page");
			if (pages) {
				let [max] = fn.gt(pages).match(/\d+/);
				srcs = await fn.getImg(".s-post-content img", max, 4);
			}
			return srcs.filter(e => !e.includes("rehanman") && !e.includes("thumbnail"));
		},
		button: [4],
		insertImg: [".s-post-content", 2],
		autoDownload: [0],
		next: ".next-page a.pg-arrow",
		prev: ".prev-page a.pg-arrow",
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: "Album –"
		}),
		hide: "[id^='quads-ad'],[id^=block]",
		category: "nsfw1"
	}, {
		name: "Byoru",
		url: {
			h: "byoru.net",
			p: /^\/[^\/]+\/$/,
			e: "h1.entry-title"
		},
		init: () => {
			let eles = fn.gae("//p[contains(text(),'Download')] | //p[contains(text(),'Password')]");
			if (eles.length > 0) {
				let x = fn.ge(".s-post-content");
				for (let e of eles) insertBefore(x, e);
			}
		},
		imgs: () => {
			let pages = fn.ge(".all-page");
			if (pages) {
				let [max] = pages.textContent.match(/\d+/);
				return fn.getImg(".s-post-content img", max, 4);
			} else if (fn.ge(".msacwl-slide>a")) {
				return fn.gae(".msacwl-slide>a").map(a => a.dataset.mfpSrc).sort((a, b) => a.match(/(\d+)\.\w+$/)[1] - b.match(/(\d+)\.\w+$/)[1]);
			} else if (fn.ge("figure.wp-block-image img[data-src]")) {
				return fn.gae("figure.wp-block-image img[data-src]").map(e => e.dataset.src.replace(/-\d+x\d+(\.\w+)/, "$1")).sort((a, b) => {
					try {
						return a.match(/(\d+)\.\w+$/)[1] - b.match(/(\d+)\.\w+$/)[1];
					} catch {
						try {
							return a.match(/\((\d+)\)\.\w+$/)[1] - b.match(/\((\d+)\)\.\w+$/)[1];
						} catch {
							return a;
						}
					}
				});
			} else if (fn.ge(".galeria_img>img")) {
				return fn.gae(".galeria_img>img");
			} else if (fn.ge(".s-post-content img[title][data-lazyloaded]")) {
				return fn.gae(".s-post-content img[title][data-lazyloaded]").map(e => e.src);
			} else if (fn.ge(".s-post-content img")) {
				return fn.gae(".s-post-content img");
			}
			return [];
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a.next-page-link",
		prev: "a.prev-page-link",
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: /Byoru – | \(Cosplay\)/g
		}),
		category: "nsfw1"
	}, {
		name: "4K Beautyful Cosplay Girl",
		host: ["oo4k.com"],
		url: () => fn.checkUrl({
			e: [
				"meta[property='og:title'][content$='4K Beautyful Cosplay Girl']",
				"link[title=JSON]"
			],
			p: "/album/",
		}) && !fn.lp.includes("/category/"),
		init: () => {
			fn.waitEle("._buttons,.post-nav-links").then(() => _unsafeWindow?.jQuery(document)?.off());
		},
		imgs: () => {
			let json_url = fn.gu("link[title=JSON]");
			fn.sm5();
			return fn.j(json_url).then(json => {
				let dom = fn.doc(json.content.rendered);
				return fn.getImgSrcArr([...dom.images]).filter(e => !e.includes("thumbnail"));
			});
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.title(" - 4K Beautyful Cosplay Girl"),
		hide: "._title>._helper",
		category: "nsfw2"
	}, {
		name: "女神社",
		url: {
			h: ["nshens.com", "inewgirl.com", "lovens.shop"]
		},
		page: () => fn.clp(/^\/web\/\d+\/\d+\/\d+\/[^\/]+$/),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			return fn.fetchDoc(fn.clp()).then(async dom => {
				let code = fn.gst("__NUXT__", dom);
				let data = fn.parseCode(code);
				apiCustomTitle = data.data[0].postData.title;
				let url = "/web" + data.routePath;
				let pageTotal = data.data[0].pageTotal;
				if (!isNumber(pageTotal) || pageTotal == 0) {
					pageTotal = 1;
				}
				let links = fn.arr(pageTotal, (v, i) => i == 0 ? url : url + "/" + (i + 1));
				let fetchNum = 0;
				let resArr = links.map((url, i, arr) => fn.fetchDoc(url).then(dom => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
					let code = fn.gst("photoList", dom);
					if (i == 0) {
						let is_v = ["videoid", "videourl"].every(k => code.includes(k));
						if (is_v) {
							console.log("有影片");
							let a = code.indexOf("videoid");
							let b = code.indexOf("}", a);
							let str = code.slice(a - 1, b + 1);
							str = str.replace(/like:[\s\w]+,/i, "")
							let obj = fn.run(str);
							console.log(obj);
							videoSrcArray = [obj.videourl];
						}
					}
					return fn.textToArray(code, "photoList");
				}));
				let photourl = await Promise.all(resArr).then(data => data.flat().map(e => e.photourl));
				if (photourl.length > [...new Set(photourl)].length) setTimeout(() => fn.showMsg("VIP套圖需升級為VIP", 5000), 1200);
				return photourl;
			});
		},
		button: [4],
		insertImg: ["//div[a[div[@class='v-image v-responsive theme--light']]] | //div[@postid]/div[@style]", 2],
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Chottie", //很多都需要VIP,不然只會重複抓到第一頁的圖片
		url: {
			h: ["chottie.com", "chottie.org", "chinesehottie.com", "www.chinesehottie.com"]
		},
		page: () => fn.clp(/^\/blog\/(\w{2}\/)?archives\/\d+$/),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			return fn.fetchDoc(fn.clp()).then(async dom => {
				let code = fn.gst("__NUXT__", dom);
				let data = fn.parseCode(code);
				apiCustomTitle = data.data[0].postData.title;
				let url = "/blog" + data.routePath;
				let pageTotal = data.data[0].pageTotal;
				if (!pageTotal || !isNumber(pageTotal) || pageTotal == 0) {
					pageTotal = 1;
				}
				console.log("pageTotal", pageTotal);
				let links = fn.arr(pageTotal, (v, i) => i == 0 ? url : url + "/" + (i + 1));
				let fetchNum = 0;
				let resArr = links.map((url, i, arr) => {
					return fn.fetchDoc(url).then(dom => {
						fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
						if (i == 0) {
							let code = fn.gst("__NUXT__", dom);
							let is_v = ["video", "poster"].every(k => code.includes(k));
							if (is_v) {
								console.log("有影片");
								let a = code.indexOf("video");
								let b = code.indexOf("{", a);
								let c = code.indexOf("}", b);
								let str = code.slice(b, c + 1);
								let obj = fn.run(str);
								console.log(obj);
								videoSrcArray = [obj.link];
							}
						}
						let code, imgs = [];
						try {
							code = fn.gst("imgList", dom);
							imgs = fn.textToArray(code, "imgList");
						} catch {
							try {
								code = fn.gst("snapshotList", dom);
								imgs = fn.textToArray(code, "snapshotList");
							} catch {}
						}
						return imgs;
					});
				});
				let imgList = await Promise.all(resArr).then(data => data.flat());
				if (imgList.length > [...new Set(imgList)].length) setTimeout(() => fn.showMsg("VIP套圖需升級為VIP", 5000), 1200);
				return imgList;
			});
		},
		button: [4],
		insertImg: ["//div[a[div[@class='v-image v-responsive theme--light']]] | //div[@style][div/video[@poster]]", 2],
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "tu928美女写真网",
		url: {
			h: ["tu928.com"],
			p: ".html"
		},
		box: [".gallery-description,.gallery-full-images", 1],
		imgs: ".wp-block-image img,.gallery-full-images img",
		button: [4],
		insertImg: [
			["box", 0, ".gallery-description,.gallery-full-images"], 2
		],
		customTitle: ".gallery-title",
		hide: "body>div[style]:has(>a>img)",
		category: "nsfw1"
	}, {
		name: "爱死美女图片站",
		host: ["www.24tupian.org", "m.24tupian.org"],
		url: {
			h: "24tupian.org",
			p: /^\/\w+\/\d+\/\d+\/\d+\.html$/,
			e: "img[data-original*='imgs.diercun.com']"
		},
		imgs: () => {
			let pid = fn.gt("#pid");
			let num;
			let is_m = fn.lh.startsWith("m.");
			if (is_m) {
				num = Number(fn.gt(".ser").match(/(\d+)张/)[1]);
			} else {
				num = Number(fn.gt(".mores>a").match(/\d+/)[0]);
			}
			let max = Math.ceil(num / 21);
			fn.sm5();
			let fetchNum = 0;
			let links = fn.arr(max, (v, i) => `/ajax${is_m ? "" : "s"}.aspx?fun=${is_m ? "getmorett" : "getmore"}&id=${pid}&p=${i * 21}`);
			let resArr = links.map(u => fetch(u).then(res => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
				return res.text();
			}));
			return Promise.all(resArr).then(data => {
				let html = data.join("");
				let dom = fn.doc(html);
				let datas = fn.gae("img[data]", dom).map(e => e.getAttribute("data"));
				thumbnailSrcArray = datas.map(data => "https://imgs.diercun.com" + data);
				return datas.map(data => "https://big.diercun.com" + _unsafeWindow.getbig(data));
			});
		},
		button: [4],
		insertImg: [
			[".mores,.kshow", 2], 2
		],
		topButton: true,
		customTitle: ".gtitle1>h1,.ser h1",
		hide: "body>.mask",
		category: "nsfw1"
	}, {
		name: "爱死美女图片鏡像站?",
		url: {
			h: "www.aisimm.com",
			p: ".html",
			e: [".gtps", "#hgg3"]
		},
		imgs: async () => {
			let imgs = fn.gae(".gtps img");
			if (fn.ge("//a[text()='尾页']")) {
				let [, max] = fn.gu("//a[text()='尾页']").match(/_(\d+)\.html$/);
				max = Number(max) + 1;
				let links = fn.arr(max, (v, i) => i == 0 ? fn.url : fn.url.replace(".html", "") + `_${i}.html`);
				imgs = await fn.getEle(links, ".gtps img");
			}
			thumbnailSrcArray = fn.getImgSrcArr(imgs);
			return thumbnailSrcArray.map(url => {
				let i = url.lastIndexOf("/");
				let murl = url.substring(i + 1);
				url = url.replace(murl, murl.substring(1));
				url = url.replace(/imgs?\./, "big.");
				return url;
			});
		},
		button: [4],
		insertImg: [
			["#hgg3", 1], 2
		],
		topButton: true,
		customTitle: ".gtitle1>h1",
		category: "nsfw1"
	}, {
		name: "爱死美女图片M鏡像站?",
		url: {
			h: "m.aisimm.com",
			p: ".html",
			e: [".center1"]
		},
		imgs: async () => {
			let imgs = fn.gae(".center1 img");
			if (fn.ge(".page a[href$=html]")) {
				let url = fn.gau(".page a[href$=html]").at(-1);
				let [, max] = url.match(/_(\d+)\.html$/);
				max = Number(max) + 1;
				let links = fn.arr(max, (v, i) => i == 0 ? fn.url : fn.url.replace(".html", "") + `_${i}.html`);
				imgs = await fn.getEle(links, ".center1 img");
			}
			thumbnailSrcArray = fn.getImgSrcArr(imgs);
			return thumbnailSrcArray.map(url => {
				let i = url.lastIndexOf("/");
				let murl = url.substring(i + 1);
				url = url.replace(murl, murl.substring(1));
				url = url.replace(/imgs?\./, "big.");
				return url;
			});
		},
		button: [4],
		insertImg: [
			[".center1", 2], 2
		],
		topButton: true,
		customTitle: ".ser h1",
		category: "nsfw1"
	}, {
		name: "爱死cos美女图片站",
		url: {
			h: ["www.24cos.org", "24cos.org"],
			p: /^\/\w+\/\d+\.html$/
		},
		imgs: async () => {
			let pages = fn.gau(".page>a");
			let liImgs = fn.gae(".mtp>li");
			if (pages.length > 0 && liImgs.length < 21) {
				await fn.getEle(pages, ".mtp>li", [".mtp", 0]);
			}
			thumbnailSrcArray = fn.gae(".mtp img").map(e => decodeURIComponent(e.src));
			return thumbnailSrcArray.map(url => {
				let i = url.lastIndexOf("/");
				let murl = url.substring(i + 1);
				url = url.replace(murl, murl.substring(1));
				return url;
			});
		},
		button: [4],
		insertImg: [
			[".mtp", 2, ".mtp"], 2
		],
		topButton: true,
		customTitle: ".tmsg>h1",
		css: ".tpmh img{filter:unset!important;}",
		category: "nsfw1"
	}, {
		name: "Huamao wallpaper 花猫壁纸",
		host: ["huamaobizhi.com", "ja.huamaobizhi.com", "en.huamaobizhi.com"],
		url: {
			h: "huamaobizhi.com",
			p: "/mix/",
			e: ".images-card"
		},
		init: async () => {
			let load = fn.ge(".load-more-photos");
			if (load) load.remove();
			await fn.getNP(".images-card", "li.active+li>a", null, ".pagination");
			for (let e of fn.gae(".thumb-nsfw")) e.classList.remove("thumb-nsfw");
		},
		imgs: async () => {
			thumbnailSrcArray = fn.gae(".images-card img").map(e => e.dataset.src ?? e.src);
			fn.clearAllTimer(2);
			fn.sm5();
			let fetchNum = 0;
			const resBlobUrl = (id, max) => fn.b("/normal-download/", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded"
				},
				"body": `wallpaperId=${id}`,
				"method": "POST"
			}).then(blob => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
				return URL.createObjectURL(blob);
			});
			let IDs = fn.gae("span[data-imgid]").map(e => e.dataset.imgid);
			let bigImgsArr = [];
			for (let id of IDs) bigImgsArr.push(await resBlobUrl(id, IDs.length));
			return bigImgsArr;
		},
		button: [4],
		insertImg: [
			["#main", 2], 0
		],
		customTitle: ".title>h1",
		ex: "jpg",
		css: "body{overflow: auto!important}",
		hide: "iframe:not([id])",
		category: "nsfw1"
	}, {
		name: "Huamao wallpaper 花猫壁纸 en.huamaobizhi.com 分類自動翻頁",
		host: ["ja.huamaobizhi.com", "en.huamaobizhi.com"],
		url: {
			h: "huamaobizhi.com",
			p: ["/mixs/", "/tags/", "/artists/", "/people-tags/"]
		},
		autoPager: {
			ele: "//div[@class='row'][div[div[@class='mixs-card']]] | //div[@class='table-responsive table-sm-no-border'] | //div[div[div[@class='thumbnail']]] | //div[@class='tags-wrap']",
			next: ".pagination li.active+li>a",
			re: ".pagination",
			pageNum: ".pagination li.active",
			bF: (dom) => {
				for (let e of fn.gae(".mixs-card-img:not(.lock)", dom)) {
					let url = e.attributes[1].value.replaceAll("'", "");
					e.outerHTML = `<div class="mixs-card-img" data-src="${url}" lazy="loaded" style="background-image: url('${url}');"></div>`;
				}
				for (let e of fn.gae(".thumbnail .img-circle[v-lazy]", dom)) {
					let url = e.getAttribute("v-lazy").replaceAll("'", "");
					e.outerHTML = `<img src="${url}" alt="${e.alt}" class="img-circle" data-src="${url}" lazy="loaded">`;
				}
				for (let e of fn.gae(".tags-item img[v-lazy]", dom)) {
					let url = e.getAttribute("v-lazy").replaceAll("'", "");
					e.outerHTML = `<img src="${url}" alt="${e.alt}" data-src="${url}" lazy="loaded">`;
				}
			}
		},
		openInNewTab: ".mixs-card-content>a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "猫猫网盘",
		url: {
			h: ["catcat.cloud"]
		},
		page: () => fn.clp().split("/").length > 2,
		SPA: () => _this.page(),
		observeURL: "nav",
		imgs: () => fn.getAList(),
		customTitle: () => fn.dt({
			d: [" | 猫猫网盘"]
		}),
		downloadVideo: true,
		category: "nsfw1"
	}, {
		name: "柚子肉 微博Coser",
		link: "https://youzirou.org/weibo/users",
		url: {
			h: ["youzirou.org"]
		},
		page: () => fn.clp(/^\/weibo\/user\/\d+(\/pics)?$/),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			let id = fn.clp().split("/").at(3);
			id = Number(id);
			let p = [...doc.querySelectorAll("main p")].find(p => p.innerText == "微博数").previousElementSibling;
			let postNum = Number(p.innerText);
			let body = {
				"operationName": "WeiboTweets",
				"variables": {
					"pagination": {
						"page": 1,
						"pageSize": postNum
					},
					"query": {
						"userId": id
					}
				},
				"query": "query WeiboTweets($pagination: Pagination!, $query: WeiboTweetsFilterQuery) {\n  weiboTweets(pagination: $pagination, query: $query) {\n    data {\n      ...WeiboTweetFragment\n      __typename\n    }\n    pager {\n      page\n      pageSize\n      total\n      __typename\n    }\n    __typename\n  }\n}\n\nfragment WeiboTweetFragment on WeiboTweet {\n  id\n  content\n  isChoice\n  isLiked\n  tweetCreateAt\n  pics {\n    ...WeiboPicFragment\n    __typename\n  }\n  user {\n    ...WeiboUserFragment\n    __typename\n  }\n  __typename\n}\n\nfragment WeiboPicFragment on WeiboPic {\n  id\n  name\n  ossKey\n  imageInfo {\n    ...WeiboImageInfoFragment\n    __typename\n  }\n  __typename\n}\n\nfragment WeiboImageInfoFragment on WeiboPicImageInfo {\n  width\n  height\n  __typename\n}\n\nfragment WeiboUserFragment on WeiboUser {\n  id\n  name\n  info\n  followersCount\n  creatorId\n  __typename\n}"
			};
			return fn.j("/graphql", {
				"headers": {
					"content-type": "application/json"
				},
				"body": JSON.stringify(body),
				"method": "POST"
			}).then(json => json.data.weiboTweets.data.map(e => e.pics).flat().map(e => "https://youzirou.org/cdn/weibo/large/" + e.name));
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? "微博" + fn.dt({
			s: "main p"
		}, doc) : null,
		category: "nsfw1"
	}, {
		name: "新美图录",
		url: {
			h: "www.xinmeitulu.com",
			p: "/photo/"
		},
		imgs: "img[data-original]",
		button: [4],
		insertImg: [".text-center", 2],
		customTitle: "h1.h3",
		category: "nsfw1"
	}, {
		name: "美图录",
		url: {
			h: ["meitulu.me"],
			p: "/item/",
			e: ".mb-4>img[alt]"
		},
		imgs: () => fn.getImg(".mb-4>img[alt]", fn.gt(".pagination>li:last-child", 2), 9),
		button: [4],
		insertImg: [".mb-4", 1],
		customTitle: ".top-title",
		category: "nsfw1"
	}, {
		name: "秀窝/RMM吧/赞MM格式",
		url: {
			e: ["#showimg img", "//p[contains(text(),'图片数量') or contains(text(),'圖片數量')]"],
			p: ".html"
		},
		init: () => fn.clearAllTimer(),
		imgs: () => fn.getImgO("#showimg img", fn.gt("//p[contains(text(),'图片数量') or contains(text(),'圖片數量')]").match(/\d+/)[0], 9),
		button: [4],
		insertImg: ["#showimg", 2],
		customTitle: ".weizhi h1",
		referer: "",
		mcss: ".content img{max-width:100%!important}",
		category: "nsfw1"
	}, {
		name: "妹妹图",
		url: {
			h: ["mm.tvv.tw"],
			p: "/archives/"
		},
		imgs: ".img-responsive",
		button: [4],
		insertImg: ["//p[img]", 2],
		customTitle: ".blog-details-headline",
		category: "nsfw1"
	}, {
		name: "Mei101",
		host: ["www.mei101.com", "m.mei101.com", "www.mei101.net", "m.mei101.net"],
		url: {
			st: "var yaomei",
			e: "#image_div",
			p: ".html",
		},
		imgs: async () => {
			let {
				PID,
				post_url,
				max_page
			} = _unsafeWindow.yaomei;
			let params = fn.cp({
				action: "mei_imageall",
				type: "all",
				lazy: "false",
				post_id: PID,
				post_url
			});
			fn.sm5();
			let images = await fn.fetchDoc("/wp-admin/admin-ajax.php", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": params,
				"method": "POST"
			}).then(dom => [...dom.images]);
			if (images.length) return images;
			let url = post_url.replace(".html", "");
			let links = fn.arr(max_page, (v, i) => i == 0 ? post_url : `${url}/${i + 1}.html`);
			return fn.getImgA("#image_div img", links);
		},
		button: [4],
		insertImg: ["#content", 2],
		customTitle: ".item_title>h1",
		hide: ".single-views,.ad_xiangguan_up,.ad_dixuan",
		category: "nsfw1"
	}, {
		name: "小姐姐么",
		url: {
			h: ["xiaojiejie.me"],
			st: "chenxing"
		},
		init: () => {
			if (fn.lh.includes("mmtuji")) {
				_unsafeWindow.fuckyou = null;
				_unsafeWindow.ck = null;
				_unsafeWindow.hehe = null;
				_unsafeWindow.comprehensiveCheck = null;
				_unsafeWindow.onWindowSizeChange = null;
				_unsafeWindow.onresize = null;
				fn.clearAllTimer(3);
			}
		},
		imgs: () => {
			fn.sm5();
			let code = fn.gst("chenxing");
			let chenxing = fn.textToObject(code, "chenxing", 2);
			return fn.fetchDoc("/wp-admin/admin-ajax.php", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": `action=chenxing_imageall&type=all&post_id=${chenxing.PID}`,
				"method": "POST",
			}).then(dom => {
				tempEles = [...dom.getElementsByTagName("p")];
				return [...dom.images];
			});
		},
		button: [4],
		insertImg: ["#content", 2],
		insertImgAF: (_, bar) => {
			bar.before(...tempEles);
			fn.gm_run("$(document).off()");
		},
		customTitle: () => fn.dt({
			d: [
				" – 小姐姐",
				/(\d+月\d+打赏群(自购)?资源)/
			]
		}),
		css: ".content_left>p{margin:0}",
		hide: ".affs",
		category: "nsfw1"
	}, {
		name: "美女视界",
		host: ["www.beapic.com"],
		url: {
			t: "美女视界",
			p: /^\/\d+\.html$/,
			e: "#image_div",
			ee: "//a[@rel='category tag'][text()='演出视频']"
		},
		imgs: () => fn.getImg("#image_div img", fn.gt("//a[@class='page-numbers prev'][@title='下一页']//preceding-sibling::a[1]"), 9, [/\?x-oss-process.+$/, ""]),
		button: [4],
		insertImg: ["#content", 2],
		insertImgAF: () => fn.run("$(document).off()"),
		customTitle: () => fn.title(" – 美女视界"),
		category: "nsfw1"
	}, {
		name: "秀人图吧",
		url: {
			h: "www.502x.com",
			p: /^\/\w+\/\d+\.html/
		},
		imgs: () => fn.getImgA("#content img", [fn.gu(".post_au>a")]),
		button: [4],
		insertImg: ["#image_div", 2],
		customTitle: ".item_title>h1",
		css: ".image_div a img{cursor:unset}",
		hide: ".affs",
		category: "nsfw1"
	}, {
		name: "FoamGirl",
		url: {
			h: "foamgirl.net",
			p: ".html",
			e: "a.imageclick-imgbox"
		},
		imgs: () => fn.getImg("a.imageclick-imgbox", Number(fn.gt(".mbx-nav-right")?.match(/\d+/g)?.at(-1)) || 1, 9),
		button: [4],
		insertImg: [
			["#image_div>*:last-child", 1, "#image_div br,a.imageclick-imgbox"], 2
		],
		customTitle: () => fn.dt({
			s: ".item_title>h1",
			d: /\n/g
		}),
		hide: ".affs",
		category: "nsfw2"
	}, {
		name: "COSPLAY Girl 18+",
		host: ["cosplay.girl18.net", "xiuren.girl18.net", "bobosocks.girl18.net", "imiss.girl18.net", "cosplay.girl18.net"],
		url: {
			h: ".girl18.net"
		},
		imgs: () => fn.getImgSrcArr("#image_div img").map(src => src.replace(/\?.+$/, "")),
		button: [4],
		insertImg: ["#image_div", 2],
		customTitle: ".item_title",
		hide: ".item_images_info",
		category: "nsfw2"
	}, {
		name: "Girl 18+",
		host: ["girl18.net"],
		url: {
			h: "girl18"
		},
		imgs: () => fn.getImgSrcArr("#content img").map(src => src.replace(/\?.+$/, "")),
		button: [4],
		insertImg: ["#content", 2],
		customTitle: ".item_title",
		hide: ".item_images_info",
		category: "nsfw1"
	}, {
		name: "18成人貼圖",
		host: ["www.sexphotos.cc"],
		reg: /^https?:\/\/www\.sexphotos\.cc\/\w+\/\d+\.html$/,
		init: () => fn.waitEle(".article-body>img").then(e => fn.createImgBox(e, 1)),
		imgs: ".article-body>img",
		button: [4],
		insertImg: [
			["box", 0, ".article-body>img"], 2
		],
		autoDownload: [0],
		next: "a.entry-page-prev[href$=html]",
		prev: "a.entry-page-next[href$=html]",
		customTitle: ".detail-title",
		category: "nsfw2"
	}, {
		name: "福利社",
		host: ["www.2kl.net", "www.meinvtu.xyz", "www.beautifuls.xyz", "www.exciteds.xyz", "www.47o.net", "www.74p.net", "www.08g.net", "www.79011.net", "www.59669.net"],
		url: {
			e: ["#body-header-top", ".logo-pc", ".logo-moible"],
			p: "/meitu/",
			st: "chenxing"
		},
		init: () => fn.addMutationObserver(() => fn.run("jQuery(document).off()")),
		box: ["#image_div", 1],
		imgs: () => fn.sm5().then(() => fn.fetchDoc("/ajax/", {
			"headers": {
				"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
				"x-requested-with": "XMLHttpRequest"
			},
			"body": `type=all&id=${_unsafeWindow.chenxing.PID}`,
			"method": "POST",
		}).then(dom => {
			tempEles = [...dom.getElementsByTagName("p")];
			return [...dom.images];
		})),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: (_, bar) => {
			bar.before(...tempEles);
			fn.hideEle("#image_div,#image_div_all");
		},
		customTitle: ".item_title>h1",
		hide: ".img-box,#installContainer,.mbx-nav-right",
		category: "nsfw1"
	}, {
		name: "福利社",
		url: {
			e: ["#body-header-top", ".logo-pc", ".logo-moible"],
			p: "/chapter/"
		},
		imgs: ".image-stack img",
		button: [4],
		insertImg: [".image-stack", 2],
		autoDownload: [0],
		next: ".nav-links .current+a",
		prev: "//div[@class='nav-links page_imges']/span[@class='page-numbers current']/preceding-sibling::a[1]",
		chapters: {
			url: ".header-mbx-nav a",
			urlIndex: 2,
			target: ".bk+ul a"
		},
		customTitle: ".item_title>h1",
		hide: "#installContainer",
		category: "hcomic"
	}, {
		name: "Coser Lab",
		url: {
			h: ["coserlab.io"],
			p: "/archives/",
			ee: ".card-body .error-empty,.post-hide-content"
		},
		imgs: () => {
			fn.showMsg("fn.xhrHEA(check)...", 0);
			let xhrNum = 0;
			return fn.gau("a.glightbox").map(u => u.replace("-scaled", "")).map(async (src, i, arr) => {
				await delay(100 * i);
				let res = await fn.xhrHEAD(src);
				fn.showMsg(`fn.xhrHEAD(${xhrNum+=1}/${arr.length})`, 0);
				let status = res.status;
				return status == 404 ? src.replace(/(\.[a-z]+)$/i, "-scaled$1") : src;
			});
		},
		thums: "a.glightbox img",
		button: [4],
		insertImg: [
			[".masonry-list", 2, ".masonry-list"], 2
		],
		customTitle: "span.current,.card-body h1",
		category: "nsfw2"
	}, {
		name: "COSv",
		host: ["cosfan.cc", "www.kawax.org"],
		url: {
			h: ["www.cosv.cc", "cosv.cc", "www.kawax.org", "kawax.org"]
		},
		page: () => fn.clp("/article/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => fn.getImgSrcset(".grid .rounded-md img", doc),
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			s: "h1.font-bold"
		}, doc),
		category: "nsfw2"
	}, {
		name: "Erohere",
		url: {
			h: "my.erohere.eu",
			p: "/album/"
		},
		box: [".simple-gallery", 1],
		imgs: () => fn.getImg(".simple-gallery-item img", fn.gt(".pagination-numbers a.pagination-number:last-child") || 1, 4),
		button: [4],
		insertImg: [
			["box", 0, ".simple-gallery,.pagination"], 2
		],
		customTitle: ".section-title",
		category: "nsfw1"
	}, {
		name: "Mega Gallery",
		url: {
			h: "ecy8.com"
		},
		imgs: ".wp-block-gallery img",
		button: [4],
		insertImg: [".wp-block-gallery", 2],
		autoDownload: [0],
		next: "a[rel=prev]",
		prev: "a[rel=next]",
		customTitle: ".wp-block-post-title",
		category: "nsfw1"
	}, {
		name: "AIHGAME",
		url: {
			h: ["aihgirl.com"],
			p: ["/manga/detail/", "/gallery/detail/"]
		},
		imgs: ".gallery-images img,.manga-images img",
		button: [4],
		insertImg: [".gallery-images,.manga-images", 2],
		customTitle: ".gallery-title,.manga-title",
		category: "hcomic"
	}, {
		name: "孔雀海/懒人看图",
		host: ["www.kongquehai.top", "www.lazymanpic.net"],
		reg: [
			/^https?:\/\/(www\.)?kongquehai\.top\/\w+\/\w+\/\w+\.html(\?btwaf=\d+)?$/i,
			/^https?:\/\/(www\.)?lazymanpic\.net\/[a-z]{2,3}\/\w+(\?btwaf=\d+)?$/
		],
		imgs: () => fn.getNP(".m-list-content img", "//a[text()='下一页'][@class='next']", null, ".link_pages").then(() => fn.gae(".m-list-content img")),
		button: [4],
		insertImg: [".m-list-content", 2],
		autoDownload: [0],
		next: ".sxpage_r>a",
		prev: ".sxpage_l>a",
		customTitle: () => fn.dt({
			s: ".m-list-tools>h2",
			d: [
				/\(\d\)/,
				/\[\d+[\s\.\+\w-\/]+\].*/,
				/全网首发|免费下载|无损图包下载|未删减版|无删减图包/g
			]
		}),
		category: "nsfw1"
	}, {
		name: "尤物秀",
		host: ["www.youwushow.net"],
		reg: /^https?:\/\/(www\.)?youwushow\.net\/pic\/\w+\.html(\?btwaf=\d+)?$/,
		imgs: () => fn.getNP(".entry-content>*:not(.page-links)", "span.current+a", null, ".page-links").then(() => fn.gae(".entry-content img")),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "a.prev-link",
		prev: "a.next-link",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: [
				/\(\d\)/,
				/\[\d+[\s\.\+\w-\/]+\].*/,
				/全网首发|免费下载|无损图包下载|未删减版|无删减图包/g
			]
		}),
		category: "nsfw1"
	}, {
		name: "比思在線圖庫",
		host: ["bisipic.xyz", "bisipic.online"],
		url: {
			h: /bisipic\./,
			p: "/thread-",
			e: "img[zoomfile]"
		},
		imgs: () => fn.gae("img[zoomfile]").map(e => fn.lo + "/" + fn.attr(e, "zoomfile")),
		button: [4, 2],
		insertImg: ["[id^=postmessage]", 2],
		customTitle: () => fn.dt({
			t: fn.ge("meta[name=keywords]").content,
			d: /【\d+P】.*$/
		}),
		category: "nsfw1"
	}, {
		name: "米兔妹妹",
		host: ["www.loxiu.com"],
		url: {
			t: "米兔妹妹",
			p: "/post/"
		},
		imgs: () => fn.getImg(".info-imtg-box>img[alt]", fn.gt(".pagebar>*:last-child", 3)),
		button: [4],
		insertImg: ["div:has(>.info-imtg-box)", 2],
		autoDownload: [0],
		next: "//a[p[text()='上一篇']]",
		prev: "//a[p[text()='下一篇']]",
		customTitle: ".info-title>h1",
		category: "nsfw1"
	}, {
		name: "遛无写真格式",
		url: {
			h: [
				"www.0xzn.com",
				"www.096d.com",
				"www.0niz.com",
				"www.1nlm.com",
				"www.1plq.com",
				"www.1tu5.com",
				"www.1vtr.com",
				"www.3pxa.com",
				"www.3tck.com",
				"www.4tck.com",
				"www.54k5.com",
				"www.5njs.com",
				"www.5pwc.com",
				"www.6evu.com",
				"www.6kpo.com",
				"www.6tck.com",
				"www.6vtr.com",
				"www.7k1a.com",
				"www.7mqk.com",
				"www.7tck.com",
				"www.7u8t.com",
				"www.09kt.com",
				"www.c0h.net",
				"www.df10.net",
				"www.eshh.net",
				"www.game1313.net",
				"www.te2zn.com",
				"www.tmm123.vip",
				"www.wangblog.net",
				"www.wjstbs.net",
				"www.wsqap.com",
				"www.wxytw.com",
				"www.zhaixiaonan.com",
				"www.vansankan.net",
				"d2nx.com"
			],
			p: /^\/\d+\.html$/,
			e: "#post_content img,.article-content img,.entry-content img",
			ee: "//a[@rel='category tag'][contains(text(),'人物简历') or contains(text(),'宅男科技') or contains(text(),'时尚玩酷') or contains(text(),'身边事') or contains(text(),'追星一族') or contains(text(),'网红头条') or contains(text(),'大众娱乐') or contains(text(),'生活热点') or contains(text(),'影评剧透') or contains(text(),'娱乐时尚') or contains(text(),'吃喝玩乐') or contains(text(),'体育') or contains(text(),'亲子宠物') or contains(text(),'番号大全') or contains(text(),'番号推荐') or contains(text(),'最新番号') or contains(text(),'素人番号')]"
		},
		imgs: () => fn.getImgA("#post_content img,.article-content img,.entry-content img", ".pagelist a,.pagination a,.article-paging a"),
		button: [4],
		insertImg: ["#post_content,.article-content,.entry-content", 2],
		autoDownload: [0],
		next: "a[rel=prev],.article-nav-prev a",
		prev: "a[rel=next],.article-nav-next a",
		customTitle: () => fn.dt({
			s: "h1",
			d: [
				/无圣光.+$/,
				/无水印.+$/,
				/无删减.+$/,
				/高品质.+$/,
				/超高清.+$/,
			]
		}),
		css: ".article_container{padding:10px 0px!important}#post_content{padding:0px!important}",
		mcss: ".container{max-width:100% !important}",
		category: "nsfw1"
	}, {
		name: "原创妹子图/尤物私房图/极品美女图/免费私房图/私房网红图/尤物妹妹图",
		//所有域名在環境變數urltz
		host: ["www.ywsft.com", "www.jpmnt.com", "www.mfsft.com", "www.sfwht.com", "www.ywmmt.com"],
		url: {
			e: [".b", "#picg", ".pagelist"],
			p: /^\/[a-z]+\/[a-z]+\/\d+\/\d+\.html$/
		},
		init: () => {
			for (let a of fn.gae(".b a")) a.removeAttribute("target");
			for (let a of fn.gae("#picg a")) a.outerHTML = a.innerHTML;
			fn.remove("iframe", 2000);
		},
		imgs: () => {
			let max = 1;
			let pages = fn.gae(".pagelist a");
			if (pages.length) max = pages.map(a => Number(a.text)).filter(Boolean).sort((a, b) => a - b).at(-1);
			return fn.getImg("#picg img[alt]", max, 9);
		},
		button: [4],
		insertImg: ["#picg", 2],
		autoDownload: [0],
		next: "//div[@class='b' and contains(text(),'下一')]/a",
		prev: "//div[@class='b' and contains(text(),'上一')]/a",
		customTitle: () => fn.dt({
			s: "h1",
			d: [
				/第\d+页|^- /g,
				/[\s-]+P\.\d/g,
				/:/g
			]
		}),
		fancybox: {
			v: 3,
			insertLibrarys: 1
		},
		css: "#imgc img{margin:0px auto !important}#picg{max-width:1110px !important;margin:0 auto}#picg img:hover{transform:none !important}#picg img{filter:blur(0px) !important}",
		hide: "body>br,body>*[id]:has(*[class*=adsby]),#apic,#bzs7,.interestline+center,center+#pic,#qpai,#d4a,#divone,#xzpap1,#divpsgx,#bdivpx,#divfts,#divftsp,#app+div,#xzappsq,div.bg-text,#divpsg,#divStayTopright2,#bdssy,#qrcode2>.erweima-text,#qrcode2>center,#qrcode2>center+div,#d5tig,#pcapicb,#google_translate_element,#d5a>*:not([id]):not([class]),.slide>a+div,.slide>img+div,#xtjpp,#divftst,.interestline+.nav~span,.interestline+.nav~br",
		category: "nsfw2"
	}, {
		name: "美女私房照/看妹图",
		host: ["www.sfjpg.com", "www.sfmm.cc", "www.kmeitu.cc", "kanmeitu.net"],
		url: {
			t: ["美女私房照", "看妹图", "看妹圖"],
			p: /^\/\w+\/\d+\.html$/,
			e: "#picg img"
		},
		init: () => {
			for (let a of fn.gae(".b a")) a.removeAttribute("target");
			for (let a of fn.gae("#picg a")) a.outerHTML = a.innerHTML;
		},
		imgs: () => fn.getImgO("#picg img", fn.gt(".pagelist span,.pagelist a[title=Page]").match(/\/(\d+)/).at(1), 9, null, 0, ".page .pagelist"),
		button: [4],
		insertImg: ["#picg", 2],
		autoDownload: [0],
		next: "//div[@class='b' and contains(text(),'上一')]/a",
		prev: "//div[@class='b' and contains(text(),'下一')]/a",
		customTitle: "h1",
		topButton: true,
		fancybox: {
			v: 3,
			insertLibrarys: 1
		},
		css: "#imgc img{margin:0px auto !important}#picg{max-width:1110px !important;margin:0 auto}#picg img:hover{transform:none !important}#picg img{filter:blur(0px) !important}",
		hide: "body>br,.interestline+center,center+#pic,#xzpap1,#divpsgx,#bdivpx,#divfts,#divftsp,#app+div,#xzappsq,div.bg-text,#divpsg,#divStayTopright2,#bdssy,#qrcode2>center,#d5tig,#pcapicb,#pcapic,#google_translate_element,#d5a>*:not([id]):not([class]),union[id]",
		category: "nsfw2"
	}, {
		name: "六色美图",
		url: {
			h: "www.06se.com",
			p: /^\/\d+\.html/
		},
		imgs: ".article-content img",
		button: [4],
		insertImg: [
			[".wp-posts-content", 2, ".wp-posts-content"], 2
		],
		autoDownload: [0],
		next: "//a[p[text()='上一篇']]",
		prev: "//a[p[text()='下一篇']]",
		customTitle: ".article-title",
		css: ".modal-open{overflow:unset!important;}",
		hide: "#modal-system-notice,.container.fluid-widget,#zibpay_modal,#mini-imgbox,.modal-backdrop",
		category: "nsfw1"
	}, {
		name: "秀图湾",
		host: ["okxx.de", "xiusz.de", "xiusz.com", "aiyes.de", "isxp.de"],
		url: {
			e: "//span[text()='xiusz.de']",
			p: "/thread"
		},
		init: () => fn.clearAllTimer(),
		box: [".pic-group", 1],
		imgs: () => {
			let pages = fn.ge(".pagination");
			if (pages) {
				let [max] = fn.gt(".pagination li:last-child", 2).match(/\d+/);
				let link = fn.gu(".pagination a");
				let url = link.replace(/-\d\.htm$/, "-");
				let links = fn.arr(max, (v, i) => url + `${i + 1}.htm`);
				return fn.getImgA(".pic-group img", links);
			}
			return fn.gae(".pic-group img");
		},
		button: [4],
		insertImg: [
			["box", 0, ".pic-group,.pagination"], 2
		],
		customTitle: ".media-body h4",
		category: "nsfw1"
	}, {
		name: "丝袜客",
		url: {
			h: "siwake.cc",
			p: "/post/"
		},
		init: () => (tempEles = fn.gae(".Content>.newfujian")),
		imgs: ".Content>a",
		button: [4],
		insertImg: [".Content", 2],
		endColor: "white",
		insertImgAF: (_, bar) => bar.before(...tempEles),
		autoDownload: [0],
		next: "a.fas",
		prev: "a.next.fas",
		customTitle: ".title",
		category: "nsfw1"
	}, {
		name: "丝袜客 分類自動翻頁",
		reg: /^https?:\/\/siwake\.cc\//,
		autoPager: {
			ele: "#main.gallery",
			observer: "#main.gallery>.thumb",
			next: "a.next.fas",
			re: ".pagelist"
		},
		openInNewTab: "#main.gallery a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "爱妹子",
		url: {
			h: ["xx.knit.bid"],
			p: /^\/([\w-]+\/)?article\/\d+\//i,
			e: ".item-image img"
		},
		box: [".image-container"],
		imgs: () => {
			if (fn.ge("li.next-page")) {
				let max = fn.gt("li.next-page", 2);
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `page/${i + 1}/`);
				return fn.getImgA(".item-image img", links);
			}
			return fn.gae(".item-image img");
		},
		button: [4],
		insertImg: [
			["box", 0, ".item-image,.loading-indicator,.pagination-nav"], 2
		],
		insertImgAF: () => setTimeout(() => fn.clearAllTimer(2), 1500),
		customTitle: ".focusbox-title",
		css: "a{white-space:unset!important}",
		hide: ".clickadu-container",
		category: "nsfw1"
	}, {
		name: "爱妹子",
		url: {
			h: ["mm.187187.xyz"],
			p: /^\/([\w-]+\/)?article\/\d+\//i,
			e: "#img-box img"
		},
		imgs: "#img-box img",
		button: [4],
		insertImg: ["#img-box", 2],
		customTitle: ".focusbox-title",
		css: "a{white-space:unset!important}",
		category: "nsfw1"
	}, {
		name: "爱妹子 反反廣告提示",
		url: {
			h: ["xx.knit.bid", "mm.187187.xyz"]
		},
		init: () => setTimeout(() => fn.clearAllTimer(2), 1000),
		openInNewTab: ".excerpts-wrapper a:not([target=_blank])",
		category: "ad"
	}, {
		name: "美女写真",
		url: {
			h: "portrait.knit.bid",
			p: /^\/\w+\/\d+$/,
			e: ".container>.container>img"
		},
		imgs: () => {
			let max = fn.gt("//li[a[text()='下页']]", 2);
			let links = fn.arr(max, (v, i) => siteUrl + "?page=" + (i + 1));
			return fn.getImgA(".container>.container>img", links, 300);
		},
		button: [4],
		insertImg: [
			[".container>.container>nav", 2, "nav[aria-label=pagination],.img-fluid"], 2
		],
		customTitle: ".container h1",
		category: "nsfw1"
	}, {
		name: "美图网",
		url: {
			h: "meitu.knit.bid",
			p: /^\/(beauty|handsome)\/[^\/]+$/,
			e: ".details_item>img"
		},
		imgs: () => {
			let [max] = fn.gau("a[href*=gotoPage]").at(-2).match(/\d+/);
			let links = fn.arr(max, (v, i) => siteUrl + "?page=" + (i + 1));
			return fn.getImgA(".details_item>img", links, 300);
		},
		button: [4],
		insertImg: [".details_item", 2],
		customTitle: () => fn.dt({
			s: ".text-center>h1",
			r: [
				["|", "-"]
			]
		}),
		category: "nsfw1"
	}, {
		name: "美图网",
		url: {
			h: "meitu.knit.bid",
			p: /^\/(news|street)\/\d+$/
		},
		imgs: ".news-body img",
		customTitle: () => fn.dt({
			s: ".text-center>h1",
			r: [
				["|", "-"]
			]
		}),
		category: "nsfw1"
	}, {
		name: "萌图社",
		url: {
			h: ["www.446m.com", "446m.com"],
			p: /^\/index\.php\/\w+\/\d+\.html$/
		},
		imgs: "span.post-item",
		button: [4],
		insertImg: [".post-content", 2],
		customTitle: () => fn.title(" - 萌图社"),
		category: "nsfw1"
	}, {
		name: "萌萝社",
		url: {
			h: ["www.042l.com", "042l.com"],
			e: "//a[text()='显示全文']"
		},
		init: () => tempEles.push(fn.ge(".tags")),
		imgs: () => fn.fetchDoc(fn.gu("//a[text()='显示全文']")).then(dom => fn.gae("#lightgallery .boximg", dom)),
		button: [4],
		insertImg: ["#lightgallery", 2],
		insertImgAF: (parent) => parent.append(...tempEles),
		autoDownload: [0],
		next: "//a[text()='上一篇']",
		prev: "//a[text()='下一篇']",
		customTitle: ".focusbox-title",
		category: "nsfw1"
	}, {
		name: "日式JK",
		url: {
			h: "www.jk.rs",
			p: ".html",
			ee: ".post-hide-content"
		},
		imgs: "a.glightbox",
		button: [4],
		insertImg: [
			[".masonry-list", 2, ".masonry-list"], 2
		],
		insertImgAF: () => fn.css("#masonry{position:unset!important;height:unset!important}"),
		customTitle: () => fn.title(" – 日式JK"),
		referer: "",
		category: "nsfw1"
	}, {
		name: "微博美女",
		url: {
			h: "weibomn.com",
			p: "/girl"
		},
		box: [".photos", 1],
		imgs: ".photos img",
		button: [4],
		insertImg: [
			["box", 0, ".photos"], 2
		],
		customTitle: () => "微博美女 - " + fn.gt(".post-content p"),
		category: "nsfw1"
	}, {
		name: "妹妹美",
		host: ["mmm.red"],
		reg: /^https?:\/\/(www\.)?mmm\.red\/art\/\d+$/,
		exclude: ".login-tip",
		imgs: "div[data-fancybox][data-src]",
		autoDownload: [0],
		next: "//div[text()='上一篇']/following-sibling::a",
		prev: "//div[text()='下一篇']/following-sibling::a",
		customTitle: ".post-info-text",
		category: "nsfw1"
	}, {
		name: "胴体的诱惑/美图吧",
		host: ["dongti.blog.2nt.com", "meituba.blog.2nt.com"],
		reg: [
			/^https?:\/\/dongti\.blog\.2nt\.com\/blog-entry-\d+.html$/,
			/^https?:\/\/meituba\.blog\.2nt\.com\/blog-entry-\d+.html$/
		],
		imgs: ".inner-contents img",
		button: [4],
		insertImg: [".inner-contents", 2],
		autoDownload: [0],
		next: "//a[div[@class='pager_entry-box next-justify']]",
		prev: "//a[div[@class='pager_entry-image-prev']]",
		customTitle: "#entry-title",
		category: "nsfw1"
	}, {
		name: "秀色女神",
		url: {
			h: ["www.xsnvshen.co", "www.xsnvshen.com"],
			p: "/album/",
			e: "//li[img[@id='bigImg']]"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("img[id^='imglist'][data-original]");
			return thumbnailSrcArray.map(e => e.replace("thumb_600x900/", ""));
		},
		button: [4],
		insertImg: ["//li[img[@id='bigImg']]", 2],
		customTitle: "h1",
		css: ".workShow li img{max-width:100%!important}",
		referer: "url",
		category: "nsfw1"
	}, {
		name: "秀色女神M",
		url: {
			h: ["m.xsnvshen.co", "m.xsnvshen.com"],
			p: "/album/",
			e: "#arcbox"
		},
		imgs: async () => {
			let [max] = fn.gt(".pg_current").match(/\d+$/);
			thumbnailSrcArray = await fn.getImg("#arcbox img.lazy", max, 6);
			return thumbnailSrcArray.map(e => e.replace("thumb_600x900/", ""));
		},
		button: [4],
		insertImg: [
			["#arcbox", 0, "//div[@id='arcbox']/p[img]"], 2
		],
		customTitle: "h1>a",
		css: "#arcbox img{margin:unset;min-width:unset}",
		referer: "url",
		category: "nsfw1"
	}, {
		name: "秀色女神news",
		url: {
			h: ["www.xsnvshen.co", "www.xsnvshen.com", "m.xsnvshen.co", "m.xsnvshen.com"],
			p: "/news/"
		},
		imgs: "#arcbox img",
		button: [4],
		insertImg: [
			["#arcbox>*:first-child", 1, "//p[img]"], 2
		],
		customTitle: "h1",
		css: "#arcbox img{margin:unset;min-width:unset}",
		referer: "url",
		category: "nsfw1"
	}, {
		name: "秀色女神OORPG",
		url: {
			h: "oorpg.com",
			e: ["#masonry img", "h1.post-title"]
		},
		imgs: () => {
			let getNum = src => Number(src.split("/").at(-1).match(/\d+/));
			return fn.getImgSrcArr("#masonry img").filter(e => !e.includes("logo_girl.png")).sort((a, b) => getNum(a) - getNum(b));
		},
		button: [4],
		insertImg: ["#masonry", 2],
		customTitle: () => fn.dt({
			s: "h1.post-title",
			d: "-[秀人套图]"
		}),
		category: "nsfw1"
	}, {
		name: "优图坊",
		url: {
			h: "www.anfn.cc",
			p: /^\/\d+\.html$/
		},
		imgs: "img[bigimg]",
		button: [4],
		insertImg: [".picshow", 2],
		customTitle: ".piccontext h2",
		category: "nsfw1"
	}, {
		name: "HotAsiaGirl分頁模式",
		url: {
			h: "hotgirl.asia"
		},
		box: [".galeria_img", 1],
		imgs: () => fn.getImgA(".galeria_img>img", ".pagination a[href]"),
		button: [4],
		insertImg: [
			["box", 0, ".galeria_img,#pagination"], 2
		],
		customTitle: ".mvic-desc h3",
		category: "nsfw2"
	}, {
		name: "HotAsiaGirl幻燈片模式",
		url: {
			h: "hotgirl.asia"
		},
		box: ["#carouselImageIndicators", 2],
		imgs: "#carouselImageIndicators img",
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".mvic-desc h3",
		category: "nsfw2"
	}, {
		name: "HotGirl World",
		url: {
			h: ["www.hotgirl2024.com", "hotgirl.world"],
			P: "/g/"
		},
		init: () => {
			for (let e of fn.gae(".blur-image")) e.classList.remove("blur-image");
		},
		imgs: () => fn.getImg(".article__image-list img", fn.gt(".pagination__total") || 1),
		button: [4],
		insertImg: [".article__image-list", 2],
		customTitle: ".article-header__title",
		category: "nsfw1"
	}, {
		name: "HotGirl World 分類自動翻頁",
		reg: [
			/^https?:\/\/(www\.hotgirl2024\.com|hotgirl\.world)\/(\?page=\d+)?$/,
			/^https?:\/\/(www\.hotgirl2024\.com|hotgirl\.world)\/(category|agency|tag)\/\d+\.html\/(\?page=\d+)?$/,
			/^https?:\/\/(www\.hotgirl2024\.com|hotgirl\.world)\/search\.html\/\?(page=\d+&)?q=/
		],
		init: () => {
			for (let e of fn.gae(".blur-image")) e.classList.remove("blur-image");
		},
		autoPager: {
			ele: ".articles-grid",
			next: ".pagination__item--active+a",
			re: ".pagination",
			lazySrc: "img[data-src]",
			pageNum: ".pagination__item--active",
			aF: () => _this.init(),
			bottom: screen.height * 2
		},
		openInNewTab: ".articles-grid a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "MaoJiuJiu/SkyBird/TightImg/SexCity",
		url: {
			h: ["www.maojiujiu.com", "www.skybirdx.com", "www.tightimg.com", "www.sexscity.com"],
			p: "/album/",
			e: "#item_list img"
		},
		imgs: () => fn.getImgA("#item_list img", ".pager>a:not(.current)"),
		capture: () => _this.imgs(),
		customTitle: "h1.title",
		setFancybox: "#item_list a:has(>img)",
		category: "nsfw1"
	}, {
		name: "Pibys",
		url: {
			h: "pibys.win",
			e: ".page-links"
		},
		box: [".entry-content img", 1],
		imgs: () => fn.getImgA(".entry-content img", ".page-links a"),
		button: [4],
		insertImg: [
			["box", 0, "#FullPictureLoadMainImgBox~*"], 2
		],
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "Pibys",
		url: {
			h: "pibys.com",
			p: "/threads/"
		},
		box: [".btnSummary", 1],
		imgs: ".divSummary img",
		button: [4],
		insertImg: [
			["box", 0, ".btnSummary,.divSummary,.w3-row-padding:has(>div>.w3-margin-bottom),.w3-container:has(>.pagination)"], 2
		],
		customTitle: "#posttitle",
		category: "nsfw1"
	}, {
		name: "TGG",
		url: {
			h: ["thegg.net"],
			e: "#header img,#body img"
		},
		imgs: () => fn.getImgSrcset("#header img:not([alt*='author']),#body img:not([alt*='author'])").filter(src => !src.includes("banner")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//a[text()='Next post']",
		prev: "//a[text()='Previous post']",
		customTitle: ".info h2",
		category: "nsfw1"
	}, {
		name: "LUVBP",
		url: {
			h: "luvbp.com",
			ee: ".c-post-upgrade-cta"
		},
		imgs: ".kg-image-card img",
		customTitle: ".c-post-hero__title",
		category: "nsfw2"
	}, {
		name: "1Y Beauties",
		url: {
			h: "www.1y.is",
			p: /^\/[\w-]+\/[^\.]+\.html$/i
		},
		imgs: () => fn.getImgA(".entry-content img", ".page-links a"),
		capture: () => _this.imgs(),
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "BeautyLeg",
		url: {
			h: "www.beautyleg6.com",
			p: /^\/\w+\/\d+\/\d+\.html/i
		},
		imgs: () => fn.getImg(".contents img[alt]", Number(fn.gt(".page a")?.match(/\d+/)) || 1, 9),
		button: [4],
		insertImg: [".contents", 2],
		autoDownload: [0],
		next: ".pre>a",
		prev: ".next>a",
		customTitle: ".content>h1",
		css: ".content .contents img{max-width:100%!important}",
		category: "nsfw1"
	}, {
		name: "BeautyLegM",
		url: {
			h: "m.beautyleg6.com",
			p: "view.php",
			s: "aid="
		},
		imgs: () => {
			let links = fn.arr(_unsafeWindow.totalpage, (v, i) => i == 0 ? siteUrl : siteUrl + "&pageno=" + (i + 1));
			return fn.getImgA("#bigImg", links);
		},
		button: [4],
		insertImg: [".show-simg", 2],
		autoDownload: [0],
		next: {
			s: ".show-top-menulist a",
			t: "上一组图"
		},
		prev: {
			s: ".show-top-menulist a",
			t: "下一组图"
		},
		customTitle: ".showcontbt>h1",
		category: "nsfw1"
	}, {
		name: "Asianude4u",
		host: ["www.asianude4u.net"],
		reg: /^https?:\/\/www\.asianude4u\.net\/.+\/.+\/(#small-1)?$/,
		exclude: "//a[@rel='category tag' and text()='Videos'] | //a[@rel='category tag' and text()='Madonna-AV']",
		imgs: () => fn.ge(".wp-block-image a[href*=attachment_id]") ? fn.gae(".wp-block-image img[data-id]") : fn.gae(".wp-block-image>a,.mgl-img-container>a,.gallery a").map(e => e.href),
		button: [4],
		insertImg: [
			["div.entry>*:last-child", 2], 2
		],
		customTitle: "h1.entry-title",
		css: "button.rmp_menu_trigger{z-index:100 !important}",
		mcss: ".entry{width:100% !important}",
		hide: ".single-box,.entry-img-300",
		category: "nsfw1"
	}, {
		name: "Nudegirls4u",
		url: {
			h: ["nudegirls4u.com"]
		},
		imgs: ".rgg-imagegrid>a",
		button: [4],
		insertImg: [".rgg-container", 2],
		customTitle: ".entry-title",
		css: ".rgg-imagegrid{height:auto!important}",
		category: "nsfw1"
	}, {
		name: "看美女",
		url: {
			h: "eyecoser.com"
		},
		imgs: ".entry-content img:not([data-src$='1616334013075.jpg'],[data-src$='AD1.jpg'])",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "a[rel=prev]",
		prev: "a[rel=next]",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "爱看 INS",
		host: ["www.ikanins.com"],
		reg: /^https?:\/\/www\.ikanins\.com\/[\w-]+\//,
		imgs: "img[srcset]",
		button: [4],
		insertImg: [
			[".entry-content", 0, "//p[img]"], 2
		],
		autoDownload: [0],
		next: "a[rel=prev]",
		prev: "a[rel=next]",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "Jablehk",
		host: ["jablehk.com"],
		url: {
			h: "jablehk.com"
		},
		imgs: ".gallery-strips-lightbox-link>img[data-src]",
		thums: "figure.gallery-strips-item",
		button: [4],
		insertImg: [
			[".gallery-strips-wrapper", 2, ".gallery-strips-wrapper"], 2, 2000
		],
		autoDownload: [0],
		next: ".item-pagination-link--next",
		prev: ".item-pagination-link--prev",
		customTitle: "h1>strong",
		category: "nsfw1"
	}, {
		name: "True Pic",
		url: {
			h: ["truepic.net"],
			p: /^\/[\w-]+\/$/,
			e: "//div[@class='entry-content']//p[img]"
		},
		box: ["//p[img]", 1],
		imgs: () => fn.getImgA("//p/img", ".pagination_split_post a"),
		button: [4],
		insertImg: [
			["box", 0, "//p[img]"], 2
		],
		customTitle: ".entry-content h2",
		category: "nsfw1"
	}, {
		name: "TangMoc",
		host: ["tangmoc.com"],
		reg: /^https?:\/\/tangmoc\.com\/blog\/show\/\w+\/.+/,
		init: () => fn.remove("//span[@id='install-pwa-box'] | //div[@class='row mt-3'] | //div[ins[@class='adsbygoogle']] | //div[@class='mt-3'][@id] | //div[@class='row my-5'] | //iframe[@id]"),
		imgs: () => fn.ge(".btn-warning+.btn-secondary") ? fn.getImgA("a[href*=media]>.media-preview", "a.btn-secondary") : fn.gae("a[href*=media]>.media-preview"),
		button: [4],
		insertImg: ["//media[article]", 2],
		customTitle: () => fn.dt({
			s: "h1",
			d: [
				"View - ",
				/[\s-]+$/
			]
		}),
		category: "nsfw1"
	}, {
		name: "TangMoc去廣告",
		host: ["tangmoc.com"],
		reg: /^https?:\/\/tangmoc\.com\//,
		init: () => fn.addMutationObserver(() => fn.remove("//span[@id='install-pwa-box'] | //div[@class='row mt-3'] | //div[ins[@class='adsbygoogle']] | //div[@class='mt-3'][@id] | //div[@class='row my-5'] | //iframe[@id]")),
		category: "ad"
	}, {
		name: "Fapeza",
		url: {
			h: "fapeza.com",
			e: ".profile-avatar-wrapper"
		},
		init: () => (siteJson.max = fn.ge("#load_more")?.dataset?.max || 1),
		imgs: () => {
			let [, avatar] = fn.lp.split("/");
			let links = fn.arr(siteJson.max, (v, i) => `/ajax/model/${avatar}/page-${i + 1}/`);
			return fn.getEle(links, ".image-row img").then(eles => {
				let images = [];
				let videos = [];
				let thumbs = [];
				for (let e of eles) {
					if (e.nextElementSibling) {
						videos.push(e.src.replace("_400px.jpg", ".mp4"));
					} else {
						thumbs.push(e.src);
						images.push(e.src.replace("_400px", ""));
					}
				}
				videoSrcArray = videos.reverse();
				thumbnailSrcArray = thumbs.reverse();
				return images.reverse();
			});
		},
		capture: () => _this.imgs(),
		button: [4],
		insertImg: [".image-grid-wrap", 3],
		insertImgAF: () => fn.run("jQuery(window).off()"),
		customTitle: () => fn.dt({
			s: ".profile-wrapper h4"
		}),
		observerClick: ".superberb_b",
		css: ".feed-profile-wrapper{padding-top: 58px}",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Picazor",
		url: {
			h: ["picazor.com"],
		},
		page: () => fn.clp(/^\/[a-z]{2}\/[\w-]+$/) && !fn.clp("/tags"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.fetchDoc(fn.clp()).then(() => fn.waitEle(".grid a")) : void 0,
		imgs: async () => {
			let [, , u] = fn.clp().split("/");
			let max = Math.ceil(Number(fn.gu(".grid a").split("/").at(-1) / 12));
			let links = fn.arr(max, (v, i) => i == 0 ? "/en/" + u : "/en/" + u + "/page/" + (i + 1));
			let eles = await fn.getEle(links, ".grid a img");
			let srcs = fn.getImgSrcArr(eles).reverse();
			let urls = srcs.map(e => {
				if (e.includes("?") && e.includes("url=")) {
					return fn.getUSP("url", e);
				}
				return e;
			});
			let videos = [];
			let thumbs = [];
			let images = [];
			for (let [i, e] of urls.entries()) {
				if (e.includes(".mp4.")) {
					let src = fn.rt(e, [
						["/500px_", "/"],
						[".mp4.jpg", ".mp4"]
					]);
					if (src.startsWith("http")) {
						videos.push(src);
					} else {
						videos.push(fn.lo + src);
					}
				} else {
					thumbs.push(srcs[i]);
					let src = fn.rt(e, [
						["/500px_", "/"]
					]);
					if (src.startsWith("http")) {
						images.push(src);
					} else {
						images.push(fn.lo + src);
					}
				}
			}
			thumbnailSrcArray = thumbs;
			videoSrcArray = videos;
			return images;
		},
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Fapello",
		url: {
			h: ["fapello.com", "pt.fapello.com"],
			p: /^\/[^\/]+\/$/
		},
		init: () => {
			let ele = fn.ge("#showmore");
			let max = ele?.dataset?.max || 1;
			siteJson.max = max;
		},
		imgs: async () => {
			let eles;
			if (siteJson.max > 1) {
				let links = fn.arr(siteJson.max, (v, i) => i == 0 ? siteUrl : siteUrl + `page-${i + 1}/`);
				eles = await fn.getEle(links, "#content>div");
			} else {
				eles = fn.gae("#content>div");
			}
			let imgSrcs = eles.map(node => {
				if (fn.ge("img[src*='icon-play.svg']", node)) {
					let videoSrc = fn.ge("img", node).src.replace("https://fapello.com/", "https://cdn.fapello.com/").replace("_300px", "").replace(/\.jpg$/i, ".mp4");
					videoSrcArray.push(videoSrc);
					return null;
				} else {
					thumbnailSrcArray.push(fn.ge("img", node).src);
					let imgSrc = fn.ge("img", node).src.replace("_300px", "");
					return imgSrc;
				}
			}).filter(Boolean).sort();
			thumbnailSrcArray.sort();
			videoSrcArray.sort();
			return imgSrcs;
		},
		button: [4],
		insertImg: ["#content", 3],
		insertImgAF: () => {
			fn.run("jQuery(window).off()");
			fn.remove("#showmore,#next_page");
		},
		customTitle: () => fn.dt({
			t: fn.title("/", 1),
			d: " - Fapello"
		}),
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Fapello",
		url: {
			h: ["fapello.pics", "xapello.com"],
			e: "link[title=JSON]"
		},
		init: () => {
			let ele = fn.ge("#showmore");
			let max = ele?.dataset?.max || 1;
			siteJson.max = max;
		},
		imgs: () => {
			fn.sm5();
			let fetchNum = 0;
			let id = fn.gu("link[title=JSON]").split("/").at(-1);
			let url = "/wp-admin/admin-ajax.php?action=get_post_datac&post_id=" + id;
			let urls = fn.arr(siteJson.max, (v, i) => i == 0 ? url : url + `&page=${i}`);
			let resArr = urls.map(u => fetch(u).then(res => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${siteJson.max}`, 0);
				return res.text();
			}));
			return Promise.all(resArr).then(data => {
				let html = data.join("");
				let dom = fn.doc(html);
				let as = fn.gae("a[data-thumb]", dom);
				thumbnailSrcArray = as.map(a => a.dataset.thumb).sort();
				return as.map(a => a.href).sort();
			});
		},
		button: [4],
		insertImg: ["#mainbb,#first-contents", 3],
		insertImgAF: () => {
			fn.run("jQuery(window).off()");
			fn.remove("#showmore");
		},
		customTitle: ".entry-content h2",
		category: "nsfw2"
	}, {
		name: "Fapachi",
		host: ["fapachi.com"],
		reg: /^https?:\/\/fapachi\.com\/[^\/]+$/,
		init: () => {
			let medias = Number(fn.gt("//p[contains(text(),'Media')]").match(/\d+/)[0]);
			siteJson.medias = medias;
		},
		imgs: async () => {
			if (siteJson.medias > 24) {
				let max = Math.ceil(siteJson.medias / 24);
				let links = fn.arr(max, (v, i) => siteUrl + "/page/" + (i + 1));
				thumbnailSrcArray = await fn.getImgA(".model-media-prew img", links).then(arr => arr.filter(src => src.includes("/models/")).sort());
				return thumbnailSrcArray.map(e => e.replace("/300px/", "/full/").replace("_300px", ""));
			}
			thumbnailSrcArray = fn.getImgSrcArr(".model-media-prew img").filter(src => src.includes("/models/")).sort();
			return thumbnailSrcArray.map(e => e.replace("/300px/", "/full/").replace("_300px", ""));
		},
		button: [4],
		insertImg: ["//div[div[contains(@class,'model-media-prew')]]", 3],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Faponic/Fapellas",
		host: ["faponic.com", "fapellas.com"],
		reg: /^https?:\/\/(faponic\.com|fapellas\.com)\/[^\/]+\/$/,
		include: ".author-content",
		init: () => {
			let ele = fn.ge("#showmore");
			let max = ele?.dataset?.max || 1;
			siteJson.max = max;
		},
		imgs: () => {
			let links = fn.arr(siteJson.max, (v, i) => i == 0 ? siteUrl : siteUrl + `page-${i + 1}/`);
			return fn.getEle(links, ".photo-item>img");
		},
		button: [4],
		insertImg: ["#content", 3],
		insertImgAF: () => {
			fn.run("scrollMore=()=>{}");
			fn.remove("#showmore,#next_page");
		},
		customTitle: ".author-content>a",
		category: "nsfw2"
	}, {
		name: "Fapullo",
		host: ["fapullo.com"],
		reg: /^https?:\/\/fapullo\.com\/[^\/]+\/$/,
		init: () => {
			let ele = fn.ge("#load_more");
			let max = ele?.dataset?.max || 1;
			siteJson.max = max;
		},
		imgs: () => {
			let links = fn.arr(siteJson.max, (v, i) => i == 0 ? siteUrl : siteUrl + `page-${i + 1}/`);
			return fn.getEle(links, ".thumb_img").then(eles => {
				thumbnailSrcArray = fn.getImgSrcArr(eles).sort();
				return thumbnailSrcArray.map(e => e.replace("_400px", ""));
			});
		},
		button: [4],
		insertImg: ["#media", 3],
		insertImgAF: () => {
			fn.run("scrollMore=()=>{}");
			fn.remove("#load_more");
		},
		customTitle: () => fn.title("/", 1),
		category: "nsfw2"
	}, {
		name: "Fapodrop/Fapsan",
		url: {
			h: ["fapodrop.com", "fapsan.com"],
			e: ".one-pack img[src*=thumbnail]"
		},
		imgs: () => fn.getNP(".one-pack>a", "//a[text()='Next page']", null, ".row:has(>div>.page-btn)").then(() => {
			thumbnailSrcArray = fn.getImgSrcArr(".one-pack img[src*=thumbnail]").reverse();
			return thumbnailSrcArray.map(e => e.replace("/thumbnails/", "/photo/").replace("_thumbnail", ""));
		}),
		button: [4],
		insertImg: [".one-pack", 3],
		customTitle: "h1.h3",
		category: "nsfw2"
	}, {
		name: "Onlytreon/FapMenu",
		url: {
			h: ["onlytreon.com", "fapmenu.com"],
			e: ".model-media-prew"
		},
		box: [".row:has(>.model-media-prew),.grig-model-media", 1],
		imgs: () => {
			let max = Math.ceil(Number(fn.gt("//p[contains(text(),'Media:')]").match(/\d+/g).at(-1)) / 24);
			let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `/page/${i + 1}`);
			return fn.getEle(links, ".model-media-prew a").then(as => {
				let ts = as.map(a => a.firstElementChild);
				thumbnailSrcArray = fn.getImgSrcArr(ts).sort();
				links = as.map(a => a.href);
				return fn.getImgA(".container .media-img", links).then(srcs => srcs.sort());
			});
		},
		button: [4],
		insertImg: [
			["box", 0, ".row:has(>.model-media-prew),.grig-model-media"], 3
		],
		customTitle: ".container h1",
		category: "nsfw2"
	}, {
		name: "WildSkirts",
		url: {
			h: "wildskirts.su",
			st: "window['cid']"
		},
		imgs: () => {
			let id = fn.ge(".like-btn").dataset.celeb;
			fn.sm5();
			return fn.j("https://api.wildskirts.su/api/media/" + id).then(json => {
				let srcs = [];
				for (let e of Object.values(json.media.items)) {
					if (e.t == "video") {
						srcs.push(e.p);
						videoSrcArray.push(e.u);
					} else if (e.t == "photo") {
						thumbnailSrcArray.push(e.p);
						srcs.push(e.u);
					}
				}
				return srcs;
			});
		},
		customTitle: ".profile-info .font-semibold",
		downloadVideo: true,
		fetch: 1,
		category: "nsfw2"
	}, {
		name: "#TheFappening",
		url: {
			h: "fap.thefappening.one",
			p: /^\/[^\/]+\/$/,
			e: ".entry-title"
		},
		imgs: () => {
			let a = fn.ge(".gallery-item a[target]");
			if (a) return fn.gae(".gallery-item a[target]");
			return fn.gae(".gallery-item img");
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.gt(".entry-title").replaceAll("/", "-"),
		category: "nsfw2"
	}, {
		name: "The Fappening Plus",
		host: ["thefappening.plus"],
		reg: /^https?:\/\/thefappening\.plus\/[^\/]+\/$/,
		imgs: () => fn.getNP(".gallery__item", "//a[text()='Next']", null, ".fusion-meta-info").then(() => {
			thumbnailSrcArray = fn.gae(".gallery_thumb").map(e => e.src).reverse();
			return thumbnailSrcArray.map(e => e.replace(/_s(\.\w+)$/, "$1"));
		}),
		button: [4],
		insertImg: [".post-content", 2],
		customTitle: () => fn.gt(".entry-title").replaceAll("/", "-"),
		category: "nsfw2"
	}, {
		name: "TheFappening",
		host: ["thefappeningblog.com"],
		reg: /^https?:\/\/thefappeningblog\.com\/[^\/]+\/(#more-\d+)?$/,
		include: "//a[noscript][not(@class)]",
		imgs: "//a[noscript]",
		button: [4],
		insertImg: [
			["//a[noscript]", 2, "//a[noscript]"], 2
		],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "TheFappening",
		url: {
			h: ["thefappeningblog.com"],
			p: "/gallery/"
		},
		imgs: () => fn.getNP(".item_content", ".nav-next>a", null, ".nav-single").then(() => {
			thumbnailSrcArray = fn.gae(".item_img>img").map(e => e.src).reverse();
			return thumbnailSrcArray.map(e => e.replace(/_\d+px(\.\w+)$/, "$1"));
		}),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: () => fn.gt(".entry-title").replaceAll("/", "-"),
		category: "nsfw2"
	}, {
		name: "The Fappening",
		url: {
			h: "fap.thefappeningnew.com"
		},
		imgs: ".entry-content img",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "The Fappening",
		url: {
			h: "thefappening2015.com"
		},
		srcset: ".lazy-gallery img,.entry-content .wp-image",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-previous a[rel=prev]",
		prev: ".nav-previous a[rel=next]",
		customTitle: "h1.entry-title",
		hide: ".header-banner",
		category: "nsfw2"
	}, {
		name: "AllPornImages",
		url: {
			h: ["allpornimages.com"]
		},
		imgs: ".entry-content img",
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Desi Porn Photo",
		url: {
			h: "desipornphoto.com"
		},
		imgs: ".gallery-item a",
		thums: ".gallery-item img",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "Fapomania",
		host: ["fapomania.com"],
		reg: /^https?:\/\/(\w+\.)?fapomania\.com\/[^\/]+\/$/,
		box: [".previzakosblo", 2],
		imgs: () => fn.getNP(".leftocontar .previzako", "//a[contains(text(),'Next')]", (dom) => !fn.ge(".leftocontar .previzako", dom), ".morebutaro").then(() => {
			thumbnailSrcArray = fn.gae(".leftocontar .previzakoimag>img:not([src$='leaks.png'])").map(e => e.src).reverse();
			return thumbnailSrcArray.map(e => e.replace(/_\d+px(\.\w+)$/, "$1"));
		}),
		button: [4],
		insertImg: [
			["box", 0, ".leftocontar .previzakosblo,.morebutaro"], 2
		],
		customTitle: () => fn.gt(".leftocontar>h1").replaceAll("/", "-"),
		category: "nsfw2"
	}, {
		name: "Shemale Leaks",
		url: {
			h: ["shemaleleaks.com"],
			p: /^\/[^\/]+\/$/
		},
		box: [".site-main", 2],
		imgs: () => fn.getNP("#main>article", (dom) => {
			let n = fn.ge(".nav-next>a", dom);
			if (isEle(n)) {
				let num = n.href.match(/\d+/).at(-1);
				return fn.lp + "?page=" + num;
			}
			return null;
		}, null, ".post-navigation").then(() => {
			thumbnailSrcArray = fn.getImgSrcArr("#main>article img").reverse();
			return thumbnailSrcArray.map(e => e.replace("_thumb.", "."));
		}),
		button: [4],
		insertImg: [
			["box", 0, ".site-main"], 2
		],
		customTitle: "h1.page-title",
		category: "nsfw2"
	}, {
		name: "NudoStar.TV",
		host: ["nudostar.tv"],
		reg: /^https?:\/\/nudostar\.tv\/models\/[^\/]+\/$/,
		imgs: () => fn.getNP("#list_videos_common_videos_list_items>.item", ".next>a", null, "#list_models_models_list_pagination").then(() => {
			thumbnailSrcArray = fn.gae("#list_videos_common_videos_list img.thumb").map(e => e.src).reverse();
			return thumbnailSrcArray.map(e => e.replace(/_\d+px(\.\w+)$/, "$1"));
		}),
		button: [4],
		insertImg: [".list-videos", 2],
		customTitle: () => fn.gt(".headline>h1").replaceAll("/", "-"),
		hide: ".zkido_div",
		category: "nsfw2"
	}, {
		name: "NudoStar",
		url: {
			h: "nudostar.com",
			p: /^\/[^\/]+\//
		},
		box: [".pagination-single", 1],
		imgs: "//p/a[img]",
		vioeos: "video.wp-video-shortcode>source",
		button: [4],
		insertImg: [
			["box", 0, "//p[a[img]] | //div[@class='wp-video']"], 2
		],
		autoDownload: [0],
		next: "a.previous-post",
		prev: "a.next-post",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "NudoStar",
		url: {
			h: "nudostar.com",
			p: /^\/model\/[^\/]+\/$/
		},
		imgs: () => fn.getNP(".entry-content div:has(.item_content)", "a.next-post", null, ".pagination-single").then(() => {
			thumbnailSrcArray = fn.getImgSrcset(".entry-content img").reverse();
			return thumbnailSrcArray.map(e => e.replace("_340", ""));
		}),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "Fapopedia",
		url: {
			h: ["fapopedia.net", "fapopedia-net.theporn.how"],
			p: /^\/[^\/]+\/$/,
			e: "a[name='photos']"
		},
		box: [".shrt-blk", 2],
		imgs: () => fn.getNP("//h2[i]/following-sibling::div[1][@class='shrt-blk']/div", "//a[text()='Next ']", null, ".nv-blk").then(() => {
			thumbnailSrcArray = fn.gae("//h2[i]/following-sibling::div[1][@class='shrt-blk']//img").map(e => e.src).sort();
			let links = fn.gau("//h2[i]/following-sibling::div[1][@class='shrt-blk']//a");
			return fn.getImgA(".lrg-pc>a", links).then(arr => arr.sort());
		}),
		button: [4],
		insertImg: [
			["box", 0, "//h2[i]/following-sibling::div[1][@class='shrt-blk']|//div[@class='nv-blk']"], 2
		],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Nudogram",
		host: ["nudogram.com", "dvir.ru"],
		reg: [
			/^https?:\/\/nudogram\.com\/models\/[^\/]+\/$/,
			/^https?:\/\/dvir\.ru\/kingdesi\/models\/[^\/]+\/$/
		],
		imgs: () => fn.getNP("#list_videos_common_videos_list_items>.item", "//li[span]/following-sibling::li[1]/a", null, ".pagination").then(() => {
			thumbnailSrcArray = fn.gae("#list_videos_common_videos_list div.img>img").map(e => e.src).reverse();
			return thumbnailSrcArray.map(e => e.replace(/_\d+(\.\w+)$/, "$1"));
		}),
		button: [4],
		insertImg: [".list-videos", 2],
		customTitle: () => fn.gt(".headline>h2").replaceAll("/", "-"),
		category: "nsfw2"
	}, {
		name: "Fappening Book",
		host: ["fappeningbook.com"],
		reg: /^https?:\/\/fappeningbook\.com\/[^\/]+\/$/,
		include: ".model-thumbs-dv",
		imgs: () => fn.getNP(".my-gallery>*", ".pages-dv a:has(.fa-angle-right)", null, ".pages-dv").then(() => {
			thumbnailSrcArray = fn.getImgSrcArr(".my-gallery li:not(.wp_xsize_class) img").reverse();
			return fn.gae(".my-gallery li:not(.wp_xsize_class) a[data-orig]").reverse();
		}),
		button: [4],
		insertImg: [".model-thumbs-dv", 2],
		customTitle: () => fn.ge("h1").textContent,
		category: "nsfw2"
	}, {
		name: "Hotleaks/Thotsbay/Hotleak/Leakedzone/BestThots/Thotporn",
		host: ["hotleaks.tv", "thotsbay.tv", "hotleak.vip", "leakedzone.com", "bestthots.com", "thotporn.tv"],
		reg: () => /^https?:\/\/(hotleaks\.tv|thotsbay\.tv|hotleak\.vip|leakedzone\.com|bestthots\.com|thotporn\.tv)\/[\w\.-]+(\/photo)?$/i.test(fn.url) && !/^\/home/.test(fn.lp),
		init: () => (location.href.split("/").length === 4 && !fn.lh.includes("bestthots")) ? (location.href = location.href + "/photo") : EClick("#photos-tab"),
		imgs: async () => {
			if (/\/photo/.test(location.href)) fn.clearAllTimer();
			let ptext = fn.gt("#photos-tab");
			let num;
			try {
				let [, m] = ptext.match(/\(([\d\.K]+)\)/);
				if (/\./.test(m) && /K/.test(m)) {
					num = (Number(m.replace(/\.|K/g, "")) + 1) * 100;
				} else if (/K/.test(m)) {
					num = Number(m.replace(/K/g, "")) * 1000 + 100;
				}
				num = Number(m);
			} catch {
				num = Number(ptext.match(/\d+/g).join(""));
			}
			let pages = Math.ceil(num / 48);
			let actorName = siteUrl.split("/")[3];
			let imgsSrcArr = [];
			let fetchNum = 0;
			fn.sm5();
			for (let i = 1; i <= pages; i++) {
				let json = await fetch(`/${actorName}?page=${i}&type=photos&order=0`, {
					"headers": {
						"x-requested-with": "XMLHttpRequest"
					}
				}).then(res => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${pages}`, 0);
					return res.json();
				});
				if (json.length == 0) break;
				let images;
				if (fn.lh == "leakedzone.com") {
					images = json.map(e => e.thumbnail.replace("_300.", "."));
				} else if (fn.lh == "bestthots.com") {
					images = json.map(e => e.image);
				} else {
					images = json.map(e => e.player);
				}
				let thumbnails = json.map(e => e.thumbnail);
				imgsSrcArr = imgsSrcArr.concat(images);
				thumbnailSrcArray = thumbnailSrcArray.concat(thumbnails);
				if (json.length < 48) break;
			}
			return imgsSrcArr;
		},
		button: [4],
		insertImg: ["#photos", 3],
		customTitle: ".actor-name>h1,.actor-title-port",
		category: "nsfw2"
	}, {
		name: "Hot Girl Pix",
		url: {
			h: "www.hotgirlpix.com",
			p: "/p/"
		},
		imgs: () => fn.getImgA("article img", "#singlePostPagination a", 300),
		button: [4],
		insertImg: ["article", 2],
		customTitle: "#singlePostTitle",
		css: ".nav-menu{z-index:10}",
		hide: "#modalAdblock,.alignCenter,.gcseSearchPlaceHolder,body~*:not(#DownloadAppUIRoot,[id^=Full],.viewer-container)",
		category: "nsfw1"
	}, {
		name: "Hot Girl Pix AD",
		host: ["www.hotgirlpix.com"],
		reg: /^https?:\/\/www\.hotgirlpix\.com\//,
		hide: "#modalAdblock,body~*:not(#DownloadAppUIRoot,[id^=Full],.viewer-container)",
		category: "ad"
	}, {
		name: "套圖TAOTU.ORG",
		url: {
			h: "taotu.org"
		},
		box: [".piclist", 2],
		imgs: "a[data-fancybox=gallery]",
		thums: "a[data-fancybox=gallery] img",
		button: [4],
		insertImg: [
			["box", 0, ".piclist"], 2
		],
		autoDownload: [0],
		next: ".next a",
		prev: ".prev a",
		customTitle: ".suit_title>h1",
		hide: "#right-bottom,#ad,.ad",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		name: "爱死美女网",
		url: {
			h: ["www.2mn.cc", "2mn.cc"],
			p: "/mm/"
		},
		imgs: "#post_content img",
		button: [4],
		insertImg: ["#post_content", 1],
		autoDownload: [0],
		next: ".post-previous a",
		prev: ".nav-links .next",
		customTitle: "#content h1",
		category: "nsfw1"
	}, {
		name: "要常来美女图片网",
		host: ["yaochanglai.com"],
		url: {
			p: "/pic/"
		},
		imgs: "#post_content img",
		button: [4],
		insertImg: ["#post_content", 1],
		customTitle: "#content h1",
		category: "nsfw1"
	}, {
		name: "美图海",
		url: {
			h: "www.meituhai.com",
			p: "/album/",
			ee: ".vip-tip"
		},
		imgs: "#gallery img",
		button: [4],
		insertImg: ["#gallery", 2],
		customTitle: ".home_title",
		category: "nsfw1"
	}, {
		name: "美推网",
		host: ["www.meinvtui.com"],
		url: {
			//h: [/meinvtui\.com$/, "bbs.2tu.me"],
			e: [".logo>a[title=美女图片]>img[alt=美女图片],nav.bg-w a[title=美女图片]", ".pp.hh,.contimglist"],
			p: ".html"
		},
		imgs: () => fn.getImg(".pp.hh img[alt],.contimglist img[alt]", Number(fn.gt(".pages>a,.page a").match(/\d+/g).at(-1)), 9),
		button: [4],
		insertImg: [".pp.hh,.contimglist", 2],
		autoDownload: [0],
		next: "//b[text()='上一篇:']/following-sibling::a | //a[@class='f-l l2'][@href]",
		prev: "//b[text()='下一篇:']/following-sibling::a | //a[@class='f-l l3'][@href]",
		customTitle: ".des>h1,.contmbx-title",
		category: "nsfw1"
	}, {
		name: "推图网",
		url: {
			h: "www.tuiimg.com",
			p: /^\/meinv\/\d+\/$/
		},
		init: () => fn.sm5().then(() => fn.url.replace("www.tuiimg.com", "m.tuiimg.com")).then(url => fn.xhrDoc(url, {
			headers: {
				"Referer": url,
				"User-Agent": Mobile_UA
			}
		}).then(dom => {
			let code = fn.gst("_pd", dom);
			let [, path, , max, prev, next] = fn.textToArray(code, "_pd");
			path = "https://i.tuiimg.net/" + path;
			let srcs = fn.arr(max, (v, i) => path + (i + 1) + ".jpg");
			siteJson = {
				srcs,
				next,
				prev
			};
		})),
		imgs: () => siteJson.srcs,
		button: [4],
		insertImg: ["#content", 2],
		insertImgAF: () => fn.remove("#tips,#myfav"),
		autoDownload: [0],
		next: () => Number(siteJson.next) > 0 ? "/meinv/" + siteJson.next + "/" : null,
		prev: () => Number(siteJson.prev) > 0 ? "/meinv/" + siteJson.prev + "/" : null,
		customTitle: "#main>h1",
		category: "nsfw1"
	}, {
		name: "推图网M",
		link: "https://m.tuiimg.com/meinv/",
		url: {
			h: "m.tuiimg.com",
			p: "/meinv/",
			st: "_pd"
		},
		init: () => {
			let code = fn.gst("_pd");
			let [, path, , max, prev, next] = fn.textToArray(code, "_pd");
			path = "https://i.tuiimg.net/" + path;
			let srcs = fn.arr(max, (v, i) => path + (i + 1) + ".jpg");
			siteJson = {
				srcs,
				next,
				prev
			};
		},
		imgs: () => siteJson.srcs,
		button: [4],
		insertImg: ["#content", 2],
		insertImgAF: () => fn.remove("#page,#tips,#myfav,#downappM"),
		autoDownload: [0],
		next: () => Number(siteJson.next) > 0 ? "/meinv/" + siteJson.next + "/" : null,
		prev: () => Number(siteJson.prev) > 0 ? "/meinv/" + siteJson.prev + "/" : null,
		customTitle: ".main>h1",
		category: "nsfw1"
	}, {
		name: "18AV",
		url: {
			h: "18av.mm-cg.com",
			st: "Large_cgurl",
			e: ".sel_enlarge_page,.sel_enlarge"
		},
		imgs: () => _unsafeWindow.Large_cgurl,
		button: [4],
		insertImg: ["#show_cg_html,#showcg_container", 2],
		customTitle: ".archive-title>h1,h1",
		hide: ".ut1_img_content",
		category: "nsfw1"
	}, {
		name: "SexyAsianGirl",
		url: {
			h: ["www.sexyasiangirl.top", "sexyasiangirl.top"],
			p: "/album/"
		},
		init: () => fn.remove("//article/div[a[img]]"),
		imgs: () => fn.getImg("img.block", fn.gt("//a[text()='Next']", 2) || 1),
		button: [4],
		insertImg: ["//div[img[@title]]", 2],
		customTitle: "header>h2",
		category: "nsfw2"
	}, {
		name: "尤物丧志/亚色图库/福利姬美图/秀人图/極品妹子圖/涩图社/三上悠亚写真图片/AHottie/Coser/HotGirl/SexyGirl",
		url: {
			t: ["尤", "图", "圖", "写真", "寫真", "AHottie", "Coser", "Girl"],
			e: ["img.block", "//div[img[@title]]", "#main>h1,header>h1"]
		},
		imgs: () => fn.getImg("img.block", fn.gt("a[rel=next]", 2) || 1).then(srcs => srcs.map(e => e.replace("teleimgs.pages.dev", "imgfiles.pages.dev"))),
		button: [4],
		insertImg: ["//div[img[@title]]", 2],
		next: "//span[contains(text(),'上一篇')]/following-sibling::a[1]",
		customTitle: () => fn.dt({
			s: "#main>h1,header>h1",
			d: [
				/\(\d+[\w\s\\\/\.+-/]+\)?|\[\d+[\w\s\\\/\.+-/]+\]?|(\d+[\w\s\\\/\.+-/]+)?|【\d+[\w\s\\\/\.+-/]+】?|\d+P/gi,
				/\s?\d+P\+?\d+V/,
				/未分类性感写真|^.+人体|AI图区/,
				/(\d+月\d+打赏群(自购)?资源)/gi,
				/🐾/g
			]
		}),
		hide: "div.flex.m-1:has(>a[style]),.my-2:has(>a[target][referrerpolicy][style]),iframe[id][class][width][height][style],div:has(>script):has(>iframe),div:has([id*='adsby'])",
		category: "nsfw2"
	}, {
		name: "胴体的秘密/AsianSexyBody/福利图库/COSER美女图",
		host: ["dongti.netlify.app", "asiansexybody.netlify.app", "fulituku.neocities.org", "coser1.neocities.org"],
		url: {
			h: /netlify\.app|neocities\.org/,
			p: "/posts/"
		},
		imgs: "#gallery img",
		button: [4],
		insertImg: ["#gallery", 2],
		autoDownload: [0],
		next: "//span[text()='Prev:']/following-sibling::a[1]",
		prev: "//span[text()='Next:']/following-sibling::a[1]",
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "网友自拍",
		url: {
			h: ["yunvpicx.top", "023vcc.com"],
			s: "id"
		},
		imgs: ".pic_center img",
		button: [4],
		insertImg: [
			[".content-text", 0, ".content-text br,.content-text .pic_center"], 2
		],
		customTitle: ".pagetitle",
		category: "nsfw2"
	}, {
		name: "四虎色图",
		host: "soq6ojmy98.sihusetu2.cfd",
		url: {
			e: {
				s: ".container h1",
				t: "四虎色图"
			},
			p: "/article/"
		},
		imgs: ".photo-container img",
		button: [4],
		insertImg: [".photo-container", 2],
		customTitle: ".album-title",
		hide: ".banner",
		category: "nsfw2"
	}, {
		name: "湿女吧",
		host: ["shinv.link"],
		url: {
			t: "湿女吧",
			p: "/posts/"
		},
		imgs: "header~div img[title]",
		button: [4],
		insertImg: ["header~div:has(>img[title])", 2],
		autoDownload: [0],
		next: "//span[text()='上一篇:']/following-sibling::a",
		prev: "//span[text()='下一篇:']/following-sibling::a",
		customTitle: "header h1",
		category: "nsfw2"
	}, {
		name: "浪女吧/Ang4u",
		url: {
			h: ["langnv.link", "langnv.neocities.org", "ang4u.neocities.org"],
			p: "/posts/"
		},
		imgs: "#images img",
		button: [4],
		insertImg: ["#images", 2],
		autoDownload: [0],
		next: "#prevpost>a",
		prev: "#nextpost>a",
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "美图鉴赏/美图鉴赏ACG",
		links: [
			"https://www.lspimg.com/page/1/",
			"https://acg.lspimg.com/page/1/"
		],
		url: {
			h: ["www.lspimg.com", "acg.lspimg.com"],
			p: "/archives/"
		},
		home: "/page/1/",
		imgs: "div[data-src]",
		button: [4],
		insertImg: ["#masonry", 2],
		customTitle: () => fn.lh === "www.lspimg.com" ? fn.title(" - 美图鉴赏") : null,
		css: "#masonry{position:unset!important;height:unset!important}",
		hide: "#popup",
		category: "nsfw2"
	}, {
		name: "VVCON美瞳网",
		url: {
			h: "www.vvcon.cn",
			p: /^\/\d+\.html$/,
			e: "//a[@class='post-list-cat-item b2-radius'][contains(text(),'Cosplay图集')]"
		},
		imgs: ".talk_pic img,.entry-content img",
		customTitle: ".entry-header>h1",
		category: "nsfw1"
	}, {
		name: "VVCON美瞳网",
		url: {
			h: "www.vvcon.cn",
			p: /^\/\d+\.html$/,
			e: "//a[@class='post-list-cat-item b2-radius'][contains(text(),'Cosplay图集')]"
		},
		imgs: ".entry-content p:has(>img)>img",
		button: [4],
		insertImg: [
			[".entry-content p:has(>img)", 1, ".entry-content p:has(>img)"], 2
		],
		customTitle: ".entry-header>h1",
		category: "nsfw1"
	}, {
		name: "TW Pornstars",
		url: {
			h: [
				"www.twpornstars.com",
				"www.twgays.com",
				"www.twmilf.com",
				"www.twlesbian.com",
				"www.twteens.com",
				"www.twonfans.com",
				"www.twtiktoks.com",
				"www.twgaymuscle.com",
				"www.twanal.com",
				"www.indiantw.com"
			],
			e: ".usercounters"
		},
		imgs: async () => {
			let pagesNum = 1;
			let p_last_t = fn.gt(".pagination li:last-child");
			if (p_last_t === "»") {
				pagesNum = fn.gt(".pagination li:last-child", 2);
			}
			let links = fn.arr(pagesNum, (v, i) => i == 0 ? fn.lp : fn.lp + `?page=${i + 1}`);
			thumbnailSrcArray = await fn.getImgA(".thumb__img", links);
			let videoLink = fn.ge(".videos-link[href]");
			if (videoLink) {
				let videoPostsLinks = [];
				await fn.fetchDoc(videoLink.href).then(async dom => {
					videoPostsLinks = fn.gae("a.thumb__link", dom);
					let pagesNum = 1;
					let p_last_t = fn.gt(".pagination li:last-child", 1, dom);
					if (p_last_t === "»") {
						pagesNum = fn.gt(".pagination li:last-child", 2, dom);
						let links = fn.arr(pagesNum, (v, i) => i == 0 ? videoLink.href : videoLink.href + `?page=${i + 1}`);
						links.shift();
						let eles = await fn.getEle(links, "a.thumb__link");
						for (let a of eles) videoPostsLinks.push(a.href);
					}
					let videos = await fn.getEle(videoPostsLinks, "#video_tag source", null, null, 100, 3);
					videoSrcArray = videos.map(e => e.src);
				});
			}
			return thumbnailSrcArray.map(e => e.replace("small", "large"));
		},
		customTitle: ".block__title",
		category: "nsfw2"
	}, {
		name: "tumbex",
		url: {
			h: "www.tumbex.com"
		},
		page: () => fn.clp("/post/"),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => _this.page() ? fn.waitEle(".hg-item").then(() => {
			let [content] = fn.gae(".post-content");
			return fn.gae(".hg-item", content);
		}) : [],
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.title(" - Tumbex") : null,
		referer: "",
		category: "nsfw2"
	}, {
		name: "Simply Cosplay",
		url: {
			h: "www.simply-cosplay.com"
		},
		page: () => fn.clp("/gallery/"),
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => fn.wait(() => !!_unsafeWindow?.user?.identifier),
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			let g = fn.clp().split("/").at(-1);
			let token = _unsafeWindow?.user?.token ?? "01730876";
			return fn.j(`https://api.simply-porn.com/v2/gallery/${g}?token=${token}&related=8`, {
				"headers": {
					"identifier": _unsafeWindow.user.identifier,
				},
			}).then(json => {
				apiCustomTitle = json.data.title;
				thumbnailSrcArray = json.data.images.map(e => e.urls.thumb.url);
				return json.data.images.map(e => e.urls.url);
			});
		},
		capture: () => _this.imgs(),
		category: "nsfw2"
	}, {
		name: "OSOSEDKI",
		url: {
			h: ["ososedki.com"],
			p: "/photos/"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("a[data-fancybox] img").sort((a, b) => a.match(/(\d+)\.\w+$/)[1] - b.match(/(\d+)\.\w+$/)[1]);
			return fn.gau("a[data-fancybox]").sort((a, b) => a.match(/(\d+)\.\w+$/)[1] - b.match(/(\d+)\.\w+$/)[1]);
		},
		button: [4],
		insertImg: ["//div[div[@id='masonry']]", 2],
		customTitle: () => fn.ge("//meta[@property='og:description']").content,
		css: ".grid-more{position:relative}",
		category: "nsfw2"
	}, {
		name: "COSPLAYD.COM/COSPLAYG.COM/COSPLAYJ.COM/COSPLAYK.COM/COSPLAYP.COM",
		url: {
			t: /COSPLAY[A-Z]\.COM/,
			h: /^cosplay[a-z]\.com$/,
			p: /^\/\d+\//,
			e: "main h1"
		},
		imgs: ".gallery img",
		button: [4],
		insertImg: [".gallery", 2],
		customTitle: () => fn.dt({
			s: "main h1",
			d: /[\s\d-]+images.+$/
		}),
		category: "nsfw2"
	}, {
		name: "TNApics",
		host: ["www.tnapics.com"],
		reg: /^https:\/\/www\.tnapics\.com\/[\w-]+\/$/,
		imgs: ".post-thumb-img-content img,a[data-fslightbox]",
		repeat: 1,
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Fapdungeon",
		url: {
			h: ["fapdungeon.com"]
		},
		init: () => fn.addMutationObserver(() => fn.remove("div[class][style*='z-index']")),
		srcset: ".entry-content img.size-full",
		videos: ".entry-content video>source",
		customTitle: "h1.entry-title",
		referer: "https://fapdungeon.com/",
		setFancybox: ".entry-content img",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Thotsbook/Ibradome/Fappenist/Lmlib/Teenswall",
		url: {
			h: ["thotsbook.com", "ibradome.com", "www.fappenist.com", "lmlib.com", "teenswall.com"],
			p: "/photos/",
			e: ["a.gallery-view", "h1.art-title"]
		},
		imgs: () => fn.getEle([fn.gu("a.gallery-view")], ".galeria").then(eles => {
			let [g] = eles;
			thumbnailSrcArray = fn.getImgSrcArr("img[data-src]", g);
			return fn.gae("a.ohidden", g);
		}),
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			s: "h1.art-title",
			d: "Gallery view"
		}),
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		url: {
			h: ["gotanynudes.com"],
		},
		srcset: ".entry-content img",
		videos: "video>source",
		customTitle: "h1.entry-title",
		downloadVideo: true,
		setFancybox: ".entry-content img",
		referer: "https://gotanynudes.com/",
		category: "nsfw2"
	}, {
		name: "Nude Cosplay Albums",
		url: {
			h: "nudecosplaygirls.com",
			p: /^\/[^\/]+\/$/
		},
		imgs: () => {
			let srcs = fn.getImgSrcset(".entry-content img.msacwl-img,#post img,.gallery-item img,figure.wp-block-image img");
			return srcs.filter(e => !e.includes("/18plus"));
		},
		button: [4],
		insertImg: [".entry-content,#post", 2],
		customTitle: ".entry-title",
		css: ".entry-content>img{width:auto !important;height:auto !important;max-width:100% !important;display:block !important;margin:0 auto !important}h1.g1-mega{text-align:center}",
		hide: "#secondary",
		category: "nsfw2"
	}, {
		name: "Jizz to Nude Girls",
		url: {
			h: "jizzy.org",
			p: /^\/[^\/]+\/$/,
			e: ".entry-content img"
		},
		imgs: () => fn.getImgSrcArr(".entry-content img").filter(src => !src.includes("18xmob")),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Leaked Models",
		host: ["leakedmodels.com"],
		reg: /^https?:\/\/leakedmodels\.com\/[^\/]+\/$/,
		include: "//a[span[@class='faux-button'][text()='View']][@class='more-link']",
		box: ["#site-content", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("img.size-large").sort();
			let links = fn.gau("//a[span[@class='faux-button'][text()='View']][@class='more-link']");
			return fn.getImgA("img.wp-image", links).then(arr => arr.sort());
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "ThotHub Leaks",
		url: {
			h: "thothub.vip",
			p: "/album/",
			e: ".images a img"
		},
		imgs: () => fn.getImgSrcArr(".images a img").map(e => e.replace(/main\/\d+x\d+/, "sources")),
		thums: ".images a img",
		button: [4],
		insertImg: [".images", 2],
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "ThotHub Leaks",
		url: {
			h: "thothub.vip",
			e: ".entry-title"
		},
		imgs: ".entry-content img",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /\([\d\s]+Photos\)/i
		}),
		category: "nsfw2"
	}, {
		name: "ThotHD Albums / Thothub Albums / Epawg Albums",
		host: ["thothd.com", "thothub.org", "thothub.su", "thothub.to", "thothub.lol", "thothub.mx", "thothub.ch", "thethothub.com", "epawg.com"],
		url: {
			h: [/thothd/, /thothub/, /epawg/],
			p: "/albums/",
			e: ".images a[data-fancybox-type] .thumb"
		},
		imgs: () => fn.getImgSrcArr(".images a[data-fancybox-type] .thumb").map(e => e.replace(/main\/\d+x\d+/, "sources")),
		thums: ".images a[data-fancybox-type] .thumb",
		button: [4],
		insertImg: [".images", 2],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Thothub.wtf",
		host: ["redthot.com"],
		url: {
			t: "Thothub.wtf",
			p: "/gallery/"
		},
		imgs: () => fn.getImgSrcset(".gallery_grid img"),
		button: [4],
		insertImg: [".gallery_grid", 2],
		customTitle: () => fn.ge("h1.singletitle")?.textContent,
		category: "nsfw2"
	}, {
		name: "BitchesFost",
		url: {
			h: ["bitchesfost.com"]
		},
		box: [".albumgrid-main", 2],
		imgs: () => {
			videoSrcArray = fn.gau(".albumgrid-main a[data-video-icon]");
			thumbnailSrcArray = fn.getImgSrcArr(".albumgrid-main a[data-fancybox]:not([data-video-icon]) img");
			return fn.gae(".albumgrid-main a[data-fancybox]:not([data-video-icon])");
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "PornTrex",
		url: {
			h: "www.porntrex.com",
			p: "/albums/"
		},
		box: [".album-info", 1],
		imgs: ".slick-list a[data-fancybox-type]",
		thums: ".slick-list a[data-fancybox-type] img",
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".title-video",
		category: "nsfw2"
	}, {
		name: "WhoresHub",
		url: {
			h: "whoreshub.com",
			p: "/albums/",
			e: [".gallery-top", ".info-buttons"]
		},
		box: [".info-buttons", 1],
		imgs: () => fn.gae(".gallery-top .swiper-wrapper img").map(e => e.dataset.srcset),
		thums: ".gallery-thumbs img",
		button: [4],
		insertImg: ["box", 2],
		customTitle: "h1.title",
		category: "nsfw2"
	}, {
		name: "EachPorn",
		url: {
			h: "eachporn.com",
			p: "/album/"
		},
		box: [".album-info", 1],
		imgs: ".images a",
		thums: ".images a img",
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".content h1",
		category: "nsfw2"
	}, {
		name: "The Hentai World",
		link: "https://thehentaiworld.com/hentai-cosplay-images/",
		url: {
			h: "thehentaiworld.com",
			p: /^\/[^\/]+\/[^\/]+\/$/
		},
		box: ["#miniThumbContainer", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("#miniThumbContainer img[itemprop='thumbnail']");
			return thumbnailSrcArray.map(e => e.replace(/-\d+x\d+(\.\w+)/, "$1"));
		},
		button: [4],
		insertImg: [
			["box", 0, "#miniThumbContainer,#doujin,div.ad"], 2
		],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Akai Hentai",
		link: "https://akaihentai.com/tag/cosplay/",
		url: {
			h: "akaihentai.com",
			p: /^\/[^\/]+\/$/
		},
		init: () => _unsafeWindow.jQuery("body").off(),
		box: [".comments", 1],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".post-wrap a.image,video[poster]");
			if (fn.ge(".single-thumbnail-wrap")) {
				thumbnailSrcArray = fn.getImgSrcArr(".single-thumbnail-wrap img");
			}
			videoSrcArray = fn.gae("video[poster]").map(e => e.src);
			return thumbnailSrcArray.map(e => e.replace(/-\d+x\d+(\.\w+)/, "$1"));
		},
		button: [4],
		insertImg: [
			["box", 0, ".single-thumbnail-wrap,.brxe-shortcode"], 2
		],
		customTitle: ".brxe-post-title",
		hide: ".brxe-code",
		category: "nsfw2"
	}, {
		name: "Cosphoria",
		url: {
			h: ["cosphoria.co"],
			p: "/albums/",
			e: "div[x-data*='carouse']"
		},
		box: [".w-full.h-full:has(div[x-data])", 2],
		imgs: () => {
			let data = fn.attr("div[x-data*='carouse']", "x-data");
			let str = fn.stringSlicer(data, "carousel(", "]");
			return fn.run(str).map(e => e.url);
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".w-full.h-full:has(div[x-data]) h1",
		category: "nsfw2"
	}, {
		name: "奈奈COS",
		url: {
			h: "nncos.com",
			p: /^\/\d+\.html$/
		},
		loop: () => {
			let cs = ".age-gate-restricted,.age-gate__restricted,.age-restriction,.age-gate__restricted--js";
			for (let e of fn.gae(cs)) {
				e.classList.remove(...cs.replaceAll(".", "").split(","));
			}
			document.body.removeAttribute("style");
		},
		loopTime: 3000,
		init: () => (document.cookie = "age_gate=18;"),
		imgs: () => fn.getImgA(".article-content>p>img,.article-content>p>a>img", ".article-paging>a"),
		button: [4],
		insertImg: [".article-content>p", 2],
		autoDownload: [0],
		next: ".article-nav-prev a",
		prev: ".article-nav-next a",
		customTitle: "h1.article-title",
		hide: "#gh-container,.fixnav,.age-gate__wrapper",
		category: "nsfw2"
	}, {
		name: "Gallery Epic",
		host: ["galleryepic.com", "galleryepic.xyz"],
		url: {
			h: "galleryepic",
			p: /^\/(zh|en)\/(cosplay|album)\/\d+$/
		},
		init: () => fn.waitEle(["img[variant=thumbnail]", "next-route-announcer"]),
		imgs: async () => {
			fn.sm5();
			try {
				let src = fn.src("img[variant=thumbnail]");
				let dir = fn.dir(src);
				let id = src.split("/").at(-1);
				let dom = await fn.fetchDoc(fn.clp());
				let data_a = [...dom.scripts].filter(script => script.textContent.includes(',\\"images\\":\\"['));
				if (data_a.length) {
					let code = data_a.at(0).textContent.replaceAll("\n", "").replaceAll("\\", "");
					let images = fn.textToArray(code, '"images":');
					return images.map(e => dir + e);
				}
				let data_b = [...dom.scripts].filter(script => [id, '[\\"', '\\"]'].every(str => script.textContent.includes(str)));
				if (data_b.length) {
					let code = data_b.at(0).textContent.replaceAll("\n", "").replaceAll("\\", "");
					let s = code.indexOf('["' + id);
					let e = code.indexOf(']', s) + 1;
					code = code.slice(s, e);
					return JSON.parse(code).map(e => dir + e);
				}
				debug("代碼解析沒有提取出圖片網址");
				await fn.wait(() => {
					let button = fn.ge("//button[text()='加载更多' or text()='More']");
					if (!!button) {
						EClick(button);
					}
					return !button;
				});
				return fn.gae("img[variant='thumbnail']");
			} catch (error) {
				console.error(error);
				return [];
			}
		},
		button: [4],
		insertImgBF: () => fn.createImgBox(".flex.flex-col.items-center:has(>.grid)", 2),
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".flex.flex-col.items-center:has(>.grid)"),
		customTitle: ".justify-between h2",
		category: "nsfw1"
	}, {
		name: "Gallery Epic Cosplays 分類自動翻頁",
		url: {
			h: "galleryepic",
			p: /^\/(zh|en)\/(cosplays|albums)\/\d+$/
		},
		autoPager: {
			ele: ".grid:has(>.relative)",
			observer: ".grid>.relative",
			next: "a[aria-label='Go to next page']:not([tabindex])",
			re: "nav[role=navigation]",
			showTitle: 0,
			bF: (dom) => {
				for (let e of fn.gae(".animate-pulse", dom)) {
					e.nextSibling.className = "h-auto w-auto object-cover transition-all hover:scale-105 aspect-[3/4]";
					e.nextSibling.dataset.src = e.nextSibling.src;
					e.remove();
				}
			},
			aF: () => {
				let last = fn.gae(".grid:has(>.relative)").at(-1);
				for (let img of fn.gae("img[data-src]", last)) {
					img.src = loading_bak;
					fn.imagesObserver.observe(img);
				}
			}
		},
		category: "autoPager"
	}, {
		name: "Gallery Epic cosers 分類自動翻頁",
		url: {
			h: "galleryepic",
			p: /^\/(zh|en)\/(cosers|models)\/\d+\??$/
		},
		autoPager: {
			ele: ".grid:has(>.flex)",
			observer: ".grid>.flex",
			next: "a[aria-label='Go to next page']:not([tabindex])",
			re: "nav[role=navigation]",
			showTitle: 0,
			bF: (dom) => {
				for (let e of fn.gae(".animate-pulse", dom)) {
					e.nextSibling.removeAttribute("class");
					e.nextSibling.dataset.src = e.nextSibling.src;
					e.remove();
				}
			},
			aF: () => {
				let last = fn.gae(".grid:has(>.flex)").at(-1);
				for (let img of fn.gae("img[data-src]", last)) {
					img.src = loading_bak;
					fn.imagesObserver.observe(img);
				}
			}
		},
		category: "autoPager"
	}, {
		name: "Gallery Epic Coser 分類自動翻頁",
		url: {
			h: "galleryepic",
			p: /^\/(zh|en)\/coser\/\d+\/\d+\??$/
		},
		autoPager: {
			ele: ".grid:has(>.relative)",
			observer: ".grid>.relative",
			next: "a[aria-label='Go to next page']:not([tabindex])",
			re: "nav[role=navigation]",
			showTitle: 0,
			bF: (dom) => {
				for (let e of fn.gae(".animate-pulse", dom)) {
					e.nextSibling.className = "h-auto w-auto object-cover transition-all hover:scale-105 aspect-[3/4]";
					e.nextSibling.dataset.src = e.nextSibling.src;
					e.remove();
				}
			},
			aF: () => {
				let last = fn.gae(".grid:has(>.relative)").at(-1);
				for (let img of fn.gae("img[data-src]", last)) {
					img.src = loading_bak;
					fn.imagesObserver.observe(img);
				}
			}
		},
		category: "autoPager"
	}, {
		name: "Nude Bird/Nude Cosplay",
		url: {
			h: ["nudebird.biz", "nudecosplay.biz"],
			p: /^\/[^\/]+\/$/,
			e: "//p[a[img]]",
		},
		init: () => {
			let video = fn.ge(".online-video");
			if (video) {
				let x = fn.ge("//p[a[img]]");
				for (let e of fn.gae(".online-video")) insertBefore(x, e);
			}
		},
		imgs: ".thecontent a,.content-inner>p>a",
		button: [4],
		insertImg: ["//p[a[img]]", 2],
		customTitle: () => fn.dt({
			s: "h1",
			d: "nudecosplay.biz"
		}),
		category: "nsfw1"
	}, {
		name: "每天来点色色",
		url: {
			h: ["mtldss.top"],
			p: /\/\d+\/\d+\/\d+\//,
		},
		imgs: ".wp-posts-content img",
		button: [4],
		insertImg: [".wp-posts-content", 2],
		autoDownload: [0],
		next: {
			s: "a[href^=http]:has(>p)",
			t: "上一篇"
		},
		prev: {
			s: "a[href^=http]:has(>p)",
			t: "下一篇"
		},
		customTitle: ".article-title",
		category: "nsfw1"
	}, {
		name: "91绅士",
		host: ["91shenshi.com"],
		url: {
			t: "91绅士",
			p: "/posts/",
		},
		box: [".prose>div:not([class])", 1],
		imgs: ".prose>div:not([class]) img",
		button: [4],
		insertImg: [
			["box", 0, ".prose>div:not([id],[class])"], 2
		],
		customTitle: ".prose-h1",
		category: "nsfw2"
	}, {
		name: "Are Girl",
		url: {
			h: ["aregirl.com"],
			p: ".html",
		},
		box: [".jeg_post_tags", 1],
		imgs: ".content-inner img",
		button: [4],
		insertImg: [
			["box", 0, ".content-inner p:has(img)"], 2
		],
		autoDownload: [0],
		next: "a.prev-post",
		prev: "a.next-post",
		customTitle: ".content-inner h1",
		category: "nsfw2"
	}, {
		name: "G-MH",
		url: {
			h: ["g-mh.com"],
			p: "/gallery/",
		},
		imgs: () => {
			let pages = fn.ge("//a[span[text()='Next']]");
			if (pages) {
				let max = Number(pages?.previousElementSibling?.lastElementChild?.innerText);
				if (max > 1) {
					let links = fn.arr(max, (v, i) => `${fn.url}page/${i + 1}/`);
					return fn.getImgA("#article img", links);
				}
			}
			return fn.gae("#article img");
		},
		button: [4],
		insertImg: ["#article", 2],
		customTitle: "main h1",
		hide: ".bg-muted:has(script),div.items-center:has(>nav)",
		category: "nsfw2"
	}, {
		name: "Cosplaytele",
		url: {
			h: ["cosplaytele.com"],
			p: /^\/[^/]+\/$/,
		},
		imgs: "figure.gallery-item a",
		button: [4],
		insertImg: [".gallery", 2],
		endColor: "white",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "Cosplay18",
		url: {
			h: "cosplay18.pics",
			p: /^\/[^/]+\/$/,
		},
		imgs: ".single-page img",
		button: [4],
		insertImg: [
			[".single-page", 0, ".single-page>ul"], 2
		],
		endColor: "white",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "HOTPIC",
		url: {
			h: ["hotpic.cc"],
			p: "/album/"
		},
		imgs: () => {
			videoSrcArray = fn.gae("a[data-media=video]").map(e => e.dataset.srcMp4);
			return fn.gae("a[data-media=image]");
		},
		capture: () => _this.imgs(),
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "RussiaSexyGirls/EuroSexyGirls/UsaSexyGirls/AsianSexyGirls/LatinSexyGirls/EbonySexyGirls",
		url: {
			h: ["russiasexygirls.com", "eurosexygirls.com", "usasexygirls.com", "asiansexiestgirls.com", "latinsexygirls.com", "ebonysexygirls.com"],
			p: /^\/\d+\/[\w-]+\/$/
		},
		imgs: ".entry-summary img:not([width='18'])",
		autoDownload: [0],
		next: ".prevPost>a",
		prev: ".nextPost>a",
		customTitle: "span.entry-title",
		category: "nsfw2"
	}, {
		name: "JimmysOnline.com",
		url: {
			h: "www.jimmysonline.com",
			p: /^\/[^\/]+\/$/,
			e: "a.aigpl-img-link[data-mfp-src]"
		},
		imgs: () => fn.gae("a.aigpl-img-link[data-mfp-src]").map(a => a.dataset.mfpSrc),
		button: [4],
		insertImg: [".aigpl-gallery", 2],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "gaidam18",
		url: {
			h: ["gaidam18.com", "gaingon18.me"],
			p: /^\/[^\/]+\/$/
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".entry-content img[src*='/img/b/']");
			thumbnailSrcArray = srcs.map(src => fn.wurl("w100", src, -2));
			return srcs.map(src => fn.wurl("s16000", src, -2));
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: "Ảnh sex "
		}),
		hide: "[class^='float']",
		category: "nsfw2"
	}, {
		name: "JJCOS",
		url: {
			h: ["jjcos.com"],
			p: "/post/"
		},
		init: () => (tempEles = fn.gae("#post-content h2")),
		imgs: "#post-content img",
		button: [4],
		insertImg: ["#post-content", 2],
		insertImgAF: (_, b) => b.before(...tempEles),
		autoDownload: [0],
		next: ".next:has(.fa-chevron-left)+a",
		prev: ".next:has(.fa-chevron-right)+a",
		customTitle: "#post-content h2",
		category: "nsfw2"
	}, {
		name: "Xiunice.com",
		url: {
			h: ["xiunice.com"]
		},
		box: [".wp-block-gallery", 1],
		imgs: ".wp-block-gallery img",
		button: [4],
		insertImg: [
			["box", 0, ".wp-block-gallery"], 2
		],
		autoDownload: [0],
		next: ".nav-previous .prev>a",
		prev: ".nav-previous .next>a",
		customTitle: "h1.tdb-title-text,h1.entry-title",
		category: "nsfw2"
	}, {
		name: "CG Cosplay",
		url: {
			h: ["cgcosplay.org"],
			p: /^\/\d+\/$/
		},
		init: () => {
			let video = fn.ge(".fluid_video_wrapper");
			if (video) {
				let x = fn.ge(".gallery");
				for (let e of fn.gae(".fluid_video_wrapper")) insertBefore(x, e);
			}
		},
		MutationObserver: () => {
			for (let e of fn.gae("body>*")) {
				if (e.innerHTML.includes("ad blocking") || e.innerHTML.includes("user-select: none;")) {
					e.remove();
				}
			}
		},
		imgs: ".gallery .gallery-item a:has(>img:not([src$='/banner'])),.elementor-image-gallery>a[data-elementor-open-lightbox]",
		next: ".nav-previous a[rel=prev]",
		prev: ".nav-next a[rel=next]",
		customTitle: ".elementor-heading-title",
		hide: "#page+[id][class]:has(.adblock_title),.code-block",
		category: "nsfw1"
	}, {
		name: "CG Cosplay AAD",
		reg: /^https?:\/\/cgcosplay\.org\//,
		MutationObserver: () => {
			for (let e of fn.gae("body>*")) {
				if (e.innerHTML.includes("ad blocking") || e.innerHTML.includes("user-select: none;")) {
					e.remove();
				}
			}
		},
		hide: "#page+[id][class]:has(.adblock_title)",
		category: "ad"
	}, {
		name: "Mitaku",
		url: {
			h: "mitaku.net",
			e: "a.msacwl-img-link[data-mfp-src]"
		},
		init: () => fn.addMutationObserver(() => {
			for (let e of fn.gae("body>div")) {
				if (e.innerHTML.includes("Ads Blocker Detected")) {
					e.remove();
					return;
				}
			}
		}),
		imgs: () => fn.gae("a.msacwl-img-link[data-mfp-src]").map(a => a.dataset.mfpSrc),
		button: [4],
		insertImg: [
			[".entry-content", 2], 2
		],
		autoDownload: [0],
		next: ".previous>a",
		prev: ".next>a",
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: /.[\smitaku]{6,7}\.net./
		}),
		hide: "div:has(.adblock_title)",
		category: "nsfw2"
	}, {
		name: "Mitaku AAD",
		url: {
			h: ["mitaku.net"]
		},
		init: () => fn.addMutationObserver(() => {
			for (let e of fn.gae("body>div")) {
				if (e.innerHTML.includes("Ads Blocker Detected")) {
					e.remove();
					return;
				}
			}
		}),
		hide: "div:has(.adblock_title)",
		category: "ad"
	}, {
		name: "Hình ảnh gái",
		url: {
			h: ["hinhanhgai.com"]
		},
		page: () => ["/image/", "/article/", "/hentai/content/"].some(p => fn.curl(p)),
		data: () => {
			fn.sm5();
			let _fetch;
			if (fn.clp("/image/")) {
				let id = fn.clp().match(/\d+/g).at(-1);
				_fetch = fn.j(`/api/photo/${id}`).then(json => (siteJson = json));
			} else if (fn.clp("/hentai/")) {
				let id = fn.clp().match(/\d+/g).at(-1);
				_fetch = fn.j(`/api/comic/chapter/${id}`).then(json => (siteJson = json));
			} else if (fn.clp("/article/")) {
				_fetch = fn.fetchDoc(fn.clp()).then(dom => (doc = dom));
			}
			return _fetch.then(() => fn.hm());
		},
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (fn.clp("/image/")) {
				return siteJson.files.map(e => e.full_url);
			} else if (fn.clp("/hentai/")) {
				return siteJson.image_urls;
			} else if (fn.clp("/article/")) {
				return fn.gae(".content img", doc);
			}
			return [];
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: ([key_a, key_b]) => {
			if (fn.clp("/image/")) {
				let a = siteJson?.iterator[key_a];
				return isObject(a) ? "/image/" + a.id : null;
			} else if (fn.clp("/hentai/")) {
				let a = siteJson[key_b];
				return isObject(a) ? "/hentai/content/" + a.id : null;
			}
			return null;
		},
		next: () => _this.np(["prev", "next_chapter"]),
		prev: () => _this.np(["next", "prev_chapter"]),
		chapters: () => ("chapter_list" in siteJson) ? siteJson.chapter_list.map(({
			id,
			title
		}) => ({
			text: title,
			url: fn.wurl(id)
		})).reverse() : [],
		customTitle: () => {
			if (fn.clp("/image/")) {
				return fn.dt({
					t: siteJson.name
				});
			} else if (fn.clp("/hentai/")) {
				return siteJson?.comic?.title + " - " + siteJson?.title;
			} else if (fn.clp("/article/")) {
				return fn.dt({
					s: "h1.title"
				}, doc);
			}
			return null;
		},
		hide: "#m_website_float,#m_website_center,#m_image_content_title,.aside_right_ad,#p_image_content_title,#p_website_float,#p_website_center,#p_website_right_float",
		category: "nsfw2"
	}, {
		name: "Maulon",
		host: "1sex.maulon.vip",
		url: {
			t: "Maulon",
			p: ".html",
			e: ".entry-content .separator"
		},
		imgs: () => fn.getImgA(".entry-content .separator>a", ".page-links a"),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "LUV.VN",
		url: {
			h: ["luv.vn"],
			p: /^\/[^\/]+\/$/
		},
		srcset: ".wp-block-image img",
		customTitle: ".jeg_post_title",
		category: "nsfw1"
	}, {
		name: "Gai.vn",
		url: {
			h: ["www.gai.vn", "gai.vn"]
		},
		page: () => fn.clp() !== "/" && !fn.clp("/tags-") && fn.ge("#startSlideshow"),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			return fn.fetchDoc(fn.clp()).then(dom => {
				apiCustomTitle = fn.gt(".nav-breadcrumb>.nav-breadcrumb-item:last-child", 1, dom);
				let c_eles = fn.gae("a[data-fancybox='slide']", dom);
				let c_t_eles = fn.gae("a[data-fancybox='slide'] img", dom);
				let pages = fn.ge(".pagination .next-page", dom);
				if (pages) {
					let max = fn.gt(".pagination .page-item:has(.next-page)", 2, dom);
					let links = fn.arr(max, (v, i) => i == 0 ? fn.clp() : fn.clp() + "-startpic-" + (i * 20));
					links.shift();
					return fn.getEle(links, "a[data-fancybox='slide']").then(p_eles => {
						let p_t_eles = p_eles.map(e => fn.ge("img", e));
						let t_eles = [...c_t_eles, ...p_t_eles];
						thumbnailSrcArray = t_eles.map(e => e.dataset.src);
						return [...c_eles, ...p_eles];
					});
				}
				thumbnailSrcArray = c_t_eles.map(e => e.dataset.src);
				return c_eles;
			});
		},
		button: [4],
		insertImgBF: () => fn.waitEle("#wrapper>.container-fluid").then(e => fn.createImgBox(e, 1, 1200)),
		insertImg: [
			["box", 0], 2
		],
		insertImgAF: () => fn.hideEle("#wrapper>.container-fluid,#secondary-navbar,#playerbutton"),
		fancybox: {
			blacklist: 1
		},
		category: "nsfw1"
	}, {
		name: "imgcup.com",
		url: {
			h: "imgcup.com",
			p: ".html"
		},
		box: [".penci-post-gallery-container", 2],
		imgs: ".item-gallery-masonry>a",
		thums: ".item-gallery-masonry>a img",
		button: [4],
		insertImg: [
			["box", 0, ".penci-post-gallery-container"], 2
		],
		autoDownload: [0],
		next: ".prev-post-inner>a",
		prev: ".next-post-inner>a",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "imgcup.com",
		url: {
			h: ["imgcup.com"],
			p: ".html"
		},
		box: [".wp-block-image", 1],
		srcset: ".wp-block-image img[srcset],.wp-block-image img[data-srcset]",
		button: [4],
		insertImg: [
			["box", 0, ".wp-block-image"], 2
		],
		autoDownload: [0],
		next: ".prev-post-inner>a",
		prev: ".next-post-inner>a",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "MissKON.com",
		host: ["misskon.com"],
		reg: /^https?:\/\/misskon\.com\/[^\/]+\/$/,
		imgs: () => fn.getImg(".entry img[decoding]", fn.gt(".page-link>*:last-child"), 4),
		button: [4],
		insertImg: ["//p[img[@decoding]]", 2],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Xiuren",
		url: {
			h: ["xiuren.biz"],
			p: /^\/[^\/]+\/$/
		},
		imgs: ".content-inner a[data-lbwps-srcsmall],.content-inner a[rel=noopener],.content-inner a[data-fancybox],.content-inner .fancybox-thumb",
		button: [4],
		insertImg: [".content-inner", 2],
		autoDownload: [0],
		next: "a.post.prev-post",
		prev: "a.post.next-post",
		customTitle: "h1.jeg_post_title",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw1"
	}, {
		name: "Asigirl.com",
		url: {
			h: "asigirl.com",
			p: /^\/[^\/]+\/$/
		},
		box: ["#asigirl-gallery", 1],
		imgs: "#asigirl-gallery a",
		thums: "#asigirl-gallery a>img",
		button: [4],
		insertImg: [
			["box", 0, "#asigirl-gallery"], 2
		],
		customTitle: () => {
			if (fn.ge("#content-header-title")) {
				return fn.dt({
					s: "#content-header-title"
				});
			} else if (fn.ge("meta[property='og:image:alt']")) {
				return fn.attr("meta[property='og:image:alt']", "content");
			}
			return document.title;
		},
		category: "nsfw1"
	}, {
		name: "Asigirl.com 分類自動翻頁",
		reg: /^https?:\/\/asigirl\.com\//,
		autoPager: {
			ele: ".oxy-posts",
			observer: ".oxy-posts>*",
			next: "span.current+a:not(.next)",
			re: ".oxy-easy-posts-pages",
			pageNum: "span.current"
		},
		openInNewTab: ".oxy-posts a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "4KHD",
		host: ["www.4khd.com", "aynzl.uuss.uk", "zrxiu.ssuu.uk"],
		url: {
			e: "//a[@rel='home'][text()='4KHD']",
			p: /^\/content\/\d+\/[^\.\/]+\.html$/
		},
		init: () => {
			if ("serviceWorker" in navigator) {
				let loop = setInterval(() => {
					navigator.serviceWorker.getRegistrations().then(registrations => {
						if (registrations.length) {
							for (let registration of registrations) {
								registration.unregister();
							}
							clearInterval(loop);
						}
					});
				}, 1000);
			}
		},
		imgs: () => fn.getImgA("figure.wp-block-image>a>img,#basicExample>a>img,.entry-content>p>a>img", ".page-link-box a").then(srcs => srcs.map(src => fn.rt(src, [
			[/i\d\.wp\.com\//, ""],
			["pic.4khd.com", "img.4khd.com"],
			[/\?.+$/, ""],
			[/\/w\d+-rw\//, "/w2500-h2500-rw/"]
		]))),
		button: [4],
		insertImg: [
			[".page-link-box,.wp-block-post-content>*:last-child,#khd", 1, "#basicExample,.wp-block-image,.entry-content>p:not(#FullPictureLoadEnd),.page-link-box"], 2
		],
		customTitle: "h3.wp-block-post-title",
		css: ".FullPictureLoadImage{max-width:100%!important}",
		hide: ".centbtd,.popup,.wp-container-13,.popup-iframe",
		category: "nsfw2"
	}, {
		name: "4KHD AAD",
		url: {
			e: "//a[@rel='home'][text()='4KHD']"
		},
		init: () => {
			if (fn.lh === "www.4khd.com") {
				const replaceSrc = () => {
					for (let e of fn.gae("img[src*='pic.4khd.com']")) {
						let src = e.src;
						src = src.replace("pic.4khd.com", "img.4khd.com");
						e.src = src;
					}
				};
				fn.addMutationObserver(replaceSrc);
			}
		},
		hide: ".centbtd,.popup,.wp-container-13,.popup-iframe",
		category: "ad"
	}, {
		name: "AsianPink",
		url: {
			h: ["asianpink.net"],
			p: /^\/[^\/]+\/$/
		},
		imgs: () => {
			let max = Number(fn.gt(".pagination .next", 2)) || 1;
			if (max > 1) {
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}?gallery_page=${i + 1}`);
				return fn.getImgA(".gallery-wrapper img", links).then(srcs => srcs.map(e => decodeURIComponent(e)));
			}
			return fn.getImgSrcArr(".gallery-wrapper img").map(e => decodeURIComponent(e));
		},
		button: [4],
		insertImg: [".gallery-wrapper", 2],
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "Buon Dua",
		url: {
			h: ["buondua.com", "buondua.us"],
			e: ".article-fulltext img[alt]"
		},
		init: () => {
			fn.remove("//div[text()='Sponsored ads']");
			fn.remove(".search-form~*");
			for (let e of fn.gae(".pagination a[previous],.pagination a[next]")) e.classList.add('disabled');
		},
		imgs: () => {
			let max = 1;
			let end = fn.ge("//nav/a[text()='End']");
			if (end) {
				max = fn.getUSP("page", end.href);
			}
			return fn.getImg(".article-fulltext img[alt]", max);
		},
		button: [4],
		insertImg: [".article-fulltext", 2],
		customTitle: ".article-header>h1",
		referrerpolicy: "strict-origin",
		hide: "div:not([class]):has(>small),a[href^=java]",
		category: "nsfw2"
	}, {
		name: "HOTGIRLchina格式",
		url: {
			h: ["hotgirlchina.com", "cucnong.com"],
			e: ".wp-block-gallery img"
		},
		init: () => fn.remove("div:has(>iframe),center:has(iframe)"),
		imgs: () => fn.getImgSrcArr(".wp-block-gallery img").filter(src => !src.endsWith(".gif")),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-previous a",
		prev: ".nav-next a",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /\(\d+\s?photos\s?\)|(\s?\(\d+\s?photos?\s?\+\s?\d+\s?videos?\))|\([0-9\s]+ảnh[0-9\s\+]+video\)|\([0-9\s]+ảnh.*\)|\/mitaku\.net\//i
		}),
		hide: "div:has(>iframe),center:has(iframe),#tpbr_topbar,.ad-container,.nwm-hidden-mobile,section[id^='custom_html']",
		category: "nsfw2"
	}, {
		name: "HOTGIRLchina 格式 AD",
		url: {
			h: ["hotgirlchina.com", "ephimsex.com", "cucnong.com"],
		},
		init: () => fn.remove("div:has(>iframe),center:has(iframe)"),
		hide: "div:has(>iframe),center:has(iframe),#tpbr_topbar,.ad-container,.nwm-hidden-mobile,section[id^='custom_html'],.boxzilla-container,.boxzilla-overlay,.sharrre-container,#vietpub-overlay",
		category: "ad"
	}, {
		name: "3600000 Beauty",
		host: ["3600000.xyz"],
		reg: /^https?:\/\/3600000\.xyz\/[^\/]+\/$/,
		imgs: () => {
			let [a, img] = ["//a[img[@file]]", ".entry-content img.ls_lazyimg[file]"];
			if (fn.ge(a)) {
				return fn.gae(a);
			} else if (fn.ge(img)) {
				return fn.gae(img).map(e => e.getAttribute("file"));
			}
			return [];
		},
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: ".entry-title",
		hide: "ins",
		category: "nsfw1"
	}, {
		name: "Big Boobs Asia",
		host: ["www.tokyobombers.com"],
		reg: /^https?:\/\/www\.tokyobombers\.com\/\d+\/\d+\/\d+\/[^\/]+\/$/,
		imgs: () => {
			if (fn.ge(".gallery img[srcset]")) {
				return fn.getImgSrcset(".gallery img[srcset]");
			}
			return fn.gae("a[itemprop='contentURL']");
		},
		button: [4],
		insertImg: [".gallery", 2],
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "NA山羊的部落格/喵魔的亂想魔境",
		link: [
			"https://nagoat.pixnet.net/blog",
			"https://felix0621.pixnet.net/blog"
		],
		url: {
			h: "pixnet.net",
			p: "/posts/",
			e: "#article-content-inner img,.article-content-inner img"
		},
		imgs: () => {
			let eles = fn.gae("#article-content-inner img,.article-content-inner img").filter(e => !e.closest(".in-read-ad"));
			thumbnailSrcArray = fn.getImgSrcArr(eles);
			return thumbnailSrcArray.map(url => {
				if (url.includes("?url")) {
					url = fn.getUSP("url", url);
				}
				return url.replace(/_\w\.(\w+)$/i, ".$1");
			});
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//li[contains(text(),'上一篇')]/a",
		prev: "//li[contains(text(),'下一篇')]/a",
		customTitle: ".title h2,.header-title div",
		category: "nsfw1"
	}, {
		name: "Nao Kanzaki and a few friends/NYO Cosplay/Navi Cosplay/Picgir",
		url: {
			h: ["aitoda.blogspot.com", "2bcosplay.blogspot.com", "navicosplay.blogspot.com", "picgir.blogspot.com"],
			p: /^\/\d+\/\d+\/[\w-]+\.html/
		},
		imgs: ".entry-content .separator a:not([data-saferedirecturl]),div.separator>img",
		thums: ".entry-content .separator a:not([data-saferedirecturl]) img,div.separator>img",
		videos: "iframe[title='YouTube video player'],iframe[id^='BLOGGER-video']",
		autoDownload: [0],
		next: ".blog-pager-older-link",
		prev: ".blog-pager-newer-link",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "jangjoo",
		url: {
			h: ["jangjooart.blogspot.com"],
			p: /^\/\d+\/\d+\/[\w-]+\.html/
		},
		imgs: ".post-body img",
		button: [4],
		insertImg: [".post-body", 2],
		autoDownload: [0],
		next: ".blog-pager-older-link",
		prev: ".blog-pager-newer-link",
		customTitle: ".post_item h1",
		category: "nsfw1"
	}, {
		name: "Photo Beach",
		url: {
			h: ["photobeach.blogspot.com"],
			p: /^\/\d+\/\d+\/[\w-]+\.html/
		},
		imgs: ".entry-content a:has(>img),br~a,br~img",
		category: "nsfw2"
	}, {
		name: "sekushipic/Idolru Channel/Cosplay Club",
		url: {
			h: ["sekushipic.blogspot.com", "janidol.blogspot.com", "cosplay-club3.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		imgs: ".separator>a",
		thums: ".separator img",
		button: [4],
		insertImg: [
			[".separator", 1, ".separator,.separator~br"], 2
		],
		autoDownload: [0],
		next: "a.blog-pager-older-link",
		prev: "a.blog-pager-newer-link",
		customTitle: ".entry-title",
		hide: ".post-header",
		category: "nsfw1"
	}, {
		name: "IDOL AREA/OppaiMag/adnvadnvvda",
		url: {
			h: ["idolarea.blogspot.com", "oppaimag.blogspot.com", "maiasihd.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		imgs: ".separator>a",
		thums: ".separator img",
		button: [4],
		insertImg: [".entry-content,.post-content", 2],
		customTitle: "h1.entry-title,h1.post-title,h3.entry-title,h3.post-title",
		category: "nsfw1"
	}, {
		name: "25精力旺盛",
		url: {
			h: ["25jingliwangsheng.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		box: [".entry-content img[alt='']", 1],
		imgs: ".entry-content img[alt='']",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content img[alt='']"], 2
		],
		customTitle: "h1.entry-title,h3.entry-title",
		category: "nsfw1"
	}, {
		name: "Nude Models/Beauty Pretty Sexy",
		url: () => isPC && (fn.lh === "blognudemodels.blogspot.com" || fn.lh === "beprse.blogspot.com"),
		page: () => fn.clp(".html"),
		SPA: () => _this.page(),
		observeURL: "loop",
		init: () => _this.page() ? fn.waitEle([".overview-header", "h1.entry-title", ".separator>a"]) : fn.waitEle("#gadget-dock"),
		imgs: () => _this.page() ? fn.gae(".separator>a") : [],
		repeat: 1,
		capture: () => _this.imgs(),
		next: () => _this.page() ? fn.gu("a.next") : null,
		customTitle: () => _this.page() ? fn.delay(200, 0).then(() => fn.dt({
			s: "h1.entry-title"
		})) : null,
		category: "nsfw2"
	}, {
		name: "Nude Models/Beauty Pretty Sexy",
		reg: /^https?:\/\/(blognudemodels\.blogspot\.com|beprse\.blogspot\.com)\/\d+\/\d+\/[^\.]+\.html\?m=1$/,
		init: () => fn.waitEle(".separator img"),
		imgs: ".separator>a",
		button: [4],
		insertImg: [
			[".separator", 1, ".separator,.separator~br"], 2
		],
		customTitle: "title",
		category: "nsfw2"
	}, {
		name: "Curvy Asian",
		url: {
			h: ["curvyasian.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		imgs: "#blogger-gallery a.item-link",
		thums: "#blogger-gallery a.item-link img",
		button: [4],
		insertImg: ["#blogger-gallery", 2],
		autoDownload: [0],
		next: "a.blog-pager-older-link",
		prev: "a.blog-pager-newer-link",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "500 Brothers/Safebooru",
		url: {
			h: ["500brothersfun.blogspot.com", "safebooru.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		box: [".separator", 1],
		imgs: () => {
			let srcs = fn.getImgSrcArr(".post-body .separator>a");
			srcs = fn.removeImageCDN(srcs);
			thumbnailSrcArray = srcs.map(src => fn.wurl("w100", src, -2));
			return srcs.map(src => fn.wurl("s16000", src, -2));
		},
		button: [4],
		insertImg: [
			["box", 0, ".separator~br,.separator"], 2
		],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "min: archive/True Pic",
		url: {
			h: ["min-bin.blogspot.com", "truepichk.blogspot.com"],
			p: /^\/\d+\/\d+\/[^\.]+\.html/
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".post-body .separator>a");
			thumbnailSrcArray = srcs.map(src => fn.wurl("w100", src, -2));
			return srcs.map(src => fn.wurl("s16000", src, -2));
		},
		button: [4],
		insertImg: [".post-body", 2],
		autoDownload: [0],
		next: "a.blog-pager-older-link",
		prev: "a.blog-pager-newer-link",
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Tabakus Gallery",
		reg: /^https?:\/\/tabakus\.blogspot\.com\/\d+\/\d+\/[^\.]+\.html/,
		init: () => fn.waitEle(".separator img"),
		box: [".separator:has(>a>img[height])", 1],
		imgs: ".separator>a:has(>img[height])",
		button: [4],
		insertImg: [
			["box", 0, ".separator:has(>a>img),.separator~br"], 2
		],
		customTitle: ".post_item>h1",
		category: "nsfw2"
	}, {
		name: "Graphis",
		host: ["20sanctuary-grahpis.blogspot.com"],
		reg: /^https?:\/\/20sanctuary-grahpis\.blogspot\.com\/\d+\/\d+\/[^\.]+\.html/,
		imgs: () => {
			let srcs = fn.getImgSrcArr(".post-body .separator>a");
			thumbnailSrcArray = srcs.map(src => fn.wurl("w100", src, -2));
			return srcs.map(src => fn.wurl("s16000", src, -2));
		},
		button: [4],
		insertImg: [".post-body", 2],
		customTitle: ".post_item>h1,.entry-titleS",
		category: "nsfw2"
	}, {
		name: "Chinese Nude Art Photos",
		url: {
			h: ["chinesenudeart.blogspot.com"],
			p: /^\/\d+\/\d+\/[\w-]+\.html/i
		},
		imgs: ".entry-content a[href]",
		thums: ".entry-content a[href]>img",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "a.blog-pager-older-link",
		prev: "a.blog-pager-newer-link",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: [
				"Chinese beautiful model Amanda -",
				"Beautiful Chinese girl -",
				"Beautiful Chinese girl ",
				"Chinese Beautiful girl -",
				" |18+ Nude model Amateur"
			]
		}),
		mcss: "#outer-wrapper{margin:0px!important;width:100%!important}",
		category: "nsfw1"
	}, {
		name: "Dicas de Animes",
		url: {
			h: ["dicadeanimesbr.blogspot.com"],
			p: /^\/\d+\/\d+\/[\w-]+\.html/i
		},
		imgs: ".entry-content a:has(>img)",
		thums: ".entry-content a:has(>img) img",
		autoDownload: [0],
		next: "a.prev-post-link",
		prev: "a.next-post-link",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "CUTE GIRLS ADDICT",
		url: {
			h: ["cutegirlsaddict.blogspot.com"],
			p: /^\/\d+\/\d+\/[a-z0-9-]+\.html/i
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".entry-content img[src*='/img/b/']");
			thumbnailSrcArray = srcs.map(src => fn.wurl("w100", src, -2));
			return srcs.map(src => fn.wurl("s16000", src, -2));
		},
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: "h1.post-title,h3.entry-title",
		category: "nsfw1"
	}, {
		name: "COSPLAYJP",
		url: {
			h: ["cosplayjp.wordpress.com"],
			p: /^\/\d+\/\d+\/\d+\/[\w-]+\//i
		},
		imgs: ".entry-content .wp-block-image a",
		thums: "entry-content .wp-block-image a img",
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: () => fn.dt({
			t: fn.ge(".entry-title").textContent
		}),
		category: "nsfw1"
	}, {
		name: "Sexy Fandom",
		url: {
			h: ["sexyfandom.com"],
			p: "/archives/"
		},
		srcset: ".post_content img",
		autoDownload: [0],
		next: "#prepost",
		prev: "#nextpost",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "Daily Cosplay",
		url: {
			h: ["dailycosplay.com"]
		},
		imgs: () => fn.gae("tbody td[width='754'] center img[title]").filter(e => !e.closest("img[alt=Previous],img[alt=Next],.t2")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "td[align=LEFT] a:has(img[alt=Previous])",
		prev: "td[align=RIGHT] a:has(img[alt=Next])",
		customTitle: () => fn.title(" - Daily Cosplay .com"),
		category: "nsfw1"
	}, {
		name: "Animexx",
		url: {
			h: ["www.animexx.de"],
			e: [".header_mitte>a", "#cosplay_tab_holder"],
			st: "PHPSESSID"
		},
		imgs: () => {
			fn.sm5();
			let data_url = new URL(document.querySelector(".header_mitte>a").href).searchParams.get("back").replace(/\?.+$/, "");
			let code = [...document.scripts].find(s => s.textContent.includes("PHPSESSID")).textContent;
			let [, id] = code.match(/PHPSESSID=(\w+)/);
			return fn.j(data_url + "photoswipe/?PHPSESSID=" + id, {
				"headers": {
					"x-requested-with": "XMLHttpRequest"
				}
			}).then(data => data.map(e => e.url));
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.title("auf Animexx.de"),
		category: "nsfw1"
	}, {
		name: "Everia.club",
		host: ["everia.club"],
		url: {
			e: ["//div[@id='site-logo']//a[@rel='home'][text()='EVERIA.CLUB']", ".wp-block-image img,.separator>a.no-lightbox,.entry-content img"]
		},
		imgs: () => {
			let [img, a] = [".wp-block-image img", ".separator>a.no-lightbox"]
			if (!!fn.ge(img)) {
				return fn.gae(img);
			} else if (!!fn.ge(a)) {
				return fn.gae(a);
			}
			return fn.gae(".entry-content img");
		},
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Everia club",
		url: {
			h: "www.everiaclub.com"
		},
		init: () => (tempEles = fn.gae(".mainleft h1")),
		imgs: ".mainleft img",
		button: [4],
		insertImg: [".mainleft", 2],
		insertImgAF: (_, bar) => bar.before(...tempEles),
		customTitle: ".mainleft h1",
		category: "nsfw2"
	}, {
		name: "SexyGirl",
		url: {
			h: ["www.sexygirl.cc", "sexygirl.cc"],
			p: ["photo/", "picture/", "cartoon/"],
			d: "pc"
		},
		imgs: ".image-container img",
		button: [4],
		insertImg: [".col-9:has(.image-container)", 2],
		next: "//a[text()='<-Previous']",
		prev: "//a[text()='Next->']",
		hide: "div[id^='exo-'],h3~.row .overflow-auto:has(div[id^='exo-'])",
		category: "nsfw2"
	}, {
		name: "SexyGirl",
		url: {
			h: ["www.sexygirl.cc", "sexygirl.cc"],
			p: ["photo/", "picture/", "cartoon/"],
			d: "m"
		},
		imgs: ".image-container img",
		button: [4],
		insertImg: [".row:has(.row .image-container)", 2],
		next: "//a[text()='<-Previous']",
		prev: "//a[text()='Next->']",
		hide: "div[id^='exo-'],h3~.row .overflow-auto:has(div[id^='exo-'])",
		category: "nsfw2"
	}, {
		name: "SexyGirl",
		url: {
			h: "cp.sexygirl.cc",
			p: "picture/"
		},
		imgs: ".image-container img",
		button: [4],
		insertImg: [".row:has(.image-container)", 2],
		next: "//a[text()='<-Previous']",
		prev: "//a[text()='Next->']",
		hide: "div[id^='exo-']",
		category: "nsfw2"
	}, {
		name: "Căng Cực",
		url: {
			h: ["cangcuc.com"]
		},
		imgs: ".post-single .royal_grid a",
		videos: ".royal_grid video>source",
		button: [4],
		insertImg: [
			[".royal_grid", 2, ".royal_grid"], 2
		],
		autoDownload: [0],
		next: ".widget-previous-post a",
		prev: ".widget-next-post a",
		customTitle: "h1.title",
		hide: ".d-flex:has(.img-float),body>div[style^='position'],.container-fluid:has(.mb-2)",
		downloadVideo: true,
		category: "nsfw1"
	}, {
		name: "pornpicxxx.com",
		url: {
			h: "pornpicxxx.com",
			p: "/gallery/"
		},
		imgs: "#grid a",
		thums: "#grid a img",
		customTitle: ".title h1",
		category: "nsfw2"
	}, {
		name: "Porn Pics",
		url: {
			h: "www.pornpics.com",
			p: "galleries/"
		},
		imgs: "#tiles a.rel-link",
		thums: "#tiles a.rel-link>img",
		button: [4],
		insertImg: ["#main", 3],
		customTitle: ".title-section h1",
		category: "nsfw2"
	}, {
		name: "NakedPics",
		url: {
			h: ["hotnakedwomen.com"],
			p: "/gals/"
		},
		imgs: ".thumb>a",
		thums: ".thumb img",
		customTitle: ".long-title",
		category: "nsfw2"
	}, {
		name: "HD Porn Pictures",
		url: {
			h: [
				"hdpornpictures.net",
				"bravotube.tv",
				"redwap.tv",
				"mofosex.net",
				"photos.mofosex.net",
				"niceporn.tv",
				"beeg.porn",
				"befuck.net"
			],
			p: "/id/",
			e: "#tiles a.rel-link"
		},
		imgs: () => {
			let imgs = fn.gau("#tiles a.rel-link");
			thumbnailSrcArray = imgs.map(e => e + "?w=300");
			return imgs;
		},
		capture: () => _this.imgs(),
		button: [4],
		insertImg: ["#main", 3],
		customTitle: () => fn.ge(".title-h1")?.textContent,
		category: "nsfw2"
	}, {
		name: "Freebigtit",
		host: ["www.freebigtitpornpics.com"],
		reg: /^https?:\/\/www\.freebigtitpornpics\.com\/content\/\d+\//,
		imgs: "//ul[@id='dylan']//a[img[@data-src]]",
		thums: "ul#dylan a>img[data-src]",
		button: [4],
		insertImg: [
			["#dylan", 2], 1
		],
		category: "nsfw2"
	}, {
		name: "NongMo.Zone",
		url: {
			h: "ilovexs.com",
			p: "/post_id/"
		},
		imgs: ".image-gallery img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		url: {
			h: "idol.gravureprincess.date",
			p: /^\/\d+\/\d+\/.+\.html/
		},
		imgs: ".separator img",
		autoDownload: [0],
		next: "a.blog-pager-older-link",
		prev: "a.blog-pager-newer-link",
		customTitle: ".post-title",
		category: "nsfw2"
	}, {
		name: "劍心回憶",
		host: ["kenshin.hk"],
		link: "https://kenshin.hk/category/jnews/photoalbum/",
		reg: /^https?:\/\/kenshin\.hk\/\d+\/\d+\/\d+\/[^/]+\/(#small-1)?$/,
		include: "//div[@class='entry-utility']/a[1][text()='寫真組圖'] | //div[@class='cat-tags']/a[1][text()='寫真組圖']",
		init: async () => {
			let p = fn.ge("//p[contains(text(),'寫真')]");
			if (p) {
				let tE = fn.ge(".entry-content,.post-page-content");
				insertBefore(tE, p);
			}
			let links = fn.gau("//a[button[contains(text(),'寫真')]]");
			await fn.getEle(links, ".entry-content>p>img,.post-page-content>p>img,.videoWrapper", ".entry-content,.post-page-content");
			let v = fn.ge(".videoWrapper");
			if (v) {
				let tE = fn.ge(".entry-content,.post-page-content");
				insertBefore(tE, v);
			}
		},
		imgs: ".entry-content>img,.post-page-content>img",
		button: [4],
		insertImg: [".entry-content,.post-page-content", 2],
		customTitle: () => fn.dt({
			s: "h1.entry-title,h2.post-title",
			d: /【寫真】|\s?\(\d+P,片\)/gi
		}),
		category: "nsfw1"
	}, {
		name: "Gravia",
		url: {
			h: ["www.gravia.site", "gravia.site"],
			p: "show.php",
			s: "id="
		},
		box: [".slideshow.for_box", 2],
		imgs: ".slideshow .item>img",
		thums: ".thums img",
		button: [4],
		insertImg: [
			["box", 0, ".slideshow.for_box"], 2
		],
		customTitle: () => fn.dt({
			s: ".container>h1",
			d: /\s?【\d+枚】/
		}),
		css: "img.small{max-width:100% !important;max-height:auto !important}",
		hide: ".cmd_bar.wide",
		category: "nsfw1"
	}, {
		name: "AI.img/AI2D",
		host: ["aiimg.fun", "ai2d.fun"],
		reg: [
			/^https?:\/\/aiimg\.fun\/note\/public\.php\?id=\d+/,
			/^https?:\/\/ai2d\.fun\/note\/public\.php\?id=\d+/,
			/^https?:\/\/ai2d\.fun\/ubox\/rom\.php\?id=\d+/
		],
		exclude: ".not_found.small",
		box: [".thums", 2],
		imgs: () => fn.getNP(".thums>.item", ".pager>a.now+a", null, ".pager").then(() => {
			thumbnailSrcArray = fn.getImgSrcArr(".thums img");
			return fn.gae("div.item[org_img_url]");
		}),
		button: [4],
		insertImg: [
			["box", 0, ".thums,.slideshow,.pager,.search_range"], 2
		],
		customTitle: () => fn.gt("h1").replace(/\s\(\d+枚\)/, "").replaceAll("/", "/"),
		category: "nsfw2"
	}, {
		name: "抜けるっ!二次元エロ画像&イラストまとめ",
		url: {
			h: "ero-gazou.jp",
			e: ".grid-container img"
		},
		init: () => fn.addMutationObserver(() => document.documentElement.classList.remove("pum-open", "pum-open-overlay", "pum-open-scrollable")),
		imgs: () => fn.getImgA(".grid-container img", ".pager-numbers a"),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a.prev-post",
		prev: "a.next-post",
		customTitle: "h1.entry-title",
		css: "html.pum-open{overflow: auto}",
		hide: "#content-top,#content-bottom,.pum-overlay",
		category: "nsfw2"
	}, {
		name: "NEWSグラビアアイドル.net",
		url: {
			h: "news.idolsenka.net",
			p: "/archives/"
		},
		imgs: ".post_content img",
		videos: "iframe[title='YouTube video player']",
		customTitle: ".c-postTitle__ttl",
		category: "nsfw1"
	}, {
		name: "グラビア週刊誌 格式",
		url: {
			h: [
				"magazinejapanese.livedoor.blog",
				"magazinejapanese.blog.jp",
				"magazinejapanese3.blog.jp",
				"magazinejapanese4.doorblog.jp",
				"magazinejapanese5.blog.jp",
				"magazinejapanese6.blog.jp",
				"gravurezasshi7.livedoor.blog",
				"gravurezasshi9.doorblog.jp",
				"gravuremagazine12.blog.jp",
				"gravurezasshiex.blog.jp"
			],
			p: "/archives/"
		},
		imgs: ".article-body-inner>a,#article-contents>a",
		thums: ".article-body-inner>a>img,#article-contents>a>img",
		button: [4],
		insertImg: [".article-body-inner,#article-contents", 2],
		autoDownload: [0],
		next: "//li[text()='前の記事: ']/a | //a[text()='前の記事'] | //li/a[text()='< 前の記事'] | //li[@class='prev']/a",
		prev: "//li[text()='次の記事: ']/a | //a[text()='次の記事'] | //li/a[text()='次の記事 >'] | //li[@class='next both']/a",
		customTitle: "h1.article-title>a,.article-header>h1",
		category: "nsfw1"
	}, {
		name: "グラビア週刊誌 - 分類自動翻頁",
		url: {
			h: [
				"magazinejapanese.livedoor.blog",
				"magazinejapanese.blog.jp",
				"magazinejapanese3.blog.jp",
				"magazinejapanese4.doorblog.jp",
				"magazinejapanese5.blog.jp",
				"magazinejapanese6.blog.jp",
				"gravurezasshi7.livedoor.blog",
				"gravurezasshi9.doorblog.jp",
				"gravuremagazine12.blog.jp",
				"gravurezasshiex.blog.jp"
			],
			p: /^\/(\?p=\d+)?$|^\/archives\/([\d-]+|cat_\d+)\.html(\?p=\d+)?$/
		},
		autoPager: {
			ele: ".autopagerize_page_element,.article-list-outer",
			observer: "article.article,.article-list-outer>li",
			next: "//li[@class='current']/following-sibling::li[1]/a | //a[span[text()='次へ']]",
			re: ".pager,.pager_fixed,.fractional-page",
			pageNum: () => nextLink.match(/\?p=(\d+)/)[1]
		},
		openInNewTab: ".autopagerize_page_element a[href]:not([target=_blank]),.article-list-outer a[href]:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "エロマニア 猿!/グラドルマニア 猿!",
		url: {
			h: ["nisokudemosandal.blog.jp", "ippondemoninjin.livedoor.blog"],
			p: "/archives/"
		},
		imgs: ".article-body a[title]:has(>img)",
		autoDownload: [0],
		next: "//li[@class='prev']/a | //a[text()='前の記事']",
		prev: "//li[@class='next both']/a | //a[text()='次の記事']",
		customTitle: ".article-title",
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "水着グラビア",
		url: {
			h: ["www.mizugigurabia.com"],
			s: "p="
		},
		init: () => {
			fn.clearAllTimer();
			fn.remove("#content-top");
		},
		imgs: () => {
			let srcs_a = fn.getImgSrcset(".article img[srcset]");
			let srcs_b = fn.gae(".entry-content a:has(>img)").map(a => {
				if (a?.firstElementChild?.src) {
					let src = a.firstElementChild.src;
					src = src.replace(/s(\.\w+)/i, "$1");
					if (src == a.href) {
						return a.href;
					}
				}
				return a?.firstElementChild?.src;
			});
			return [...srcs_a, ...srcs_b];
		},
		capture: () => _this.imgs(),
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "エロ酒場",
		url: {
			h: ["ero-sakaba.com"],
			s: "p="
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".post_thum img,#post_body img[data-srcset]");
			return srcs.map(e => e.replace(/-\d+x\d+\./, "."));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a.nav_link_l",
		prev: "a.f_row_r",
		customTitle: "h1.post_title",
		hide: "#cboxOverlay,#colorbox",
		category: "nsfw2"
	}, {
		name: "エロ画像まとめ",
		host: ["geinou-nude.com"],
		reg: /^https?:\/\/geinou-nude\.com\/[^\/]+\/(#.*)?$/,
		init: () => fn.addMutationObserver(() => fn.remove(".widgetarea_sp,.widget_execphp,.adContainer")),
		imgs: ".post_thum>img,.post_content a[href*='/uploads/']",
		videos: "iframe[src*=youtube]",
		autoDownload: [0],
		next: "a.nav_link_l",
		prev: "a.f_row_r",
		customTitle: "h1.post_title",
		hide: ".widgetarea_sp,.widget_execphp,.adContainer",
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "お宝エログ幕府",
		url: {
			h: "bakufu.jp",
			p: "/archives/"
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".entry-content a[href*=bakufu]:has(img[src*=bakufu])");
			return srcs.map(e => e.replace("-scaled.", "."));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: "h1.entry-title",
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "お宝エロ画像ぷにぷに",
		url: {
			h: ["puni-puni.com"]
		},
		srcset: ".p-articleThumb>img,.wp-block-image img",
		customTitle: "h1.c-postTitle__ttl",
		category: "nsfw2"
	}, {
		name: "惚れた.net",
		url: {
			h: ["horeta.net"],
			p: /^\/[\w-]+\/$/
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".entry-content p>img.alignnone,.gallery-item img");
			return srcs.map(e => e.replace("-scaled.", "."));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".st-next-link",
		prev: ".st-prev-link",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "エロ画像女神ちゃんねる",
		url: {
			h: ["megamich.com"],
			p: /^\/[^\/]+\/\d+\.html$/
		},
		imgs: () => {
			let pages = fn.ge(".page-numbers");
			if (pages) {
				let max = fn.gt(".page-numbers a:last-child");
				return fn.getImg("img[id^='entry_image']", max, 9);
			}
			return fn.gae("img[id^='entry_image']");
		},
		capture: () => _this.imgs(),
		customTitle: "#Single_h1",
		hide: ".sidesticky_l:has(#im_wrap_left),.sidesticky_r:has(#im_wrap_right)",
		category: "nsfw2"
	}, {
		name: "裏ピク",
		url: {
			h: "www.urapic.com",
			p: "/blog-entry-"
		},
		imgs: "//div[@class='entry-body']//a[img[@title]] | //div[@class='entry_body']//a[img[@title]]",
		autoDownload: [0],
		next: "link[rel=prev],.next_entry>a",
		prev: "link[rel=next],.prev_entry>a",
		customTitle: () => fn.gt(".entry-title,.entry_title>h1").replace(/[w]+$/, ""),
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "画像ナビ!",
		url: {
			h: "gazounabi.com",
			p: "/archives/"
		},
		imgs: ".article-body-more a[title],#article-contents a[title]",
		autoDownload: [0],
		next: ".article-pager>.prev a",
		prev: ".article-pager>.next a",
		customTitle: "h2.entry-title,h1.article-title",
		category: "nsfw2"
	}, {
		name: "エロ画像ぱしゃりずむ",
		url: {
			h: "pashalism.com"
		},
		imgs: ".single-post-main a:has(>img[class*='wp-image'])",
		customTitle: "h1.single-post-title",
		category: "nsfw2"
	}, {
		name: "肉感美ガール/コスッピ!",
		url: () => fn.checkUrl({
			h: ["bi-girl.net", "cosppi.net"],
			p: [/\/[^\/]+$/, "/user/"],
			e: ".img_wrapper_nontop .img_wrapper"
		}) && !fn.lp.startsWith("/search"),
		imgs: () => {
			let links = [fn.lp];
			let pages = fn.ge(".pagination_num_wrapper");
			if (pages) {
				let max = fn.gt(".pagination_num_wrapper .next", 2);
				links = fn.arr(max, (v, i) => i == 0 ? fn.lp + "?sort=old" : fn.lp + `/page/${i + 1}?sort=old`);
			}
			return fn.getEle(links, ".img_wrapper_nontop .img_wrapper").then(eles => eles.map(e => {
				let video = fn.ge("div[data-link]:has(.video)", e);
				if (video) {
					videoSrcArray.push(video.dataset.link);
				}
				return fn.ge("img", e)?.dataset.src?.replace(":small", "");
			}));
		},
		capture: () => _this.imgs(),
		customTitle: ".entry-title",
		hide: ".ad_caution,aside:has(.box_ad_sp_top)",
		category: "nsfw2"
	}, {
		name: "アイドルセクシー画像集&裏",
		link: "http://intervalues.com/idol.html",
		url: {
			h: "intervalues",
			p: /^\/\w\/\w+\.html$/,
			e: ".idolname"
		},
		box: ["body", 0, 1200],
		imgs: async () => {
			let eles = fn.gae("a:has(>img)");
			let url = fn.gu("a:has(.idolname)");
			let max = fn.gae("div[class^=Page] a").length;
			if (max > 0) {
				let links = fn.arr(max, (v, i) => i == 0 ? url : url.replace(".html", "") + `${i + 1}.html`);
				eles = await fn.getEle(links, "a:has(>img)");
			}
			return eles.map(a => {
				let src = fn.src("img", a);
				thumbnailSrcArray.push(src);
				return a;
			});
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".idolname",
		category: "nsfw2"
	}, {
		name: "エロ画像-ラブコアラ-",
		url: {
			h: "lovekoala.com",
			p: /^\/[^\/]+\/$/,
			e: ".gallery"
		},
		imgs: async () => {
			let links = [fn.lp];
			let pages = fn.ge("p.pmt");
			if (pages) {
				let max = fn.gu("//a[text()='最後']")?.match(/\d+/g)?.at(-1) || fn.gu(".pmt a:last-child")?.match(/\d+/g)?.at(-1);
				links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `${i + 1}/`);
			}
			return fn.getEle(links, ".gallery .pbox>a").then(eles => eles.map(a => {
				let src = fn.src("img", a);
				thumbnailSrcArray.push(src);
				return a;
			}));
		},
		capture: () => _this.imgs(),
		customTitle: "h1.htxt1",
		category: "nsfw2"
	}, {
		name: "Rikitake.com",
		url: {
			h: ["rikitake.com"],
			p: "/g/"
		},
		imgs: "a[data-lightbox]",
		videos: "video>source",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: () => fn.dt({
			d: "|Rikitake.com"
		}),
		downloadVideo: true,
		observerClick: ".age-link.enter",
		category: "nsfw2"
	}, {
		name: "マブい女画像集/ちょい懐女画像集",
		url: {
			h: ["mabui-onna.com", "cyoinatu-onna.com"],
			p: "blog-entry-"
		},
		init: () => {
			let texts = fn.gae("//div[@class='entry_body']//div[not(br)][not(a[img])][not(@class='fc2_footer')][not(@class='topentry_text')][not(@class='fc2button-clap')][not(@class='entry_footer')][not(@class='entry_data')]");
			if (texts.length > 0) {
				let te = fn.ge(".topentry_text,.entry_body");
				for (let e of texts) insertBefore(te, e);
			}
		},
		box: [".entry_body", 1],
		imgs: ".topentry div>a:not([href*='.html'],[href*='.dmm.']),.wrapper section div>a:not([href*='.html'],[href*='.dmm.'])",
		button: [4],
		insertImg: [
			["box", 0, "div:has(>a[target]>img[alt]),div[id^='bnc_ad']"], 2
		],
		insertImgAF: () => {
			let e = fn.ge("div:has(>a[href*='.dmm.'])");
			if (e) {
				let x = fn.ge(".entry_body");
				insertBefore(x, e);
			}
		},
		autoDownload: [0],
		next: "a.pager_next,.next_entry>a",
		prev: "a.pager_prev,.prev_entry>a",
		customTitle: ".topentry_title span,.entry_title h1>strong",
		hide: "div[class$=Ad]",
		category: "nsfw1"
	}, {
		name: "アイドル村",
		host: ["idol-gazoum.net", "zilli-on.ru"],
		reg: [
			/^https?:\/\/idol-gazoum\.net\/\d+\.html$/,
			/^https?:\/\/zilli-on\.ru\/rushporn\/\d+\.html$/
		],
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr(".blog-feed-content-image .blog-image img");
			let pages = fn.ge(".pagination");
			if (pages) {
				let max = fn.gt("span.next", 2);
				thumbnailSrcArray = await fn.getImg(".blog-feed-content-image .blog-image img", max);
			}
			return thumbnailSrcArray.map(e => e.replace("middle_resize_", ""));
		},
		videos: "iframe[src*='youtube']",
		button: [4],
		insertImg: [".blog-feed-content-image", 2],
		customTitle: "h1.articles_header",
		category: "nsfw1"
	}, {
		name: "アイドル画像魂",
		host: ["blog.livedoor.jp"],
		reg: /^https?:\/\/blog\.livedoor\.jp\/idol_gravure_sexy\/archives\/\d+\.html$/,
		imgs: () => fn.getImgSrcArr(".pict").map(e => e.replace("-s.", ".")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".article-pager>.prev a",
		prev: ".article-pager>.next a",
		customTitle: "h1.article-title",
		category: "nsfw1"
	}, {
		name: "グラビア大銀河",
		url: {
			h: "gravuregalaxy.hatenablog.com",
			p: "/entry/"
		},
		imgs: "img.hatena-fotolife",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "美女の集い",
		url: {
			h: ["bizyonotudoi.com"],
			p: /^\/d\/\d+\.html$/
		},
		imgs: ".thumb-img-area>img",
		button: [4],
		insertImg: [".kizi-thumb-list", 2],
		customTitle: ".page-title",
		hide: "#pagemap-navi",
		category: "nsfw1"
	}, {
		name: "水着画像まとめ",
		url: {
			h: ["mizugazo.com"],
			p: "/archives/"
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".single_thumbnail>img,.wp-block-gallery img");
			return srcs.map(e => e.replace(/-\d+x\d+\./, "."));
		},
		capture: () => _this.imgs(),
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "裏垢女子ランキングナビ",
		url: {
			h: "uraaka-ranking.com"
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".in-pict img");
			return srcs.map(e => e.replace(":small", ""));
		},
		capture: () => _this.imgs(),
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "女体エロエロ画像集~",
		url: {
			h: "www.eroero-gazou.net",
			p: "/archives/"
		},
		imgs: ".entry-content a:has(img):not(.yarpp-thumbnail,[href$='8f5a-8.png'])",
		autoDownload: [0],
		next: ".prev a[rel=prev]",
		prev: ".next a[rel=next]",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "芸能人のエロ画像",
		url: {
			h: "geinoujin-gazou.mixh.jp"
		},
		imgs: ".eye-catch-wrap img,.entry-content img",
		autoDownload: [0],
		next: "a.prev-post",
		prev: "a.next-post",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "JKワールド",
		link: "https://jkeroina.net/3zigazou/",
		url: {
			h: "jkeroina.net"
		},
		imgs: () => fn.gae(".single_thumbnail img,.single-post-main .content img").filter(e => !e.closest("#wp_rp_first")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".navigation a[rel=prev]",
		prev: ".navigation a[rel=next]",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "JK太ももコレクション",
		url: {
			h: "suginamijk.blog.2nt.com",
			p: "/blog-entry-"
		},
		imgs: () => fn.gae(".ently_text img").filter(e => !e.closest(".relate_dl")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a[title='次ページへ進む']",
		prev: "a[title='前ページへ戻る']",
		customTitle: ".ently_title",
		category: "nsfw1"
	}, {
		name: "美巨乳美女図鑑@素人画像サイト",
		url: {
			h: "bikyonyu-bijo-zukan.com",
			p: "/post"
		},
		imgs: () => fn.getImgSrcArr(".entry-content img:not(.w_b_ava_img,[src$='ps-loader.svg'])").map(e => e.replace("-scaled.", ".")),
		capture: () => _this.imgs(),
		customTitle: "h1.entry-title",
		hide: "div:has(.adblock_title),.widget_custom_html",
		category: "nsfw2"
	}, {
		name: "性癖エロ画像",
		url: {
			h: "1000giribest.com",
			p: ".html"
		},
		imgs: ".entry-content img:not([alt^='管理人']),.entry-content-more img:not([alt^='管理人'])",
		autoDownload: [0],
		next: ".nav-single-previous a,.nav-previous a[rel=prev]",
		prev: ".nav-single-next a,.nav-next a[rel=next]",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "写真倉庫/いあんの女神たち",
		link: "https://ameblo.jp/shashinsouko/,https://ameblo.jp/himemiyaian/",
		url: {
			h: ["ameblo.jp"]
		},
		page: () => fn.clp("/entry-"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => fn.waitEle("a.pagingNext,a[href$=html]:has(p.skinWeakColor)"),
		imgs: () => _this.page() ? fn.waitEle(["#entryBody .PhotoSwipeImage,main article img"]).then(eles => {
			let imgs = eles.filter(e => !e.closest(".snslink"));
			return fn.getImgSrcset(imgs).map(e => e.replace(/\?caw=\d+$/, ""));
		}) : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//a[contains(@class,'pagingNext')] | //a[p[text()='次の記事']]",
		prev: "//a[contains(@class,'pagingPrev')] | //a[p[text()='前の記事']]",
		customTitle: () => _this.page() ? fn.waitEle(".js-entryWrapper h1,main article h1").then(e => fn.gt(e)) : null,
		hide: "div[aria-hidden]:has(#blogPCOverlayGeneral)",
		category: "nsfw2"
	}, {
		name: "日刊エログ",
		url: {
			h: "nikkanerog.com",
			p: "/blog-entry-"
		},
		imgs: () => {
			let eles = fn.gae(".mainEntryBody img,.mainEntryMore img,#entry .entry-body img").filter(e => !e.closest("a[href*='html'],a[href*='?']"));
			let srcs = fn.getImgSrcArr(eles);
			return srcs.map(e => e.replace(/s(\.\w+)$/, "$1"));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a:has(>img[src$='next.png']),#nav-top .next a",
		prev: "a:has(>img[src$='previous.png']),#nav-top .prev a",
		customTitle: ".entry_title_h2_ver2,header.entry-title h1",
		category: "nsfw2"
	}, {
		name: "素人エロ画像やったる夫",
		url: {
			h: "yaruo.info"
		},
		imgs: ".entry-content img",
		autoDownload: [0],
		next: ".prev a",
		prev: ".next a",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "パンダ28号の有名人DAI好キング!",
		url: {
			h: "www.pandagazo.net",
			s: "p="
		},
		srcset: ".eye-catch img,.entry-content .wp-block-image img,.wp-block-gallery img",
		autoDownload: [0],
		next: "a.prev-post",
		prev: "a.next-post",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "JKちゃんねる",
		url: {
			h: "channel-jk.com",
			s: "p="
		},
		imgs: "#the-content img,.content-box .content img",
		customTitle: "h1.entry-title,h1.title",
		category: "nsfw1"
	}, {
		name: "ぷるるんお宝画像庫",
		link: "http://blog.livedoor.jp/pururungazou/",
		reg: /^https?:\/\/blog\.livedoor\.jp\/pururungazou\/archives\/\d+\.html$/,
		imgs: () => {
			videoSrcArray = fn.gae("video[src]").map(e => e.src);
			return fn.gae(`
            .entry-content img[src*='/pururungazou/imgs/'],
            .entry-content img[src*='/media/'],
            .article-body img[src*='/pururungazou/imgs/'],
            .article-body img[src*='/media/'],
            a[title][href*='thetv.jp/i/']
            `).map(e => {
				if (e.nodeName === "A") {
					return e.href.replace(/\?w=.+$/, "");
				}
				return e.src.replace(/-s(\.\w+)$/, "$1");
			});
		},
		capture: () => _this.imgs(),
		customTitle: ".entry-title,.article-title",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Love Asian Babes",
		url: {
			h: ["amazon-love.com"],
			p: /^\/[^.]+\.html$/
		},
		imgs: () => fn.getImg(".entry-content img", fn.gt("//a[text()='Next Page »']", 2) || 1, 7),
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "span.prev>a",
		prev: "span.next>a",
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "Permanent Bachelor",
		host: ["www.saladpuncher.com"],
		reg: /^https?:\/\/www\.saladpuncher\.com\/\d+\/\d+\/[^\/]+\//,
		box: [".entry-container", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".rsTmb>img");
			return thumbnailSrcArray.map(e => e.replace(/-\d+x\d+(\.\w+)$/, "$1"))
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".posttitle",
		category: "nsfw1"
	}, {
		name: "Kemono/Coomer SPA",
		links: [
			"https://kemono.cr/artists",
			"https://coomer.st/artists",
			"https://kemono.cr/fantia/user/17148",
			"https://coomer.st/fansly/user/365239425979916288",
			"https://coomer.st/onlyfans/user/arty42575619"
		],
		url: {
			h: ["kemono.cr", "coomer.st"]
		},
		page: () => fn.clp("/post/") || fn.clp("/discord/server/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => {
			if (fn.clp("/post/")) {
				return fn.waitEle(["#main", ".post__user-name", ".post__title"]);
			}
			if (fn.clp("/discord/server/")) {
				return fn.waitEle("section[class*=discord] li[class*=active]");
			}
			return fn.waitEle("#main");
		},
		headers: () => ({
			"headers": {
				"accept": "text/css"
			}
		}),
		getPostJson: url => fn.j("/api/v1" + new URL(url).pathname, _this.headers()).then(json => {
			let {
				previews,
				videos
			} = json;
			let images = previews?.map(e => e.server + "/data" + e.path + "?f=" + e.name);
			videos = videos?.map(e => e.server + "/data" + e.path + "?f=" + e.name);
			return {
				images,
				videos
			}
		}),
		imgs: () => {
			if (fn.clp("/post/")) {
				fn.sm5();
				return _this.getPostJson(document.URL).then(obj => {
					videoSrcArray = obj.videos;
					return obj.images;
				});
			}
			if (fn.clp("/discord/server/")) {
				fn.sm5();
				return fn.j(`/api/v1/discord/channel/${fn.clp().split("/").at(-1)}`, _this.headers()).then(array => {
					let paths = array.map(e => e.attachments).flat().filter(e => fn.isImage(e.path)).map(e => e.path);
					return paths.map(p => `https://n1.${fn.lh}/data${p}`);
				});
			}
			return [];
		},
		customTitle: () => {
			if (fn.clp("/post/")) {
				return fn.gt(".post__user-name") + " - " + fn.gt(".post__title");
			}
			if (fn.clp("/discord/server/")) {
				return fn.gt("section[class*=discord]>aside>div") + " - " + fn.gt("section[class*=discord] li[class*=active]");
			}
			return null;
		},
		downloadVideo: true,
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		name: "Nekohouse",
		url: {
			h: "nekohouse.su",
			p: "/post/",
			e: "div.fileThumb[href]"
		},
		box: [".scrape__body", 2],
		imgs: () => {
			let urls = fn.gau("a[download]");
			if (urls.length) {
				for (let url of urls) {
					if (fn.isVideo(url)) {
						videoSrcArray.push(url);
					} else if (fn.isZip(url)) {
						fileUrlArray.push(url);
					}
				}
			}
			thumbnailSrcArray = fn.gae("div.fileThumb>img").map(e => e.dataset.src ?? e.src);
			return fn.gae("div.fileThumb[href]").map(e => fn.lo + e.getAttribute("href"));
		},
		button: [4],
		insertImg: ["box", 3],
		customTitle: [".scrape__user-name", ".scrape__title"],
		fetch: 1,
		category: "nsfw2"
	}, {
		name: "俊美图",
		host: ["www.meijuntu.com", "www.junmeitu.com", "www.jeya.de", "www.jeya.jp"],
		url: {
			h: [
				/^(www\.)?meijuntu\.com$/,
				/^(www\.)?junmeitu\.com$/,
				/^(www\.)?jeya\.\w+$/,
			],
			p: /\/([a-z]{2}\/)?\w+\/\w+\.html$/i,
			e: ".pictures img"
		},
		imgs: async () => {
			let imgsArr = [];
			let max = fn.gt("#pages>*:last-child", 2) || 1;
			let url = siteUrl.replace(/(-\d+)?\.html$/, "");
			let links = fn.arr(max, (v, i) => url + "-" + (i + 1) + ".html");
			for (let [page, link] of links.entries()) {
				let dom = await new Promise(async resolve => {
					for (let check = 1; check <= 100; check++) {
						let res = await fetch(link);
						if (res.status == 304 || res.status == 200) {
							let buffer = await res.arrayBuffer();
							let decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
							let htmlText = decoder.decode(buffer);
							let dom = fn.doc(htmlText);
							resolve(dom);
							break;
						} else {
							fn.showMsg(`第${page + 1}頁${res.status}重試第${check}次`, 2900);
							await delay(3000);
						}
					}
				});
				let imgs = fn.gae(".pictures img", dom);
				let te = fn.gae(".pictures img").at(-1);
				for (let e of imgs) {
					imgsArr.push(e.cloneNode(true));
					if (page != 0) insertAfter(te, e.cloneNode(true));
				}
				if (page != 0) {
					let ce = fn.gae("#pages");
					let re = fn.gae("#pages", dom);
					if (ce.length == re.length) {
						for (let [i, e] of ce.entries()) e.outerHTML = re[i].outerHTML;
					}
				}
				await delay(1000);
			}
			return imgsArr;
		},
		button: [4],
		insertImg: [".pictures", 1],
		autoDownload: [0],
		next: "//span[contains(text(),'下一')]/following-sibling::a",
		prev: "//span[contains(text(),'上一')]/following-sibling::a",
		customTitle: "h1.title",
		hide: ".pre_picture,.next_picture",
		category: "nsfw1"
	}, {
		name: "妹子图",
		url: {
			h: ["www.mt316.com", "mt316.com"],
			p: /^\/\w+\/\d+\.html$/
		},
		imgs: ".m-list-content img",
		button: [4],
		insertImg: [".m-list-content", 2],
		autoDownload: [0],
		next: ".sxpage_l>a",
		prev: 1,
		customTitle: ".m-list-tools>h2",
		css: ".m-list-content img{max-width:100%!important}",
		category: "nsfw1"
	}, {
		name: "美女集合",
		url: {
			h: ["meinvjihe.cc"],
			p: "/thread-"
		},
		imgs: ".message>img",
		button: [4],
		insertImg: [".message", 2],
		customTitle: ".media-body>span.break-all",
		category: "nsfw1"
	}, {
		name: "图宅网/咔咔西三/YouFreeX",
		url: {
			h: ["www.tuzac.com", "www.kkc3.com", "www.youfreex.com"],
			p: "/file/"
		},
		imgs: () => {
			let a = fn.ge("#the-photo-link");
			if (a) a.outerHTML = a.innerHTML;
			let max = fn.attr("#auto-play", "total");
			let [id] = fn.attr("#auto-play", "data").match(/\d+/);
			fn.sm5();
			let fetchNum = 0;
			return fn.arr(max, (v, i) => fn.j(`/api/?ac=get_album_images&id=${id}&num=${i + 1}`).then(json => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
				return json.src;
			}));
		},
		button: [4],
		insertImg: ["#task,#fdp-photo,#fdp-photo-old", 2],
		customTitle: () => fn.dt({
			s: ".fc-text-content>h1",
			d: /(\[\d+P\]|\n|\(\d+P\))/gi
		}),
		css: ".content-container .content{margin-right:0px!important}",
		hide: ".ad-container,.fdp-click-area,.ad-side-right,.footer",
		category: "nsfw2"
	}, {
		name: "图宅网/咔咔西三/YouFreeX",
		url: {
			h: ["www.tuzac.com", "www.kkc3.com", "www.youfreex.com"]
		},
		hide: ".ad-container",
		category: "ad"
	}, {
		name: "七仙子图片",
		host: ["www.qixianzi.com"],
		reg: /^https?:\/\/www\.qixianzi\.com\/\w+\/\d+\.html$/,
		imgs: () => {
			let url = fn.src("#diggnum script");
			let classid = fn.getUSP("classid", url);
			let id = fn.getUSP("id", url);
			let links = [`/e/wap/show.php?classid=${classid}&id=${id}`];
			return fn.getImgA(".arcmain img", links);
		},
		button: [4],
		insertImg: [".picture_content", 2],
		endColor: "white",
		next: "//li[contains(text(),'上一篇')]/a",
		prev: "//li[contains(text(),'下一篇')]/a",
		customTitle: "h1.diy-h1",
		hide: "nav:has(.pagination)",
		category: "nsfw1"
	}, {
		name: "七仙子图片M",
		host: ["www.qixianzi.com"],
		link: "https://www.qixianzi.com/e/wap/",
		reg: /^https?:\/\/www\.qixianzi\.com\/e\/wap\/show\.php\?/,
		imgs: ".arcmain img",
		button: [4],
		insertImg: [".arcmain", 1],
		customTitle: ".header>span",
		category: "nsfw1"
	}, {
		name: "嘿~色女孩",
		url: {
			h: ["heysexgirl.com"],
			p: "/archives/"
		},
		imgs: () => fn.getImg(".entry-content p>a,.entry-content p>img", fn.gt(".page-links>*:last-child"), "4"),
		button: [4],
		insertImg: [".entry-container", 2],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: "h1.page-title",
		category: "nsfw2"
	}, {
		name: "嘿~色女孩 分類自動翻頁",
		reg: [
			/^https?:\/\/heysexgirl\.com\/(page\/\d+)?$/,
			/^https?:\/\/heysexgirl\.com\/archives\/category\/\w+(\/page\/\d+)?$/
		],
		init: () => fn.waitEle(".blog-posts-wrapper[style]"),
		autoPager: {
			mode: 1,
			waitEle: ".blog-posts-wrapper[style]",
			ele: ".blog-posts-wrapper",
			observer: ".blog-posts-wrapper",
			next: "span.current+a",
			re: ".nav-links",
			pageNum: () => nextLink.match(/\d+$/)[0]
		},
		openInNewTab: ".blog-posts-wrapper a:not([target=_blank])",
		css: ".blog-posts-wrapper article.has-post-thumbnail .entry-container{margin:0 auto 0 !important}",
		category: "autoPager"
	}, {
		name: "性趣套图",
		host: ["tt.539765.xyz", "tt.xqtt.de"],
		url: {
			e: ["//div[@class='logo']/a[text()='性趣套图']", ".entry img"],
			p: "/e/action/ShowInfo.php"
		},
		imgs: async () => {
			if (fn.ge("embed[src*='sendvid']")) {
				let links = fn.gae("embed").map(e => e.src);
				let resArr = links.map(url => fn.xhrDoc(url).then(dom => fn.src("video>source", dom)));
				videoSrcArray = await Promise.all(resArr);
			}
			return fn.getImg(".entry img", fn.gt("a[title=总数]"), 8)
		},
		button: [4],
		insertImg: ["//div[@class='entry']//img/parent::*", 1],
		autoDownload: [0],
		next: "//p[contains(text(),'上一')]/a",
		prev: "//p[contains(text(),'下一')]/a",
		customTitle: ".contitle",
		css: ".main-content{margin-left:0px!important;}body{background:#ededed!important;}",
		hide: "aside.side",
		category: "nsfw2"
	}, {
		name: "苍井优图/榴榴杂谈",
		host: ["34.28tyu.com", "w33.28rty.com", "33.28ery.com", "www.28wer.com", "www.028kkp.com", "sldlxz.com", "34.yuxiangcao.com", "282471.xyz", "284019.xyz", "3az.447743.xyz"],
		url: {
			e: "//div[@class='logo']/a[text()='苍井优图' or text()='榴榴杂谈']",
			p: "/e/action/ShowInfo.php"
		},
		imgs: "img[id^='aimg'],.entry img",
		button: [4],
		insertImg: [".entry", 2],
		autoDownload: [0],
		next: "//p[contains(text(),'上一')]/a",
		prev: "//p[contains(text(),'下一')]/a",
		customTitle: ".contitle",
		category: "nsfw2"
	}, {
		name: "AVJB/The AV Porn",
		host: ["avjb.com", "theavporn.com"],
		link: "https://avjb.github.io/,https://avjb.com/albums/,https://theavporn.com/albums/",
		url: {
			e: "//a[text()='爱微社区'] | //title[contains(text(),'The AV Porn')]",
			p: /^\/albums\/\d+\//
		},
		init: () => new MutationObserver((mutations, observer) => {
			if (fn.ge(".chatra--webkit")) {
				fn.ge(".chatra--webkit").remove();
				observer.disconnect();
			}
		}).observe(document.body, MutationObserverConfig),
		box: [".images", 2],
		imgs: () => fn.getImgSrcArr(".images>a>img").map(e => e.replace(/\/main\/\d+x\d+\//, "/sources/")),
		thums: ".images>a>img",
		button: [4],
		insertImg: [
			["box", 0, ".images"], 2
		],
		customTitle: ".headline>h1",
		hide: ".sponsor,.chatra--webkit",
		category: "nsfw2"
	}, {
		name: "AVJB 去廣告",
		url: {
			e: "//a[text()='爱微社区']",
		},
		init: () => new MutationObserver((mutations, observer) => {
			if (fn.ge(".chatra--webkit")) {
				fn.ge(".chatra--webkit").remove();
				observer.disconnect();
			}
		}).observe(document.body, MutationObserverConfig),
		hide: ".sponsor,.chatra--webkit",
		category: "ad"
	}, {
		name: "Asian To Lick",
		url: {
			h: ["asiantolick.com"],
			p: "/post"
		},
		box: [".spotlight-group", 2],
		imgs: () => fn.removeImageCDN(fn.gae("div[data-src]").map(e => e.dataset.src)),
		button: [4],
		insertImg: [
			["box", 0, ".spotlight-group"], 2
		],
		customTitle: "h1",
		hide: "#touch_to_see",
		category: "nsfw2"
	}, {
		name: "Asian To Lick 移除圖片CDN",
		url: {
			h: ["asiantolick.com"]
		},
		init: () => fn.addMutationObserver(() => {
			for (let e of fn.gae("#container img[data-src*='wsrv.nl']")) {
				e.src = fn.getUSP("url", e.dataset.src);
				e.removeAttribute("data-src");
				e.removeAttribute("src-original");
			}
		}),
		category: "none"
	}, {
		name: "Goddess247/BestPrettyGirl/Girl Sweetie/Girl Dreamy/BestGirlSexy",
		url: () => fn.checkUrl({
			h: ["goddess247.com", "bestprettygirl.com", "girlsweetie.com", "girldreamy.com", "bestgirlsexy.com"]
		}) && !/^\/tag\/|^\/category\//.test(fn.lp),
		box: ["//p[img] | //img[@class='aligncenter size-full']", 1],
		imgs: ".elementor-widget-container p img[alt],.elementor-widget-container img.aligncenter.size-full,.elementor-widget-theme-post-content img",
		button: [4],
		insertImg: [
			["box", 0, "//p[img] | //img[@class='aligncenter size-full']"], 2
		],
		customTitle: () => fn.title(/ - Goddess247| - BestPrettyGirl| - Girl Sweetie| - Girl Dreamy| - BestGirlSexy/),
		category: "nsfw1"
	}, {
		name: "WordPress樣板",
		links: [
			"https://niwatori.my.id/category/uncategorized/",
			"https://okami.my.id/category/uncategorized/",
			"https://quenbox.top/?cat=1",
			"https://nekobox.top/index.php/category/blog/",
			"https://imgyagi.top/category/blog/"
		],
		url: {
			h: ["niwatori.my.id", "okami.my.id", "quenbox.top", "nekobox.top", "imgyagi.top"],
			e: ".post-navigation .nav-links"
		},
		srcset: ".entry-content .wp-block-gallery img",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: "h1.entry-title",
		category: "nsfw1"
	}, {
		name: "Sexy Girl Pictures",
		url: {
			h: "beautypics.org",
			p: "/archives/"
		},
		srcset: ".elementor-widget-theme-post-content img:not(.emoji)",
		button: [4],
		insertImg: [".elementor-widget-theme-post-content", 2],
		autoDownload: [0],
		next: ".elementor-post-navigation a[rel=prev]",
		prev: ".elementor-post-navigation a[rel=next]",
		customTitle: "h1.elementor-heading-title",
		category: "nsfw1"
	}, {
		name: "Girl Atlas",
		host: ["www.girl-atlas.com", "girl-atlas.com", "www.girl-atlas.cc", "girl-atlas.cc", "www.girl-atlas.net", "girl-atlas.net"],
		url: {
			t: "Girl Atlas",
			p: "/album",
			s: "id="
		},
		imgs: ".gallery a[data-fancybox]",
		thums: ".gallery img",
		customTitle: ".header-title",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw1"
	}, {
		name: "Danryoku",
		url: {
			h: ["danryoku.com"]
		},
		imgs: () => fn.getImgA(".dynamic-entry-content img", ".ipp-image-nav .nav-center a"),
		button: [4],
		insertImg: [".dynamic-entry-content", 2],
		customTitle: "h1.gb-headline",
		category: "nsfw1"
	}, {
		name: "BreakBrunch",
		url: {
			h: ["breakbrunch.com"]
		},
		imgs: ".single-content img",
		customTitle: "h1.single-title",
		category: "nsfw2"
	}, {
		name: "PhimVu",
		host: ["m.phimvuspot.com"],
		reg: /^https?:\/\/m\.(phimvuspot|kutekorean)\.com\/\w+\/\w+\.cfg/i,
		include: [".post-content img", "h1.post-title"],
		imgs: () => {
			let max = Number(fn.gt("h1.post-title")?.match(/\/(\d+)$/)?.at(1));
			return /\?m=1/.test(siteUrl) ? fn.getImg(".post-content img", max, "8") : fn.getImg(".post-content img", max);
		},
		button: [4],
		insertImg: [".post-content", 2],
		customTitle: () => fn.dt({
			s: "h1.post-title",
			d: [
				/[\s\|]+Page[\s\d\/]+/,
				"E-CUP"
			]
		}),
		category: "nsfw2"
	}, {
		name: "Kutekorean.Com",
		url: {
			h: "nv.kutekorean.com",
			p: ".html",
			e: ["article.type-post", ".entry-content img", ".entry-title"]
		},
		imgs: () => fn.getImgA(".entry-content img", ".nav-links a:not([href='#'])"),
		button: [4],
		insertImg: [".entry-content ", 2],
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: [
				/[\s\|]+Page[\s\d\/]+/,
				"E-CUP"
			]
		}),
		category: "nsfw2"
	}, {
		name: "Poringa!",
		host: ["www.poringa.net", "m.poringa.net"],
		url: {
			h: "poringa.net",
			p: "/posts/"
		},
		imgs: ".post-content img,.content-post-img>img",
		customTitle: ".post-title,h1.title",
		category: "nsfw2"
	}, {
		name: "HayVn.Net",
		url: {
			h: "www.hayvn.net"
		},
		imgs: () => {
			let srcs = fn.getImgSrcArr(".entry-content img");
			return srcs.map(src => src.includes("/s1600/") ? fn.wurl("s16000", src, -2) : src);
		},
		capture: () => _this.imgs(),
		customTitle: ".entry-title",
		category: "nsfw1"
	}, {
		name: "YeuGai.Net",
		host: ["yeugai.vip"],
		url: {
			t: "YeuGai.Net",
			p: /^\/[^\/]+\/$/,
			e: ".entry-title"
		},
		init: async () => {
			await fn.waitEle(".mirror-image img");
			fn.run("jQuery(document).off()");
			let e = fn.ge(".relpost-thumb-wrapper");
			let f = fn.ge(".penci-entry-footer");
			if (e && f) {
				insertBefore(f, e);
			}
		},
		imgs: () => {
			videoSrcArray = fn.gau("video>source[type='video/mp4']+a[href*='.mp4']");
			let srcs = fn.getImgSrcArr(".mirror-image img");
			return srcs.map(src => src.includes("/s1600/") ? fn.wurl("s16000", src, -2) : src);
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /^Ảnh.+Xinh\s|^Ảnh Cosplay 18\+\s|^Clip.+Em\s/
		}),
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Gái Đẹp Sexy",
		url: {
			h: "gaidepsexy.vaileu.com"
		},
		imgs: ".entry p>img",
		button: [4],
		insertImg: [".entry", 2],
		customTitle: "h2.title",
		category: "nsfw1"
	}, {
		name: "GenZ Relax/ẢNH GÁI XINH/Hình ảnh gái xinh",
		url: {
			h: ["genzrelax.com", "anhgaixinh.tv", "gaixinh.photo"],
			e: ".entry-image img,.entry-content img:not(#img_video)"
		},
		imgs: () => fn.gae(".entry-image img,.entry-content img:not(#img_video)").filter(e => !e.closest("a[href*='?']")),
		capture: () => _this.imgs(),
		customTitle: "h1.entry-title,h1.page-title",
		category: "nsfw1"
	}, {
		name: "DopaGirls.Com",
		url: {
			h: ["dopagirls.com"]
		},
		srcset: ".wp-block-gallery img",
		autoDownload: [0],
		next: ".next_prev a[rel=prev]",
		prev: ".next_prev a[rel=next]",
		customTitle: ".xtra-post-title",
		category: "nsfw1"
	}, {
		name: "Tin Hay VIP",
		url: {
			h: ["tinhayvip.com"]
		},
		srcset: "img.entry-thumb[srcset],img[class*='wp-image'][srcset]",
		customTitle: "h1.tdb-title-text",
		category: "nsfw1"
	}, {
		name: "Hot Girl Xinh 18+",
		url: {
			h: ["girlxinh18.com"]
		},
		srcset: ".row-main p>img[srcset]",
		customTitle: ".row-main h1",
		category: "nsfw1"
	}, {
		name: "Ảnh Sex",
		url: {
			h: "anhsex.asia"
		},
		box: ["article p:has(img)", 1],
		imgs: "article p img",
		button: [4],
		insertImg: [
			["box", 0, "article p:has(img)"], 2
		],
		endColor: "white",
		customTitle: "h1.entry-title",
		hide: ".tbpopup",
		category: "nsfw1"
	}, {
		name: "Quatvn Club",
		url: {
			h: "quatvnclub.com",
			p: ".html"
		},
		srcset: ".wp-block-image img",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /^Ảnh.+Xinh\s|^Ảnh Cosplay 18\+\s|^Clip.+Em\s/
		}),
		observerClick: ".catfish-bottom-close",
		category: "nsfw2"
	}, {
		name: "Asia Idols",
		url: {
			h: ["asiaidols.wordpress.com"],
			p: /^\/\d+\/\d+\/\d+\/[^\/]+\/$/
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("img[alt='image host']");
			let imageHostLinks = fn.gau("//a[img[@alt='image host']]");
			return fn.getImageHost(imageHostLinks);
		},
		button: [4],
		insertImg: [".entry-content", 3],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "Asia Porn Photo/Asses Photo/Nuded Photo",
		url: {
			h: ["www.asiapornphoto.com", "www.assesphoto.com", "www.nudedxxx.com"],
			p: /^\/[^\.]+\.shtml$/
		},
		box: [".image-container:has([onclick])", 1],
		imgs: ".image-container>.image-wrapper[onclick]>img",
		button: [4],
		insertImg: [
			["box", 0, ".image-container:has([onclick])"], 2
		],
		customTitle: ".container h1",
		category: "nsfw2"
	}, {
		name: "4KUP",
		host: ["4kup.net"],
		reg: /^https?:\/\/4kup\.net\/(?!getlink)[^\/]+\/$/,
		exclude: "//button[text()='Click here to continue']",
		imgs: "a.thumb-photo",
		thums: "a.thumb-photo>img",
		button: [4],
		insertImg: ["#gallery", 2],
		autoDownload: [0],
		next: "a[rel=prev]",
		prev: "a[rel=next]",
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "呦糖社",
		host: ["www.nicesss.com"],
		reg: /^https?:\/\/www\.nicesss\.com\/archives\/[\w-]+\/([\w-]+\/)?\d+\.html$/i,
		box: [".entry-content>img[data-srcset],.entry-content>p>img[data-srcset],.entry-content>center>img", 1],
		imgs: () => fn.gae(".entry-content>img[data-srcset],.entry-content>p>img[data-srcset],.entry-content>center>img").map(e => e.dataset.srcset || e.src),
		button: [4],
		insertImg: [
			["box", 0, ".entry-content>img[data-srcset],.entry-content>p:has(>img[data-srcset]),.entry-content>center>imgs"], 2
		],
		customTitle: ".entry-title>a",
		category: "nsfw1"
	}, {
		name: "呦糖社C+",
		host: ["www.nicezzz.com", "www.niceff.com"],
		url: {
			t: "呦糖社C",
			p: "/archives/"
		},
		box: [".wp-posts-content>img,.wp-posts-content>p>img,.wp-posts-content>center:has(img)", 1],
		imgs: ".wp-posts-content>img,.wp-posts-content>p>img,.wp-posts-content>center img",
		button: [4],
		insertImg: [
			["box", 0, ".wp-posts-content>img,.wp-posts-content>p:has(>img),.wp-posts-content>center:has(img)"], 2
		],
		customTitle: ".article-title>a",
		category: "nsfw1"
	}, {
		name: "Fliporn/性性图",
		host: ["fliporn.biz", "www.xingtupicx.buzz"],
		reg: [
			/^https?:\/\/fliporn\.biz\/videos\//,
			/^https?:\/\/www\.xingtupicx\.buzz\/\?videos\//
		],
		include: "//span[@class='entry-category']/a[text()='亚洲贴图' or text()='写真' or text()='动漫贴图' or text()='性感贴图' or text()='欧美贴图' or text()='网友自拍']",
		box: ["//center[img] | //center[p[img]] | //div[@id='conttpc' and img] | //div[@id='conttpc' and p[img]] | //div[@class='entry-content']//p[img] | //div[figure[div[img]]]", 1],
		imgs: async () => {
			let srcs = fn.getImgSrcArr("article img");
			let pages = fn.ge(".custom-pagination");
			if (pages) {
				let max = fn.gt(".next.page-numbers", 2);
				srcs = await fn.getImg("article img", max, 7);
			}
			return srcs.map(e => e.replace("%3C/center%3E%3C/p%3E%3Cdiv%20class=", "").replace(/\?w=858(&ssl=1)?/, ""));
		},
		button: [4],
		insertImg: [
			["box", 0, "//br | //div[@class='custom-pagination'] | //center[img] | //center[p[img]] | //div[@id='conttpc' and img] | //div[@id='conttpc' and p[img]] | //div[@class='entry-content']//p[img] | //div[figure[div[img]]]"], 2
		],
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /\n|[\s\d]+$/g
		}),
		category: "nsfw2"
	}, {
		name: "91图录",
		url: {
			h: "www.91tulu.com",
			p: /^\/\d+\.html$/
		},
		imgs: ".wp-posts-content img",
		button: [4],
		insertImg: [".wp-posts-content", 2],
		autoDownload: [0],
		next: "//a[p[text()='上一篇']]",
		prev: "//a[p[text()='下一篇']]",
		customTitle: ".article-title",
		css: ".wp-posts-content{max-height:unset!important}",
		category: "nsfw1"
	}, {
		name: "淫淫小说写真馆",
		host: ["books.xxgirls.vip"],
		url: {
			h: "xxgirls",
			p: "artdetail"
		},
		imgs: "#read_tpc img,.hl-article-content img",
		button: [4],
		insertImg: ["#read_tpc,.hl-article-content", 2],
		autoDownload: [0],
		next: ".hl-next",
		prev: ".hl-prev",
		customTitle: () => fn.dt({
			s: ".hl-article-title",
			d: /-[\d\s]+P?$|\(\d+P\)?.*$|【\d+P】$/i
		}),
		category: "nsfw2"
	}, {
		name: "成人图片 Qinimg",
		url: {
			h: "www.qinimg.com",
			p: "/image/"
		},
		init: () => fn.rd(),
		box: ["#image", 1],
		imgs: () => {
			thumbnailSrcArray = fn.gae("#image a>img", doc).map(e => e.getAttribute("img"));
			return fn.gae("#image a", doc);
		},
		button: [4],
		insertImg: [
			["box", 2, "#image"], 2
		],
		customTitle: ".box>h1",
		category: "nsfw2"
	}, {
		name: "Elite Babes格式",
		url: {
			h: ["www.elitebabes.com", "pmatehunter.com", "www.jperotica.com", "www.metarthunter.com", "www.femjoyhunter.com", "nakedporn.pics", "plum.gent", "uludagspot.com", "funphotoguys.com", "suikachallenge.com"],
			e: ".list-gallery",
			ee: "#content video"
		},
		init: () => fn.waitEle(".list-gallery a[data-fancybox]"),
		imgs: () => fn.gae(".list-gallery a[data-fancybox]"),
		thums: ".list-gallery a[data-fancybox]>img",
		button: [4],
		insertImg: [
			[".list-gallery", 2], 2
		],
		customTitle: "#content>p",
		fancybox: {
			v: 3,
			css: false
		},
		category: "nsfw2"
	}, {
		name: "Naked Women Pics/VIEW GALS/Hot Pussy Pics/Busty Women Pics",
		host: ["nakedwomenpics.com", "viewgals.com", "hotpussypics.com", "bustypassion.com"],
		reg: [
			/^https?:\/\/nakedwomenpics\.com\/pics\/[^\/]+\/$/,
			/^https?:\/\/viewgals\.com\/pics\/[^\/]+\/$/,
			/^https?:\/\/hotpussypics\.com\/pics\/[^\/]+\/$/,
			/^https?:\/\/bustypassion\.com\/pics\/[^\/]+\/$/,
		],
		imgs: "a.ss-image",
		button: [4],
		insertImg: [".m-content-con", 2],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "TeenPussyPics.com",
		url: {
			h: ["teenpussypics.com"],
			p: "/images/"
		},
		imgs: "//div[@id='lucrezia']//a[img[@data-src]]",
		button: [4],
		insertImg: ["#lucrezia", 2],
		customTitle: "h1",
		css: "#lucrezia{height:auto!important}",
		category: "nsfw2"
	}, {
		name: "Wb-express porno",
		url: {
			h: "wb-express.ru"
		},
		imgs: ".pw-description img",
		button: [4],
		insertImg: [".pw-description", 2],
		customTitle: ".page-wrap h1",
		category: "nsfw2"
	}, {
		name: "NSFWalbum",
		url: {
			h: ["nsfwalbum.com"],
			p: "/album/"
		},
		box: [".album", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".albumPhoto");
			fn.sm5();
			let fetchNum = 0;
			return fn.gae(".album .item>a").map(async (a, i, arr) => {
				let img = fn.ge("img", a);
				let src = img.dataset.src ?? img.src;
				if (/imx\.to/.test(src)) {
					return src.replace("/t/", "/i/");
				} else {
					await delay(100 * i);
					return fn.t(a.href).then(async text => {
						await delay(200 * i);
						let id = a.href.split("/").at(-1);
						text = fn.stringSlicer(text, "spirit = ", "))");
						let spirit = fn.run(text);
						let api = `/backend.php?&spirit=${spirit}&photo=${id}`;
						return fn.j(api).then(json => {
							fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
							return json[0];
						});
					});
				}
			});
		},
		button: [4, 3],
		insertImg: [
			["box", 0, ".album"], 2
		],
		customTitle: ".gallery_name",
		ot: 1,
		category: "nsfw2"
	}, {
		name: "Adult photo sets",
		url: {
			h: "adultphotosets.best",
			e: "//a[img[@data-src][@data-maxwidth]] | //a[img[@data-src][@border='0']]"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("//img[@data-src][@data-maxwidth] | //img[@data-src][@border='0']");
			let [src] = thumbnailSrcArray;
			if (src.includes("imx.to/u/t/")) {
				return thumbnailSrcArray.map(e => e.replace("/t/", "/i/"));
			}
			let URLs = fn.gau("//a[img[@data-src][@data-maxwidth]] | //a[img[@data-src][@border='0']]");
			return fn.getImageHost(URLs);
		},
		button: [4],
		insertImg: [
			["//a[img[@data-src][@data-maxwidth]] | //a[img[@data-src][@border='0']]", 2, "//a[img[@data-src][@data-maxwidth]] | //a[img[@data-src][@border='0']]"], 2
		],
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "Ciberhentai",
		url: {
			h: "www.ciberhentai.com",
			p: ".html"
		},
		imgs: "a[data-gallery],#mangacomic img",
		thums: "a[data-gallery]>img",
		autoDownload: [0],
		next: ".prev-post a",
		prev: ".next-post a",
		customTitle: "span.post-title",
		hide: ".arcenter-container.flex-container",
		category: "nsfw2"
	}, {
		name: "ChoChoX",
		url: {
			h: ["chochoxhd.com"]
		},
		box: ["#fullscreen-btn+p", 2],
		imgs: "#fullscreen-btn+p img",
		button: [4],
		insertImg: [
			["box", 0, "#fullscreen-btn+p"], 2
		],
		autoDownload: [0],
		next: ".prev-post a",
		prev: ".next-post a",
		customTitle: "span.post-title",
		hide: ".arcenter-container.flex-container",
		category: "hcomic"
	}, {
		name: "Lucious Hentai",
		url: {
			h: ["lucioushentai.com"]
		},
		box: [".entry-content p:has(>a>img)", 2],
		imgs: ".entry-content img",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content p:has(>a>img)"], 2
		],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "Pics-X",
		url: {
			h: ["pics-x.com"],
			p: "/gallery/"
		},
		init: () => fn.waitEle("#images-container img"),
		imgs: "#images-container .images-container-image",
		button: [4],
		insertImg: ["#images-container", 2],
		customTitle: () => fn.title(" | Pics-X"),
		category: "nsfw2"
	}, {
		name: "Redpics",
		host: ["www.redpics.top"],
		reg: /^https?:\/\/www\.redpics\.top\/(japanese|korean|chinese|hardcore|softcore|lesbian)\/[\w-]+\/?$/,
		imgs: () => {
			let aEles = fn.gae("#extra-content>a,.post-content a");
			thumbnailSrcArray = aEles.map(a => fn.src("img", a));
			let [src] = thumbnailSrcArray;
			if (src.includes("imx.to/u/t/")) {
				return thumbnailSrcArray.map(e => e.replace("/t/", "/i/"));
			}
			let URLs = aEles.map(a => a.href);
			return fn.getImageHost(URLs);
		},
		button: [4],
		insertImg: ["#post-content", 3],
		autoDownload: [0],
		next: () => fn.gu("//div[text()='Previous Post']/following-sibling::div[1]/a"),
		prev: () => fn.gu("//div[text()='Next Post']/following-sibling::div[1]/a"),
		customTitle: "#photoset-title",
		category: "nsfw2"
	}, {
		name: "SXYPIX",
		url: {
			h: ["sxypix.com"],
			p: "/w/"
		},
		box: [".gallgrid", 2],
		imgs: async () => {
			fn.sm5();
			let pid = fn.ge("div.grid-item").dataset.photoid;
			let aid = fn.gu(".gall_info_panel a.tdn").split("/").at(-1);
			let ghash = fn.ge(".gall_cp[data-ghash]").dataset.ghash;
			let total = Number(fn.gt(".ip_count"));
			let pages = Math.ceil(total / 36);
			let headers = {
				"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
				"x-requested-with": "XMLHttpRequest"
			};
			let resArr = fn.arr(pages, (v, i) => fn.j("/php/apg.php", {
				"headers": headers,
				"body": `mode=w&param={"page":${(i + 1)},"ghash":"${ghash}"}`,
				"method": "POST"
			}).then(json => json.r));
			thumbnailSrcArray = await Promise.all(resArr).then(data => data.flat()).then(arr => {
				let html = arr.join("");
				let dom = fn.doc(html);
				return fn.gae(".gall_cover", dom).map(e => e.dataset.src ?? e.src);
			});
			return fn.j("/php/gall.php", {
				"headers": headers,
				"body": `x=x&pid=${pid}&aid=${aid}&ghash=${ghash}&width=1920`,
				"method": "POST"
			}).then(json => {
				let arr = json.r;
				let html = arr.join("");
				let dom = fn.doc(html);
				return fn.gae("div.gall_pix_el", dom);
			});
		},
		button: [4],
		insertImg: [
			["box", 0, ".grid"], 2
		],
		endColor: "white",
		customTitle: ".gall_title",
		category: "nsfw2"
	}, {
		name: "Boombo!",
		host: ["hot.boombo.biz", "boombo.biz"],
		url: {
			h: "boombo.biz"
		},
		imgs: () => fn.getImgSrcArr(".text div[style] img,.text div.fimg img").map(e => e.replace("thumbs/", "")),
		thums: ".text div[style] img,.text div.fimg img",
		button: [4],
		insertImg: [".text div[style],.news .text", 2],
		customTitle: "#dle-content h1",
		category: "nsfw2"
	}, {
		name: "GayBoysTube",
		url: {
			h: "www.gayporntube.com",
			p: "/galleries/"
		},
		init: () => isM ? fn.addMutationObserver(() => fn.remove(".after_header")) : void 0,
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("#tab5 img");
			return thumbnailSrcArray.map(e => e.replace(/main\/\d+x\d+/, "sources").replace("thumbs/", ""));
		},
		button: [4],
		insertImg: ["#tab5", 2],
		customTitle: "h1.title",
		hide: ".content>.block-album",
		category: "nsfw2"
	}, {
		name: "BoyFriendTv.com",
		url: {
			h: "www.boyfriendtv.com",
			p: "/pics/",
			d: "pc"
		},
		box: [".gallery-detail", 2],
		imgs: async () => {
			let eles = fn.gae(".gallery-detail .thumb-item a[style^='background-image']");
			if (fn.ge("//a[@class='rightKey'][text()='Next']")) {
				let max = fn.gt("//a[text()='Next']", 2) ?? 1;
				let links = [fn.lp, ...fn.gau(".gallery-detail .ajax-pager a[href]")];
				eles = await fn.getEle(links, ".gallery-detail .thumb-item a[style^='background-image']", null, null, 0);
			}
			thumbnailSrcArray = eles.map(a => {
				let backgroundImage = a.style.backgroundImage;
				return backgroundImage.slice(5, -2).trim();
			});
			return thumbnailSrcArray.map(e => e.replace("-320-", "-800-"));
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: "#gallery h1",
		category: "nsfw2"
	}, {
		name: "МЕДИА ТРЕНД",
		link: "https://jb5.ru/photo-zvezd/",
		url: {
			h: ["jb5.ru"]
		},
		srcset: ".gallery-item a,span[itemprop=image]>img,.entry-content img[srcset],.entry-content img[class*='wp-image']",
		customTitle: ".entry-title>h1",
		category: "nsfw2"
	}, {
		name: "alt Goddess",
		url: {
			h: "altgoddess.com"
		},
		init: () => ("adde_modal_detector" in _unsafeWindow) ? _unsafeWindow.adde_modal_detector(false) : void 0,
		imgs: "a[data-fancybox],.mpc-grid-images img",
		autoDownload: [0],
		next: ".mk-post-next",
		prev: ".mk-post-prev",
		customTitle: ".page-title",
		observerClick: ".adde_modal_detector-action-btn-close",
		category: "nsfw2"
	}, {
		name: "alt Goddess AAD",
		url: {
			h: "altgoddess.com"
		},
		init: () => ("adde_modal_detector" in _unsafeWindow) ? _unsafeWindow.adde_modal_detector(false) : void 0,
		observerClick: ".adde_modal_detector-action-btn-close",
		category: "ad"
	}, {
		name: "GamEYE",
		url: {
			h: ["gameye.ru", "gameye.kz"]
		},
		imgs: ".wp-block-gallery img",
		customTitle: "section h1",
		category: "nsfw1"
	}, {
		name: "CQ",
		url: {
			h: ["cq.ru"]
		},
		imgs: ".p__header-image img[srcset],a.swipebox:has(img[srcset]),.gallery-top a.swiper-slide",
		customTitle: "h1.h1-h2",
		hide: ".m.--top",
		category: "nsfw1"
	}, {
		name: "GameMAG",
		url: {
			h: "gamemag.ru"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcset("#gallery img");
			return thumbnailSrcArray.map(src => src.replace("/small", "/original"));
		},
		capture: () => _this.imgs(),
		videos: "iframe[src*='vk.com/video']",
		customTitle: "h1.overview__title",
		category: "nsfw1"
	}, {
		name: "GameFans",
		url: {
			h: "gamefans.ru"
		},
		imgs: "#fstory img",
		customTitle: "#pageTitle",
		category: "nsfw1"
	}, {
		name: "Картинки и фото",
		url: {
			h: "cojo.ru",
			e: ".entry-title"
		},
		imgs: ".wp-block-image img",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /\([\d\s]+фото\)|\(\d+[\sфотfots]+\)|\d+[\sфотfots]+/
		}),
		setFancybox: true,
		category: "nsfw1"
	}, {
		name: "geekfan.site",
		url: {
			h: "geekfan.site",
			e: [".sgb-data,.entry-content img", ".entry-title"]
		},
		imgs: () => {
			let data = fn.ge(".sgb-data");
			if (data) {
				return fn.gae(".sgb-data").flatMap(data => {
					let text = data.textContent;
					let json = JSON.parse(text);
					return json.images.map(e => e.url.replace("-scaled", ""));
				});
			} else if (fn.ge("a[href*='/images/']")) {
				return fn.gae("a[href*='/images/']");
			}
			return fn.gae(".entry-content img");
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".nav-previous a[rel=prev]",
		prev: ".nav-next a[rel=next]",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: [
				/\(\d+[\sфотfots]+\)|[\d\sфотfots]+/,
				/\(?[\d\s]+фото\)?/,
				/[\d\s]+горячих/,
				"слив"
			]
		}),
		category: "nsfw1"
	}, {
		name: "CLANNAD",
		url: {
			h: "clannadhouse.com",
			p: /^\/[^\/]+\/$/
		},
		imgs: () => {
			let g = "a.fox-lightbox-gallery-item";
			let g2 = "div[class*='lightbox'] img";
			if (fn.ge(g)) {
				return fn.gae(g);
			} else if (fn.ge(g2)) {
				return fn.getImgSrcset(g2);
			}
			return fn.getImgSrcset(".hero56__background>img,.entry-content img");
		},
		capture: () => _this.imgs(),
		customTitle: ".post-title",
		category: "nsfw1"
	}, {
		name: "Szexképek",
		url: {
			h: "szexkepek.net",
			p: ".html",
			e: ".row:has(>.col-xs-6>a>img.gallerythumb)",
			ee: "h3.page-header"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".gallerythumb");
			return thumbnailSrcArray.map(e => e.replace("x160.", "."));
		},
		button: [4],
		insertImg: [".row:has(>.col-xs-6)", 2],
		customTitle: "h1.page-header:not([style])",
		category: "nsfw2"
	}, {
		name: "BugilOnly",
		url: {
			h: "bugilonly.com"
		},
		imgs: ".s-post-content img",
		button: [4],
		insertImg: [".s-post-content", 2],
		autoDownload: [0],
		next: "a.next-page-link",
		prev: "a.prev-page-link",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "Terekspos",
		url: {
			h: "terekspos.com"
		},
		imgs: () => {
			let is = ".post-content>center>a>img,.post-content>p>a>img";
			let as = ".post-pagination a";
			let pages = fn.ge(as);
			return pages ? fn.getImgA(is, as) : fn.gae(is);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "div.next a",
		prev: "div.previous a",
		customTitle: "h1.post-title",
		category: "nsfw2"
	}, {
		name: "SoCaseiras",
		url: {
			h: "www.socaseiras.com.br",
			p: "/galeria/"
		},
		imgs: ".galeria .fotos img",
		button: [4],
		insertImg: [".galeria .fotos", 2],
		customTitle: ".galeria h1",
		category: "nsfw2"
	}, {
		name: "LigaDasNovinhas",
		url: {
			h: "www.ligadasnovinhas.com"
		},
		imgs: "#post-info img",
		customTitle: ".post h1",
		category: "nsfw2"
	}, {
		name: "Não Conto",
		url: {
			h: "www.naoconto.com",
			p: ".html",
			e: ".title"
		},
		imgs: "article img",
		customTitle: () => fn.ge(".title")?.textContent,
		category: "nsfw2"
	}, {
		name: "Vagabundas Do Orkut",
		url: {
			h: "www.vagabundasdoorkut.net"
		},
		srcset: ".post-texto img",
		customTitle: ".pagina-titulo",
		category: "nsfw2"
	}, {
		name: "Nudes",
		url: {
			h: "nudes.blog.br"
		},
		srcset: ".gallery-item img[srcset]",
		customTitle: ".meio h1",
		category: "nsfw2"
	}, {
		name: "MinhaMulher",
		url: {
			h: "www.minhamulher.com"
		},
		box: [".conteudo p:has(>img)", 1],
		imgs: ".conteudo img",
		button: [4],
		insertImg: [
			["box", 0, ".conteudo p:has(>img)"], 2
		],
		customTitle: ".titulo>h1",
		category: "nsfw2"
	}, {
		name: "Fotos Porno",
		url: {
			h: "www.fotosporno.blog"
		},
		imgs: ".gallery img",
		videos: ".wp-video source",
		button: [4],
		insertImg: [".gallery", 2],
		customTitle: ".cn-article h1",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "Nevsepic",
		host: ["nevsepic.com.ua"],
		url: {
			h: "nevsepic",
			e: ["//div[@class='full-comms']/a[text()='18+']", ".full-text img,a.highslide", ".share_widget"]
		},
		box: [".share_widget", 1],
		imgs: async () => {
			let srcs = fn.getImgSrcArr("a.highslide,.full-text img");
			let pages = fn.ge(".bottom-nav");
			if (pages) {
				let last = fn.ge(".navigation>a:last-child");
				let max = last.innerText;
				let url = last.pathname;
				let links = fn.arr(max, (v, i) => i == 0 ? fn.url : url.replace(/(\/page\,)(\d+\,)/, `$1${(i + 1) + ","}`));
				srcs = await fn.getImgA("a.highslide,.full-text img", links);
			}
			return srcs.filter(src => !src.includes("/thumbs/") && !src.includes("attach.png"));
		},
		button: [4],
		insertImg: [
			["box", 0, ".full-text img:not(.FullPictureLoadImage,[src$='attach.png']),.full-text img:not(.FullPictureLoadImage,[src$='attach.png'])~br,a.highslide,a.highslide~br,.bottom-nav"], 2
		],
		customTitle: ".f-page-title",
		category: "nsfw2"
	}, {
		name: "Nevsepic",
		host: ["nevsepic.com.ua"],
		url: {
			h: "nevsepic",
			e: [".full-text img,a.highslide", ".share_widget"]
		},
		imgs: async () => {
			let srcs = fn.getImgSrcArr("a.highslide,.full-text img");
			let pages = fn.ge(".bottom-nav");
			if (pages) {
				let last = fn.ge(".navigation>a:last-child");
				let max = last.innerText;
				let url = last.pathname;
				let links = fn.arr(max, (v, i) => i == 0 ? fn.url : url.replace(/(\/page\,)(\d+\,)/, `$1${(i + 1) + ","}`));
				srcs = await fn.getImgA("a.highslide,.full-text img", links);
			}
			return srcs.filter(src => !src.includes("/thumbs/") && !src.includes("attach.png"));
		},
		capture: () => _this.imgs(),
		button: [4],
		customTitle: ".f-page-title",
		category: "nsfw2"
	}, {
		name: "erohd.icu",
		host: ["erohd.su"],
		url: {
			e: ".logo a[title='erohd.icu']"
		},
		imgs: ".sigFreeThumb a.fancybox-gallery",
		thums: ".sigFreeThumb a.fancybox-gallery img",
		next: "li.next a",
		prev: "li.previous a",
		customTitle: ".article-title",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		name: "Ero-Top",
		url: {
			h: "ero-top.name",
			p: ".html"
		},
		imgs: "#img-bl a",
		thums: "#img-bl a img",
		customTitle: "#dle-content h1",
		category: "nsfw2"
	}, {
		name: "ADULT SITE 18+",
		host: ["go1.kiski.top"],
		url: {
			e: ".prev_row_full .statya",
			p: ".html"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".prev_row_full .statya img");
			return thumbnailSrcArray.map(e => e.replace("thumbs/", ""));
		},
		capture: () => _this.imgs(),
		customTitle: "main h1",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw2"
	}, {
		name: "erovizor.top",
		url: {
			h: "erovizor.top"
		},
		imgs: ".entry-content a.lg-thumb-item",
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "bdsmlr",
		link: "https://chasti-wabbit.bdsmlr.com/post/265859932",
		url: {
			h: ".bdsmlr.com",
			e: ".image_container img",
			d: "pc"
		},
		SPA: true,
		init: () => fn.capture({
			s: ".image_container img:not(.get)",
			vs: "video.vjs-tech[value][poster]:not(.get)",
			vcb: video => setArray.add(video.poster)
		}),
		imgs: () => setArray,
		capture: () => _this.imgs(),
		infiniteCapture: 1,
		hide: ".reblogcontainerouter",
		downloadVideo: true,
		focus: "last:.image_container",
		closeAF: () => {
			let ask = fn.ge(".askholder");
			if (ask) {
				EClick(".cancelbutton");
			}
		},
		aeg: 0,
		category: "nsfw2"
	}, {
		name: "Дзен",
		url: () => fn.dls() === "" && fn.checkUrl({
			h: ["dzen.ru"],
			p: "/a/"
		}),
		imgs: () => {
			//每張圖片讀取完成後會將圖片網址存到sessionStorage屬性hermioneStatPixels裡
			//sessionStorage.getItem("hermioneStatPixels");
			return fn.wait(() => {
				fn.sm4();
				let imgs = fn.gae("figure img");
				let loadeds = fn.gae("figure img[srcset*='w, ']");
				if (imgs.length > 0) {
					fn.showMsg("Waiting for loading " + loadeds.length + "/" + imgs.length, 0);
					return imgs.at(-1)?.getAttribute("srcset")?.includes("w, ");
				} else {
					return false;
				}
			}, 6000).then(() => {
				fn.hm();
				//return fn.getImgSrcArr("figure img[srcset]");
				let srcs = JSON.parse(sessionStorage.getItem("hermioneStatPixels"));
				srcs = srcs.filter(src => src.includes("/pub_"));
				thumbnailSrcArray = [...new Set(srcs.map(src => src.replace(/\d+$/, "360")))];
				return [...new Set(srcs.map(src => src.replace(/\w+$/, "orig")))];
			});
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.delay(1000, 0).then(() => fn.dt({
			d: /\|.+$/
		})),
		category: "nsfw2"
	}, {
		name: "NUDE_ART_EROTIC",
		url: {
			h: "nude-art-erotic.livejournal.com",
			p: /^\/\d+\.html$/
		},
		imgs: ".aentry-post__content img:not([src$='19736856'])",
		customTitle: ".aentry-post__title",
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "Развлекательно-эротический блог",
		url: {
			h: "tettie.net",
			s: "p="
		},
		imgs: () => fn.getImgSrcArr(".postContent img").filter(e => !e.includes("-ads")),
		customTitle: ".postTitle",
		setFancybox: true,
		category: "nsfw2"
	}, {
		name: "URLGalleries",
		host: ["urlgalleries.net"],
		url: {
			h: "urlgalleries",
			p: "/porn-gallery-"
		},
		imgs: () => fn.getEle([fn.url + "&a=10000"], "#wtf>a").then(aArr => {
			thumbnailSrcArray = aArr.map(a => fn.src("img", a));
			let links = aArr.map(a => a.href);
			fn.sm5();
			let fetchNum = 0;
			let imageHostLinks = links.map(url => fn.t(url).then(text => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${links.length}`, 0);
				let dom = fn.doc(text);
				let code = fn.gst("window.location.href", dom);
				let [, link] = code.match(/window\.location\.href[\s\='"]+([^'";]+)/);
				return link;
			}));
			return Promise.all(imageHostLinks).then(urls => fn.getImageHost(urls));
		}),
		button: [4],
		insertImg: [
			["#wtf", 2, "#wtf"], 3
		],
		customTitle: ".galleryhead>h3>a,.galleryhead h1",
		hide: ".mobilehide",
		category: "nsfw2"
	}, {
		name: "GirlsTop",
		url: {
			h: "girlstop.info",
			p: "/psto",
			s: "id="
		},
		imgs: "a[id^=pic]",
		thums: "a[id^=pic] img",
		customTitle: ".content-block h1,.gallery h1",
		category: "nsfw2"
	}, {
		name: "wikiFeetX / wikiFeet",
		host: ["wikifeet.com", "wikifeetx.com"],
		url: {
			h: "wikifeet",
			st: "gallery"
		},
		init: () => fn.waitEle("#gallery a").then(() => (siteJson = _unsafeWindow.tdata)),
		imgs: () => {
			let src = fn.gu("#gallery a");
			let dir = fn.dir(src);
			thumbnailSrcArray = siteJson.gallery.map(e => "https://thumbs.wikifeet.com/" + e.pid + ".jpg").sort();
			return siteJson.gallery.map(e => dir + e.pid + ".jpg").sort();
		},
		capture: () => _this.imgs(),
		customTitle: () => siteJson.cname,
		hide: "div:has(>iframe),div:has(>a>picture)",
		category: "nsfw2"
	}, {
		name: "VK",
		host: ["vk.com", "m.vk.com"],
		url: {
			h: "vk.com",
			p: "/album"
		},
		getVK: (list, picNum) => {
			fn.sm5();
			let max = Math.ceil(Number(picNum) / 10);
			let fetchNum = 0;
			let resArr = [];
			for (let i = 0, n = Number(picNum); i < n; i += 10) {
				let data = fn.cp({
					act: "show",
					al: 1,
					direction: 1,
					list,
					offset: i
				});
				let res = fn.xhr("https://vk.com/al_photos.php?act=show", {
					headers: {
						"content-type": "application/x-www-form-urlencoded",
						"x-requested-with": "XMLHttpRequest"
					},
					data,
					responseType: "json",
					method: "POST"
				}).then(json => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
					return json.payload[1][3].map(e => e.w_src ?? e.z_src ?? e.y_src ?? e.x_src);
				});
				resArr.push(res);
			};
			return Promise.all(resArr).then(data => data.flat());
		},
		imgs: () => {
			let list = fn.lp.split("/").at(-1);
			let picNum;
			if (fn.lh.startsWith("m.")) {
				[picNum] = document.title.split("–").at(-1).replaceAll(",", "").match(/\d+/);
			} else {
				picNum = fn.gt(".ui_crumb_count").replaceAll(",", "");
			}
			return _this.getVK(list, picNum);
		},
		capture: () => _this.imgs(),
		customTitle: ".photos_album_intro>h1,.AlbumPage__title",
		category: "nsfw2"
	}, {
		name: "CyberDrop",
		url: {
			h: "cyberdrop.me",
			p: "/a/"
		},
		box: ["#table", 2],
		imgs: async () => {
			let fileIds = fn.gau("a.image").map(u => u.split("/").at(-1));
			fn.sm5();
			let fetchNum = 0;
			let resArr = [];
			for (let id of fileIds) {
				let api = `https://api.cyberdrop.me/api/file/info/${id}`
				let res = fn.j(api, {
					"headers": {
						"accept": "application/json, text/plain, */*",
					},
				}).then(json => {
					let isV = /^video/.test(json.type);
					let isI = /^image/.test(json.type);
					let isO = json.type === "application/octet-stream";
					if (isV || isI || isO) {
						return fn.j(json.auth_url, {
							"headers": {
								"accept": "application/json, text/plain, */*",
							}
						}).then(obj => {
							fn.showMsg(`${DL.str_06}${fetchNum+=1}/${fileIds.length}`, 0);
							if (isV) {
								return {
									v: obj.url
								}
							} else {
								return {
									i: obj.url
								}
							}
						});
					} else {
						fn.showMsg(`${DL.str_06}${fetchNum+=1}/${fileIds.length}`, 0);
						return {
							n: null
						}
					}

				});
				resArr.push(res);
			}
			return Promise.all(resArr).then(data => {
				videoSrcArray = data.filter(obj => "v" in obj)?.map(e => e.v);
				return data.filter(obj => "i" in obj)?.map(e => e.i);
			});
		},
		button: [4],
		insertImg: ["box", 3],
		customTitle: "#title",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "FitNakedGirls",
		url: {
			h: ["fitnakedgirls.com"],
			p: "/gallery/"
		},
		imgs: () => {
			let srcs;
			let [a, b] = [".wp-block-image img[data-src]", ".entry-content img"];
			if (!!fn.ge(a)) {
				srcs = fn.gae(a).map(e => e.dataset.src.replace(/-\d+x\d+(\.\w+)$/, "$1"));
			} else {
				srcs = fn.gae(b).map(e => e.dataset.src ?? e.src);
			}
			return srcs.filter(src => !src.includes("18xmob.png") && !src.includes("/18plus"));
		},
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		css: ".g1-column-2of3{width:100%!important}",
		hide: "#secondary",
		category: "nsfw2"
	}, {
		name: "R18hub",
		link: "https://r18hub.com/photos",
		url: {
			h: ["r18hub.com"],
			p: "/photo/"
		},
		imgs: () => {
			let eles = fn.gae("#photos>li");
			thumbnailSrcArray = eles.map(e => e.dataset.thumb);
			return eles.map(e => e.dataset.src);
		},
		button: [4],
		insertImg: ["#photos", 2],
		customTitle: () => fn.title(" - R18hub"),
		category: "nsfw2"
	}, {
		name: "Up2Img/AI Porn Pix",
		url: {
			h: ["www.up2img.com", "up2img.com", "www.aipornpix.com", "aipornpix.com"],
			p: "/album/"
		},
		box: [".album-row", 2],
		imgs: () => fn.getNP(".album-card", ".pagination .active+li>a", null, ".pagination").then(() => fn.getEle(".album-card a", "center a:has(img)>img").then(eles => fn.lh.includes("aipornpix") ? eles.map(e => fn.url + e.src.replace(fn.lo + "/", "")) : eles)),
		button: [4],
		insertImg: [
			["box", 2, ".album-row,.pagination-container,div:has(>form[onsubmit*='goJump'])"], 2
		],
		category: "nsfw2"
	}, {
		name: "FreeXcafe",
		host: ["www.freexcafe.com"],
		reg: /^https?:\/\/www\.freexcafe\.com\/erotica\/[\w-]+\/[\w-]+\/index\.php/,
		box: ["#content>*:last-child", 2],
		imgs: () => fn.getImgA("#imagelink>img,#bigphoto>img", ".thumbs>a", 500),
		thums: ".thumbs>a>img",
		button: [4],
		insertImg: [
			["box", 2, ".thumbs"], 2
		],
		category: "nsfw2"
	}, {
		url: {
			name: "TUPIC.TOP",
			h: "tupic.top",
			p: ".html",
			e: "#post_content h1"
		},
		box: ["#metadata_qrcode", 2],
		imgs: ".gallery_img",
		button: [4],
		insertImg: [
			["box", 0, ".spotlight-group,#touch_to_see"], 2
		],
		customTitle: () => fn.ge("#post_content h1").textContent.replaceAll("\n", "").trim(),
		category: "nsfw2"
	}, {
		name: "EPORNER Photo",
		host: ["www.eporner.com"],
		url: {
			h: ".eporner.com",
			p: "/gallery/"
		},
		box: [".photosgrid", 2],
		imgs: () => {
			thumbnailSrcArray = fn.gae("#container img").map(e => e.src);
			return thumbnailSrcArray.map(e => e.replace("_296x1000", ""));
		},
		button: [4],
		insertImg: [
			["box", 2, ".photosgrid"], 2
		],
		endColor: "white",
		customTitle: "#galleryheader>h1",
		category: "nsfw2"
	}, {
		name: "EPORNER Albums",
		url: {
			h: "www.eporner.video",
			p: "/album/"
		},
		box: [".album-info", 1],
		imgs: ".images a",
		thums: ".images a img",
		button: [4],
		insertImg: ["box", 2],
		endColor: "white",
		customTitle: ".content h1",
		hide: ".link-sponsor",
		category: "nsfw2"
	}, {
		name: "KISSJAV",
		url: {
			h: "kissjav.com",
			p: "/album/"
		},
		imgs: ".images a",
		thums: ".images img",
		button: [4],
		insertImg: [".images", 2],
		customTitle: "h1.title",
		category: "nsfw2"
	}, {
		name: "X1HUB",
		url: {
			h: "x1hub.com",
			p: "/albums/",
			e: ".album-info"
		},
		imgs: ".images a",
		thums: ".images img",
		button: [4],
		insertImg: [".images", 2],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Xasiat",
		link: "https://www.xasiat.com/albums/",
		url: {
			h: "www.xasiat.com",
			p: /^\/([\w]{2}\/)?albums\/\d+\/[\w-]+\/$/
		},
		init: () => {
			for (let img of fn.gae("img.thumb[data-original]")) img.src = img.dataset.original;
			fn.remove(".sponsor,.footer-margin");
		},
		box: [".images", 2],
		imgs: ".images>a",
		thums: ".images>a>img[data-original]",
		button: [4],
		insertImg: [
			["box", 0, ".images"], 2
		],
		endColor: "white",
		customTitle: ".headline>h1",
		css: ".block-album{display:block !important}",
		hide: ".block-album>.table,.top,.footer~*:not([id^='Full'],[class^='Full'],[id^='pv-'],[class^='pv-'],#comicRead,#fab,*[class^=fancybox])",
		category: "nsfw2"
	}, {
		name: "Xasiat 自動翻頁",
		url: {
			h: "www.xasiat.com",
			p: /^\/([\w]{2}\/)?albums\/(\d+\/)?/
		},
		init: () => {
			setInterval(() => {
				fn.remove("//div[iframe] | //iframe");
				if (document.body.getAttribute("class").length > 13) document.body.setAttribute("class", "big-container");
			}, 500);
			fn.remove(".footer~*:not(#DownloadAppUIRoot)", 2000);
		},
		autoPager: {
			ele: "#list_albums_common_albums_list_items",
			observer: "#list_albums_common_albums_list_items>.item",
			next: ".page-current+li>a",
			pageNum: ".page-current",
			lazySrc: "img[data-original]"
		},
		openInNewTab: "#list_albums_common_albums_list_items a:not([target=_blank])",
		hide: ".footer~*:not(#DownloadAppUIRoot)",
		category: "autoPager"
	}, {
		name: "Erotic Pics",
		url: {
			h: ["erotic.pics"],
			p: /^\/[^\/]+\/$/
		},
		imgs: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /\s–\s\d+\spics/
		}),
		category: "nsfw2"
	}, {
		name: "Erotic Pics 分類自動翻頁",
		reg: /^https?:\/\/erotic\.pics\//,
		autoPager: {
			ele: "#masonry",
			observer: "#masonry>article",
			next: "span.current+a",
			re: ".wp-pagenavi",
			pageNum: "span.current"
		},
		openInNewTab: "a.entry-thumbnail:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "xHamster gallery",
		host: ["xhamster.com"],
		link: "https://zh.xhamster.com/users/eros721_official/photos",
		url: {
			h: "xhamster.com",
			p: /^\/photos\/gallery\/[^/]+$/,
			e: "div[class*=photosList]",
			d: "pc"
		},
		imgs: () => fn.getNP("#initials-script", "//div[@class='prev-next-list']//li[a[contains(@class,'active')]]/following-sibling::li[1]/a", null, "nav:has(>.prev-next-list)").then(() => {
			let photos = fn.gae("#initials-script").map(script => {
				let json = JSON.parse(script.innerText.replace(/window.initials=|;/g, ""));
				return json.photosGalleryModel.photos;
			}).flat();
			thumbnailSrcArray = photos.map(e => e.thumbURL);
			return photos.map(e => e.imageURL);
		}),
		button: [4],
		insertImg: [
			["main>article", 2, "main>article,nav:has(>.prev-next-list),div:has(>.start-slideshow)"], 2
		],
		customTitle: "div[data-role='gallery-page'] h1",
		category: "nsfw2"
	}, {
		name: "xHamsterM gallery M",
		url: {
			h: "xhamster.com",
			p: /^\/photos\/gallery\/[^/]+$/,
			e: "div[class*=photosList]",
			d: "m"
		},
		imgs: () => fn.getNP("#initials-script", ".prev-next-list a[rel=next]", null, "nav:has(>.prev-next-list)").then(() => {
			let photos = fn.gae("#initials-script").map(script => {
				let json = JSON.parse(script.innerText.replace(/window.initials=|;/g, ""));
				return json.galleryPage.photoItems;
			}).flat();
			thumbnailSrcArray = photos.map(e => e.imgSrcset);
			return photos.map(e => e.imgSrc);
		}),
		button: [4],
		insertImg: [
			["main>article", 2, "main>article,nav:has(>.prev-next-list),div:has(>.start-slideshow)"], 2, 1000
		],
		customTitle: "div[data-role='gallery-page'] h1",
		category: "nsfw2"
	}, {
		name: "BITCHES GIRLS/FAPSLY LIVE",
		url: {
			h: ["bitchesgirls.com", "fapsly.live", "fapsly.net"],
			st: "pagesAmount",
			d: "pc"
		},
		imgs: () => {
			fn.sm5();
			const getUrls = (dom = document, pageUrl = siteUrl) => {
				let images = [];
				let thums = [];
				let videos = [];
				let code = fn.gst("thumbnailUrl", dom);
				let json = JSON.parse(code.replace(/\n/g, "").replace(/\s+/g, " "));
				let {
					image,
					video
				} = json;
				image = image?.filter(e => e["@type"] === "ImageObject");
				video = video?.filter(e => e["@type"] === "VideoObject");
				if (video.length > 0) {
					videos = video.map(e => e.url);
				} else {
					videos = fn.gae(".albumgrid img[type=video]").map(e => e.getAttribute("original"));
				}
				if (image.length > 0) {
					thums = image.map(e => e.thumbnailUrl);
					images = image.map(e => e.url);
					thums = thums.filter(e => !e.includes("/logos/"));
					images = images.filter(e => !e.includes("/logos/"));
				} else {
					thums = fn.gae(".albumgrid img[type=image]", dom).map(e => e.src);
					images = fn.gae(".albumgrid img[type=image]", dom).map(e => e.getAttribute("original"));
				}
				return {
					images,
					thums,
					videos
				}
			}
			const max = _unsafeWindow.adConstants.pagesAmount;
			if (max > 1) {
				fn.sm5();
				let fetchNum = 0;
				let resArr = fn.arr(max, (v, i) => {
					let url = i == 0 ? siteUrl : siteUrl + `${i + 1}/`;
					return fn.fetchDoc(url).then(dom => {
						fn.showMsg(`${DL.str_06}${fetchNum += 1}/${max}`, 0);
						return getUrls(dom, url);
					});
				});
				return Promise.all(resArr).then(data => {
					thumbnailSrcArray = data.map(e => e.thums).flat();
					videoSrcArray = data.map(e => e.videos).flat();
					return data.map(e => e.images).flat();
				});
			}
			let obj = getUrls();
			thumbnailSrcArray = obj.thums;
			videoSrcArray = obj.videos;
			return obj.images;
		},
		button: [4],
		insertImg: [
			[".button-container", 2, ".albumgrid,.popup-container"], 2
		],
		hide: "a#loadMore,.my-girls-popup-element",
		category: "nsfw2"
	}, {
		name: "X-video",
		url: {
			h: ["x-video.tube"],
			p: "/albums/"
		},
		box: [".album-view", 2],
		imgs: () => {
			fn.sm5();
			let total = Number(fn.gt(".media-data__list-value"));
			let max = 1;
			if (total > 12) {
				max = Math.ceil(total / 100) + 1;
			}
			let fetchNum = 0;
			let resArr = fn.arr(max, (v, i) => {
				let url = i == 0 ? "?mode=async&function=get_block&block_id=album_view_album_view" : "?mode=async&function=get_block&block_id=album_view_album_view&load=more&from=" + i;
				return fn.fetchDoc(url, {
					"headers": {
						"x-requested-with": "XMLHttpRequest"
					}
				}).then(dom => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
					return {
						thumbs: fn.getImgSrcArr("a.grid-item img", dom),
						originals: fn.gae("a.grid-item", dom)
					}
				});
			});
			return Promise.all(resArr).then(data => {
				thumbnailSrcArray = data.map(e => e.thumbs).flat();
				return data.map(e => e.originals).flat();
			});
		},
		button: [4],
		insertImg: [
			["box", 0, ".album-view"], 2
		],
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "jimpicotphotography.com",
		url: {
			h: "jimpicotphotography.com"
		},
		imgs: ".con>img,#post-navigation img",
		customTitle: () => fn.dt({
			d: " - jimpicotphotography.com"
		}),
		category: "nsfw2"
	}, {
		url: {
			h: ["sarlatimmobilier.com", "studiobangchau.com", "monsterbusterclub.tv", "ecopak.cz"]
		},
		imgs: "#gallery .img-blur a",
		button: [4],
		insertImg: ["#gallery", 2],
		customTitle: "#page h1:not(:has(i))",
		category: "nsfw2"
	}, {
		name: "luxurybeachresorts.net",
		host: ["www.luxurybeachresorts.net"],
		url: {
			h: [/luxurybeachresorts\.net$/, "artlantic.design"],
			e: "#gallery .media-group",
			d: "pc"
		},
		box: [".media-group", 1],
		imgs: () => {
			videoSrcArray = fn.gae(".video source[type='video/mp4']").map(e => e.src);
			thumbnailSrcArray = fn.getImgSrcArr(".media-group div.img[data-src]");
			return thumbnailSrcArray.map(src => src.replace(/(\?)([^&]+&)/, "$1"));
		},
		button: [4],
		insertImg: [
			["box", 0, ".media-group"], 2
		],
		customTitle: "#page #page h1",
		category: "nsfw2"
	}, {
		name: "Pornotaran.com photo",
		url: {
			h: "pornotaran.com",
			p: ".html",
			e: ".inner-page__desc div:has(img[data-src])"
		},
		imgs: () => fn.getImgSrcArr(".inner-page__desc img[data-src]").map(e => e.replace("/thumbs", "")),
		button: [4],
		insertImg: [".inner-page__desc div:has(img[data-src])", 2],
		customTitle: ".inner-page__title",
		category: "nsfw2"
	}, {
		name: "Babepedia",
		url: {
			h: "www.babepedia.com",
			p: ["/gallery/", "/babe/"]
		},
		imgs: "#gallery a[data-fancybox],.gallery a[rel=gallery]",
		thums: "#gallery a[data-fancybox] img,.gallery a[rel=gallery] img",
		autoDownload: [0],
		next: ".gallerynavigation a:has(>img[alt*=older])",
		prev: ".gallerynavigation a:has(>img[alt*=newer])",
		customTitle: "#gallery h1,#babename",
		category: "nsfw2"
	}, {
		name: "Hot Celebs Home",
		url: {
			h: "www.hotcelebshome.com",
			e: ".tiled-gallery__gallery img"
		},
		imgs: () => fn.getImgSrcArr(".tiled-gallery__gallery img").map(e => e.replace(/(-\d+x\d+)(.\w+)/i, "$2")),
		capture: () => _this.imgs(),
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "PicHunter",
		url: {
			h: "www.pichunter.com",
			p: "/gallery/"
		},
		imgs: () => {
			thumbnailSrcArray = fn.gae("#main-grid a img").map(e => e.src);
			if (fn.ge(".flex-images figure>a>img")) {
				thumbnailSrcArray = fn.gae(".flex-images figure>a>img").map(e => e.getAttribute("xs"));
			}
			return fn.gae(".flex-images figure>a,#main-grid a");
		},
		button: [4],
		insertImg: [
			[".flex-images,#main-grid", 2], 1
		],
		customTitle: "h1",
		category: "nsfw2"
	}, {
		name: "Pictoa",
		url: {
			h: "www.pictoa.com",
			p: ["/thumbs/", "/albums/"],
			e: "#player img"
		},
		imgs: () => fn.getImgA("#player img", fn.gau(".thumb-nav-img a")),
		thums: ".thumb-nav-img img",
		button: [4],
		insertImg: ["#player", 2],
		customTitle: ".title>h1",
		css: "#gallery #player{cursor:unset!important}",
		hide: ".ad-placement",
		category: "nsfw2"
	}, {
		name: "PimpAndHost",
		host: ["pimpandhost.com"],
		link: "https://pimpandhost.com/site/trending",
		reg: /^https?:\/\/pimpandhost\.com\/(image|album)\/\d+/,
		init: () => {
			if (/image/.test(location.href)) location.href = fn.ge("a[title=Album]").href;
			fn.remove(".flex-block-1,.flex-block-2,#comments,.ano_po");
		},
		imgs: () => fn.getNP("#album-images>.image-block", "li.active+li:not(.next)>a", null, ".pagination").then(() => fn.gae("#album-images .image-block a[data-src]")),
		button: [4],
		insertImg: [
			[".summary", 2], 2
		],
		customTitle: ".author-header__album-name",
		category: "nsfw2"
	}, {
		name: "PimpAndHost 隱藏廣告",
		reg: /^https?:\/\/pimpandhost\.com\//,
		init: () => fn.remove(".flex-block-1,.flex-block-2,#comments,.ano_po"),
		hide: ".list-view:not(#main-list-view) .item:not(.image-block)",
		category: "ad"
	}, {
		name: "Pornpaw",
		url: {
			h: "www.pornpaw.com",
			p: "/gallery/"
		},
		box: [".row .row:has(.frame)", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("img.img");
			return thumbnailSrcArray.map(e => e.replace("x160.", "."));
		},
		button: [4],
		insertImg: [
			["box", 0, ".row .row:has(.frame)"], 2
		],
		customTitle: "h1",
		hide: "div:has(>ins)",
		category: "nsfw2"
	}, {
		name: "ImageFap 圖片列表頁",
		url: {
			h: "www.imagefap.com",
			p: ["/gallery/", "/pictures/"],
			e: "#gallery table a"
		},
		box: ["#gallery", 2],
		imgs: async () => {
			let temps = [];
			let originals = [];
			let thumbs = [];
			let gid;
			let gid_url = fn.gu("a[href*='&gid']");
			if (gid_url) {
				gid = fn.getUSP("gid", gid_url);
			} else {
				[, , gid] = fn.lp.split("/");
				if (!Number(gid)) return [];
			}
			let loop = true;
			let pn = 0;
			fn.sm5();
			const get = () => {
				return fn.fetchDoc(`/ajax/actions.php?gid=${gid}&page=${pn}&action=getGallery`).then(dom => {
					fn.showMsg(`${DL.str_05} (Page${pn + 1})`, 0);
					if (!fn.ge("#hgallery", dom)) {
						loop = false;
						return;
					}
					for (let img of [...dom.images]) {
						let noParams = new URL(img.dataset.full).pathname;
						if (temps.includes(noParams)) {
							loop = false;
							return;
						} else {
							temps.push(noParams);
							originals.push(img.dataset.full);
							thumbs.push(img.dataset.original);
						}
					}
				});
			};
			while (loop) {
				await get();
				pn++;
			}
			thumbnailSrcArray = thumbs;
			return originals;
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: () => {
			if (fn.ge("#menubar font,h1 b")) {
				return fn.gt("#menubar font,h1 b");
			}
			return document.title;
		},
		category: "nsfw2"
	}, {
		name: "ImageFap",
		url: {
			h: "www.imagefap.com",
			p: "/photo/",
			d: "pc"
		},
		init: () => {
			fn.remove("//td[div[@id='main']]/following-sibling::td[1] | //div[iframe]");
			fn.ge("#main").removeAttribute("style");
			fn.ge("//table[@width='750']").width = "1000";
		},
		imgs: async () => {
			let temps = [];
			let originals = [];
			let thumbs = [];
			let gid = fn.ge("#galleryid_input").value;
			let loop = true;
			let pn = 0;
			fn.sm5();
			const get = () => fn.fetchDoc(`/ajax/actions.php?gid=${gid}&page=${pn}&action=getGallery`).then(dom => {
				fn.showMsg(`${DL.str_05} (Page${pn + 1})`, 0);
				if (!fn.ge("#hgallery", dom)) {
					loop = false;
					return;
				}
				for (let img of [...dom.images]) {
					let noParams = new URL(img.dataset.full).pathname;
					if (temps.includes(noParams)) {
						loop = false;
						return;
					} else {
						temps.push(noParams);
						originals.push(img.dataset.full);
						thumbs.push(img.dataset.original);
					}
				}
			});
			while (loop) {
				await get();
				pn++;
			}
			thumbnailSrcArray = thumbs;
			return originals;
		},
		button: [4],
		insertImg: ["//td[div[@id='slideshow']]", 2],
		customTitle: "#main h1",
		category: "nsfw2"
	}, {
		name: "ImageFapM",
		url: {
			h: "beta.imagefap.com",
			p: ["/gallery/", "/pictures/"],
			d: "m"
		},
		imgs: async () => {
			let gid = fn.ge("#gid").value;
			let max = Number(fn.gt(".newNav b")?.match(/\d+/g)?.at(-1)) || 1;
			let pages = [`/ajax/actions.php?gid=${gid}&page=0&action=getGallery`];
			if (max > 1) {
				pages = fn.arr(max, (v, i) => `/ajax/actions.php?gid=${gid}&page=${i}&action=getGallery`);
			}
			let resArr = [];
			let fetchNum = 0;
			fn.sm5();
			for (let url of pages) {
				let res = await fn.fetchDoc(url).then(dom => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
					return [...dom.images].map(img => {
						let original = img.dataset.full;
						let thumb = img.dataset.original;
						return {
							original,
							thumb
						}
					});
				});
				resArr.push(res);
				//await delay(1000);
			}
			return Promise.all(resArr).then(data => data.flat()).then(arr => {
				let thumbs = arr.map(e => e.thumb);
				thumbnailSrcArray = thumbs;
				let originals = arr.map(e => e.original);
				return originals;
			});
		},
		button: [4],
		insertImg: ["#gallery", 2],
		customTitle: ".nMobHeader>h1,.userPageInfoGal strong",
		hide: ".ad_placeholder",
		category: "nsfw2"
	}, {
		name: "Fuskator",
		host: ["fuskator.com"],
		reg: /^https?:\/\/fuskator\.com\/thumbs\/[\w-~]+\/[\w-~]+\.html$/i,
		init: () => fn.sm4().then(() => fn.waitEle(".pic_pad").then(() => fn.hm())),
		imgs: "#thumbimages a,.swipebox a",
		thums: "#thumbimages a>img,.swipebox a>img",
		button: [4],
		insertImg: [
			["//a[text()='View full images']", 2], 2
		],
		category: "nsfw2"
	}, {
		name: "TOKYO Motion",
		host: ["www.tokyomotion.net"],
		link: "https://www.tokyomotion.net/albums",
		reg: /^https?:\/\/www\.tokyomotion\.net\/album\/\d+\/.+/,
		imgs: () => fn.getNP("div[id^=album_photo]", ".pagination li.active+li>a", null, ".pagination").then(() => {
			thumbnailSrcArray = fn.gae(".thumb-overlay img").map(e => e.src);
			return thumbnailSrcArray.map(e => e.replace("tmb/", ""));
		}),
		button: [4],
		insertImg: [
			["//div[div[div[contains(@id,'album_photo')]]]", 0], 2
		],
		customTitle: () => fn.gae(".pull-left")[2].innerText.trim(),
		category: "nsfw2"
	}, {
		name: "JavBangers",
		url: {
			h: "javbangers.com",
			p: "/albums/",
			e: ".album-info"
		},
		imgs: () => fn.gau(".images a"),
		thums: ".images img",
		button: [4],
		insertImg: [
			[".album-info", 2, ".images"], 2
		],
		customTitle: ".headline>h1",
		category: "nsfw2"
	}, {
		name: "multi.xnxx.com",
		url: {
			h: ["multi.xnxx.com"],
			p: "/gallery/"
		},
		imgs: ".galleryPage .boxImg",
		button: [4],
		insertImg: [
			[".originalLink", 2], 1
		],
		category: "nsfw2"
	}, {
		name: "色情圖片網",
		host: ["www.photos18.com", "www.photos18.org"],
		url: {
			h: "photos18",
			p: "/v/"
		},
		imgs: ".imgHolder a[data-fancybox]",
		button: [4],
		insertImg: ["#content", 2],
		customTitle: "h1.title",
		hide: ".no-gutters",
		category: "nsfw2"
	}, {
		name: "趣事館",
		link: "https://17sex.vip/list/4858",
		url: {
			h: ["17sex.vip"],
			p: "/pic/"
		},
		imgs: () => fn.getImg(".page>img", fn.gt(".count-pageindex") || 1, "4"),
		button: [4],
		insertImg: [
			[".page", 0], 2
		],
		customTitle: "h3",
		hide: ".topzanpage",
		category: "nsfw2"
	}, {
		name: "久久热/GavPorn",
		host: ["www.99re.com", "cavporn.com"],
		url: {
			e: ".logo img[alt^='久久热'],.logo img[alt^='CAVPorn']",
			p: "/albums/"
		},
		imgs: "a[data-fancybox-type]",
		button: [4],
		insertImg: [".sponsor,.images", 2],
		customTitle: ".headline>h1",
		hide: ".top",
		category: "nsfw2"
	}, {
		name: "Hentai Image",
		host: ["hentai-img.com", "hentai-cosplay-xxx.com", "porn-images-xxx.com"],
		url: {
			h: [/hentai-img\.com$/, /hentai-cosplay-xxx\.com$/, /porn-images-xxx\.com$/],
			p: "/image/",
			e: ["#display_image_detail,#detail_list", "#title>h2,#page h3"]
		},
		imgs: () => {
			fn.sm1();
			let [, , url] = fn.lp.split("/");
			url = `/story/${url}/`;
			return fn.xhrDoc(url).then(dom => {
				let srcs = fn.getImgSrcArr("amp-story-page[id='cover'] amp-img,amp-story-page[id^='page'] amp-img", dom);
				thumbnailSrcArray = srcs.map(src => {
					let f = src.split("/").at(-1);
					let dir = fn.dir(src);
					return dir + "p=160x200/" + f;
				});
				return srcs;
			});
		},
		button: [4],
		insertImg: ["#display_image_detail,#detail_list", 2],
		insertImgAF: () => fn.remove("#paginator:has(a[href*='/page/'])"),
		autoDownload: [0],
		next: {
			s: "a[href^='/image/']",
			t: ["Prev Article", "前の記事", "Précédent article", "Zurück Artikel", "Предыдущая статья", "前一篇", "이전 기사", "Anterior artículo", "Sebelumnya Pasal", "ก่อนหน้าบทความ", "Trước Điều"]
		},
		prev: {
			s: "a[href^='/image/']",
			t: ["Next Article", "次の記事", "article suivant", "Nächster Artikel", "Следующая статья", "下一篇文章", "다음 글", "Siguiente artículo", "Pasal berikutnya", "บทความถัดไป", "Điều tiếp theo"]
		},
		customTitle: () => fn.dt({
			s: "#title>h2,#page h3",
			d: /\s?Photo\s?\d+P|\s?-\s?\d+\/\d+\s?|\([0-9\s]+ảnh\)/i
		}),
		css: "#display_image_detail img{max-width:100% !important}",
		hide: "#adsense_header",
		category: "nsfw2"
	}, {
		name: "Fapator",
		host: ["www.fapator.com"],
		reg: /^https?:\/\/www\.fapator\.com\/\?content_id=/i,
		init: () => fn.remove("//div[@class='img' and a[@target and img]]"),
		imgs: "a[data-lightbox]",
		thums: "a[data-lightbox]>img",
		button: [4],
		insertImg: [".fcon+.fapad", 1],
		autoDownload: [0],
		next: "//a[contains(text(),'next photos')]",
		prev: 1,
		css: ".fapad{width:auto !important;height:auto !important}",
		category: "nsfw2"
	}, {
		name: "SMUTPOND",
		url: {
			h: "www.smutpond.com",
			p: ["/gallery-thumbs/", "/gallery-pics/"],
			s: "uid="
		},
		imgs: () => {
			fn.sm5();
			let cdn = "https://cdn.smutpond.com/";
			let id = fn.getUSP("uid");
			return fn.j(`https://api.smutpond.com/content/cm/${id}/?media_type=photo_gallery`).then(json => {
				thumbnailSrcArray = json.media_data.thumbs.map(e => cdn + e);
				customTitle = json.title;
				return json.media_data.images.map(e => cdn + e);
			});
		},
		capture: () => _this.imgs(),
		category: "nsfw2"
	}, {
		name: "Hoastie",
		url: {
			h: "hoastie.com",
			p: "/a/",
			e: "h1.entry-title"
		},
		imgs: () => {
			let s = ".entry-content img";
			let v = ".entry-content video>source";
			if (fn.ge(v)) {
				videoSrcArray = fn.gae(v).map(e => e.src);
				s = ".entry-featured-media img,.entry-content img";
			}
			let imgs = fn.gae(s).filter(e => !e.closest("aside,.g1-teaser"));
			return fn.getImgSrcset(imgs);
		},
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "a.g1-teaser-prev",
		prev: "a.g1-teaser-next",
		customTitle: () => fn.ge("h1.entry-title").textContent,
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "DirtyShip.com",
		url: {
			h: ["dirtyship.com"],
			p: "/gallery/"
		},
		srcset: ".gallery_grid img,.gallery_grid~img",
		thums: ".gallery_grid img,.gallery_grid~img",
		button: [4],
		insertImg: [
			[".gallery_grid", 0, ".gallery_grid img:not(.FullPictureLoadImage),.gallery_grid~img"], 2
		],
		customTitle: () => fn.title(" - DirtyShip.com"),
		category: "nsfw2"
	}, {
		name: "ᑕ❶ᑐ Onlyfans +18",
		host: ["www.tiktaks.de"],
		reg: /^https?:\/\/www\.tiktaks\.de\/onlyfans\/[^\/]+\/$/,
		imgs: "figure.wp-block-image>img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".title",
		category: "nsfw2"
	}, {
		name: "SexyGirlsPics",
		url: {
			h: ["sexygirlspics.com"],
			p: "/pics/"
		},
		imgs: "a.ss-image",
		thums: "a.ss-image>img",
		button: [4],
		insertImg: [
			[".sponsor-button", 2], 1
		],
		category: "nsfw2"
	}, {
		name: "PornPic",
		url: {
			h: ["www.pornpic.com", "pornpic.com"],
			p: "/gallery/"
		},
		imgs: ".gallery-grid a.item-link[data-fancybox]",
		thums: ".gallery-grid a.item-link[data-fancybox] img",
		button: [4],
		insertImg: [
			[".gallery-info", 2], 1
		],
		category: "nsfw2"
	}, {
		name: "Girlsreleased",
		url: {
			h: ["girlsreleased.com"],
		},
		page: () => fn.clp("/set/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => fn.sm5().then(() => fn.j("/api/0.2" + fn.clp()).then(json => {
			siteJson = json;
			debug("\n此頁JSON資料\n", siteJson);
			fn.hm();
		})),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let xhrNum = 0;
			const images = siteJson.set.images.map(a => ({
				o: a.at(3),
				t: a.at(4)
			}));
			thumbnailSrcArray = images.map(e => e.t);
			let total = images.length;
			return images.map(({
				o,
				t
			}) => {
				if (t.includes("imx.to/u/t/")) {
					total -= 1;
					return t.replace("/t/", "/i/");
				}
				if (t.includes("imgadult.com")) {
					total -= 1;
					return t.replace("small-medium/", "big/");
				}
				if (t.includes("pixhost.to")) {
					total -= 1;
					return t.replace("https://t", "https://img").replace("/thumbs/", "/images/");
				}
				if (t.includes("imagevenue")) {
					if (o.includes("_o.jpg")) {
						total -= 1;
						return o;
					}
				}
				return fn.xhr(o, {
					responseType: "document"
				}).then(dom => {
					fn.showMsg(`${DL.str_02}${xhrNum+=1}/${total}`, 0);
					let img = fn.ge("#imgpreview,#image,.pic.img.img-responsive,#imageid,#img.image-content,.card-body img,.image.img-fluid,img.pic[alt][title]", dom);
					return img ? img.src : null;
				});
			});
		},
		button: [4],
		insertImgBF: () => fn.waitEle(".align-middle:has(h1)").then((e) => fn.createImgBox(e, 2)),
		insertImg: [
			["box", 0], 3
		],
		referer: "src",
		mcss: "#FullPictureLoadMainImgBox{width:100%;max-width:1400px;margin:0 auto}",
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				id,
				site,
				models,
				name
			} = siteJson.set;
			return `GR ${site} - ${models?.at(0)?.at(1)} - ${(name || "#" + id)}`;
		},
		category: "nsfw2"
	}, {
		name: "ViperGirls/PornCoven/ErotiCity",
		link: "https://viper.to/threads/10623260-Coser-UmekoJ-NieR-2B",
		url: {
			h: ["vipergirls.to", "viper.to", "viperohilia.art", "vipervault.link", "viperbb.rocks", "viperkats.eu", "planetviper.club", "porncoven.com", "eroticity.net"],
			p: "/threads/",
			e: ".postdetails",
			d: "pc"
		},
		init: () => {
			document.addEventListener("click", event => {
				if (event.target.className === "postdetails") {
					tempEles = [];
					if (event.target.querySelector("img[src*='imx.to/u/t/']")) {
						tempEles = [...event.target.querySelectorAll("img[src*='imx.to/u/t/']")];
						return fn.showMsg(`Capture ${tempEles.length} Links`);
					}
					let links = [];
					if (event.target.querySelector("a[href$='.jpg']:not([href^='http://imagetwist.com/'])")) {
						links = [...event.target.querySelectorAll("a[href$='.jpg']")].map(a => a.href);
					} else {
						links = [...event.target.querySelectorAll(`
                            a[href^='https://imgspice.com/'],
                            a[href*='pixhost.to'],
                            a[href^='http://imagetwist.com/'],
                            a[href*='postimg.cc'],
                            a[href*='fastpic.org'],
                            a[href*='vipr.im'],
                            a[href*='turboimagehost'],
                            a[href*='imgbox.com'],
                            a[href*='imagevenue'],
                            a[href*='imagebam']
                            `)].map(a => a.href);
					}
					captureLinksArray = links;
					fn.showMsg(`Capture ${links.length} Links`);
					debug("captureLinksArray", captureLinksArray);
				}
			});
		},
		imgs: () => {
			if (tempEles.length) {
				return fn.getImgSrcArr(tempEles).map(e => e.replace("/t/", "/i/"));
			}
			return fn.getImageHost();
		},
		repeat: 1,
		category: "nsfw2"
	}, {
		name: "Kitty Kats Forum",
		url: {
			h: ["kitty-kats.net"],
			p: "/threads/",
			e: ".message-cell.message-cell--user",
			d: "pc"
		},
		init: () => {
			document.addEventListener("click", event => {
				cancelDefault(event);
				if (event.target.className === "message-cell message-cell--user") {
					tempEles = [];
					if (event.target.querySelector("img[src*='imx.to/u/t/']")) {
						tempEles = [...event.target.querySelectorAll("img[src*='imx.to/u/t/']")];
						return fn.showMsg(`Capture ${tempEles.length} Links`);
					}
					let links = [];
					if (event.target.parentNode.querySelector("a[href$='.jpg']:not([href^='http://imagetwist.com/'])")) {
						links = [...event.target.parentNode.querySelectorAll("a[href$='.jpg']")].map(a => a.href);
					} else {
						links = [...event.target.parentNode.querySelectorAll(`
                        a[href^='https://imgspice.com/'],
                        a[href*='pixhost.to'],
                        a[href^='http://imagetwist.com/'],
                        a[href*='postimg.cc'],
                        a[href*='fastpic.org'],
                        a[href*='vipr.im'],
                        a[href*='turboimagehost'],
                        a[href*='imgbox.com'],
                        a[href*='imagevenue'],
                        a[href*='imagebam']
                        `)].map(a => a.href);
					}
					captureLinksArray = links;
					fn.showMsg(`Capture ${links.length} Links`);
					debug("captureLinksArray", captureLinksArray);
				}
			});
		},
		imgs: () => {
			if (tempEles.length) {
				return fn.getImgSrcArr(tempEles).map(e => e.replace("/t/", "/i/"));
			}
			return fn.getImageHost();
		},
		repeat: 1,
		category: "nsfw2"
	}, {
		name: "Teen Photos",
		link: "https://teenphotos.forumes.ru/viewtopic.php?id=324",
		url: {
			h: ["teenphotos.forumes.ru"],
			p: "viewtopic.php",
			s: "id=",
			e: ".container",
			d: "pc"
		},
		init: () => {
			document.addEventListener("click", event => {
				cancelDefault(event);
				tempEles = [];
				if (event.target.querySelector("img[src*='imx.to/u/t/']")) {
					tempEles = [...event.target.querySelectorAll("img[src*='imx.to/u/t/']")];
					return fn.showMsg(`Capture ${tempEles.length} Links`);
				}
				if (event.target.className === "container") {
					let links = [...event.target.querySelectorAll(`
                    a[href^='https://imgspice.com/'],
                    a[href*='pixhost.to'],
                    a[href^='http://imagetwist.com/'],
                    a[href*='postimg.cc'],
                    a[href*='fastpic.org'],
                    a[href*='vipr.im'],
                    a[href*='turboimagehost'],
                    a[href*='imgbox.com'],
                    a[href*='imagevenue'],
                    a[href*='imagebam']
                    `)].map(a => a.href);
					captureLinksArray = links;
					fn.showMsg(`Capture ${links.length} Links`);
					debug("captureLinksArray", captureLinksArray);
				}
			});
		},
		imgs: () => {
			if (tempEles.length) {
				return fn.getImgSrcArr(tempEles).map(e => e.replace("/t/", "/i/"));
			}
			return fn.getImageHost();
		},
		repeat: 1,
		category: "nsfw2"
	}, {
		name: "XONLY",
		host: ["xonly8.com"],
		link: "https://xonly8.com/index.php?topic=229069.0",
		url: {
			h: /xonly\d?\.com$/,
			p: "index.php",
			s: "topic=",
			e: ".post_wrapper",
			d: "pc"
		},
		init: () => {
			document.addEventListener("click", event => {
				cancelDefault(event);
				if (event.target.className === "post_wrapper") {
					tempEles = [];
					if (event.target.querySelector("img[src*='imx.to/u/t/']")) {
						tempEles = [...event.target.querySelectorAll("img[src*='imx.to/u/t/']")];
						return fn.showMsg(`Capture ${tempEles.length} Links`);
					}
					let links = [...event.target.querySelectorAll(`
                    a[href^='https://imgspice.com/'],
                    a[href*='pixhost.to'],
                    a[href^='http://imagetwist.com/'],
                    a[href*='postimg.cc'],
                    a[href*='fastpic.org'],
                    a[href*='vipr.im'],
                    a[href*='turboimagehost'],
                    a[href*='imgbox.com'],
                    a[href*='imagevenue'],
                    a[href*='imagebam']
                    `)].map(a => a.href);
					captureLinksArray = links;
					fn.showMsg(`Capture ${links.length} Links`);
					debug("captureLinksArray", captureLinksArray);
				}
			});
		},
		imgs: () => {
			if (tempEles.length) {
				return fn.getImgSrcArr(tempEles).map(e => e.replace("/t/", "/i/"));
			}
			return fn.getImageHost();
		},
		repeat: 1,
		category: "nsfw2"
	}, {
		name: "Teen Models",
		host: ["teen-models.forum"],
		link: "https://teen-models.forum/thread-13449.html",
		url: {
			h: "teen-models.forum",
			p: "/thread-",
			e: ".post_author",
			d: "pc"
		},
		init: () => {
			document.addEventListener("click", event => {
				cancelDefault(event);
				if (event.target.className === "post_author") {
					tempEles = [];
					if (event.target.nextElementSibling.querySelector("img[src*='imx.to/u/t/']")) {
						tempEles = [...event.target.nextElementSibling.querySelectorAll("img[src*='imx.to/u/t/']")];
						return fn.showMsg(`Capture ${tempEles.length} Links`);
					}
					let links = [...event.target.nextElementSibling.querySelectorAll(`
                    a[href*='https://imgspice.com/'],
                    a[href*='pixhost.to'],
                    a[href^='http://imagetwist.com/'],
                    a[href*='postimg.cc'],
                    a[href*='fastpic.org'],
                    a[href*='vipr.im'],
                    a[href*='turboimagehost'],
                    a[href*='imgbox.com'],
                    a[href*='imagevenue'],
                    a[href*='imagebam']
                    `)].map(a => {
						if (a.href.includes("linkanonymous")) {
							return a.href.replace("https://linkanonymous.com/?", "");
						}
						return a.href;
					});
					captureLinksArray = links;
					fn.showMsg(`Capture ${links.length} Links`);
					debug("captureLinksArray", captureLinksArray);
				}
			});
		},
		imgs: () => {
			if (tempEles.length) {
				return fn.getImgSrcArr(tempEles).map(e => e.replace("/t/", "/i/"));
			}
			return fn.getImageHost();
		},
		repeat: 1,
		category: "nsfw2"
	}, {
		name: "imx.to gallery",
		host: ["imx.to"],
		reg: /^https?:\/\/imx\.to\/g\/\w+$/i,
		imgs: () => fn.gae("img.imgtooltip").map(e => e.src.replace("/t/", "/i/")),
		button: [4],
		insertImg: [
			["#content", 2], 2
		],
		category: "nsfw2"
	}, {
		name: "imx.to",
		host: ["imx.to"],
		reg: /^https?:\/\/imx\.to\/i\/\w+$/i,
		autoClick: ".button.blue.large,#continuebutton,a[title='Show gallery']",
		category: "none"
	}, {
		name: "imgbox gallery",
		url: {
			h: ["imgbox.com"],
			p: "/g/"
		},
		imgs: () => fn.getImgSrcArr("#gallery-view-content img").map(src => fn.rt(src, [
			["thumbs", "images"],
			["_t.", "_o."],
			["_b.", "_o."]
		])),
		button: [4],
		insertImg: [
			["#gallery-view-content", 2], 2
		],
		category: "nsfw2"
	}, {
		name: "亚洲色吧",
		host: ["yazhouseba.com", "yazhouse8.com"],
		link: "https://yazhouseba.com/meinv/index.php",
		url: {
			h: "yazhouse",
			p: "/meinv/img-",
			e: "#next-url"
		},
		imgs: () => {
			fn.sm5();
			let pid = fn.ge("#next-url").rel;
			return fetch("/meinv/ajax.php", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": `action=src&pid=${pid}`,
				"method": "POST"
			}).then(async res => {
				try {
					return await res.json();
				} catch {
					return {};
				}
			}).then(json => json?.urls?.map(e => _unsafeWindow.img_dir + e) ?? []);
		},
		button: [4],
		insertImg: [".content>.image", 2],
		customTitle: ".content>h1",
		category: "nsfw2"
	}, {
		name: "1000艺术摄影/169图片大全",
		url: {
			h: ["www.1000yishu.com", "www.169tp.com", "wap.169tp.com"],
			p: /^\/\w+\/\d+\/\d+\/\d+\.html/
		},
		imgs: () => fn.getImg(".big-pic img,.inside_box img", Number(fn.gt(".pagelist a")?.match(/\d+/)) || 1, 9),
		button: [4],
		insertImg: [".big-pic,.inside_box", 2],
		autoDownload: [0],
		next: ".fenxianga a,.pre_arct a",
		prev: ".fenxianga a:last-child,.next_arct a",
		hide: ".ad,union",
		category: "nsfw1"
	}, {
		name: "亿秀美女",
		host: ["www.itu11.com", "m.itu11.com"],
		reg: /^https?:\/\/(www|m)\.i?tu11\.com\/\w+\/(\d+\/)?\d+\/\d+\.html$/i,
		include: "#showimg img,.img-box img",
		imgs: () => fn.getNP("#showimg img,.img-box img", "a.curpage+a:not(.prepage)", null, "#paginationEle", 0, null, 0, 0).then(() => fn.gae("#showimg img,.img-box img")),
		button: [4],
		insertImg: ["#showimg,.img-box", 2],
		autoDownload: [0],
		next: "//div[contains(text(),'上一篇')]/a | //a[text()='上一篇']",
		prev: "//div[contains(text(),'下一篇')]/a | //a[text()='下一篇']",
		category: "nsfw1"
	}, {
		name: "热图站",
		host: ["www.retu8.com", "www.simei8.com"],
		link: "https://www.retu8.com/ji/leisitubaobao.html",
		url: {
			t: "热图站",
			p: /\.htm$/,
			e: ".pp.hh"
		},
		imgs: () => {
			let max = fn.um(".page-show>*");
			if (max > 1) {
				let url = fn.lp.replace(".htm", "");
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${url}${i + 1}.htm`);
				return fn.getImgA(".pp.hh img", links);
			}
			return fn.gae(".pp.hh img");
		},
		button: [4],
		insertImg: [".pp.hh", 2],
		customTitle: ".des>h1",
		category: "nsfw1"
	}, {
		name: "热图站M",
		host: ["m.retu8.com", "m.simei8.com"],
		url: {
			e: ["//a[text()='热图站']", "#ImageBox"],
			p: /\.htm$/
		},
		imgs: () => {
			let max = Number(fn.gt(".article_page a")?.match(/\d+/g)?.at(-1));
			if (max > 1) {
				let url = fn.lp.replace(".htm", "");
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${url}${i + 1}.htm`);
				return fn.getImgA("#ImageBox img", links);
			}
			return fn.gae("#ImageBox img");
		},
		button: [4],
		insertImg: ["#ImageBox", 2],
		customTitle: ".ArticleHead>h1",
		category: "nsfw1"
	}, {
		name: "爱美女网",
		url: {
			h: "www.aimeinv6.com",
			p: /^\/\w+\/\d+\.html$/
		},
		init: () => {
			let a = fn.ge("a[href*=dPlayNext]");
			a.outerHTML = `<div class="imgBox">${a.innerHTML}</div>`;
		},
		imgs: () => fn.getImg("#bigimg", Number(fn.gt("//a[contains(text(),'共')]")?.match(/\d+/)) || 1, 9),
		button: [4],
		insertImg: [".imgBox", 2],
		autoDownload: [0],
		next: "//span[contains(text(),'上一篇')]/a",
		prev: "//span[contains(text(),'下一篇')]/a",
		category: "nsfw1"
	}, {
		name: "JavCup",
		url: {
			h: "javcup.com",
			p: "/movie/",
			e: ["#video[poster]", ".movies-images li"]
		},
		box: ["#play-card", 2],
		imgs: () => {
			let videoSrc = fn.src("#video>source");
			videoSrcArray[0] = videoSrc;
			let poster = fn.attr("#video[poster]", "poster");
			let srcs = fn.getImgSrcArr(".movies-images li");
			srcs.unshift(poster);
			return srcs;
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: "h1.title",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "JavCup",
		url: {
			h: "javcup.com",
			p: "/video/",
			e: "#video[poster]"
		},
		imgs: () => {
			let videoSrc = fn.src("#video>source");
			videoSrcArray[0] = videoSrc;
			let poster = fn.attr("#video[poster]", "poster");
			return [poster];
		},
		customTitle: "h1.title",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		name: "JavCup",
		url: {
			h: "javcup.com",
			p: "/photo/"
		},
		box: [".content>.body", 2],
		imgs: "#photos>li",
		button: [4],
		insertImg: ["box", 2],
		customTitle: "h1.title",
		category: "nsfw2"
	}, {
		name: "JavCup",
		url: {
			h: "javcup.com",
			p: "/model/"
		},
		init: () => {
			for (let e of fn.gae("section img[data-src]")) e.src = e.dataset.src;
		},
		box: [".content>.body", 2],
		imgs: () => {
			let links = fn.gau("a[href*='type=photos']");
			if (links.length > 1) {
				let url = links.at(0);
				let [max] = links.at(-1).match(/\d+$/);
				links = fn.arr(max, (v, i) => url + "&page=" + (i + 1));
				return fn.getEle(links, "#photos>ul").then(uls => {
					links = uls.map(ul => fn.gau(".photo-grid-item a", ul));
					links = links.flat();
					return fn.getImgA("#photos>li", links, 1);
				});
			}
			links = fn.gau("#photos .photo-grid-item a");
			return fn.getImgA("#photos>li", links, 1);
		},
		button: [4],
		insertImg: ["box", 3],
		customTitle: "h1 span",
		category: "nsfw2"
	}, {
		name: "JJGirls",
		url: {
			h: "jjgirls.com",
			e: ".L664 a:has(>img:not([src^='/thumbs/']))",
			d: "pc"
		},
		box: [".L664"],
		imgs: () => {
			let pagesE = fn.ge(".matchlinks");
			let pages = /\/\d+\/$/.test(fn.lp);
			if (pagesE && pages) {
				let url = fn.lp.replace(/\/\d+\/$/, "");
				let max;
				let link = fn.gu(".matchlinks>a:has(+img)");
				if (/more$/.test(link)) {
					max = fn.gt(".matchlinks>a+b");
				} else {
					[, max] = link.match(/\/(\d+)\/$/);
				}
				let links = fn.arr(max, (v, i) => `${url}/${(i + 1)}/`);
				return fn.getImgA(".L664 a:has(>img:not([src^='/thumbs/']))", links, 1);
			}
			return fn.getImgA(".L664 a:has(>img:not([src^='/thumbs/']))", [fn.url]);
		},
		button: [4],
		insertImg: ["box", 2],
		category: "nsfw2"
	}, {
		name: "エロ画像 オナップル",
		url: {
			h: "onapple.jp",
			p: "/archives/"
		},
		imgs: ".permanent_text img",
		customTitle: ".permanent_title",
		category: "nsfw2"
	}, {
		name: "JavTube/PureJapanese/ThumbNow/69DV/JapaneseThumbs/AsiaUncensored",
		url: {
			h: [
				"javtube.com",
				"purejapanese.com",
				"thumbnow.com",
				"69dv.com",
				"japanesethumbs.com",
				"asiauncensored.com"
			],
			e: ".L664 a:has(>img:not([src^='/thumbs/']))",
			d: "pc"
		},
		box: [".L664,.L996"],
		imgs: () => {
			let pagesE = fn.ge(".matchlinks");
			let pages = /\/\d+\/$/.test(fn.lp);
			if (pagesE && pages) {
				let url = fn.lp.replace(/\/\d+\/$/, "");
				let max;
				let last = fn.ge("//div[@class='matchlinks']/a[text()='Last']");
				if (last) {
					let link = fn.gu("//div[@class='matchlinks']/a[text()='Last']");
					[, max] = link.match(/\/(\d+)\/$/);
				} else {
					max = fn.gt(".matchlinks>a:last-child", 2);
				}
				let links = fn.arr(max, (v, i) => `${url}/${(i + 1)}/`);
				return fn.getImgA(".L664 a:has(>img:not([src^='/thumbs/']))", links, 1);
			}
			return fn.getImgA(".L664 a:has(>img:not([src^='/thumbs/']))", [fn.url]);
		},
		button: [4],
		insertImg: ["box", 2],
		category: "nsfw2"
	}, {
		name: "人体艺术",
		link: "https://dsqs8.com/",
		url: {
			e: ".umBody",
			p: /^\/post\/\d+/
		},
		init: () => fn.clearAllTimer(),
		box: [".viewall_plugin", 2],
		imgs: ".LightGallery_Item",
		button: [4],
		insertImg: [
			["box", 0, ".viewall_plugin"], 2
		],
		autoDownload: [0],
		next: ".prev>a",
		prev: ".next>a",
		customTitle: "h1.tit",
		category: "nsfw2"
	}, {
		name: "Girl Girl Go",
		reg: /^https?:\/\/(\w{2}\.)?(girlgirlgo|girlygirlpic)\.(org|net|xyz|icu|com|biz|top)\/a\/\w+/,
		imgs: ".figure-link",
		button: [4],
		insertImg: [".post-media-body", 2],
		next: () => fn.waitEle("a[rel=next]", 30).then(a => a ? a.href : null),
		prev: "a[rel=prev]",
		customTitle: () => fn.waitEle(".figure-link").then(() => fn.gt(".entry-title a").split(" No.")[0].trim()),
		category: "nsfw1"
	}, {
		name: "QGirlz/CuteLadyPic",
		url: {
			e: [
				".main-image",
				"//a[@data-title and picture/source]",
				".next",
				".main-title"
			]
		},
		imgs: () => fn.getImg("//a[@data-title and picture/source]", (fn.gt(".next", 2) || 1), 16),
		button: [4],
		insertImg: [".main-image", 2],
		customTitle: () => fn.gt(".main-title").split(" No.")[0].trim(),
		category: "nsfw1"
	}, {
		name: "QGirlz/CuteLadyPic M",
		url: {
			p: "/m/",
			e: [
				".place-padding+.place-padding",
				"//a[@data-title and picture/source]",
				".prev-next-page",
				".blog-title"
			]
		},
		box: ["#post-tag", 1],
		imgs: () => fn.getImg("//a[@data-title and picture/source]", fn.gt(".prev-next-page")?.match(/\d+/g)?.at(1) || 1, "4"),
		button: [4],
		insertImg: [
			["box", 0, "#content>div:first-child[style],#content>article,#content>.place-padding:not([id])"], 2
		],
		customTitle: () => fn.gt(".blog-title").split(" No.")[0].trim(),
		category: "nsfw1"
	}, {
		name: "cn.angirlz.com",
		url: {
			h: /^\w{2}\.angirlz\.com$/
		},
		page: () => fn.clp("/album/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => _this.page() ? fn.gae("#divGallery a", doc) : [],
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.dt({
			s: "div[key=album_info] h1"
		}, doc) : null,
		css: "div[key=album_main]{text-align:-webkit-center}",
		category: "nsfw2"
	}, {
		name: "KawaiiX系列 一 分頁",
		url: {
			p: /^\/[^/]+\/\w+/,
			e: [
				".separator>a[href]",
				".album-post-body .clear,.album-post-share-wrap",
				".nav-links"
			]
		},
		imgs: () => {
			let max;
			if (isM && fn.ge(".current-page")) {
				max = fn.gt(".current-page").match(/\d+/g).at(-1);
			} else {
				max = fn.gt(".nav-links>*:last-child", 2) || 1
			}
			return fn.getImg(".separator>a[href]", max, 16);
		},
		button: [4],
		insertImg: [
			[".album-post-body .clear,.album-post-share-wrap", 1, "div[itemprop='description articleBody'],.album-post-body>*:not(.album-post-inner):not(.album-post-share-wrap):not(#FullPictureLoadOptionsButtonParentDiv,.FullPictureLoadImage,a[data-fancybox]):not(#FullPictureLoadEnd)"], 2
		],
		customTitle: ".breadcrumbs>span:last-child",
		hide: "#openRss",
		category: "nsfw2"
	}, {
		name: "KawaiiX系列 一",
		url: {
			e: ".album-post-inner,.album-postmeta-primarypix"
		},
		imgs: ".separator>a[href]",
		button: [4],
		insertImg: [
			[".album-post-inner,.album-postmeta-primarypix", 2, ".separator"], 2
		],
		customTitle: ".breadcrumbs>span:last-child",
		hide: "#openRss",
		category: "nsfw2"
	}, {
		name: "KawaiiX系列 二 分頁",
		url: {
			e: [
				"//a[@data-title and picture/source]",
				".hero+.hero,.entry-content,.d-flex>.col-24,.album-post",
				".entry-title,.album-title,.album-post-title,.col-12>h1,.album-h1",
				".nav-links"
			]
		},
		imgs: () => {
			let max;
			if (isM && fn.ge(".current-page")) {
				max = fn.gt(".current-page").match(/\d+/g).at(-1);
			} else {
				max = fn.gt(".nav-links>*:last-child", 2) || 1
			}
			return fn.getImg("//a[@data-title and picture/source]", max, 16);
		},
		button: [4],
		insertImg: [".hero+.hero,.entry-content,.d-flex>.col-24,.album-post", 2],
		customTitle: () => fn.gt(".entry-title,.album-title,.album-post-title,.col-12>h1,.album-h1").split(" No.")[0].trim(),
		css: ".flex-grid:not(.masonry){display:block!important;}",
		hide: "#openRss,div.loading[style]",
		category: "nsfw2"
	}, {
		name: "KawaiiX系列 二",
		url: {
			e: [
				".hero+.hero,.entry-content,.d-flex>.col-24,.album-post",
				".entry-title,.album-title,.album-post-title,.col-12>h1,.album-h1",
				"//a[@data-title and picture/source]"
			]
		},
		imgs: "//a[@data-title and picture/source]",
		button: [4],
		insertImg: [".hero+.hero,.entry-content,.d-flex>.col-24,.album-post,.album-h1", 2],
		customTitle: () => fn.title(/\s-\s[\w\.]+$/i).replace(/\s?\(\d+\s?photos\)/, "").trim(),
		hide: "#openRss,div.loading[style]",
		category: "nsfw2"
	}, {
		name: "壹纳网",
		host: ["yinaw.com"],
		reg: /^https?:\/\/yinaw\.com\/\d+\.html$/,
		include: [".article-content img:not([src*='yinaw.png'])", ".article-social"],
		init: async () => {
			let baiduApi = "https://image.baidu.com/search/down?thumburl=https://baidu.com&url=";
			let links = fn.gau(".fenye>a");
			if (links.length > 0) {
				await fn.getEle(links, ".article-content>*:not(.open-message,.fenye,.article-social)", [".article-social", 1], ".fenye");
			}
			let imgs = fn.gae(".article-content img:not([src*='yinaw.png'])");
			for (let img of imgs) {
				if (/^https?:\/\/\w+\.sinaimg\.cn\//.test(img.src)) {
					img.dataset.src = img.src.replace(/^(https?:\/\/\w+\.sinaimg\.cn\/)/, `${baiduApi}$1`).replace(/\/orj\d+\/|\/mw\d+\//, "/large/");
				} else if (/^https?:\/\/i\d\.wp\.com\//.test(img.src)) {
					img.dataset.src = img.src.replace(/\/orj\d+\/|\/mw\d+\//, "/large/").replace(/\?w=.+$/, "").replace(/^https?:\/\/i\d\.wp\.com\//, `${baiduApi}https://`);
				} else {
					img.dataset.src = img.src.replace(/\/orj\d+\/|\/mw\d+\//, "/large/");
				}
			}
			if (setYinawSinaOriginalURL == 1) {
				for (let img of imgs) img.dataset.src = img.dataset.src.replace(baiduApi, "");
			}
			for (let img of imgs) {
				img.src = loading_bak;
				fn.imagesObserver.observe(img);
			}
		},
		imgs: ".article-content img:not([src*='yinaw.png'])",
		autoDownload: [0],
		next: ".article-nav-prev>a",
		prev: ".article-nav-next>a",
		customTitle: ".article-title",
		referer: "https://weibo.com/",
		category: "nsfw1"
	}, {
		name: "瞎扯",
		url: {
			h: "shyhot.com",
			p: ["/mingxing/", "/bizhi/", "/dongman/", "/taotu/", "/simi/", "/wlmn/"]
		},
		imgs: ".text img",
		customTitle: ".text-title",
		category: "nsfw1"
	}, {
		name: "尼克成人網 人體寫真",
		host: ["nick20.com"],
		link: "https://nick20.com/pic/index.html",
		reg: /^https?:\/\/nick20\.com\/pic\/pic\d+\.html$/i,
		imgs: () => {
			thumbnailSrcArray = _unsafeWindow.Large_cgurl.filter(Boolean);
			return thumbnailSrcArray.map(e => e.replace("https://thumbs", "https://images").replace("_t.", "_o."));
		},
		button: [4],
		insertImg: ["//center[img]", 2],
		customTitle: ".bbs_entry_wrapper>h2",
		category: "nsfw2"
	}, {
		name: "尼克成人網 成人漫畫",
		reg: /^https?:\/\/nick20\.com\/bbs2\/index\.cgi\?read=\d+/i,
		imgs: "a[id][onclick]",
		button: [4],
		insertImg: ["p.img", 2],
		customTitle: ".bbs_entry_wrapper>h2",
		category: "nsfw2"
	}, {
		name: "尼克成人網 成人貼圖 本土自拍 走光偷拍",
		reg: /^https?:\/\/nick20\.com\/bbs(3|5)?\/\d+\.html/i,
		imgs: "p#img>img",
		button: [4],
		insertImg: ["p#img", 2],
		customTitle: ".bbs_entry_wrapper>h2",
		category: "nsfw2"
	}, {
		name: "尼克成人網M",
		host: ["m.nick20.com"],
		link: "https://nick20.com/pic/index.html",
		reg: [
			/^https?:\/\/m\.nick20\.com\/pic\/index\.(html|cgi)\?read=\d+$/i,
			/^https?:\/\/m\.nick20\.com\/bbs(2|3|5)?\/\d+\.html$/i
		],
		imgs: () => {
			let [bp] = fn.gae(".bbs_pictures");
			let imgs = fn.gae("img", bp);
			return fn.getImgSrcArr(imgs).filter(src => !/\/images\/share|\/add\/|aav999/.test(src));
		},
		button: [4],
		insertImg: [".bbs_pictures", 2],
		customTitle: ".entryBlock>strong",
		category: "nsfw2"
	}, {
		name: "小濕妹圖庫",
		url: {
			h: ["xsmpic.com"],
			p: /^\/\d+\/$/
		},
		imgs: ".entry-content img:not([data-src])",
		customTitle: "h1.entry-title",
		category: "nsfw2"
	}, {
		name: "五歌的开心网",
		url: {
			h: ["happy.5ge.net"],
			p: "/archives/",
			e: "//ul[@class='joe_bread__bread']//a[contains(text(),'图册')]"
		},
		imgs: ".joe_detail__article img",
		button: [4],
		insertImg: [".joe_detail__article", 2],
		customTitle: () => fn.dt({
			t: fn.gt(".joe_detail__title").replaceAll("---", " "),
			d: /[-PVGMB\d\.]+$/
		}),
		hide: "div:has(>center>a>img)",
		category: "nsfw2"
	}, {
		name: "好视角 lianjiajr.net",
		host: ["www.mshijiao.com"],
		url: {
			t: "视角",
			p: /^\/\w+\.html$/
		},
		imgs: () => {
			let pages = fn.ge(".page-normal a");
			if (pages) {
				let [, max] = fn.gu("//a[text()='尾页']").match(/_(\d+).html/);
				max = Number(max) + 1;
				return fn.getImg(".tit+.text img:not([onerror]),.tit+.pic img:not([onerror])", max, 3);
			}
			return fn.gae(".tit+.text img:not([onerror]),.tit+.pic img:not([onerror])");
		},
		button: [4],
		insertImg: [".tit+.text,.tit+.pic", 2],
		insertImgAF: () => fn.hideEle(".page-normal"),
		autoDownload: [0],
		next: "//p[contains(text(),'上一篇')]/a",
		prev: "//p[contains(text(),'下一篇')]/a",
		customTitle: ".tit>h1,.grjs h1",
		css: ".tit+.text img{width:100%!important}.tit+.pic img{margin:auto!important}",
		mcss: ".pro_article .tpxq .pic{width: calc(100% - 10px)!important}",
		hide: ".mbx_nav~div:not([class]),body>em,audio",
		gallery: 1,
		category: "nsfw2"
	}, {
		name: "秘秘秘/美鲍儿",
		host: ["ktacf.click", "lingleis.info"],
		url: {
			e: "#menu_top_gg+.table,#content_top_gg"
		},
		imgs: "#content_top_gg+.titletablerow img",
		button: [4],
		insertImg: ["#content_top_gg+.titletablerow", 2],
		autoDownload: [0],
		next: "//div[text()='下篇']/preceding-sibling::div[1]/a",
		prev: "//div[text()='上篇']/following-sibling::div[1]/a",
		customTitle: ".cell3.clmtop3",
		hide: "#header,#sidebar_left,#sidebar_right,.logo_top_gg,#menu_top_gg,#menu_bottom_gg,#content_top_gg,#content_bottom_gg,#page_bottom_top_gg,#page_bottom_bottom_gg,div:has(>#page_bottom_link_gg)",
		category: "nsfw2"
	}, {
		name: "秘秘秘/美鲍儿 AD",
		url: {
			e: ".topbody .logo+.table,#menu_top_gg+.table"
		},
		hide: "#tnoticegg,.topnotice,#header,#sidebar_left,#sidebar_right,.logo_top_gg,#menu_top_gg,#menu_bottom_gg,#page_bottom_top_gg,#page_bottom_bottom_gg,div:has(>#page_bottom_link_gg),.titletablerow:has(>.titletablecell>a:not([href$=html]))",
		category: "ad"
	}, {
		name: "啪啪凸凸",
		host: ["papatutu.com"],
		url: {
			e: "#content.card-body",
			p: "/a/show/"
		},
		imgs: "div.lightbox",
		button: [4],
		insertImg: ["#content", 2],
		autoDownload: [0],
		next: "a:has(.fa-arrow-right)",
		prev: "a:has(.fa-arrow-left)",
		customTitle: ".container>h4",
		hide: "#span_h4",
		category: "nsfw2"
	}, {
		name: "自拍图库.com",
		host: ["xn--25c-zptkk-com-9x6wp54c.xn--07zr2b8o884c.com"],
		url: {
			t: "自拍图库.com",
			p: "/content"
		},
		init: () => fn.wait((d, w) => isFn(w?.getRealPath) && ("jQuery" in w)).then(() => fn.clearAllTimer()),
		imgs: () => fn.gae(".showimg").map(e => _unsafeWindow.getRealPath(fn.attr(e, "rdata"))),
		button: [4],
		insertImg: ["#imgviewer", 2],
		autoDownload: [0],
		next: "//a[text()='下一组']",
		prev: "//a[text()='上一组']",
		customTitle: () => {
			let dt = "自拍图库";
			let at = fn.dt({
				s: ".afav .creator",
				d: "作者:"
			});
			let pt = fn.dt({
				s: ".artical-content .ttle"
			});
			return `${dt} - [${at}] ${pt}`;
		},
		hide: ".artical-content>a",
		category: "nsfw2"
	}, {
		name: "行形涉摄",
		host: ["https://xn--25c-zptkk-com-9x6wp54c.xn--07zr2b8o884c.com/"],
		url: {
			t: "行形涉摄",
			p: "/xs"
		},
		imgs: ".wp-block-image img",
		videos: ".wp-block-video video",
		autoDownload: [0],
		next: ".previous-post",
		prev: ".next-post",
		customTitle: ".entry-title",
		downloadVideo: true,
		category: "nsfw2"
	}, {
		url: {
			p: "/show/"
		},
		imgs: "#content img[loading]",
		button: [4],
		insertImg: ["#content", 2],
		customTitle: ".container .bg-info",
		category: "nsfw2"
	}, {
		name: "G-AVSTAR",
		url: {
			h: "g-avstar.com",
			p: /^\/\d+\/\d+\/\d+\/[^\/]+\/$/,
			e: "//p[contains(text(),'更多美图')]"
		},
		box: [".ngg-galleryoverview", 1],
		imgs: () => fn.getNP(".ngg-gallery-thumbnail-box", ".ngg-navigation>span.current+a:not(.prev)", null, ".ngg-navigation").then(() => fn.gae(".ngg-gallery-thumbnail a")),
		thums: ".ngg-gallery-thumbnail img",
		button: [4],
		insertImg: [
			["box", 0, ".ngg-galleryoverview,.ngg-navigation"], 2
		],
		customTitle: ".entry-title",
		category: "nsfw2"
	}, {
		name: "XO福利圖",
		links: [
			"https://kb1.a7xofulitu.com/%E5%84%BF%E6%AD%8C%E4%B8%89%E7%99%BE%E9%A6%96/",
			"https://www.xofulitu521.xyz/xoxo",
			"https://www.xofulitu9ok999.xyz/xoxo",
			"https://diedk1123-ake33i.xofulitu2za222.sbs/xoxo",
			"https://ponds-attract-ducks.xofulitu1qqq111.xyz/xoxo"
		],
		url: {
			t: "XO福利圖",
			h: "xofulitu",
			e: ".picture-wrap img",
			p: /\/art\/pic\/id\/\d+\/$/i
		},
		imgs: () => fn.getImgSrcArr(".picture-wrap img").filter(src => !src.includes("loading")),
		button: [4],
		insertImg: [".container.clearfix", 2],
		customTitle: () => fn.dt({
			d: [
				/ - XO福利圖.+$/,
				/[\/\s]?[\(\[(【“]\d+[\w\s\\\/\.+-/]+[\)\])】”]|\s?\d+p[\+\s]+\d+v|\s?\d+p\d+v|\s?\d+P|\(\d\)/gi,
				/[\s-]+$/
			]
		}),
		hide: ".custom_link-wrapper,div:has(>#floating-ad),body>*[style*='display: block; z-index: 2147483646; width: 10%;']",
		category: "nsfw2"
	}, {
		name: "XO福利圖 分類自動翻頁",
		url: {
			h: "xofulitu",
			t: "XO福利圖",
			p: /^\/arttype\//i
		},
		autoPager: {
			ele: ".container.clearfix",
			observer: ".container.clearfix .album",
			next: ".paging-item--current+a",
			re: ".pagging-div",
			lazySrc: "img[data-src]",
			pageNum: ".paging-item--current"
		},
		openInNewTab: ".picture-list a:not([target=_blank])",
		hide: ".custom_link-wrapper,div:has(>#floating-ad),body>*[style*='display: block; z-index: 2147483646; width: 10%;']",
		category: "autoPager"
	}, {
		name: "XO福利圖AD",
		url: {
			h: "xofulitu",
			t: "XO福利圖"
		},
		hide: ".custom_link-wrapper,div:has(>#floating-ad),body>*[style*='display: block; z-index: 2147483646; width: 10%;']",
		category: "ad"
	}, {
		name: "ONS漂亮MM图库",
		link: "https://www.rb1.es/momotk/",
		url: {
			h: ["ons.ooo"],
			p: "/article/"
		},
		imgs: ".article-content img",
		button: [4],
		insertImg: [".article-content", 2],
		customTitle: ".focusbox-title",
		category: "nsfw1"
	}, {
		name: "XXAV",
		host: ["xxav.one", "www.xxav2235.com"],
		url: {
			t: "XXAV",
			p: ["/view/", "/artdetail"]
		},
		box: ["article:has(>img),article:has(>p>img)", 1],
		imgs: "article>img,article>p>img",
		button: [4],
		insertImg: [
			["box", 0, "article:has(>img)"], 2
		],
		autoDownload: [0],
		next: "//em[text()='上一篇:']/a",
		prev: "//em[text()='下一篇:']/a",
		customTitle: () => fn.title("-XXAV"),
		hide: ".suspend",
		category: "nsfw1"
	}, {
		name: "多多影视/多多影音/全网影视/哥哥在线/微微资讯/酷酷影音/男人社区 模式A",
		link: "https://xxselove.com/artmv/",
		url: {
			e: [
				".v_nav .sel_wrap",
				"#content_news img"
			],
			p: /^\/art\w+\//
		},
		imgs: () => {
			let pages = fn.ge("//div[@id='page']/a[@class='next'][starts-with(text(),'尾')]");
			if (pages) {
				let [max] = fn.gt(pages).match(/\d+/);
				let dir = fn.dir(fn.lp);
				let links = fn.arr(max, (v, i) => i == 0 ? dir : dir + `index${i + 1}.html`);
				return fn.getImgA("#content_news img", links);
			}
			return fn.gae("#content_news img");
		},
		button: [4],
		insertImg: ["#content_news", 2],
		customTitle: ".title h1 a",
		category: "nsfw2"
	}, {
		name: "多多影视/多多影音/全网影视/哥哥在线/微微资讯/酷酷影音/男人社区 模式B",
		link: "https://m.rusese.org/artmv/",
		url: {
			e: [
				"a.fed-nav-title[href='/artmv/']",
				".fed-arti-content img"
			],
			p: /^\/art\w+\//
		},
		imgs: () => {
			let pages = fn.ge(".fed-page-info a[href*='/index']");
			if (pages) {
				let [max] = fn.gt(".fed-page-info a:last-child").match(/\d+/);
				let dir = fn.dir(fn.lp);
				let links = fn.arr(max, (v, i) => i == 0 ? dir : dir + `index${i + 1}.html`);
				return fn.getImgA(".fed-arti-content img", links);
			}
			return fn.gae(".fed-arti-content img");
		},
		button: [4],
		insertImg: [".fed-arti-content", 2],
		customTitle: ".fed-arti-info h2",
		category: "nsfw2"
	}, {
		name: "多多影视/多多影音/全网影视/哥哥在线/微微资讯/酷酷影音/男人社区 模式C",
		link: "https://xxk555.com/arttype/meituqu.html",
		url: {
			e: [
				"a.fed-nav-title[href='/arttype/meituqu.html']",
				".fed-arti-content img"
			],
			p: "/artdetail/"
		},
		imgs: () => {
			let pages = fn.ge("//a[text()='尾页']");
			if (pages) {
				let max = fn.gu("//a[text()='尾页']").match(/\d+/g).at(-1);
				let url = fn.lp.replace(/(-\d+)?\.html$/, "");
				let links = fn.arr(max, (v, i) => i == 0 ? url + ".html" : url + `-${i + 1}.html`);
				return fn.getImgA(".fed-arti-content img", links);
			}
			return fn.gae(".fed-arti-content img");
		},
		button: [4],
		insertImg: [".fed-arti-content", 2],
		customTitle: ".fed-arti-info h2",
		category: "nsfw2"
	}, {
		name: "多多影视/多多影音/全网影视/哥哥在线/微微资讯/酷酷影音/男人社区 模式D",
		link: "https://xoxvi.com/arttype/jipinmeinv.html",
		url: {
			e: [
				"#sidebarTogglePcDown",
				".single-video-info-content img"
			],
			p: "/artdetail/"
		},
		imgs: () => fn.getNP(".single-video-info-content>*", ".page-item.active+li>a:not([title='下一页'])", null, ".pagination").then(() => fn.gae(".single-video-info-content img")),
		button: [4],
		insertImg: [".single-video-info-content", 1],
		customTitle: ".single-video-title h2",
		category: "nsfw2"
	}, {
		name: "SexBee.TV",
		link: "https://sexbee.tv/arttype/jipinmeinv/",
		host: ["sexbee.tv", "m.beebee.top", "m.beeku.top", "蜜.2025tv.top", "m.aistv.top", "xiaobee.vip", "meimeibee.com"],
		url: {
			e: [
				"#site-header .app-nav-toggle>.lines",
				"#site-header a.logo>img[src='/assets/images/logo.png']",
				"#list_art_common_art_show img"
			],
			st: ["pageContext", "toastMessage"],
			p: "/artdetail/"
		},
		imgs: () => {
			let pages = fn.ge(".pagination");
			if (pages) {
				let max = fn.gu("//a[text()='最後 »']").match(/\d+/g).at(-1);
				let links = fn.arr(max, (v, i) => `?mode=async&function=get_block&block_id=list_art_common_art_show&sort_by=&from=${i + 1}`);
				return fn.getImgA("#list_art_common_art_show img", links);
			}
			return fn.gae("#list_art_common_art_show img");
		},
		button: [4],
		insertImg: ["#list_art_common_art_show", 2],
		customTitle: ".content-header h2",
		category: "nsfw2"
	}, {
		name: "美女写真图集",
		url: {
			h: ["www.112ze.com", "112ze.com"],
			p: ".html"
		},
		imgs: ".post-content img",
		button: [4],
		insertImg: [".post-content", 2],
		customTitle: ".mdui-text-black",
		fancybox: {
			blacklist: 1
		},
		category: "nsfw1"
	}, {
		name: "adultspic色情成人圖片",
		url: {
			h: ["adultspic.com"],
			p: ".html"
		},
		imgs: () => fn.getNP(".wp-block-image", "//a[text()='下一頁']").then(() => fn.gae(".wp-block-image img").map(e => e.src)),
		button: [4],
		insertImg: [".article-content", 2],
		autoDownload: [0],
		next: ".article-nav-prev>a",
		prev: ".article-nav-next>a",
		customTitle: ".article-title",
		hide: ".ssr-content",
		category: "nsfw2"
	}, {
		name: "中国街拍",
		host: ["jiepai.sifang.app"],
		url: {
			e: "meta[content=中国街拍]",
			p: /^\/\d+\/[\w-]+\.html$/
		},
		imgs: "a[data-fancybox]",
		button: [4],
		insertImg: [
			["//p[a[img]]", 2, "//p[a[img]]"], 2
		],
		customTitle: "article>h1",
		mcss: "article{width:100%!important}",
		category: "nsfw1"
	}, {
		name: "美图收藏夹",
		url: {
			h: ["sifang.app"],
			p: "/node/"
		},
		imgs: "a[data-fancybox]",
		button: [4],
		insertImg: [
			["//p[a[img]]", 2, "//p[a[img]]"], 2
		],
		customTitle: ".page-title",
		fancybox: {
			blacklist: 1
		},
		mcss: "article{width:100%!important}",
		category: "nsfw1"
	}, {
		name: "名腿网",
		host: ["www.mingtuiw.com", "mingtui.net"],
		reg: /^https?:\/\/(www\.mingtuiw\.com|mingtui\.net)\/archives\/\d+$/,
		exclude: ".swpm-more-tag-not-logged-in,.swpm-more-tag-restricted-msg",
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".entry-content img");
			return thumbnailSrcArray.map(e => e.replace(/-\d+x\d+(\.\w+)$/, "$1"))
		},
		button: [4],
		insertImg: [".entry-content>p", 2],
		autoDownload: [0],
		next: ".nav-previous>a[rel=prev]",
		prev: ".nav-next>a[rel=next]",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /(\d+图)/
		}),
		category: "nsfw1"
	}, {
		name: "名腿网",
		host: ["www.mingtuiw.com"],
		url: () => {
			if (fn.curl(/^https?:\/\/www\.mingtuiw\.com\/archives\/\d+$/)) {
				let [, num] = fn.gt(".entry-title").match(/((\d+)图)/);
				let tImgsNum = fn.gae(".entry-content img").length;
				if (num == tImgsNum) return true;
			}
			return false;
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".entry-content img");
			return thumbnailSrcArray.map(e => e.replace(/-\d+x\d+(\.\w+)$/, "$1"))
		},
		button: [4],
		insertImg: [".entry-content>p", 2],
		autoDownload: [0],
		next: ".nav-previous>a[rel=prev]",
		prev: ".nav-next>a[rel=next]",
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: /(\d+图)/
		}),
		category: "nsfw1"
	}, {
		name: "名腿网",
		host: ["www.mingtuiw.com"],
		reg: /^https?:\/\/www\.mingtuiw\.com\/archives\/\d+\/.+$/,
		exclude: "#div_img_vip",
		imgs: () => {
			let links = fn.gau("#thumb_imglist>a");
			return fn.getImgA(".entry-content img.attachment-large", links).then(srcs => srcs.map(e => e.replace(/-\d+x\d+(\.\w+)$/, "$1")));
		},
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: () => fn.dt({
			d: /(\d+\/\d+).+/
		}),
		category: "nsfw1"
	}, {
		name: "Rule34Comic",
		url: {
			h: "rule34comic.party",
			p: "/comics/"
		},
		box: [".block-album"],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".thumbs-gallery img");
			fn.sm5();
			let url = fn.gu("//a[span[text()='Read']]");
			return fn.fetchDoc(url).then(dom => fn.gae("#album_view_album_view img[data-page]", dom));
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".title_video",
		category: "hcomic"
	}, {
		name: "AhentaiZ.net",
		url: {
			h: "ahentaiz.net",
			e: "#imageContainer"
		},
		imgs: () => {
			fn.sm5();
			let json_url = fn.attr("#imageContainer", "data-json-url");
			let s = new URL(json_url).origin;
			return fn.j(json_url).then(arr => arr.map(e => s + e));
		},
		button: [4],
		insertImgBF: () => fn.waitEle("#imageContainer img[alt]"),
		insertImg: ["#imageContainer", 2],
		customTitle: () => fn.dt({
			d: [
				"Read online Hentai Manga 2025 year",
				" - Ahentaiz",
				/"/g
			]
		}),
		category: "hcomic"
	}, {
		name: "HentaiBe",
		url: {
			h: "hentaibe.com",
			p: "/g/"
		},
		box: [".masonry", 2],
		imgs: () => {
			fn.sm5();
			thumbnailSrcArray = fn.getImgSrcArr(".entry__thumb img");
			let url = fn.gu("//a[text()='SHOW ALL ORIGINAL']");
			return fn.fetchDoc(url).then(dom => fn.gae(".s-content img", dom));
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".masonry"),
		customTitle: ".s-content__header-title",
		category: "hcomic"
	}, {
		name: "Hentai City",
		url: {
			h: "www.hentaicity.com",
			p: "/gallery/"
		},
		box: [".thumb-list.ac:not(.title-spacing)", 2],
		imgs: () => {
			let b = ".thumb-list.ac:not(.title-spacing) a.thumb-img";
			let t = ".thumb-list.ac:not(.title-spacing) img";
			thumbnailSrcArray = fn.getImgSrcArr(t);
			return fn.ge(b) ? fn.gae(b) : fn.gae(t);
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".thumb-list.ac:not(.title-spacing)"),
		customTitle: ".content h1",
		category: "hcomic"
	}, {
		name: "Cartoon Porn",
		url: {
			h: "www.zzcartoon.com",
			p: "/pictures/"
		},
		box: [".zoom-gallery", 2],
		imgs: ".zoom-gallery a",
		thums: ".zoom-gallery a img",
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".zoom-gallery"),
		customTitle: () => fn.ge(".title-block h2").textContent,
		category: "hcomic"
	}, {
		name: "ComicsPorno10",
		url: {
			h: "comicsporno10.com"
		},
		box: [".entry-content p:has(img[data-srcset]),.gallery", 1],
		srcset: ".entry-content p:has(img[data-srcset]) img,.gallery img",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content p:has(img[data-srcset]),.gallery"], 2
		],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "HentaiKisu",
		url: {
			h: "hentaikisu.com",
			p: /^\/g\/\d+$/
		},
		box: [".card-hentai:has(.book-list)", 2],
		init: () => fn.waitVar("decode_base64"),
		imgs: () => fn.getCode(fn.gu("a:has(.irx-eye)"), {
			mode: "dom",
			key: "la ="
		}).then(() => {
			let {
				decode_base64,
				la
			} = _unsafeWindow;
			return decode_base64(la).split(",");
		}),
		button: [4],
		insertImg: ["box", 2],
		customTitle: () => fn.dt({
			s: "#info h1",
			d: /"/g
		}),
		category: "hcomic"
	}, {
		name: "Cutie Comics",
		url: {
			h: "cutiecomics.com",
			P: ".html"
		},
		imgs: ".galery img",
		button: [4],
		insertImg: [".galery", 2],
		customTitle: "#page-title",
		category: "hcomic"
	}, {
		name: "Hentai FR",
		url: {
			h: "hentaifr.net"
		},
		imgs: ".rl-gallery-container img",
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "Prismblush",
		url: {
			h: "prismblush.com",
			p: "/comic/"
		},
		imgs: () => {
			let jump = fn.gae(".comic-nav-jumptocomic").at(0);
			let links = fn.gae(".level-0", jump).map(e => e.value);
			return fn.getImgA("#comic img", links);
		},
		button: [4],
		insertImg: ["#comic", 2],
		endColor: "white",
		customTitle: "h1.elementor-heading-title",
		category: "hcomic"
	}, {
		name: "Xpicvid",
		host: ["www.xpicvid.com", "www.nicohentai.com"],
		url: {
			e: "#Comic_Top_Nav img[alt=logo][src$='_nico.png']",
			p: /^\/(moeupup-\d-\d+\.html|showinfo-\d+-\d+-\d\.html)$/,
			ee: ".dplayer-container"
		},
		init: () => fn.getNP(".row.thumb-overlay-albums img,.artwork-container .artwork img", ".pagination li.active+li>a:not(.prevnext)"),
		imgs: ".row.thumb-overlay-albums img,.artwork-container .artwork img",
		button: [4],
		insertImg: [".row.thumb-overlay-albums,.artwork-container .artwork", 2],
		autoDownload: [0],
		next: {
			s: ".ph-active a[href$=html]",
			t: "下一页"
		},
		prev: {
			s: ".ph-active a[href$=html]",
			t: "上一页"
		},
		customTitle: () => {
			let url = fn.gu("//a[span[text()='漫畫簡介']]");
			if (url) {
				return fn.fetchDoc(url).then(dom => {
					let comicName = fn.gt(".panel-heading h1", 1, dom);
					let episode = fn.ge(".episode", dom);
					return episode ? comicName + " - " + fn.gt(".panel-heading>.pull-left") : comicName;
				}).then(text => fn.dt({
					t: text,
					d: [
						/\(\d+[\w\s\.\+-]+\)/i,
						/[\d+[\w\s\.\+-]+]/i
					]
				}));
			}
			return document.title;
		},
		category: "hcomic"
	}, {
		name: "Doujindesu.XXX",
		url: {
			h: "doujindesu.tv",
			e: "#reader>.main"
		},
		init: () => fn.waitEle("#reader>.main img").then(() => {
			for (const sheet of document.styleSheets) {
				if (sheet.href?.includes("doujindesu.css")) {
					for (const rule of sheet.rules) {
						if (rule.selectorText === ".darkmode input, .darkmode button") {
							rule.style.setProperty("color", "#fff");
							return;
						}
					}
				}
			}
		}),
		imgs: () => fn.gae("#reader>.main img"),
		button: [4],
		insertImg: ["#reader>.main", 2],
		next: "a:has(>.fa-chevron-right):not([href='#'])",
		prev: "a:has(>.fa-chevron-left):not([href='#'])",
		customTitle: "#reader h1",
		hide: "center:has(a>img)",
		category: "hcomic"
	}, {
		name: "NAKAL",
		url: {
			h: "www.nakal.me",
			p: "/chapter/"
		},
		imgs: ".chapter-content img",
		button: [4],
		insertImg: [".chapter-content", 2],
		autoDownload: [0],
		np: (k) => {
			let chapters = fn.gae("#chapter-list option");
			let c = chapters.find(e => e.value == fn.url);
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("nextElementSibling"),
		prev: () => _this.np("previousElementSibling"),
		customTitle: () => fn.dt({
			t: fn.ge(".container h1").textContent
		}),
		category: "hcomic"
	}, {
		name: "Hentai18/Truyện Hentaivn/HentaiFull",
		host: ["hentai18.net", "truyenhentaivn.icu", "hentaifull.net"],
		url: {
			e: ".header-logo img[alt='Hentai18'],.header-logo img[alt='Truyện Hentaivn'],.header-logo img[alt='HentaiFull']",
			p: ["/read-hentai/", "/oneshot", "/chap"]
		},
		imgs: ".chapter-content img",
		button: [4],
		insertImg: [".chapter-content", 2],
		autoDownload: [0],
		next: ".btn-chapter-next[href*='chap']",
		prev: ".btn-chapter-prev[href*='chap']",
		chapters: {
			target: "#chap-list a",
			sort: "r"
		},
		customTitle: ".headInfo h1",
		category: "hcomic"
	}, {
		name: "DocTruyen3Q",
		host: ["doctruyen3qui19.com"],
		url: {
			e: "meta[property='og:site_name'][content^=DocTruyen3Q]",
			p: "/chapter-"
		},
		imgs: () => fn.gae(".list-image-detail>div[id].page-chapter>img").map(e => e.src),
		button: [4],
		insertImg: [".list-image-detail", 2],
		autoDownload: [0],
		next: "a.previous-chapter",
		prev: "a.next-chapter",
		chapters: {
			target: "#select_chapter>option",
			sort: "r"
		},
		customTitle: [".breadcrumb>li", 1, 2],
		category: "hcomic"
	}, {
		name: "Manga Lotus/Yaoi Manga Online",
		url: {
			h: ["mangalotus.com", "yaoimangaonline.com"]
		},
		box: [".meta-tags", 1],
		imgs: ".entry-content img",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content .code-block,.entry-content p:has(img)"], 2
		],
		next: ".nav-links a[rel=next]",
		prev: ".nav-links a[rel=previous]",
		chapters: () => fn.gae(".mpp-toc a,.mpp-toc span").map(e => e.textContent == "Intro" ? null : ({
			text: e.textContent,
			url: e.classList.contains("current") ? fn.url : e.href
		})).filter(Boolean),
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "XZhentai",
		host: ["xzhentai.net", "hz-hentai.ru", "www.hz-hentai.com"],
		url: {
			e: "//a[text()='XZhentai']",
			p: /^\/m\/\d+$/
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".gallery img");
			return thumbnailSrcArray.map(e => e.replace("/t", "/"));
		},
		button: [4],
		insertImg: [".gallery", 2],
		customTitle: () => fn.getText(["h2", "h1"]),
		category: "hcomic"
	}, {
		name: "Naruto hentai Doujins/Ai Generated Hentai MILFS",
		host: ["narutodoujins.com", "syntheticgirls.com"],
		reg: [
			/^https?:\/\/(www\.)?narutodoujins\.com\/\d+\//,
			/^https?:\/\/(www\.)?syntheticgirls\.com\/\d+\//
		],
		imgs: async () => {
			let srcs = [];
			let links;
			if (fn.ge(".post-items-list")) {
				let pages = fn.ge(".page-item-next");
				if (pages) {
					let max = fn.gt(".page-item-next", 2);
					links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `?page=${i + 1}`);
					srcs = await fn.getEle(links, ".post-items-list a").then(eles => {
						links = eles.map(a => a.href);
						return fn.getImgA(".lightbox", links);
					});
				} else {
					links = fn.gau(".post-items-list a");
					srcs = await fn.getImgA(".lightbox", links);
				}
			} else if (fn.ge(".post-images-carousel-wrap")) {
				links = fn.gau(".post-images-carousel-wrap a");
				srcs = await fn.getImgA(".lightbox", links);
			} else {
				srcs = fn.getImgSrcArr(".lightbox");
			}
			let hd = srcs.filter(src => src.includes("/original/"));
			if (hd.length) {
				return hd;
			}
			return srcs;
		},
		capture: () => _this.imgs(),
		customTitle: "h1.text-center",
		category: "hcomic"
	}, {
		name: "熱辣漫畫M SPA",
		home: "/v2h5/index",
		url: {
			h: ["m.relamanhua.org", "m.2024manga.com", "m.manga2024.com", "m.manga2025.com"],
			i: 0,
			d: "m"
		},
		clearLoop: true,
		page: () => fn.clp("/v2h5/comicContent/"),
		getHeaders: () => ({
			headers: {
				accept: "application/json",
				platform: 1,
				version: "2025.08.08",
				webp: 1
			}
		}),
		json: (url = fn.clp(), msg = 1) => {
			if (msg == 1) fn.sm5();
			let split = url.split("/");
			let word = split.at(-2);
			let id = split.at(-1);
			let api = `https://mapi.hotmangasf.com/api/v3/comic/${word}/chapter/${id}`;
			return axios.get(api, _this.getHeaders()).then(json => json.data);
		},
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? _this.json().then(json => (siteJson = json) && fn.hm()) : (_unsafeWindow.aboutBlank = null),
		imgs: (json = siteJson) => {
			if (!_this.page()) return [];
			return json.results.chapter.contents.map(e => e.url);
		},
		capture: () => _this.imgs(),
		button: [4],
		insertImgBF: () => fn.waitEle(".van-image__img").then(() => fn.createImgBox(".comicContentPopupImageList", 2)),
		insertImg: [
			["box", 0, ".comicContentPopupImageList"], 2
		],
		insertImgAF: (p) => {
			const addHtml = (url, text) => {
				let str = `<div style="padding: 10px 0; text-align: center; font-size: initial !important;"><a href="${url}"style="width: 100%;font-size: 26px;line-height: 50px;height: 50px;text-align: center;">${text}</a></div>`;
				p.insertAdjacentHTML("afterend", str);
			};
			let word = fn.clp().split("/").at(-2);
			let url = `/v2h5/details/comic/${word}`;
			let hUrl = "/v2h5/index";
			addHtml(hUrl, "首頁");
			addHtml(url, "目錄");
			if (nextLink) addHtml(nextLink, "點選進入下一話");
			fn.hideEle(".comicFixed,div:has(>.noApp)");
		},
		next: () => {
			if (!_this.page()) return null;
			let next = siteJson.results.chapter.next;
			return next ? fn.dir(fn.clp()) + next : null;
		},
		prev: 1,
		chapters: () => fn.RLMH_M_C(),
		customTitle: (json = siteJson) => _this.page() ? json.results.comic.name + " - " + json.results.chapter.name : null,
		preloadNext: () => {
			_this.json(nextLink, 0).then(json => {
				let srcs = _this.imgs(json);
				let title = _this.customTitle(json);
				fn.picPreload(srcs, title, "next");
			});
		},
		fancybox: {
			blacklist: 1
		},
		gallery: 0,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "熱辣漫畫M 自動翻頁",
		url: {
			h: ["m.relamanhua.org", "m.2024manga.com", "m.manga2024.com", "m.manga2025.com"],
			p: "/v2h5/comicContent/",
			i: 1
		},
		clearLoop: true,
		getHeaders: () => ({
			headers: {
				accept: "application/json",
				platform: 1,
				version: "2025.08.08",
				webp: 1
			}
		}),
		get: () => {
			let split = document.URL.split("/");
			let word = split.at(-2);
			let id = split.at(-1);
			let api = `https://mapi.hotmangasf.com/api/v3/comic/${word}/chapter/${id}`;
			return axios.get(api, _this.getHeaders()).then(json => json.data).then(json => {
				let {
					contents,
					name,
					next
				} = json.results.chapter;
				const images = contents.map(e => e.url);
				if (!!next) {
					next = fn.dir(document.URL) + next;
				} else {
					next = null;
				}
				siteJson = {
					images,
					name,
					next
				}
				console.log("\n熱辣漫畫M_JSON\n", siteJson);
			});
		},
		init: async () => {
			fn.showMsg(DL.str_135, 0);
			await _this.get();
			fn.hideEle(".comicContentPopupImageList");
			await fn.caae("#comicContentMain", fn.createImgArray(siteJson.images));
			fn.clearAllTimer(3);
			if ("aboutBlank" in _unsafeWindow) _unsafeWindow.aboutBlank = null;
			fn.hm();
		},
		autoPager: {
			ele: () => fn.createImgArray(siteJson.images),
			pos: ["#comicContentMain", 0],
			observer: "#comicContentMain>img",
			next: () => siteJson.next,
			wait: () => _this.get(),
			title: () => siteJson.name,
			list: () => "/v2h5/details/comic/" + fn.clp().split("/").at(-2),
			chapters: () => fn.RLMH_M_C(),
		},
		css: ".comicContentPopup #comicContentMain{position:unset!important}",
		hide: ".comicFixed",
		category: "comic autoPager"
	}, {
		name: "熱辣漫畫",
		url: {
			h: [
				"www.relamanhua.org",
				"relamanhua.org",
				"www.2024manga.com",
				"2024manga.com",
				"www.manga2024.com",
				"manga2024.com",
				"www.manga2025.com",
				"manga2025.com"
			],
			e: [
				".disData[contentKey]",
				".disPass[contentkey]",
				".comicContent-list"
			],
			i: 0
		},
		update: "/comics?type=1",
		init: async () => {
			await fn.waitVar("webpackJsonp");
			fn.copymangaUI();
			fn.createImgBox(".comicContent-list", 1);
			let readHistoryData = localStorage.getItem("readHistory");
			let [, , word, , id] = fn.lp.split("/");
			let json;
			readHistoryData ? json = JSON.parse(readHistoryData) : json = {};
			json[word] = id;
			localStorage.setItem("readHistory", JSON.stringify(json));
		},
		imgs: async (dom = document) => {
			let key = fn.attr(".disPass", "contentkey", dom);
			let raw = fn.attr(".disData", "contentkey", dom);
			let images = await fn.copymanga_decrypt_A(raw, key);
			return images.map(({
				url
			}) => url.replace("800x.", "1500x."));
		},
		button: [4, 2],
		insertImg: [
			["box", 0, ".comicContent-list"], 2
		],
		endColor: "white",
		next: "//a[text()='下一話'][starts-with(@href,'/')]",
		prev: "//a[text()='上一話'][starts-with(@href,'/')]",
		chapters: () => fn.RLMH_PC_C(),
		customTitle: (dom = document) => fn.dt({
			t: dom.title,
			d: / - 熱辣漫畫.+$/
		}),
		preloadNext: true,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "熱辣漫畫 自動翻頁",
		url: {
			h: [
				"www.relamanhua.org",
				"relamanhua.org",
				"www.2024manga.com",
				"2024manga.com",
				"www.manga2024.com",
				"manga2024.com",
				"www.manga2025.com",
				"manga2025.com"
			],
			e: [
				".disData[contentKey]",
				".disPass[contentkey]",
				".comicContent-list"
			],
			i: 1
		},
		setReadHistory: () => {
			let readHistoryData = localStorage.getItem("readHistory");
			let [, , word, , id] = fn.clp().split("/");
			let json;
			readHistoryData ? json = JSON.parse(readHistoryData) : json = {};
			json[word] = id;
			localStorage.setItem("readHistory", JSON.stringify(json));
		},
		getSrcs: async (dom) => {
			let key = fn.attr(".disPass", "contentkey", dom);
			let raw = fn.attr(".disData", "contentkey", dom);
			let images = await fn.copymanga_decrypt_A(raw, key);
			return images.map(({
				url
			}) => url.replace("800x.", "1500x."));
		},
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: async () => {
			await fn.waitVar("webpackJsonp");
			fn.copymangaUI();
			await _this.getImgs().then(imgs => {
				let s = ".comicContent-list";
				return fn.caae(fn.createImgBox(s, 1), imgs, s);
			});
			_this.setReadHistory();
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: "//a[text()='下一話'][starts-with(@href,'/')]",
			title: (dom) => dom.title.replace(/ - 熱辣漫畫.+$/, ""),
			re: ".header,.footer",
			preloadNextPage: 1,
			aF: () => _this.setReadHistory(),
			update: "/comics?type=1",
			list: ".list a",
			chapters: () => fn.RLMH_PC_C(),
		},
		category: "comic autoPager"
	}, {
		name: "熱辣漫畫 目錄頁",
		url: {
			h: [
				"www.relamanhua.org",
				"relamanhua.org",
				"www.2024manga.com",
				"2024manga.com",
				"www.manga2024.com",
				"manga2024.com",
				"www.manga2025.com",
				"manga2025.com"
			],
			p: /^\/comic\/\w+$/
		},
		init: async () => {
			await fn.waitEle(".tab-pane.show.active a");
			const updateLastChapter = () => {
				let [, , comic] = fn.lp.split("/");
				let readHistoryData = localStorage.getItem("readHistory");
				if (!!readHistoryData) {
					let json = JSON.parse(readHistoryData);
					if (comic in json) {
						let selector = `.tab-content a[href$="${json[comic]}"]`;
						for (let a of fn.gae(".lastchapter")) a.classList.remove("lastchapter");
						for (let a of fn.gae(selector)) a.classList.add("lastchapter");
						setTimeout(() => {
							let lastReadUrl = fn.lp + "/chapter/" + json[comic];
							let lastText = fn.ge(".lastchapter").title;
							let lastE = fn.ge("#lastRead");
							if (!lastE && !fn.ge("//span[contains(text(),'最後閱讀')]")) {
								let a = fn.ce("a", {
									id: "lastRead",
									href: lastReadUrl,
									target: "_blank",
									innerText: lastText
								});
								let span = fn.ce("span", {
									innerText: "最後閱讀:"
								});
								let tableRight = fn.ge(".table-default-right");
								tableRight.insertAdjacentElement("afterbegin", a);
								tableRight.insertAdjacentElement("afterbegin", span);
							} else if (!!lastE) {
								let a = lastE;
								a.href = lastReadUrl;
								a.innerText = lastText;
							}
						}, 200);
					}
				}
			};
			updateLastChapter();
			document.addEventListener("visibilitychange", updateLastChapter);
			if ("aboutBlank" in _unsafeWindow) _unsafeWindow.aboutBlank = null;
			setTimeout(() => fn.clearAllTimer(3), 1000);
		},
		css: ".lastchapter{color:#fff !important;background:#ff0000}",
		hide: ".comicDetailAds",
		category: "none"
	}, {
		name: "熱辣漫畫 清除不給開啟開發人員工具",
		url: {
			h: [
				/^(www\.|m.)?relamanhua\.org$/,
				/^(www\.|m.)?2024manga\.com$/,
				/^(www\.|m.)?manga2024\.com$/,
				/^(www\.|m.)?manga2025\.com$/
			],
		},
		init: () => {
			if ("aboutBlank" in _unsafeWindow) _unsafeWindow.aboutBlank = null;
			setTimeout(() => fn.clearAllTimer(3), 1000);
		},
		category: "ad"
	}, {
		name: "禁漫天堂",
		host: ["18comic.vip"],
		url: {
			e: "meta[property='og:site_name'][content=禁漫天堂]",
			p: /^\/photo\/\d+/
		},
		imgs: async () => {
			await fn.getNP(".scramble-page", ".pagination li.active+li>a:not(.prevnext)");
			fn.sm1();
			const {
				aid,
				scramble_id,
				get_num
			} = _unsafeWindow;
			let arr = [];
			let fetchNum = 0;
			let imgs = fn.gae(".scramble-page img[id],.owl-item .center img[id]");
			for (let i = 0; i < imgs.length; i++) {
				let getRedraw = new Promise(async resolve => {
					const url = imgs[i].dataset.original ?? imgs[i].dataset.src;
					let error = false;
					if (url.includes(".gif") || aid < scramble_id) {
						resolve(url);
					} else {
						const blob = await fn.b(url);
						const fileName = new URL(url).pathname.split("/").at(-1);
						const [id, ex] = fileName.split(".");
						const img = new Image();
						await new Promise(load => {
							img.onload = load;
							img.onerror = () => {
								error = true;
								resolve(null);
							}
							img.src = URL.createObjectURL(blob);
						});
						if (error) return;
						const imgWidth = img.naturalWidth;
						const imgHeight = img.naturalHeight;
						const canvas = new OffscreenCanvas(imgWidth, imgHeight);
						const canvas_2d = canvas.getContext("2d");
						const num = get_num(btoa(aid), btoa(id));
						const cropHeight = Number(imgHeight % num);
						const sHeight = Math.floor(imgHeight / num);
						let sy = imgHeight - cropHeight - sHeight;
						let dy = cropHeight;
						canvas_2d.drawImage(img, 0, sy, imgWidth, cropHeight + sHeight, 0, 0, imgWidth, cropHeight + sHeight);
						for (let i = 1; i < num; ++i) {
							canvas_2d.drawImage(img, 0, sy -= sHeight, imgWidth, sHeight, 0, dy += sHeight, imgWidth, sHeight);
						}
						URL.revokeObjectURL(img.src);
						canvas.convertToBlob({
							type: blob.type,
							quality: 0.9
						}).then(blob => {
							fn.showMsg(`DrawImage ${fetchNum+=1}/${imgs.length}`, 0);
							resolve(URL.createObjectURL(blob));
						});
					}
				});
				arr.push(getRedraw);
				await delay(100);
			}
			return arr;
		},
		button: [4, 1],
		insertImg: ["//div[@class='panel-body'][div[@class='row thumb-overlay-albums']]", 0],
		autoDownload: [0],
		next: {
			s: ".menu-bolock-ul a[href^='/photo/']",
			t: "下一"
		},
		prev: {
			s: ".menu-bolock-ul a[href^='/photo/']",
			t: "上一"
		},
		chapters: {
			url: "//a[span[text()='漫畫簡介']]",
			target: ".episode a",
			cb: (t, url) => ({
				text: t.replace(/(話|话).+/, "$1"),
				url
			})
		},
		customTitle: () => fn.fetchDoc(fn.gu("//a[span[text()='漫畫簡介']]")).then(dom => {
			let comicName = fn.gt("#book-name", 1, dom).replaceAll("/", "").replace(/\s?\[禁漫漢化組\]/, "");
			let episode = fn.ge(".episode", dom);
			if (episode) {
				let [id] = fn.lp.match(/\d+/);
				let selector = `a[data-album="${id}"] .h2_series`;
				let text = fn.ge(selector, episode)?.textContent;
				let chapterName = fn.dt({
					t: String(text)
				});
				chapterName = chapterName.replace(/(話|话).+/, "$1");
				return comicName + " - " + chapterName;
			} else {
				return fn.dt({
					t: comicName
				});
			}
		}),
		hide: ".hidden-lg:not(.panel)[style*='z-index'],div:has(>.photo_center_div)",
		observerClick: ["#chk_cover", "#chk_guide", "div[class^='btn_hide']"],
		category: "hcomic"
	}, {
		name: "禁漫天堂",
		url: {
			e: "meta[property='og:site_name'][content=禁漫天堂]",
		},
		observerClick: ["#chk_cover", "#chk_guide", "div[class^='btn_hide']"],
		category: "ad"
	}, {
		name: "E-Hentai",
		url: {
			h: ["e-hentai.org", "exhentai.org", "ex.moonchan.xyz", "ex.nmbyd2.top"],
			p: "/g/",
			ee: "//h1[text()='Content Warning']"
		},
		box: ["#gdt", 2],
		imgs: async () => {
			await fn.getNP("#gdt>*", ".ptds+td>a", null, "//tr[td[@class='ptds']]");
			if (E_HENTAI_LoadOriginalImage == 1) {
				fn.sm1();
				let fetchNum = 0;
				return fn.gau(".gdtm a,.gdtl a,#gdt a").map(async (url, i, arr) => {
					await delay(100 * i);
					return fn.fetchDoc(url).then(async (dom) => {
						fn.showMsg(`${DL.str_02}${fetchNum+=1}/${arr.length}`, 0);
						let fullimg = fn.ge("a[href*=fullimg]", dom);
						let img = fn.ge("#img", dom);
						if (fullimg) {
							url = fullimg.href;
							let res = await fn.xhrHEAD(url);
							let finalUrl = res.finalUrl;
							return /login\.php/.test(finalUrl) ? img.src : url;
						} else {
							return img.src;
						}
					});
				});
			}
			let links = fn.gau(".gdtm a,.gdtl a,#gdt a");
			return fn.getImgA("#img", links, 100);
		},
		button: [4],
		insertImg: ["box", 3],
		customTitle: () => fn.dt({
			t: fn.getText(["#gj", "#gn"])
		}),
		topButton: true,
		category: "hcomic"
	}, {
		name: "E-Hentai",
		link: "https://e-hentai.org/lofi/",
		url: {
			h: ["e-hentai.org"],
			p: "/lofi/g/"
		},
		imgs: () => fn.getNP(".gi,#gh>a", "//a[text()='Next Page >' or text()='下一页 >']", null, "#ia").then(() => {
			let links = fn.gau(".gi>a,#gh>a");
			return fn.getImgA("#sm", links, 100);
		}),
		button: [4],
		insertImg: [
			["#ia", 2], 3
		],
		customTitle: () => fn.title(" - E-Hentai", 1).replace(/\|.+/, "").replace(/\//, "").trim(),
		topButton: true,
		category: "hcomic"
	}, {
		name: "Chin² Scanlations",
		url: {
			h: "chin2.net",
			p: /^\/Gallery\/Translation\/\d+$/
		},
		box: [".row-cols-lg-5", 2],
		imgs: () => fn.getNP(".row-cols-lg-5>*", "div[role=toolbar] a.disabled+a", null, "div[role=toolbar]").then(() => {
			let links = fn.gau(".row-cols-lg-5 a");
			return fn.getImgA("main img", links, 100);
		}),
		button: [4],
		insertImg: ["box", 3],
		customTitle: () => {
			let texts = fn.gat(".release-title");
			let text = texts.at(-1);
			return fn.dt({
				t: text
			});
		},
		category: "hcomic"
	}, {
		name: "nhentai",
		url: {
			h: [
				"nhentai.net",
				"www.hentai.name",
				"nhentai.xxx",
				"nhentai.website",
				"nhentai.wtf",
				"simplyhentai.org"
			],
			p: /^\/g\/\d+\/?$/
		},
		clearLoop: true,
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr(".gallerythumb img,.gallery_thumbs img");
			if (fn.lh === "nhentai.net") {
				let image_domain = "i1.nhentai.net";
				let srcs = _unsafeWindow._gallery.images.pages.map((e, i) => `https://image_domain/galleries/${_unsafeWindow._gallery.media_id}/${i + 1}.${fn.ex(e.t)}`);
				let hostArray = ["i.nhentai.net", "i5.nhentai.net", "i6.nhentai.net", "i7.nhentai.net", "i8.nhentai.net", "i9.nhentai.net", "i1.nhentai.net", "i2.nhentai.net", "i3.nhentai.net", "i4.nhentai.net"];
				let code = fn.gst("image_cdn_urls");
				if (code) {
					hostArray = fn.textToArray(code, "image_cdn_urls");
				}
				for (let host of hostArray.reverse()) {
					fn.showMsg(DL.str_56 + "\n" + host, 0);
					let src = srcs[0].replace("image_domain", host);
					let status = await fn.xhrHEAD(src).then(res => res.status);
					if (status == 200) {
						image_domain = host;
						break;
					}
				}
				fn.hm();
				return srcs.map(e => e.replace("image_domain", image_domain));
			} else if (fn.lh === "nhentai.xxx") {
				await fn.hentai_t("/modules/thumbs_loader.php");
				let [src] = thumbnailSrcArray;
				let dir = fn.dir(src);
				let url = fn.gu(".gallery_thumbs a");
				return fn.getCode(url, {
					mode: "dom",
					key: "g_th"
				}).then(code => Object.entries(fn.textToObject(code, "g_th", 1, 1).fl).map(([i, v]) => `${dir}${i}.${fn.ex(v.split(",").at(0))}`));
			} else if (["nhentai.website", "nhentai.wtf"].some(h => fn.lh === h)) {
				fn.sm5();
				let url = fn.gu("a.gallerythumb");
				return fn.fetchDoc(url).then(dom => {
					let code = fn.gst("reader", dom);
					let json = fn.textToObject(code, "reader", 1, 1);
					let [src] = thumbnailSrcArray;
					let dir = fn.dir(src);
					return json.gallery.images.pages.map((e, i) => `${dir}${(i + 1)}.${fn.ex(e.t)}`);
				});
			} else if (fn.lh === "simplyhentai.org") {
				return fn.gae(".thumbs img,.thumb-container img").map(e => e.dataset.src ? e.dataset.src.replace(/t(\.\w+)$/, "$1") : e.src.replace(/t(\.\w+)$/, "$1"));
			} else if (fn.lh === "www.hentai.name") {
				return fn.gae(".thumb-container img").map(e => e.src.replace(/_thumb(\.\w+)$/, "$1"));
			}
		},
		button: [4],
		insertImg: [".thumbs,#thumbnail-container,.outer_thumbs", 2],
		customTitle: () => {
			if (fn.lh === "nhentai.net") {
				const {
					_gallery
				} = _unsafeWindow;
				return _gallery.title.japanese ?? _gallery.title.english;
			}
			let h2 = fn.gt("h2.title,h2");
			return h2.length > 4 ? h2 : fn.gt("h1.title,h1");
		},
		hide: ".advt,ins[data-key]",
		category: "hcomic"
	}, {
		name: "Yabai!",
		url: {
			h: ["yabai.si"],
		},
		page: () => fn.clp("/g/"),
		json: () => fn.sm5().then(() => fn.fetchDoc(fn.clp()).then(dom => {
			let pageData = JSON.parse(fn.ge("#app", dom).dataset.page);
			let {
				version
			} = pageData;
			let token = decodeURIComponent(fn.cookie("XSRF-TOKEN"));
			let readApi = fn.curl() + "/read";
			return fn.j(readApi, {
				"headers": {
					"x-inertia": "true",
					"x-inertia-version": version,
					"x-requested-with": "XMLHttpRequest",
					"x-xsrf-token": token
				}
			}).then(json => (siteJson = json) && fn.hm());
		})),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				code,
				hash,
				head,
				rand,
				root,
				type
			} = siteJson.props.pages.data.list;
			let srcs = [];
			for (let [i, e] of head.entries()) srcs[Number(e) - 1] = `${root}/${code}/${e.padStart(4, "0")}-${hash[i]}-${rand[i]}.${type[i]}`;
			return srcs;
		},
		button: [4],
		insertImgBF: () => fn.waitEle(".grid img").then(() => fn.createImgBox(".article>:last-child", 2)),
		insertImg: [
			["box", 0], 2
		],
		customTitle: () => _this.page() ? siteJson.props.post.data.name : null,
		referer: "src",
		category: "hcomic"
	}, {
		name: "akuma.moe",
		url: {
			h: ["akuma.moe"],
			p: /^\/g\/\w+$/i
		},
		init: () => fn.waitEle("#pages"),
		imgs: async () => {
			let url = fn.gu("#pages a");
			await fn.getCode(url, {
				mode: "dom",
				key: "img_prt"
			});
			const {
				pag,
				ajx,
				img_prt
			} = _unsafeWindow;
			if (options.fancybox == 1 && !isDownloading) {
				let pages = pag.cnt;
				if (pages > 40) {
					let max = Math.ceil(pages / 20);
					let resArr = fn.arr(max, (v, i) => fn.t(pag.act, {
						"headers": {
							"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
							"x-csrf-token": ajx.hdr["X-CSRF-TOKEN"],
							"x-requested-with": "XMLHttpRequest"
						},
						"body": `index=${i}`,
						"method": "POST",
					}).then(text => fn.doc(text)).then(dom => [...dom.images]));
					thumbnailSrcArray = await Promise.all(resArr).then(data => fn.getImgSrcArr(data.flat()));
				} else {
					thumbnailSrcArray = fn.getImgSrcArr("#pages img");
				}
			}
			return fn.j(siteUrl, {
				"headers": {
					"x-csrf-token": ajx.hdr["X-CSRF-TOKEN"],
					"x-requested-with": "XMLHttpRequest"
				},
				"method": "POST"
			}).then(arr => arr.map(e => img_prt + "/" + e));
		},
		button: [4],
		insertImg: [
			["#pages", 0], 2
		],
		customTitle: () => fn.getText([".entry-header>span", ".entry-title"]),
		category: "hcomic"
	}, {
		name: "3hentai/HentaiVox",
		host: ["3hentai.net", "hentaivox.com"],
		reg: [
			/^https?:\/\/(\w{2}\.)?3hentai\.net\/d\/\d+$/,
			/^https?:\/\/hentaivox\.com\/view\/\d+$/
		],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".single-thumb>a>img");
			fn.sm5();
			let url = fn.gu(".single-thumb>a");
			return fn.fetchDoc(url).then(dom => {
				let code = fn.gst("readerPages", dom);
				let jsonCode = fn.stringSlicer(code, "readerPages =", "))");
				return fn.run(jsonCode);
			}).then(json => {
				let max = json.lastPage;
				let dir = json.baseUriImg.replace("%s", "");
				return fn.arr(max, (v, i) => dir + json.pages[(i + 1)].f);
			});
		},
		button: [4],
		insertImg: ["#thumbnail-gallery,#gallery-pages", 2],
		customTitle: () => fn.getText(["#main-info>h2", "#main-info>h1", "#gallery-main-info>h2", "#gallery-main-info>h1"]),
		hide: "div[id$='-ban-agsy']",
		category: "hcomic"
	}, {
		name: "9Hentai",
		host: ["9hentai.so"],
		reg: /^https:\/\/9hentai\.so\/g\/\d+\//,
		imgs: async () => {
			let [, , id] = fn.lp.split("/");
			let data = {
				id
			};
			let json = await fn.j("/api/getBookByID", {
				method: "POST",
				body: JSON.stringify(data),
				headers: {
					"Content-Type": "application/json",
				}
			});
			let {
				total_page,
				image_server,
				title
			} = json.results;
			apiCustomTitle = title;
			thumbnailSrcArray = fn.arr(total_page, (v, i) => image_server + id + "/preview/" + (i + 1) + "t.jpg");
			return fn.arr(total_page, (v, i) => image_server + id + "/" + (i + 1) + ".jpg");
		},
		capture: () => _this.imgs(),
		category: "hcomic"
	}, {
		name: "HentaiForce",
		host: ["hentaiforce.net"],
		reg: /^https?:\/\/hentaiforce\.net\/view\/\d+$/,
		init: () => fn.fetchDoc(fn.gu(".single-thumb a")).then(dom => {
			let code = fn.gst("readerPages", dom);
			let s = code.indexOf("JSON");
			let e = code.lastIndexOf(";");
			siteJson = fn.run(code.slice(s, e));
		}),
		imgs: () => fn.arr(siteJson.lastPage).map((v, i) => siteJson.baseUriImg.replace("%c", siteJson.pages[i + 1].l).replace('%s', siteJson.pages[i + 1].f)),
		thums: ".single-thumb img",
		button: [4],
		insertImg: ["#gallery-pages", 2],
		customTitle: () => fn.dt({
			t: siteJson.title,
			d: / - Page.+$/
		}),
		category: "hcomic"
	}, {
		name: "HenTalk",
		url: {
			h: ["hentalk.pw", "fakku.cc"]
		},
		page: () => fn.clp(/^\/g\/\d+$/),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.j(`${fn.clp()}/__data.json?x-sveltekit-trailing-slash=1&x-sveltekit-invalidated=001`).then(json => {
			let data = json.nodes[2].data;
			let gallery = data?.[data.find((e) => e?.gallery)?.gallery];
			let slug = data?.[gallery?.hash] || data?.[data.find((e) => e?.hash && e?.id).hash];
			let images = data?.[gallery.images].map((i) => data[i]).map((i) => data[i.filename]);
			siteJson = {
				data,
				gallery,
				slug,
				images
			};
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => _this.page() ? siteJson.images.map(e => `https://hentalk.pw/image/${siteJson.slug}/${e}`) : [],
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.data[siteJson.gallery.title] : null,
		category: "hcomic"
	}, {
		name: "HentaiRead",
		url: {
			h: "hentairead.com",
			p: "/hentai/",
			e: "//span[text()='Read Now']"
		},
		box: [".main-container:has(.chapter-image-item)", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".chapter-image-item img");
			return thumbnailSrcArray.map(e => e.replace("hencover.xyz", "henread.xyz").replace("preview/", ""));
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: () => fn.getText([".manga-titles h2", ".manga-titles h1"]),
		category: "hcomic"
	}, {
		name: "ManhwaRead",
		url: {
			h: "manhwaread.com",
			p: "/chapter-"
		},
		imgs: () => {
			let {
				data,
				base
			} = _unsafeWindow.chapterData
			let srcs = JSON.parse(atob(data)).map(e => base + "/" + e.src);
			fn.sm5();
			let fetchNum = 0;
			let resArr = srcs.map((src, i, arr) => fn.b(src, {
				headers: {
					"accept": !!localStorage.getItem("webp_support") ? "image/webp,image/*" : "image/*",
				}
			}).finally(() => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
			}));
			return Promise.all(resArr).then(blobs => blobs.map(blob => URL.createObjectURL(blob)));
		},
		np: (i) => {
			let cs = fn.gae("#chaptersList>a");
			let ci = cs.findIndex(a => a.classList.contains("current"));
			let ti = ci + i;
			return isEle(cs[ti]) ? cs[ti].href : null;
		},
		autoDownload: [0],
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		customTitle: ["h2", "h1"],
		chapters: {
			target: "#chaptersList>a",
			cb: (t, url, a) => ({
				text: a.textContent,
				url
			})
		},
		category: "hcomic"
	}, {
		name: "lhentai.com",
		host: ["lhentai.com"],
		reg: /^https?:\/\/lhentai\.com\/g\/\d+$/,
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr(".gallerythumb img");
			fn.sm5();
			let url = fn.gu("a.gallerythumb");
			let dom = await fn.fetchDoc(url);
			let code = fn.gst("images_ext", dom);
			let images_ext = fn.textToArray(code, "images_ext");
			let post_url = fn.textVar(code, "post_url");
			return images_ext.map((e, i) => `${post_url}${(i + 1)}.${fn.ex(e)}`);
		},
		button: [4],
		insertImg: [".thumbs", 2],
		customTitle: () => fn.getText(["#info>h2", "#info>h1"]),
		category: "hcomic"
	}, {
		name: "EAHentai",
		url: {
			h: ["eahentai.com"]
		},
		page: () => fn.clp("/a/"),
		json: () => fn.sm5().then(() => fn.clp().split("/").at(-1)).then(id => fn.j(`/api/image/album/${id}`).then(arr => (siteJson = arr[0]) && fn.hm())),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let cdn = "https://i.eahentai.com/file/ea-gallery/";
			return siteJson.images.map(({
				thumbnailUri,
				imageUri
			}) => {
				thumbnailSrcArray.push(cdn + thumbnailUri);
				return cdn + imageUri;
			});
		},
		button: [4],
		insertImgBF: () => fn.waitEle(".gallery-img"),
		insertImg: [".gallery-container", 2],
		customTitle: () => _this.page() ? siteJson.title : null,
		category: "hcomic"
	}, {
		name: "Fhentai",
		url: {
			h: "fhentai.net",
			p: "/f/"
		},
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr(".rounded-md:has(>.grid) img");
			return thumbnailSrcArray.map(e => e.replace("/thumb/", "/raw/"));
		},
		button: [4],
		insertImg: [".rounded-md:has(>.grid)", 2],
		customTitle: "main h1",
		category: "hcomic"
	}, {
		name: "HentaiNexus",
		host: ["hentainexus.com"],
		reg: /^https?:\/\/hentainexus\.com\/view\/\d+$/,
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".card-image img");
			fn.sm5();
			let url = fn.gu("//a[div[@class='card']]");
			return fn.iframe(url, {
				wait: (_, frame) => isArray(frame?.pageData),
			}).then(async ({
				frame
			}) => {
				let CDN_Srcs = frame.pageData.map(e => e.image);
				let siteSrcs = CDN_Srcs.map(e => e.replace(/i\d\.wp\.com\/|\?filter=null/g, ""));
				fn.showMsg(DL.str_56, 0);
				let status = await fn.xhrHEAD(siteSrcs[0]).then(res => res.status);
				fn.hm();
				return status === 200 ? siteSrcs : CDN_Srcs;
			});
		},
		button: [4],
		insertImg: [".container .box:has(.card-image)", 2],
		customTitle: ".title",
		category: "hcomic"
	}, {
		name: "HentaiLoop",
		host: ["hentailoop.com"],
		reg: /^https?:\/\/hentailoop\.com\/manga\/[^\/]+\/$/,
		box: [".preview", 2],
		imgs: async () => {
			fn.sm5();
			thumbnailSrcArray = await fn.t("/wp-admin/admin-ajax.php", {
				"headers": {
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": `action=loadpreviews&postID=${_unsafeWindow.ajaxData.postID}`,
				"method": "POST"
			}).then(text => fn.doc(text)).then(dom => [...dom.images].map(e => e.src));
			let url = fn.gu(".previews>a");
			return fn.getCode(url, {
				mode: "dom",
				key: "var ajax ="
			}).then(() => {
				let html = _unsafeWindow.ajax.pages.join("");
				let dom = fn.doc(html);
				return [...dom.images];
			});
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: "//meta[@content='4']/preceding-sibling::span[1]",
		category: "hcomic"
	}, {
		name: "The Hentai",
		url: {
			h: "thehentai.net",
			p: /^\/[^\/]+\/$/
		},
		init: () => fn.waitVar("imagensbg"),
		imgs: () => {
			thumbnailSrcArray = _unsafeWindow.imagensbg;
			return thumbnailSrcArray.map(e => fn.lo + e.replace("-300x400.", "."));
		},
		button: [4],
		insertImg: [".post_imgs", 2],
		autoDownload: [0],
		np: (k) => {
			let c = fn.ge(".select option[selected]");
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		customTitle: () => fn.title(/\s-\s[^-]+\s-\s[^-]+$/),
		category: "hcomic"
	}, {
		name: "MangaHen",
		host: ["manga-hen.com"],
		reg: /^https?:\/\/manga-hen\.com\/manga\/[\w-]+\/$/,
		box: [".rounded-lg", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".img-thumb img,.lazy-img-thumb img");
			fn.sm5();
			return fn.xhrDoc(fn.gu(".img-thumb>a"), {
				cookie: "reader_mode=1"
			}).then(dom => fn.gae(".justify-between~img[data-src]", dom));
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: "h1[class^=text]",
		category: "hcomic"
	}, {
		name: "TMOHentai",
		url: {
			h: ["tmohentai.com"],
			p: "/contents/"
		},
		imgs: (s = "div[style*='background']") => fn.waitEle(s).then(div => {
			let [, src] = div.style.background.split('"');
			let dir = fn.dir(src);
			let max = fn.gae(s).length;
			return fn.arr(max, (v, i) => dir + String(i).padStart(3, "0") + ".webp");
		}),
		button: [4],
		insertImg: [".panel-body:has(.well)", 2],
		customTitle: ".panel-title h3",
		category: "hcomic"
	}, {
		name: "Download Doujin",
		host: ["cin.cx", "cin.mom"],
		url: {
			h: "cin",
			p: /^\/v\/\d+$/
		},
		checkStatus: async (src) => {
			let host = new URL(src).host;
			let hosts = ["a", "b", "c", "d", "e", "f", "g"].map(e => host.replace(/^[a-g]/i, e));
			let cs = hosts.map(h => src.replace(host, h));
			for (let url of cs) {
				let status;
				try {
					let res = await fetch(url, {
						method: "HEAD"
					});
					status = res.status;
				} catch {
					status = 503;
				}
				if (status == 200) {
					return url;
				}
			}
			return src;
		},
		imgs: async () => {
			fn.sm5();
			let json = JSON.parse(fn.gt("#__NEXT_DATA__"));
			let srcs;
			if (json?.props?.pageProps?.data) {
				let {
					images: {
						pages
					},
					title: {
						english,
						japanese,
						pretty

					}
				} = json.props.pageProps.data;
				srcs = pages.map(e => e.t);
				customTitle = japanese ?? english ?? pretty;
			} else {
				let id = json.query.id;
				srcs = await fn.j("https://same.yui.pw/api/v6/book/" + id).then(json => {
					let {
						images: {
							pages
						},
						title: {
							english,
							japanese,
							pretty

						}
					} = json;
					customTitle = japanese ?? english ?? pretty;
					return pages.map(e => e.t);
				});
			}
			let fetchNum = 0;
			return srcs.map(async (src, i, arr) => {
				await delay(i * 500);
				src = await _this.checkStatus(src);
				return fn.b(src).then(blob => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
					return URL.createObjectURL(blob);
				});
			});
		},
		gallery: 1,
		category: "hcomic"
	}, {
		name: "Pururin",
		host: ["pururin.me"],
		reg: /^https?:\/\/pururin\.me\/gallery\/\d+\/.+/,
		box: [".box:has(.gallery-preview)", 2],
		imgs: () => fn.fetchDoc(fn.gu(".gallery-preview>a")).then(dom => {
			let ele = fn.ge(".img-viewer", dom);
			let svr = ele.dataset.svr;
			let data = JSON.parse(ele.dataset.img);
			let arr = data.images.sort((a, b) => a.page - b.page);
			arr = arr.map(e => svr + "/" + data.directory + "/" + e.filename);
			thumbnailSrcArray = arr.map(e => e.replace(/(\.\w+)$/, "t$1"));
			return arr;
		}),
		button: [4],
		insertImg: ["box", 2],
		endColor: "white",
		insertImgAF: () => {
			setTimeout(() => {
				fn.css(FullPictureLoadStyle, "FullPictureLoadMainStyle");
				if (siteData.key != 0 && !isAddKeyEvent) {
					document.addEventListener("keydown", addKeyEvent);
					isAddKeyEvent = true;
				}
				if (options.icon == 1 || siteData.icon == 1) addFullPictureLoadButton();
				if (isPC && ShowFullPictureLoadFixedMenu === 1) addFullPictureLoadFixedMenu();
			}, 1000);
		},
		customTitle: () => fn.ge("[placeholder=Japanese]")?.value || fn.ge("[placeholder='Alternative names']")?.value,
		category: "hcomic"
	}, {
		name: "Manga Mischief",
		url: {
			h: ["xmanga.org"],
		},
		page: () => fn.clp("/album/"),
		json: () => fn.sm5().then(() => fn.clp().split("/").at(2)).then(id => fn.j(`https://mangamischief.com/backend/image?albumId=${id}`).then(json => (siteJson = json) && fn.hm())),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json().then(() => fn.waitEle(["div:has(>.max-w-gallery) img", "h1.text-lg"])) : void 0,
		imgs: () => _this.page() ? siteJson.data.map(e => e.url) : [],
		button: [4],
		insertImg: ["div:has(>.max-w-gallery)", 2],
		endColor: "white",
		customTitle: "h1.text-lg",
		category: "hcomic"
	}, {
		name: "MultPorn",
		url: {
			h: "multporn.net",
			st: "configUrl"
		},
		imgs: () => {
			fn.sm5();
			let code = fn.gst("configUrl")
			let [, url] = code.match(/configUrl":"([^"]+)/);
			url = url.replaceAll("\\", "");
			return fn.t(url).then(text => {
				let xml = fn.xml(text);
				let imgs = fn.gae("image", xml);
				thumbnailSrcArray = imgs.map(e => e.getAttribute("thumbURL"));
				return imgs.map(e => e.getAttribute("linkURL"));
			});
		},
		button: [4],
		insertImg: [
			[".juicebox-parent", 2], 2
		],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='Next Part']",
		prev: "//a[text()='Previous Part']",
		customTitle: "#page-title",
		category: "hcomic"
	}, {
		name: "KingComiX/ReyComiX/Chochox/Comics18",
		url: {
			h: ["kingcomix.com", "reycomix.com", "chochox.com", "comics18.org"]
		},
		imgs: "figure img,.entry-content img:not(a img),.wp-content img",
		button: [4],
		insertImg: [".entry-content,.wp-content", 2],
		customTitle: "h1.singleTitle-h1,h1.titl,h1.title",
		category: "hcomic"
	}, {
		name: "ILikeComiX",
		url: {
			h: ["ilikecomix.com"],
			e: ".entry-content img[data-jg-srcset],.pswp-gallery__item a"
		},
		imgs: () => fn.getImgSrcset(".entry-content img[data-jg-srcset],.pswp-gallery__item a").map(src => src.replace("-scaled", "")),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: () => fn.ge(".entry-title")?.textContent,
		category: "hcomic"
	}, {
		name: "Comics Army",
		url: {
			h: ["comicsarmy.com"]
		},
		box: [".dgwt-jg-gallery", 1],
		srcset: ".dgwt-jg-gallery img",
		button: [4],
		insertImg: [
			["box", 0, ".dgwt-jg-gallery"], 2
		],
		customTitle: ".elementor-page-title h1",
		category: "hcomic"
	}, {
		name: "COMICS.NET",
		url: {
			h: ["comics18.net"]
		},
		imgs: ".the-content img",
		button: [4],
		insertImg: [".the-content", 2],
		customTitle: "main h1",
		category: "hcomic"
	}, {
		name: "ComicsXD",
		url: {
			h: ["comicsxd.com"],
			e: ".pps-slide-count"
		},
		imgs: () => {
			let max = fn.gt(".pps-slide-count").match(/\d+/g).at(-1);
			let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}${i + 1}/`)
			return fn.getImgA(".pps-content img", links);
		},
		button: [4],
		insertImg: [".pps-content", 2],
		insertImgAF: () => fn.hideEle(".pps-slider-nav"),
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "MyReadingManga",
		url: {
			h: "myreadingmanga.info",
			p: /^\/[^\/]+\/$/,
			e: [".entry-content img,video[poster]", ".entry-meta"]
		},
		imgs: async () => {
			if (fn.ge("video[poster]")) {
				await fn.waitEle("#MRM_video_html5_api");
				videoSrcArray = [fn.ge("video[poster] source").src];
				return [fn.ge("video[poster]").poster];
			}
			return fn.getImgA(".entry-content img.img-myreadingmanga", ".entry-pagination a");
		},
		button: [4],
		insertImg: [".entry-content", 2],
		endColor: "white",
		customTitle: ".entry-title",
		hide: "div[class^=root][style]:has(video)",
		category: "hcomic"
	}, {
		name: "MANGA HENTAI",
		url: {
			h: ["adulthentai.net", "www.manga-hentai.net", "hentaiweb.net", "hentai-freak.com"],
		},
		box: [".thumbs", 2],
		imgs: () => {
			let links = fn.gau(".thumbs:not(:last-child) a");
			return fn.getImgA(".big-picture img", links);
		},
		thums: ".thumbs:not(:last-child) img",
		button: [4],
		insertImg: [
			["box", 0, ".thumbs"], 2
		],
		customTitle: ".wrapper h2",
		category: "hcomic"
	}, {
		name: "HENTAI NARUTO/HENTAI SITE",
		url: {
			h: ["hentai-naruto.org", "hentai-site.net"],
		},
		box: [".gallerywrapper", 2],
		imgs: ".gallerywrapper a",
		thums: ".gallerywrapper img",
		button: [4],
		insertImg: [
			["box", 0, ".gallerywrapper"], 2
		],
		customTitle: ".wrapper h1",
		category: "hcomic"
	}, {
		name: "HENTAISET.COM/HENTAIVID.NET/HENTAITOP.ORG/HENTAI-IMAGES.COM/HENTAIKA.ORG/HENTAISIN.COM/WWW.HENTAIGALLERY.ORG/HENTAIHOOKED.COM",
		url: {
			h: ["www.hentaiset.com", "hentaivid.net", "hentaitop.org", "hentai-images.com", "hentaika.org", "hentaisin.com", "www.hentaigallery.org", "hentaihooked.com"],
			e: ".main-container h1"
		},
		box: ["#lightgallery", 2],
		imgs: "#lightgallery li.thumb,#lightgallery div.thumb",
		thums: "#lightgallery img[is='lazyload-image']",
		button: [4],
		insertImg: [
			["box", 0, "#lightgallery"], 2
		],
		customTitle: () => fn.ge(".main-container h1")?.textContent,
		category: "hcomic"
	}, {
		name: "HENTAIHUG.COM/HENTAIDOWN.COM/FANHENTAI.NET/HENTAIBRO.COM/HENTAIEVA.COM/HENTAI24X7.COM/GURUHENTAI.COM/HOSTHENTAI.COM/HENTAIDL.NET/HENTAIUP.NET/HENTAILOVE.ORG/COMICSPORN.ORG/HENTAIRIPS.COM",
		url: {
			h: ["www.hentaihug.com", "www.hentaidown.com", "www.fanhentai.net", "www.hentaibro.com", "hentaieva.com", "hentai24x7.com", "www.guruhentai.com", "hosthentai.com", "hentaidl.net", "hentaiup.net", "www.hentailove.org", "comicsporn.org", "hentairips.com"],
			e: [".image-gallery-box", ".content h1"]
		},
		imgs: ".gallery-thumbs a",
		thums: ".gallery-thumbs img",
		button: [4],
		insertImg: [".image-gallery-box", 2],
		customTitle: () => fn.ge(".content h1")?.textContent,
		category: "hcomic"
	}, {
		name: "JAVMOBILE.MOBI",
		link: "https://javmobile.mobi/latest/?content=hentai",
		url: {
			h: ["javmobile.mobi"]
		},
		box: [".gal-obol", 2],
		imgs: "#imgs_container img",
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".topbar h1",
		category: "hcomic"
	}, {
		name: "Neko Hentai",
		host: ["neko-hentai.net"],
		reg: /^https?:\/\/neko-hentai\.net\//i,
		include: "#manga-content img",
		imgs: "#manga-content img",
		button: [4],
		insertImg: ["#manga-content", 2],
		endColor: "white",
		customTitle: () => fn.title(/ - Neko Hentai.*$/),
		category: "hcomic"
	}, {
		name: "Super Hentai",
		host: ["superhentai.blog"],
		reg: /^https?:\/\/superhentai\.blog\/[^\/]+\/$/i,
		include: ".gallery",
		imgs: ".gallery img",
		button: [4],
		insertImg: [".gallery", 2],
		endColor: "white",
		customTitle: "#single h1",
		category: "hcomic"
	}, {
		name: "HENTAICELEB.COM",
		host: ["www.hentaiceleb.com"],
		reg: /^https?:\/\/www\.hentaiceleb\.com\/\w+\/\w+\/[^\.]+\.html$/i,
		imgs: ".gallery-thumbs a[data-src]",
		button: [4],
		insertImg: [".media-bg", 2],
		endColor: "white",
		customTitle: ".full-main-col h1",
		category: "hcomic"
	}, {
		name: "HENTAICREDO.COM",
		host: ["www.hentaicredo.com"],
		reg: /^https?:\/\/www\.hentaicredo\.com\/content\/\w+\/[^\/]+\/$/i,
		imgs: () => {
			let [thumbs] = fn.gae(".thumbs");
			let imgs = fn.gae("img", thumbs);
			let links = fn.gau("a", thumbs);
			thumbnailSrcArray = fn.getImgSrcArr(imgs);
			return fn.getImgA(".big-picture img", links);
		},
		button: [4],
		insertImg: [".thumbs", 2],
		customTitle: "h2",
		category: "hcomic"
	}, {
		name: "HentaiHere",
		host: ["hentaihere.com"],
		reg: /^https?:\/\/hentaihere\.com\/m\/\w+\/\d+\/\d+\/$/i,
		init: () => fn.waitVar(["rff_imageList", "jQuery"]),
		imgs: () => _unsafeWindow.rff_imageList.map(e => "https://hentaicdn.com/hentai" + e),
		button: [4],
		insertImg: ["#reader-content", 2],
		autoDownload: [0],
		current: () => {
			let node = fn.ge({
				s: ".dropdown-toggle",
				t: "Chapter"
			}).nextElementSibling;
			return fn.ge(".bg-info", node);
		},
		next: () => {
			let next = _this.current()?.parentElement?.nextElementSibling?.firstElementChild;
			return next ? fn.wurl(next.dataset.cid, fn.url, -3) : null;
		},
		prev: () => {
			let prev = _this.current()?.parentElement?.previousElementSibling?.firstElementChild;
			return prev ? fn.wurl(prev.dataset.cid, fn.url, -3) : null;
		},
		chapters: () => {
			let node = fn.ge({
				s: ".dropdown-toggle",
				t: "Chapter"
			}).nextElementSibling;
			return fn.gae("a", node).map(a => ({
				text: fn.dt({
					t: a.text
				}),
				url: ("cid" in a.dataset) ? fn.wurl(a.dataset.cid, fn.url, -3) : fn.url
			}));
		},
		customTitle: ["#detail span", "#chapter span"],
		hide: ".afs_ads,[data-type]",
		category: "hcomic"
	}, {
		name: "Gensura",
		url: {
			h: ["gensura.net"],
			p: "/manga/"
		},
		box: ["div:has(>.grid>.img-thumb)", 2],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".img-thumb img,.lazy-img-thumb img");
			return thumbnailSrcArray.map(src => fn.rt(src, /-t.(\w+)$/, ".$1"));
		},
		button: [4],
		insertImg: ["box", 2],
		autoDownload: [0],
		np: (i) => {
			let cs = fn.gae("h2+ul a");
			let ci = cs.findIndex(a => a.href == fn.url);
			let ti = ci + i;
			return isEle(cs[ti]) ? cs[ti].href : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		customTitle: "#main_element h1",
		category: "hcomic"
	}, {
		name: "HentaiPaw/Hentai-One/エロ漫画SHOW",
		url: {
			h: [/^([a-z]{2}\.)?hentaipaw\.com$/, /^([a-z]{2}\.)?hentai-one\.com$/, "eromanga-show.com"],
		},
		page: () => fn.clp(/^\/articles\/\d+$/),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => {
			let id = fn.clp().split("/").at(-1);
			let res_a = fn.fetchDoc(`/viewer?articleId=${id}&page=1`).then(dom => {
				let text = fn.__next_f(dom);
				return fn.textToArray(text, '"slides":').map(e => e.src);
			}).then(images => (siteJson.images = images));
			return Promise.all([res_a, fn.rd()]).then(() => fn.hm());
		},
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (_this.page()) {
				thumbnailSrcArray = fn.getImgSrcArr(".grid .group>img", doc);
				return siteJson.images;
			}
			return [];
		},
		button: [4],
		insertImgBF: () => fn.waitEle(".container .grid .group>img").then(() => fn.createImgBox(".container:has(>.grid)")),
		insertImg: [
			["box", 0, "//div[@id='FullPictureLoadMainImgBox']/preceding-sibling::div[1]"], 2
		],
		customTitle: () => {
			if (_this.page()) {
				if (fn.lh.includes("hentai-one.com")) {
					let text = fn.gt("h1.text-wrap", 1, doc);
					return text.includes("|") ? text.split("|")[1].trim() : text;
				} else {
					return fn.gt("h1.text-wrap", 1, doc).replace(/\/|\|/g, " ");
				}
			}
			return null;
		},
		css: "#article-details{margin-top:5rem!important}",
		hide: "#article-details+.mx-auto,.container:has(>div>script),#button-group a,.container:has(video)",
		category: "hcomic"
	}, {
		name: "Cartoon Porn Comics",
		url: {
			h: ["cartoonporn.to"],
			e: "#readerPages"
		},
		update: "/porncomic/?m_orderby=latest",
		init: () => (siteJson.chapters = JSON.parse(fn.attr("#readerPages", "data-chapters")).reverse()),
		imgs: ".reader-page img",
		button: [4],
		insertImg: ["#readerPages", 2],
		np: (i) => {
			let slug = fn.lp.split("/").at(-2);
			let ci = siteJson.chapters.findIndex(o => o.slug == slug);
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? o.url : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			name,
			url
		}) => ({
			text: name,
			url
		})),
		customTitle: ".reader-header h1",
		category: "hcomic"
	}, {
		name: "HDpornComics",
		url: {
			h: "hdporncomics.com",
			e: [".my-gallery.scrollmenu", "#infoBox>h1"]
		},
		imgs: ".my-gallery a[data-size]",
		thums: ".my-gallery a[data-size] img",
		button: [4],
		insertImg: [
			[".postContent>.items-center,#likeDislikeVue", 2], 2
		],
		customTitle: () => fn.dt({
			s: "#infoBox>h1",
			d: [
				" – Gay Manga",
				" Comic Porn"
			]
		}),
		category: "hcomic"
	}, {
		name: "HDpornComics",
		url: {
			h: "hdporncomics.com",
			p: "/chapter"
		},
		imgs: "#imageContainer img",
		button: [4],
		insertImg: ["#imageContainer", 2],
		autoDownload: [0],
		next: "#nextChapter a",
		prev: "#previousChapter a",
		chapters: {
			node: "#selectChapter",
			target: "option",
			sort: "r",
			cb: (text, url) => {
				if (!url.endsWith("/")) {
					url = url + "/";
				}
				return {
					text,
					url
				}
			}
		},
		customTitle: [".list-reset a,option[selected]", 2, 3],
		category: "hcomic"
	}, {
		name: "Doujins",
		host: ["doujins.com"],
		reg: /^https?:\/\/doujins\.com\/.+\/.+/i,
		include: "#thumbnails",
		exclude: ".thumbnails .gallery-info",
		init: () => fn.waitEle(".doujin"),
		imgs: () => {
			let imgs = fn.gae(".doujin[data-file]");
			thumbnailSrcArray = imgs.map(e => e.dataset.thumb);
			return imgs.map(e => e.dataset.file);
		},
		button: [4],
		insertImg: [
			["#thumbnails", 2], 2
		],
		customTitle: ".folder-title>a:last-child",
		category: "hcomic"
	}, {
		name: "Simply Hentai",
		url: {
			h: ["www.simply-hentai.com"]
		},
		page: () => fn.clp("/page/"),
		json: () => fn.rd().then(() => JSON.parse(fn.gt("#__NEXT_DATA__", 1, doc))).then(json => (siteJson = json)),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			thumbnailSrcArray = siteJson.props.pageProps.data.pages.map(e => e.sizes.small_thumb);
			return siteJson.props.pageProps.data.pages.map(e => e.sizes.full)
		},
		button: [4],
		insertImgFB: () => fn.waitEle("#reader-image img"),
		insertImg: ["#reader-image", 2],
		customTitle: () => _this.page() ? siteJson.props.pageProps.data.title.replace(/\/|\|/g, "-") : null,
		category: "hcomic"
	}, {
		name: "Hanime1",
		host: ["hanime1.me"],
		link: "https://hanime1.me/comics",
		reg: /^https?:\/\/hanime1\.me\/comic\/\d+$/,
		imgs: () => {
			fn.sm5();
			let url = fn.gu(".comics-thumbnail-wrapper>a");
			return fn.fetchDoc(url).then(dom => {
				let dir = fn.ge("#current-page-image", dom).dataset.prefix;
				let code = fn.gst("extensions", dom);
				code = code.replaceAll("&quot;", '"');
				let extensions = fn.textToArray(code, "extensions");
				return extensions.map((e, i) => {
					if (dir.includes("nhentai")) {
						return `${dir}${(i + 1)}.${fn.ex(e)}`;
					}
					return dir + e + ".jpg";
				});
			});
		},
		button: [4],
		insertImg: [".comics-thumbnail-wrapper", 2],
		endColor: "white",
		customTitle: "h4.title",
		referer: "src",
		category: "hcomic"
	}, {
		name: "My Hentai Gallery",
		host: ["myhentaigallery.com", "myhentaicomics.com", "mymangacomics.com"],
		reg: [
			/^https?:\/\/myhentaigallery\.com\/g\/\d+$/,
			/^https?:\/\/myhentaicomics\.com\/gallery\/thumbnails\/\d+$/,
			/^https?:\/\/mymangacomics\.com\/mangacomic\/\d+$/
		],
		imgs: () => {
			thumbnailSrcArray = fn.gae(".comic-thumb>img").map(e => e.src);
			return thumbnailSrcArray.map(e => e.replace("thumbnail", "original"));
		},
		button: [4],
		insertImg: [".comic-listing:has(.comics-grid)", 2],
		endColor: "white",
		customTitle: ".comic-description>h1",
		hide: ".featured-comic,.header-spot,.header-image center",
		category: "hcomic"
	}, {
		name: "XYZ PORN COMICS",
		host: ["xyzcomics.com"],
		reg: /^https?:\/\/xyzcomics\.com\/[^\/]+\/$/,
		include: ".post-title",
		init: () => fn.waitEle(".jig-link>img"),
		imgs: ".jig-link",
		thums: ".jig-link>img",
		button: [4],
		insertImg: [
			[".entry-content", 0], 2
		],
		endColor: "white",
		customTitle: ".post-title",
		category: "hcomic"
	}, {
		name: "LoLHentai.net",
		host: ["www.lolhentai.net"],
		link: "https://www.lolhentai.net/index?/category/chinese",
		reg: /^https?:\/\/www\.lolhentai\.net\/index\?\/category\/\d+-.+$/i,
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("#thumbnails img");
			return thumbnailSrcArray.map(src => {
				let dir = fn.dir(src);
				dir = dir.replace("/_data/i", "");
				let file = src.split("/").at(-1);
				let ex = file.split(".").at(-1);
				ex = "." + ex;
				let [a, b] = file.split("-");
				b = b.replace(/\.\w+$/i, "");
				return `${dir}${a}-${b}${ex}`;
			});
		},
		box: ["#thumbnails", 2],
		button: [4],
		insertImg: [
			["box", 0, "#thumbnails"], 2
		],
		endColor: "white",
		customTitle: "h1.name a:last-child",
		category: "hcomic"
	}, {
		name: "BestPornComix",
		url: {
			h: "bestporncomix.com",
			p: "/gallery/"
		},
		box: [".dgwt-jg-gallery", 2],
		imgs: "figure a",
		button: [4],
		insertImg: [
			["box", 0, ".dgwt-jg-gallery"], 2
		],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "FSIComics",
		url: {
			h: "fsicomics.com"
		},
		imgs: ".wp-block-gallery img",
		button: [4],
		insertImg: [".wp-block-gallery", 2],
		customTitle: ".s-title",
		category: "hcomic"
	}, {
		name: "XX COMIC",
		url: {
			h: "xx-comic.com",
			p: /^\/\d+\/\d+\/\d+\//
		},
		imgs: ".content img",
		button: [4],
		insertImg: [".content", 2],
		customTitle: ".single_title",
		category: "hcomic"
	}, {
		name: "GNTAI.net",
		url: {
			h: "www.gntai.net",
			st: "pages"
		},
		imgs: () => {
			let code = fn.gst("pages");
			return fn.textToArray(code, "pages").map(e => e.page_image);
		},
		button: [4],
		insertImg: ["#img-page", 2],
		insertImgAF: () => fn.hideEle("#chapter-pages,#grid-buttons"),
		customTitle: "#main h1",
		category: "hcomic"
	}, {
		name: "BRHENTAI",
		url: {
			h: ["brhentai.win"]
		},
		imgs: ".listaImagens img",
		button: [4],
		insertImg: [".listaImagens", 2],
		customTitle: "h1.post-titulo",
		category: "hcomic"
	}, {
		name: "IMHentai/HentaiRox/HentaiEra/Comic Porn XXX/HentaiZap/HentaiClap/HentaiEnvy/HentaiFox",
		url: {
			h: ["imhentai.xxx", "hentairox.com", "hentaiera.com", "comicporn.xxx", "hentaizap.com", "hentaiclap.com", "www.hentaienvy.com", "hentaienvy.com", "hentaifox.com"],
			p: "/gallery/"
		},
		box: ["#comments_div,.gallery_second:has(#append_thumbs),.gallery_thumbs,.gallery_bottom"],
		imgs: async () => {
			let code = fn.gst("var g_th =");
			if (!code) {
				let url = fn.gu(".left_cover a,.gp_read a,.gt_left a,.gallery_left a");
				code = await fn.getCode(url, {
					mode: "dom",
					key: "var g_th ="
				});
			}
			let g_th = fn.textToObject(code, "g_th");
			return fn.hentai_t(`/${fn.lh == "hentaifox.com" ? "includes" : "inc"}/thumbs_loader.php`).then(srcs => fn.dir(srcs.at(0))).then(dir => Object.entries(g_th).map(([i, v]) => `${dir}${i}.${fn.ex(v.split(",").at(0))}`));
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: () => fn.getText([".info>h1", ".gp_top_right h1", ".gt_right h1", ".subtitle", "h1"]),
		category: "hcomic"
	}, {
		name: "AsmHentai/APE XXX",
		url: {
			h: ["asmhentai.com", "ape.su"],
			p: [/^\/g\/\d+\/$/, /^\/\d+\/$/],
			e: "#append_thumbs"
		},
		box: ["#comments_div,.gallery"],
		imgs: async () => {
			thumbnailSrcArray = fn.getImgSrcArr("#append_thumbs img");
			if (fn.ge("#load_id")) {
				await fn.hentai_t(fn.lh == "ape.su" ? "/thumbs_loader" : "/inc/thumbs_loader.php");
			}
			return thumbnailSrcArray.map(src => fn.rt(src, [
				[/-\d+x\d+\./, "."],
				["t.", "."]
			]));
		},
		button: [4],
		insertImg: ["box", 2],
		endColor: "white",
		customTitle: () => fn.getText([".right_details h1", ".info>h2", ".info>h1"]),
		hide: "div:has(>iframe)",
		category: "hcomic"
	}, {
		name: "nHentai/HentaiHand",
		url: {
			h: ["nhentai.com", "hentaihand.com"]
		},
		page: () => fn.clp("/en/comic/"),
		json: () => fn.sm5().then(() => {
			let comic = fn.clp().split("/").at(3);
			let csrfToken = fn.ge("meta[name='csrf-token']").content;
			let xsrfToken = fn.cookie("XSRF-TOKEN");
			return fn.j(`/api/comics/${comic}/images`, {
				"headers": {
					"x-csrf-token": csrfToken,
					"x-requested-with": "XMLHttpRequest",
					"x-xsrf-token": xsrfToken
				}
			}).then(json => (siteJson = json) && fn.hm());
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json().then(() => fn.waitEle(".vertical-image img[data-src],.comic-gallery img,.comic-gallery img")) : void 0,
		imgs: async () => {
			if (!_this.page()) return [];
			thumbnailSrcArray = siteJson.images.map(e => e.thumbnail_url);
			return siteJson.images.map(e => e.source_url);
		},
		button: [4],
		insertImgBF: () => fn.createImgBox("div:has(>div>.comic-gallery),.reader", 2),
		insertImg: [
			["box", 0, ".box-header,div:has(>div>.comic-gallery),.reader"], 2
		],
		customTitle: () => _this.page() ? siteJson.comic.alternative_title ?? siteJson.comic.title : null,
		category: "hcomic"
	}, {
		name: "同人エロ漫画・エロ同人誌ならエロコミックハンター",
		host: ["ero-comic-hunter.net"],
		reg: /^https?:\/\/ero-comic-hunter\.net\/\d+\.html$/,
		imgs: "#single-more_wid~a[href*='/wp-content/uploads/']",
		customTitle: ".kijibox_title a",
		category: "hcomic"
	}, {
		name: "エロ漫画 ヌキブックス",
		url: {
			h: "nukibooks.com",
			p: "/articles/"
		},
		init: () => fn.waitEle("next-route-announcer"),
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".grid-container .image-item img,.article-page-list img");
			let text = fn.__next_f();
			return fn.textToArray(text, '"pages":').map(e => "https://gazou.nukibooks.com/" + e.fileName);
		},
		capture: () => _this.imgs(),
		customTitle: ".detail-ttl",
		category: "hcomic"
	}, {
		name: "エロモモ",
		url: {
			h: "momoniji.com",
			e: "#cif"
		},
		imgs: () => fn.getImgA("#cif img", ".singlepager a"),
		capture: () => _this.imgs(),
		customTitle: "main h1",
		category: "hcomic"
	}, {
		name: "エロ画像まとめ えっちなお姉さん。",
		url: {
			h: "hnalady.com",
			p: "/blog-entry-"
		},
		imgs: () => fn.gae(".entry_body img,#more img,.entry_more img").filter(e => !e.closest(".relation_entry,.wakupr")),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".page_next a,.next_entry a",
		prev: ".page_prev a,.prev_entry a",
		customTitle: "#main h2,.big_title h2",
		category: "hcomic"
	}, {
		name: "キモ男陵辱同人道",
		url: {
			h: "kimootoko.net",
			p: "/archives/"
		},
		imgs: () => fn.gae(".post_content .midashigazou img,.post_content a[data-wpel-link]:not(.syousaimoji):has(img)").filter(e => !e.closest(".fanzakiji-hako,.pickup")),
		capture: () => _this.imgs(),
		customTitle: ".c-postTitle__ttl",
		category: "hcomic"
	}, {
		name: "二次萌エロ画像ブログ",
		url: {
			h: "moeimg.net",
			p: ".html"
		},
		imgs: ".box:not(.moeimg-ad) img",
		autoDownload: [0],
		next: ".nav-next a[rel=prev]",
		prev: ".nav-previous a[rel=next]",
		customTitle: "h1.title",
		category: "hcomic"
	}, {
		name: "エロ画像が見たいんだ!",
		url: {
			h: "eromitai.com",
			p: "/archives/"
		},
		imgs: ".entry-content img",
		autoDownload: [0],
		next: "a.prev-post",
		prev: "a.next-post",
		customTitle: "h1.entry-title",
		category: "hcomic"
	}, {
		name: "もぎたてエロ画像",
		url: {
			h: ["mogiero.com"]
		},
		imgs: ".entry-content p:has(br) img",
		autoDownload: [0],
		next: ".st-prev-link",
		prev: ".st-next-link",
		customTitle: "h1.entry-title",
		category: "hcomic"
	}, {
		name: "ヌケマン-エロ漫画",
		url: {
			h: ["nukemanga.com"]
		},
		imgs: ".entry-content p:has(img) img",
		autoDownload: [0],
		next: ".nav-prev>a,.nav-previous>a",
		prev: ".nav-next>a",
		customTitle: ".entry-content h3",
		hide: "div[id^='bnc_ad']",
		category: "hcomic"
	}, {
		name: "エロ漫画の艶",
		url: {
			h: ["eromanga-milf.com"],
			p: /\/\d+$/
		},
		box: [".content_subtit", 2],
		imgs: ".content_subtit~img,.content_subtit~p>img",
		button: [4],
		insertImg: [
			["box", 0, ".content_subtit~img,.content_subtit~p"], 2
		],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: "h1.entry-title,h1.article-title",
		hide: "div[id^='bnc_ad']",
		category: "hcomic"
	}, {
		name: "同人らんど",
		url: {
			h: ["doujinland.info"],
			p: "/blog-entry"
		},
		box: [".book_content", 1],
		imgs: ".book_content img",
		button: [4],
		insertImg: [
			["box", 0, ".book_content"], 2
		],
		next: "//a[text()='<<前の本へ']",
		prev: "//a[text()='次の本へ>>']",
		customTitle: "article h1",
		hide: "div[class^='ad_']",
		category: "hcomic"
	}, {
		name: "同人らんど",
		url: {
			h: ["doujinland.info"],
			p: "/blog-entry"
		},
		box: [".book_content", 1],
		imgs: ".book_content img",
		button: [4],
		insertImg: [
			["box", 0, ".book_content"], 2
		],
		next: "//a[text()='<<前の本へ']",
		prev: "//a[text()='次の本へ>>']",
		customTitle: "article h1",
		hide: "div[class^='ad_']",
		category: "hcomic"
	}, {
		name: "いたどう エロマンガ同人誌",
		url: {
			h: ["ita-do.com"],
			p: /\/\d+$/
		},
		box: [".singleBox p:has(img)", 1],
		imgs: ".singleBox p:has(img) img",
		button: [4],
		insertImg: [
			["box", 0, ".singleBox p:has(img)"], 2
		],
		next: "//a[text()='<<前の本へ']",
		prev: "//a[text()='次の本へ>>']",
		customTitle: "article h1",
		hide: "div[class^=ad],.aspect_03",
		category: "hcomic"
	}, {
		name: "絶望漫画館",
		host: ["無料同人誌.com"],
		url: {
			t: "絶望漫画館"
		},
		srcset: ".single-post img",
		button: [4],
		insertImg: [".single-post", 2],
		next: {
			s: "a.prev",
			t: "前の記事"
		},
		prev: {
			s: "a.next",
			t: "次の記事"
		},
		customTitle: ".singlemain h1",
		hide: "div[id^='bnc_ad']",
		category: "hcomic"
	}, {
		name: "H研-成年コミック研究会",
		url: {
			h: "www.b-hentai.com",
			p: ".html"
		},
		imgs: () => fn.getImgA(".content img", ".article-pagination a"),
		autoDownload: [0],
		next: "//a[div[div[div[text()='Previous']]]]",
		prev: "//a[div[div[div[text()='Next']]]]",
		customTitle: "h1.post-title",
		category: "hcomic"
	}, {
		name: "エロ漫画同人誌画像",
		url: {
			h: "eromangarev.blog"
		},
		box: [".entry-content>p:has(>a>img)", 1],
		imgs: ".entry-content>p>a:has(img)",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content>p:has(>a>img)"], 2
		],
		autoDownload: [0],
		next: "a:has(.prev-post-title)",
		prev: "a:has(.next-post-title)",
		customTitle: "h1.entry-title",
		category: "hcomic"
	}, {
		name: "俺のエロ本",
		url: {
			h: "oreno-erohon.com",
			p: "/public/",
			d: "pc"
		},
		srcset: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: ".nav-prev a",
		prev: ".nav-next a",
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "俺のエロ本",
		url: {
			h: "oreno-erohon.com",
			p: "/public/",
			d: "m"
		},
		box: [".entry-content .wpfp-area", 1],
		srcset: ".entry-content img",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content>div:not([class],[id])"], 2
		],
		autoDownload: [0],
		next: ".nav-previous a",
		prev: ".nav-next a",
		customTitle: ".article-title",
		hide: ".sp_head_box,.sp_footer,.sp_widget_box",
		category: "hcomic"
	}, {
		name: "ひめぼん",
		url: {
			h: "himebon.blog",
			P: "/eromanga/"
		},
		box: [".entry-content>p:has(>a>img)", 1],
		srcset: ".entry-content>p>a:has(img)",
		button: [4],
		insertImg: [
			["box", 0, ".entry-content>p:has(>a>img)"], 2
		],
		customTitle: "h1.entry-title",
		category: "hcomic"
	}, {
		name: "エロジン",
		url: {
			h: "erozine.jp",
			p: ["/eromanga/", "/gazou/", "/3d/"]
		},
		imgs: "#ar_content img",
		autoDownload: [0],
		next: "a.ab:has(img[alt=next])",
		prev: "a.ab:has(img[alt=prev])",
		customTitle: "#ar_title",
		category: "hcomic"
	}, {
		name: "モモンガッ!!",
		url: {
			h: ["momon-ga.com", "momon-ga.me", "pingporn.ru"],
			p: ["/fanzine/mo", "/magazine/mo"]
		},
		imgs: "#post-hentai img",
		button: [4],
		insertImg: ["#post-hentai", 2],
		customTitle: "#post-data h1",
		hide: "div[style]:has(>div[id^='bnc_ad']),div[style]:has(>script[src*='.ad'])",
		category: "hcomic"
	}, {
		name: "同人村",
		url: {
			h: "doumura.com",
			p: "/archives/"
		},
		imgs: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "Hentai2Read",
		host: ["hentai2read.com"],
		reg: /^https?:\/\/hentai2read\.com\/\w+\/\d+\/$/,
		imgs: () => _unsafeWindow.gData.images.map(e => "https://static.hentai.direct/hentai" + e),
		button: [4],
		insertImg: ["#js-reader", 2],
		autoDownload: [0],
		current: () => {
			let node = fn.ge("button:has(.si-list)").nextElementSibling;
			return fn.ge(".bg-info", node);
		},
		next: () => {
			let next = _this.current()?.parentElement?.previousElementSibling?.firstElementChild;
			return next ? fn.wurl(next.dataset.cslug, fn.url, -2) : null;
		},
		prev: () => {
			let prev = _this.current()?.parentElement?.nextElementSibling?.firstElementChild;
			return prev ? fn.wurl(prev.dataset.cslug, fn.url, -2) : null;
		},
		chapters: () => {
			let node = fn.ge("button:has(.si-list)").nextElementSibling;
			return fn.gae("a", node).map(a => ({
				text: fn.dt({
					t: a.text
				}),
				url: ("cslug" in a.dataset) ? fn.wurl(a.dataset.cslug, fn.url, -2) : fn.url
			})).reverse();
		},
		customTitle: () => fn.gt(".reader-left-text.text-ellipsis").replace(/\//g, "-"),
		category: "hcomic"
	}, {
		name: "XlecX",
		url: {
			h: ["xlecx.one"],
			p: /^\/[^\.\/]+\.html$/
		},
		imgs: () => fn.getImgSrcArr(".ug-thumb-image,img[data-src]").map(e => e.replace("thumbs/", "")),
		button: [4],
		insertImg: [
			[".page__col-left", 0], 2
		],
		customTitle: ".page__col-left>h1",
		category: "hcomic"
	}, {
		name: "HentaiPorns",
		url: {
			h: ["hentaiporns.net"],
			p: "/d/"
		},
		init: () => fn.rd(),
		imgs: () => fn.getImgSrcset("#chapter-gallery-wrapper img", doc),
		button: [4],
		insertImg: ["#chapter-gallery-wrapper", 2],
		customTitle: "#main-content h1",
		category: "hcomic"
	}, {
		name: "8muses",
		host: ["comics.8muses.com"],
		reg: /^https?:\/\/comics\.8muses\.com\/comics\/album\/[\w-]+\/[\w-]+\//i,
		include: ".gallery",
		exclude: ".image-title>.title-text",
		imgs: () => {
			let srcs = fn.gae("img[data-src]").map(e => e.dataset.src.replace("/image/th/", "https://comics.8muses.com/image/fl/"));
			let xhrNum = 0;
			fn.showMsg("fn.xhrHEAD...", 0);
			return srcs.map(async src => {
				let res = await fn.xhrHEAD(src);
				fn.showMsg(`fn.xhrHEAD(${xhrNum+=1}/${srcs.length})`, 0);
				let status = res.status;
				return status == 404 ? src.replace("/fl/", "/fm/") : src;
			});
		},
		button: [4],
		insertImg: [
			[".gallery", 2], 1
		],
		endColor: "white",
		category: "hcomic"
	}, {
		name: "EROFUS",
		url: {
			h: ["www.erofus.com"],
			e: ".thumbnail img[alt^=picture]"
		},
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".thumbnail img[alt^=picture]");
			return thumbnailSrcArray.map(e => e.replace("/thumb/", "/medium/"));
		},
		capture: () => _this.imgs(),
		customTitle: () => fn.dt({
			d: " | Erofus - Sex and Porn Comics"
		}),
		category: "hcomic"
	}, {
		name: "MULT34",
		url: {
			h: ["mult34.com"]
		},
		srcset: ".gallery img[srcset],.gallery img[data-src]",
		customTitle: () => fn.ge(".entry-title")?.textContent,
		category: "hcomic"
	}, {
		name: "X-Manga",
		url: {
			h: ["x-manga.net"]
		},
		imgs: ".wpb_content_element img",
		button: [4],
		insertImg: [".wpb_content_element:has(img)", 2],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "FreeAdultComix",
		url: {
			h: ["freeadultcomix.com"]
		},
		imgs: ".foto img,.post-texto a:has(img[data-jg-srcset])",
		endColor: "white",
		customTitle: ".post-conteudo h1",
		category: "hcomic"
	}, {
		name: "Manga18.club/hanman18.com/18PornComic",
		init: () => fn.waitVar("jQuery").then(() => fn.run("jQuery(document).off()")),
		url: {
			h: [
				"manga18.club",
				"hanman18.com",
				"18porncomic.com"
			],
			st: "slides_p_path"
		},
		imgs: () => _unsafeWindow.slides_p_path.map(e => atob(e)),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => _unsafeWindow.next_chapter ? _unsafeWindow.next_chapter : null,
		prev: () => _unsafeWindow.prev_chapter ? _unsafeWindow.prev_chapter : null,
		customTitle: () => {
			if (fn.lh === "manga18.club" || fn.lh === "hanman18.com" || fn.lh === "18porncomic.com") {
				return document.title;
			}
			return fn.gt(".story_name>h1");
		},
		category: "hcomic"
	}, {
		name: "ReadManga18",
		url: {
			h: ["www.readmanga18.com", "readmanga18.com", "manhwahub.me", "manga18fx.com"],
			p: "/chapter-"
		},
		imgs: ".read-content img",
		button: [4],
		insertImg: [".read-content", 2],
		autoDownload: [0],
		next: "a.navi-change-chapter-btn-next",
		prev: "a.navi-change-chapter-btn-prev",
		chapters: {
			node: "select.navi-change-chapter",
			target: "option",
			sort: "r",
			cb: (text, _, o) => {
				let url;
				if (fn.lp.endsWith("/")) {
					url = fn.wurl(o.dataset.c, fn.url, -2);
				} else {
					url = fn.wurl(o.dataset.c, fn.url);
				}
				return {
					text,
					url
				}
			}
		},
		customTitle: ".read-manga h1,.entry-title",
		category: "hcomic"
	}, {
		name: "AllPornComic",
		host: ["allporncomic.com"],
		reg: /^https?:\/\/allporncomic\.com\/porncomic\/[^\/]+\/[^\/]+\/$/i,
		include: ".read-container",
		imgs: ".wp-manga-chapter-img",
		button: [4],
		insertImg: [".read-container", 2],
		endColor: "white",
		autoDownload: [0],
		next: "a.next_page",
		prev: "a.prev_page",
		customTitle: "#chapter-heading",
		category: "hcomic"
	}, {
		name: "vermangasporno/vercomicsporno",
		url: {
			h: ["vermangasporno.com", "vercomicsporno.com"]
		},
		imgs: ".wp-content img",
		button: [4],
		insertImg: [".wp-content", 2],
		customTitle: "h1.titl",
		category: "hcomic"
	}, {
		name: "18H",
		url: {
			h: ["18h.mm-cg.com"],
			st: "Large_cgurl"
		},
		imgs: () => _unsafeWindow.Large_cgurl,
		button: [4],
		insertImg: ["#show_cg_html", 2],
		customTitle: () => fn.title("-", 1),
		hide: ".ut1_img_content",
		category: "hcomic"
	}, {
		name: "H 次元",
		host: ["h-ciyuan.com"],
		reg: /^https?:\/\/h-ciyuan\.com\/\d+\/\d+\/.+\//,
		include: "a[data-fancybox],.rl-gallery-container a",
		imgs: "a[data-fancybox],.rl-gallery-container a",
		thums: "a[data-fancybox] img,.rl-gallery-container a img",
		button: [4],
		insertImg: [
			[".entry-content,.rl-gallery-container", 2], 2
		],
		next: ".nav-previous>a",
		prev: ".nav-next>a",
		customTitle: ".post-title",
		category: "hcomic"
	}, {
		name: "淫漫画",
		host: ["www.yinmh.com", "www.yinmh.top", "www.yinmh.xyz"],
		reg: /^https?:\/\/www\.yinmh\.(com|top|xyz)\/\d+\.html$/,
		init: () => fn.rd(),
		imgs: () => fn.gae(".left>.image img.lazy", doc).map(e => e.getAttribute("img") ?? e.src),
		button: [4],
		insertImg: [".left>.image", 2],
		customTitle: ".box>h1",
		category: "hcomic"
	}, {
		name: "爱漫画网",
		host: ["www.iimhw.com", "iimhw.com", "www.iimhw.top", "eemh.top", "mhmao.com", "mhjia.com", "mhxia.com"],
		url: {
			e: "a[title=爱漫画网],a[title=漫画猫],a[title=漫画家],a[title=漫画侠]",
			p: "/chapter"
		},
		imgs: () => fn.gae(".chapter-content img"),
		button: [4],
		insertImg: [".chapter-content", 2],
		next: "a#next_chap[href$=html]",
		prev: "a#prev_chap[href$=html]",
		chapters: () => {
			let a = fn.ge("a:has(.glyphicon-list-alt)");
			return fn.fetchDoc(a).then(dom => {
				const get = (_dom) => fn.gae(".title-list:not([id])+.row .list-chapter a", _dom).map(a => ({
					text: a.title,
					url: a.href
				}));
				let pages = fn.ge("//a[text()='Last']", dom);
				if (pages) {
					let doms = [dom];
					let max = Number(fn.getUSP("p", pages.href)) - 1;
					let links = fn.arr(max, (v, i) => `${a.href}?p=${i + 2}`);
					let resArr = links.map(fn.fetchDoc);
					return Promise.all(resArr).then(res => {
						doms = [...doms, ...res];
						return doms.map(get).flat();
					});
				}
				return get(dom);
			});
		},
		customTitle: [".truyen-title", ".chapter-title"],
		hide: "#goTop~div[class][style]",
		category: "hcomic"
	}, {
		name: "丽图·污漫画",
		url: {
			h: "litu100.xyz",
			p: "comic/id-"
		},
		imgs: ".comic-images img",
		button: [4],
		insertImg: [".comic-images", 2],
		autoDownload: [0],
		next: "a.next",
		prev: "a.prev",
		chapters: {
			target: "//h3[text()='漫画章节']/following-sibling::a"
		},
		customTitle: () => fn.dt({
			s: ".breadcrumb span:nth-child(2)",
			d: "首页"
		}),
		css: "body{overflow:unset!important}",
		hide: ".banner_ad,.swal2-container,.article:has(.media),.jquery-modal.blocker.current,.push-top-container",
		category: "hcomic"
	}, {
		name: "漫小肆/漫画大叔/桃心漫画/韩漫连连看/漫画仓/爱看漫画/漫画世界",
		host: ["www.mxsweb.cc", "manhuadashu.xyz", "txcomic.com", "www.hmkll.com", "manhuacang.xyz", "akmahua.com", "manhuashijie.xyz"],
		url: {
			t: ["漫小肆", "漫画大叔", "桃心漫画", "韩漫连连看", "漫画仓", "爱看漫画", "漫画世界"],
			p: "/chapter/",
			st: "bookInfo"
		},
		init: () => {
			fn.clearAllTimer();
			fn.remove("//body/div[div[@id][@style][a]]|//body/div[div[@id][@style]][a[@id][@style]] | //div[@class='comicpage']/a[img] | //div[@class='comicpage']/div[script] | //div[@id='cp_img']/a[img] | //div[@id='cp_img']/div[script]");
		},
		imgs: () => fn.getNP(".comicpage>img", "#nextPage", null, ".fanye").then(() => fn.gae(".comiclist img,#cp_img img,#enc_img img")),
		button: [4],
		insertImg: [".comicpage,#cp_img,#enc_img", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/chapter/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/chapter/')]",
		chapters: () => isPC ? fn.getChapters({
			target: ".mCustomScrollBox a"
		}) : fn.getChapters({
			url: "//a[p[text()='目录']]",
			target: "#detail-list-select a"
		}),
		customTitle: () => {
			let code = fn.gst("bookInfo");
			let bookInfo = fn.textToObject(code, "bookInfo");
			return bookInfo.book_name + " - " + bookInfo.chapter_name;
		},
		referer: "src",
		hide: "h5[id]:has(h5[id]),.swiper-container,ins,#pubcdnModal",
		category: "hcomic"
	}, {
		name: "Avbebe",
		host: ["avbebe.com"],
		link: "https://avbebe.com/archives/category/%e6%88%90%e4%ba%bah%e6%bc%ab%e7%95%ab",
		reg: /^https?:\/\/avbebe\.com\/archives\/\d+/,
		include: "//a[@rel='category tag' and text()='成人漫畫']",
		imgs: ".elementor-widget-container>p>img,.content-inner>p>img",
		button: [4],
		insertImg: [
			["//p[img]", 2, "//p[img]"], 2
		],
		customTitle: ".jeg_post_title",
		category: "hcomic"
	}, {
		name: "ACG漫画网",
		host: ["acgmhx.com", "acgxmh.com", "porn-comic.com"],
		url: {
			e: [".header>.header-con>.logo", ".manga-page,.main-picture"],
			p: /^\/([\w-]+\/)?(h|hentai|cos|webtoon|western)\/\d+\.html$/
		},
		imgs: (s = ".manga-page img,.main-picture img") => fn.getNP(s, "#pages span+a:not(.a1)", null, "#pages", 200).then(() => fn.gae(s)),
		button: [4],
		insertImg: [".manga-page,.main-picture", 2],
		autoDownload: [0],
		next: ".next_pics>.fr>a[href$=html],.post-next a",
		prev: ".next_pics>.fl>a[href$=html],.post-pre a",
		customTitle: "h2.title,h1.title,.entry-header>h1",
		hide: ".pre_picture,.next_picture,[class^=ad300],[class^=ad900]",
		category: "hcomic"
	}, {
		name: "ACG漫画网",
		host: ["www.acgxbus.com"],
		url: {
			e: ["#page.site", ".main-picture"],
			p: /^\/\w+\/\d+\.html$/,
			d: "m"
		},
		imgs: () => fn.getNP(".main-picture", "#pages span+a:not(.a1)", null, "#pages", 200).then(() => fn.gae(".main-picture img")),
		button: [4],
		insertImg: [".entry-content", 2],
		next: ".post-next a",
		prev: ".post-pre a",
		customTitle: ".entry-header>h1",
		hide: ".pre_picture,.next_picture,.tips,.adbox",
		category: "hcomic"
	}, {
		name: "Naxter",
		url: {
			h: ["naxter.net"]
		},
		page: () => fn.clp("/gallery/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			let [, , id] = fn.clp().split("/");
			return fn.fetchDoc("/gallery/" + id).then(dom => JSON.parse(fn.gst("files", dom)));
		},
		imgs: () => {
			if (_this.page()) {
				fn.sm5();
				return _this.json().then(json => {
					let {
						props: {
							pageProps: {
								gallery: {
									files,
									originalTitle,
									title
								}
							}
						},
						runtimeConfig: {
							media: {
								filesBaseUrl
							}
						}
					} = json;
					apiCustomTitle = originalTitle ? originalTitle : title;
					thumbnailSrcArray = files.map(e => filesBaseUrl + "/media/" + e.id + "?size=preview&format=webp");
					return files.map(e => filesBaseUrl + "/media/" + e.id);
				});
			}
			return [];
		},
		capture: () => _this.imgs(),
		category: "hcomic"
	}, {
		name: "HManga",
		url: {
			h: ["hmanga.world"]
		},
		page: () => fn.clp("/manga/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			let id = fn.clp().split("/").at(-1);
			return fn.j("/api/getdoujin?id=" + id);
		},
		imgs: () => {
			if (_this.page()) {
				fn.sm5();
				return _this.json().then(json => {
					let {
						baseurl,
						page,
						titles: {
							english,
							original
						}
					} = json;
					apiCustomTitle = original ? original : english;
					return page.map((e, i) => baseurl + (i + 1) + "." + e);
				});
			}
			return [];
		},
		capture: () => _this.imgs(),
		hide: "div[style]:has(>div[id*='_ad_'])",
		referrerpolicy: "no-referrer",
		category: "hcomic"
	}, {
		name: "Schale Network/HManga",
		links: ["https://schale.network/mirrors", "https://gehenna.jp/mirrors"],
		host: ["anchira.to", "shupogaki.moe", "hoshino.one", "niyaniya.moe", "hdoujin.org"],
		url: {
			t: ["Schale Network", "HDoujin Galleries"]
		},
		page: () => fn.clp("/g/") && ("clearance" in localStorage),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			fn.sm5();
			let [, , id, key] = fn.clp().split("/");
			let domain = document.title.includes("Schale") ? "api.schale.network" : "api.hdoujin.org";
			return fn.j(`https://${domain}/books/detail/${id}/${key}`).then(json => {
				let detailJson = json;
				return fn.j(`https://${domain}/books/detail/${id}/${key}?crt=${localStorage.getItem("clearance")}`, {
					"method": "POST"
				}).then(json => {
					let {
						id: oid,
						key: okey
					} = json.data["0"];
					return fn.j(`https://${domain}/books/data/${id}/${key}/${oid}/${okey}/0?crt=${localStorage.getItem("clearance")}`).then(json => {
						Reflect.set(detailJson, "originals", json);
						siteJson = detailJson;
						debug("\n此頁JSON資料\n", siteJson);
						fn.hm();
					});
				});
			});
		},
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (_this.page()) {
				fn.sm5();
				let {
					originals: {
						base: ob,
						entries: oe
					},
					thumbnails: {
						base: tb,
						entries: te
					},
				} = siteJson;
				thumbnailSrcArray = te.map(({
					path
				}) => tb + path);
				let fetchNum = 0;
				return oe.map(async ({
					path
				}, i) => {
					await fn.delay(i * 500, 0);
					return axios.get(ob + path, {
						responseType: "blob"
					}).then(res => {
						fn.showMsg(`${DL.str_06} ${fetchNum += 1}/${oe.length}`, 0);
						return URL.createObjectURL(res.data);
					});
				});
			}
			return [];
		},
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				subtitle,
				title
			} = siteJson;
			return subtitle || title;
		},
		category: "hcomic"
	}, {
		name: "H-Comic",
		url: {
			t: "H-Comic",
			h: "h-comic.com",
			e: "body[data-theme='h-comic-blue-theme']"
		},
		page: () => ["/comics/", "/1"].every(e => fn.clp(e)),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => fn.fetchDoc(fn.clp()).then(dom => {
			let code = fn.gst("num_pages", dom);
			siteJson.env = fn.textToObject(code, "env:");
			let a = code.indexOf("data:");
			let b = code.indexOf("[", a);
			let c = code.lastIndexOf("],") + 1;
			let data = code.slice(b, c);
			data = fn.run(data);
			return data.find(d => !!d?.data?.comic);
		}),
		imgs: () => {
			if (_this.page()) {
				fn.sm5();
				return _this.json().then(json => {
					let {
						data: {
							comic: {
								num_pages,
								media_id,
								comic_source,
								title: {
									japanese,
									english,
									pretty
								}
							}
						}
					} = json;
					apiCustomTitle = japanese ?? english ?? pretty;
					return fn.arr(num_pages, (v, i) => `${siteJson.env.PUBLIC_IAMGE_SERVER_URL}/${comic_source}/${media_id}/pages/${i + 1}`);
				});
			}
			return [];
		},
		capture: () => _this.imgs(),
		category: "hcomic"
	}, {
		name: "NiceCat",
		url: {
			h: "web.nicecat.cc"
		},
		page: () => fn.clp("/comic/book/reader/"),
		data: () => {
			let id = fn.clp().split("/").at(-1);
			return fn.fetchDoc("/comic/info/" + id).then(dom => (doc = dom));
		},
		SPA: () => _this.page() ? true : (siteJson.imageData = null) && false,
		observeURL: "head",
		init: () => {
			if (!isAddAjaxHooker) {
				isAddAjaxHooker = true;
				const ajaxHooker = addAjaxHookerLibrary();
				ajaxHooker.filter([{
					url: "/api/ComicOrder/getComicOrder"
				}]);
				ajaxHooker.hook(request => {
					//console.log(request);
					request.response = res => {
						if (res.status === 200 && request.url.includes("/api/ComicOrder/getComicOrder")) {
							let json = JSON.parse(res.responseText);
							//console.log("imageData", json);
							siteJson.imageData = json.data.imageData;
						}
					}
				});
			}
			return _this.page() ? fn.sm5().then(() => _this.data().then(() => fn.wait(() => isArray(siteJson.imageData)))).then(() => fn.hm()) : void 0;
		},
		imgs: () => _this.page() ? siteJson.imageData.map(e => e.imageUrl) : [],
		capture: () => _this.imgs(),
		customTitle: () => {
			if (!_this.page()) return null;
			let ele = fn.ge(".pc-mode", doc);
			let [a, b] = fn.gae("span", ele).map(e => e.textContent);
			return b || a;
		},
		category: "hcomic"
	}, {
		name: "摸摸漫画",
		host: ["mhclscn.life", "mhupfic.live", "mhirtbg.life", "dskjm.live", "mmadd.site", "mmland.xyz", "mmero.com", "ainuc.live"],
		url: {
			t: "摸摸漫画"
		},
		page: () => fn.clp(/^\/comics\/\d+\/\d+$/),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => {
			fn.sm5();
			let [, , mid, cid] = fn.clp().split("/");
			let res_a = fn.j("/api/comic/chapter", {
				"headers": {
					"content-type": "application/json"
				},
				"body": `{"id":${Number(mid)},"chapter":${Number(cid)}}`,
				"method": "POST"
			}).then(json => (siteJson = json));
			let res_b = fn.j("/api/comic/content", {
				"headers": {
					"content-type": "application/json"
				},
				"body": `{"id":${Number(mid)}}`,
				"method": "POST"
			});
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					content: b
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			let fetchNum = 0;
			let [, , mid, cid] = fn.clp().split("/");
			let srcs = fn.arr(siteJson.pages, (v, i) => `https://themose.xyz/comic/${mid}/${cid}/${i + 1}.jpg`);
			return srcs.map(src => fn.t(src).then(text => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${srcs.length}`, 0);
				return fn.dataURLtoBlobURL(`data:image/jpeg;base64,${text}`);
			}));
		},
		repeat: 1,
		autoDownload: [0],
		next: () => siteJson?.hadNext ? fn.wurl(siteJson.number + 1) : null,
		prev: () => siteJson?.hadPrevious ? fn.wurl(siteJson.number - 1) : null,
		chapters: () => siteJson.content.chapters.map(({
			number,
			title
		}) => ({
			text: title,
			url: fn.wurl(number)
		})),
		customTitle: () => {
			if (!_this.page()) return null;
			return siteJson.content.title + " - " + siteJson.title;
		},
		category: "hcomic"
	}, {
		name: "隐秘漫画",
		host: ["yinmimh.com"],
		url: {
			t: "隐秘漫画",
			p: "/comic/"
		},
		imgs: () => {
			fn.sm5();
			let fetchNum = 0;
			let srcs = fn.getImgSrcArr("#comic img");
			return srcs.map(src => fn.t(src).then(text => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${srcs.length}`, 0);
				return fn.dataURLtoBlobURL(`data:image/jpeg;base64,${text}`);
			}));
		},
		autoDownload: [0],
		next: "//span[text()='下一章']",
		prev: "//span[text()='上一章']",
		chapters: {
			url: "//a[span[text()='目录']]",
			target: "#hl-plays-list a"
		},
		customTitle: () => fn.title(" - 隐秘漫画"),
		category: "hcomic"
	}, {
		name: "紳士漫畫",
		link: "https://wnacg.date/,https://wnacg01.org/",
		//第3方API直接取得"寫真 & Cosplay"分類一整頁的畫廊資料
		//https://meoden.net/gallery?page=1&site=WN&siteTag=
		//https://meoden.net/api/gallery/wnacg?page=1
		url: {
			t: ["紳士漫畫", "绅士漫画"],
			p: "/photos-index-aid-"
		},
		init: () => {
			fn.remove(".sh,.dlh,div:not([id],[class],[style]):has(>a>img[alt]),iframe");
			fn.remove("//body/div[a[img]] | //div[@class='Introduct']/a[div[img]] | //div[a[img[@alt='Game Tip']]]");
			fn.addMutationObserver(() => fn.remove(".sh,.dlh,div:not([id],[class],[style]):has(>a>img[alt]),iframe"));
		},
		imgs: () => {
			fn.sm5();
			let [galleryId] = fn.lp.match(/\d+/);
			let galleryUrl = `/photos-gallery-aid-${galleryId}.html`;
			return fn.t(galleryUrl).then(text => {
				text = text.replaceAll("\\", "").replaceAll("fast_img_host+", "");
				let s = text.indexOf("[{");
				let e = text.indexOf(";", s);
				text = text.slice(s, e);
				let array = fn.run(text);
				return array.map(e => e.url).filter(e => !e.includes("/themes/"));
			});
		},
		button: [4],
		insertImg: [
			[".gallary_wrap,.Introduct", 0, ".gallary_wrap>.cc"], 2
		],
		customTitle: () => fn.dt({
			d: / - 紳士漫畫.*$| - 绅士漫画.*$|-紳士漫畫.*$|-绅士漫画.*$/
		}),
		category: "hcomic"
	}, {
		name: "宅男漫画",
		host: ["www.znmh.net"],
		url: {
			t: "宅男漫画",
			p: "/view/",
			st: "encodedImages"
		},
		init: () => fn.clearAllTimer(3),
		box: ["#imageContainer", 1],
		imgs: () => {
			let code = fn.gst("encodedImages");
			let encodedImages = fn.textVar(code, "encodedImages");
			encodedImages = atob(encodedImages);
			let images = "";
			for (let i = 0, n = encodedImages.length; i < n; i++) {
				images += String.fromCharCode(encodedImages.charCodeAt(i) ^ "comicreader2024".charCodeAt(i % 15));
			}
			return JSON.parse(images);
		},
		button: [4],
		insertImg: [
			["box", 0, "#imageContainer"], 2
		],
		customTitle: () => fn.title(" - 宅男漫画"),
		hide: "#inviteModal,.float-ad",
		category: "hcomic"
	}, {
		name: "宅男漫画",
		host: ["www.znmh.net"],
		url: {
			t: "宅男漫画",
			p: /^\/\w+$/
		},
		MutationObserver: () => {
			let item;
			for (item of fn.gae(".gallery-item[onclick]")) {
				item.innerHTML = `<a href="${item.getAttribute("onclick").split("'").at(1)}" target="_blank">${item.innerHTML}</a>`;
				item.removeAttribute("onclick");
			}
		},
		hide: ".float-ad",
		category: "none"
	}, {
		name: "紳夜漫畫/工口動漫",
		host: ["syacomic.com"],
		url: {
			h: "syacomic",
			t: ["紳夜漫畫", "工口動漫"]
		},
		page: () => fn.clp("/comic/detail/"),
		json: () => {
			fn.sm5();
			let [id] = fn.clp().match(/\d+/);
			return fn.j(`https://api.nftbaoyi.com/comic/${id}`).then(json => {
				siteJson = json;
				debug("\n此頁JSON資料\n", siteJson);
				apiCustomTitle = siteJson.name;
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? fn.wait(() => isArray(siteJson.book_pages)).then(() => siteJson.book_pages.map(e => e.img_url)) : [],
		button: [4],
		insertImgBF: () => fn.waitEle(".grid img").then(() => fn.createImgBox(".grid", 1, 1200)),
		insertImg: [
			["box", 0, ".grid,a.justify-center,div:has(>a.block),div:has(>.custom-pagination)"], 2
		],
		customTitle: () => _this.page() ? fn.wait(() => isString(siteJson.name)).then(() => siteJson.name) : [],
		hide: "body>ins,div:not([id],[class]):has(div.items-center)",
		category: "hcomic"
	}, {
		name: "嗶咔漫畫PICACG",
		url: {
			h: ["manhuabika.com", "manhuapica.com"],
			p: "/pchapter/",
			s: "chapter=",
			d: "pc"
		},
		imgs: () => {
			const {
				jQuery: $,
				getTimeOnece,
				cid,
				chapter,
				catMaxPage: max,
				ProxyBaseUrl,
				postHeader,
				getsignature,
				getS3ProxySet
			} = _unsafeWindow;
			fn.sm5();
			let fetchNum = 0;
			const get = (page) => new Promise(resolve => {
				const setTime = getTimeOnece();
				const mothod = "GET";
				const pathname = "comics/" + cid + "/order/" + chapter + "/pages?page=" + page;
				$.ajax({
					type: mothod,
					contentType: "application/json; charset=UTF-8",
					crossBrowser: true,
					url: ProxyBaseUrl + pathname,
					beforeSend: (request) => {
						$.each(postHeader(setTime, pathname, mothod), (idx, obj) => request.setRequestHeader(obj.name, obj.value));
						request.setRequestHeader("image-quality", "original");
					},
					success: resolve
				});
			}).then(json => {
				const {
					ep: {
						title
					},
					pages
				} = json.data;
				if (page == 1) {
					customTitle += " " + title;
					debug(`\n自定義標題:${customTitle}`);
				}
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
				const proxy = getS3ProxySet();
				return pages.docs.map(e => proxy + e.media.path);
			});
			let resArr = fn.arr(max, (v, i) => get(i + 1));
			return Promise.all(resArr).then(data => data.flat());
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => {
			const {
				chapter,
				maxchapter
			} = _unsafeWindow;
			if (chapter < maxchapter) {
				let url = new URL(fn.url);
				url.searchParams.set("chapter", chapter + 1)
				return url.href;
			}
			return null;
		},
		prev: 1,
		chapters: () => {
			const {
				jQuery: $,
				cid,
				maxchapter,
				ProxyBaseUrl,
				getTimeOnece,
				postHeader
			} = _unsafeWindow;
			let max = Math.ceil(maxchapter / 40);
			let get = (page) => new Promise(resolve => {
				let setTime = getTimeOnece();
				let mothod = "GET";
				let pathname = "comics/" + cid + "/eps?page=" + page;
				$.ajax({
					type: mothod,
					contentType: "application/json; charset=UTF-8",
					crossBrowser: true,
					url: ProxyBaseUrl + pathname,
					beforeSend: function (request) {
						$.each(postHeader(setTime, pathname, mothod), function (idx, obj) {
							request.setRequestHeader(obj.name, obj.value);
						});
					},
					success: resolve
				});
			});
			let resArr = fn.arr(max, (v, i) => get(i + 1));
			let chapter_url = (num) => {
				let url = new URL(location.href);
				url.searchParams.set("chapter", num);
				return url.href;
			};
			return Promise.all(resArr).then(datas => datas.map(e => e?.data?.eps?.docs).filter(Boolean).flat().reverse().map(({
				order,
				title
			}) => ({
				text: title,
				url: chapter_url(order)
			})));
		},
		checkCurrentChapter: (url) => {
			let cid = fn.getUSP("chapter", fn.curl());
			let uid = fn.getUSP("chapter", url);
			return cid == uid;
		},
		customTitle: () => {
			const {
				jQuery: $,
				getTimeOnece,
				cid,
				ProxyBaseUrl,
				postHeader,
				getsignature
			} = _unsafeWindow;
			return new Promise(resolve => {
				const setTime = getTimeOnece();
				const mothod = "GET";
				const pathname = "comics/" + cid;
				$.ajax({
					type: mothod,
					contentType: "application/json; charset=UTF-8",
					crossBrowser: true,
					url: ProxyBaseUrl + pathname,
					beforeSend: (request) => {
						$.each(postHeader(setTime, pathname, mothod), (idx, obj) => request.setRequestHeader(obj.name, obj.value));
					},
					success: resolve
				});
			}).then(json => {
				const {
					author,
					title
				} = json.data.comic;
				if (author) {
					if (title.includes(author)) {
						return title;
					}
					return `[${author}] ${title}`;
				}
				return title;
			});
		},
		category: "hcomic"
	}, {
		name: "喜漫漫画",
		url: {
			h: ["www.favcomic.com", "www.favcomic.net"],
			p: "/chapter/"
		},
		imgs: "#content img",
		next: "a:has(>img[alt=下一话])",
		prev: "a:has(>img[alt=上一话])",
		customTitle: () => fn.dt({
			d: [" - 全集 在线阅读 | 喜漫漫画", " 在线阅读 | 喜漫漫画"]
		}),
		category: "hcomic"
	}, {
		name: "Comics",
		url: {
			h: ["pixiv.app"]
		},
		page: () => fn.clp("/comics/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => {
			if (_this.page()) {
				let code = fn.__next_f(doc);
				return code.match(/\"src\":\"([^\"])+\"/g).filter(e => e.includes("/image/")).map(src => src.slice(7, -1));
			}
			return [];
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.gt("main h1", 1, doc) : null,
		hide: ".overflow-hidden:has(iframe[src*=ads]),div.overflow-hidden:has(a[href*=link]),div:has(>div>a>img[data-nimg]):not(:has(h2))",
		category: "hcomic"
	}, {
		name: "日韩漫画/歪歪漫画",
		host: ["www.diyihm.com", "www.lltoon.com", "www.rrtoon.com", "wwtoon.com", "www.zztoon.com", "www.vvtoon.com", "www.fftoon.com", "www.wwtoon.com", "www.niumh.com"],
		link: "https://hm8.in,hstoon.com",
		url: {
			t: ["第一漫画", "歪歪漫画", "第一韩漫", "太极漫画网"],
			p: /^\/view\/\d+\/\d+$/,
			d: "m"
		},
		init: () => {
			try {
				let code = fn.gst("$(document).ready");
				let objStr = code.match(/window\.\w+\s?=\s?([^;]+)/)[1];
				let json = JSON.parse(objStr);
				debug("\n此頁JSON資料\n", json);
				siteJson = json;
			} catch {}
		},
		imgs: async () => {
			if (isArray(siteJson?.volume?.pages) && siteJson?.volume?.pages?.length > 0) {
				return siteJson.volume.pages;
			} else if (fn.ge("//a[text()='本章已分页']")) {
				fn.sm1();
				let arr = [];
				let src;
				let page = 1;
				let loop = true;
				const getData = () => fn.fetchDoc(location.href + "/" + page).then(dom => {
					fn.showMsg(`${DL.str_02}${page}/???`, 0);
					const srcs = fn.getImgSrcArr(".charpetBox img", dom);
					for (src of srcs) {
						if (arr.includes(src)) {
							loop = false;
							return;
						} else {
							arr.push(src);
						}
					}
				});
				while (loop) {
					await getData();
					page++;
				}
				return arr;
			}
			return fn.gae(".charpetBox img");
		},
		button: [4, 3],
		insertImg: [".charpetBox", 2],
		autoDownload: [0],
		next: "#loadNextChapter",
		prev: "#loadPrevChapter",
		customTitle: () => siteJson?.volume?.title ? siteJson.comic.title + " - " + siteJson.volume.title : fn.gt(".BarTit"),
		hide: "body>div[class][style]:first-of-type,body>div[class][style*='display: block; width: 100%; height: 128.75px;'],.letchepter[style*='20px'],#FullPictureLoadGoToLastImage~*:not([id^='Full'],[class^='Full'],[id^='pv-'],[class^='pv-'],#comicRead,#fab,*[class^=fancybox])",
		category: "hcomic"
	}, {
		name: "顶点韩漫/红本子漫画",
		link: "https://mh4.top,aetoon.com",
		host: ["mgtoon.com", "hktoon.com", "www.redbz.com"],
		url: {
			t: ["顶点韩漫", "红本子漫画"],
			p: /^\/view\/\d+\/\d+$/,
			d: "m"
		},
		init: () => fn.waitVar("chapter_id").then(() => (siteJson = Object.entries(_unsafeWindow).filter(([k, v]) => !!v?.comic)[0][1])),
		imgs: () => siteJson.volume.pages,
		button: [4, 3],
		insertImg: [".charpetBox", 2],
		autoDownload: [0],
		next: "#loadNextChapter",
		prev: "#loadPrevChapter",
		customTitle: () => {
			let {
				comic: {
					title: mn
				},
				volume: {
					title: cn
				}
			} = siteJson;
			return cn.includes(mn) ? cn : mn + " - " + cn;
		},
		fancybox: {
			blacklist: 1
		},
		hide: "body>div[class][style]",
		category: "hcomic"
	}, {
		name: "头牌漫画网/顶点漫画/第一漫画网",
		link: "https://xs8.me/,https://mh8.in/",
		host: ["dmmtu.com", "dmmpic.com", "dymmt.com", "kkmnt.com", "mmxzt.com"],
		url: {
			t: ["头牌漫画网", "顶点漫画", "顶点韩漫", "第一漫画网"],
			p: /^\/chapter\/\d+\.html$/
		},
		init: () => fn.getNP(".mip-box-body img", "//a[text()='下一页']", (dom) => !fn.ge(".mip-box-body img", dom), ".info"),
		box: [".info", 2],
		imgs: ".mip-box-body img",
		button: [4],
		insertImg: [
			["box", 0, ".mip-box-body>img"], 2
		],
		autoDownload: [0],
		np: (key) => (key in _unsafeWindow && _unsafeWindow[key] != 0) ? fn.dir(fn.lp) + _unsafeWindow[key] + ".html" : null,
		next: () => _this.np("nextid"),
		prev: () => _this.np("previd"),
		customTitle: ".mip-box-heading",
		fancybox: {
			blacklist: 1
		},
		hide: "body>div[class][style]",
		category: "hcomic"
	}, {
		name: "松鼠症倉庫 詳情頁",
		host: ["ahri8-2025-08-03-c.monster"],
		url: {
			e: "//div[@id='logo-group']//a[contains(text(),'松鼠症倉庫') or contains(text(),'松鼠症仓库')]",
			p: "/post",
			s: "ID="
		},
		init: () => {
			let e = fn.ge("//a[text()='預覽圖片']");
			e.innerText = "圖片";
		},
		imgs: async () => {
			let url = fn.gu("#more-information1 a:has(i.fa-book)");
			await fn.getCode(url, {
				mode: "dom",
				key: "Original_Image_List"
			});
			const {
				Original_Image_List,
				HTTP_IMAGE
			} = _unsafeWindow;
			return Original_Image_List.map(e => HTTP_IMAGE + e.new_filename + "_w1500." + e.extension);
		},
		button: [4],
		insertImg: ["#more-information1>div:has(img)", 2],
		category: "hcomic"
	}, {
		name: "Caitlin.top/Ahri Gallery分機 詳情頁",
		host: [
			"caitlin.top",
			"ahri-gallery-lzgwo.top",
			"ahri-gallery-20250322.top",
			"xayahentai.com",
			"xayahentai-hrr2q.top",
			"xr2ggt95ie0202.top",
			"lux-hentai.com",
			"dvamh.top",
			"zeri-m.top"
		],
		url: () => fn.checkUrl({
			h: /caitlin/,
			p: "index",
			s: "article&comic_id"
		}) || fn.checkUrl({
			h: /ahri|hentai|dvamh|zeri/,
			p: "index",
			s: "comic/article"
		}) || fn.checkUrl({
			e: {
				s: ".page-logo-text",
				t: ["Xayahentai", "Lux-Hentai"]
			},
			p: "index",
			s: "comic/article"
		}),
		init: () => {
			if (fn.ge("//a[text()='Read']")) {
				fn.createImgBox(".container:has(.gallery_card)");
			} else {
				fn.createImgBox("#more-information1>div.row:has(img),div[id='2div'],#default-tab-thumbnail", 2);
			}
			_unsafeWindow.onscroll = null;
		},
		imgs: async () => {
			let url;
			if (fn.ge("//a[text()='Read']")) {
				url = fn.gu("//a[text()='Read']");
			} else if (fn.ge("a:has(.fa-eye)")) {
				url = fn.gu("a:has(.fa-eye)");
			} else {
				url = fn.gu("#more-information1 a:has(i.fa-book)");
			}
			await fn.getCode(url, {
				mode: "dom",
				key: "Image_List"
			});
			const {
				Image_List,
				IMAGE_SERVER,
				image_server_id,
				IMAGE_FOLDER
			} = _unsafeWindow;
			let counter = 0;
			let srcArr = [];
			for (let Image of Image_List) {
				let ext = fn.ex(Image.extension.toLowerCase());
				let src = IMAGE_SERVER[image_server_id][counter] + IMAGE_FOLDER + Image.sort + "." + ext;
				srcArr.push(src);
				counter += 1;
				if (counter >= Object.keys(IMAGE_SERVER[image_server_id]).length) {
					counter = 0;
				}
			}
			return srcArr;
		},
		button: [4],
		insertImg: [
			["box", 0, "#more-information1>div.row:has(img),div[id='2div'],#default-tab-thumbnail"], 2
		],
		customTitle: () => fn.getText([".row>.col-xs-12>h2", "div.name>h2", ".gallery_title", ".gallery_title2", "div[id='1div'] .h2", ".app-content .page-header"]),
		category: "hcomic"
	}, {
		name: "蚂蚁搬运网/紳士泛漫畫",
		links: [
			"https://www.antbyw.com/plugin.php?id=jameson_manhua",
			"https://itsacg.top/"
		],
		url: {
			h: ["www.antbyw.com", /itsacg/],
			s: "=read",
			st: "urls",
			d: "pc"
		},
		imgs: async () => {
			let pages = fn.ge("//a[text()='无分页阅读']");
			if (pages) {
				fn.sm5();
				let url = fn.gu("//a[text()='无分页阅读']");
				return fn.fetchDoc(url).then(dom => {
					let code = fn.gst("urls", dom);
					return fn.textToArray(code, "urls");
				});
			}
			let code = fn.gst("urls");
			let srcs = fn.textToArray(code, "urls");
			let max = 1;
			if (fn.ge("span[title^=共]")) {
				max = Number(fn.gt("span[title^=共]").match(/\d+/));
			}
			if (max > 1) {
				fn.sm5();
				let fetchNum = 1;
				let nextPage;
				while (nextPage = fn.ge(".pg .nxt", doc)) {
					fetchNum++;
					fn.showMsg(`${DL.str_06}${fetchNum}/${max}`, 0);
					doc = await fn.fetchDoc(nextPage);
					code = fn.gst("urls", doc);
					srcs = [...srcs, ...fn.textToArray(code, "urls")];
				}
			}
			return srcs;
		},
		button: [4],
		insertImg: [".uk-zjimg", 2],
		insertImgAF: () => fn.hideEle(".pg.page"),
		autoDownload: [0],
		next: "//a[contains(text(),'下一章')]",
		prev: "//a[contains(text(),'上一章')]",
		chapters: {
			url: "//a[text()='[目录]']",
			target: ".muludiv a[href]",
			sort: "r"
		},
		customTitle: () => {
			if (fn.lh.includes("antbyw")) {
				return getTitle([".uk-breadcrumb li", -2, -1]);
			}
			let ct = fn.gt(".uk-breadcrumb>li:nth-child(4)");
			let nt = fn.gt(".uk-breadcrumb>li:nth-child(5)");
			if (ct.includes("|")) {
				ct = ct.split("|")[0].trim();
			}
			ct = ct.replace(/【.+】/g, "").trim();
			if (nt === "阅读浏览") {
				return ct;
			}
			return ct + " - " + nt;
		},
		category: "comic"
	}, {
		name: "蚂蚁搬运网M",
		url: {
			h: "www.antbyw.com",
			s: "=read",
			st: "urls",
			d: "m"
		},
		imgs: () => {
			let code = fn.gst("urls");
			return fn.textToArray(code, "urls");
		},
		button: [4],
		insertImg: ["#img_list", 2],
		insertImgAF: () => fn.hideEle("#img_load"),
		np: (key) => {
			let a = fn.ge(`//a[text()='${key}一章']`);
			if (a) {
				let [id] = fn.attr(`//a[text()='${key}一章']`, "onclick").match(/\d+/);
				if (Number(id)) {
					let searchParams = new URLSearchParams(fn.ls);
					searchParams.set("zjid", id);
					return fn.lp + "?" + searchParams.toString();
				}
				return null;
			}
			return null;
		},
		next: () => _this.np("下"),
		prev: () => _this.np("上"),
		chapters: {
			url: ".title a",
			target: ".media-list a[href]",
			textNode: ".item-title",
			sort: "r"
		},
		customTitle: [".title a", ".title span"],
		category: "comic"
	}, {
		name: "紳士泛漫畫M",
		url: {
			h: /itsacg/,
			s: "=read",
			st: "urls",
			d: "m"
		},
		imgs: () => {
			let pages = fn.ge("//a[text()='无分页阅读模式']");
			if (pages) {
				fn.sm5();
				let url = fn.gu("//a[text()='无分页阅读模式']");
				return fn.fetchDoc(url).then(dom => {
					let code = fn.gst("urls", dom);
					return fn.textToArray(code, "urls");
				});
			}
			let code = fn.gst("urls");
			return fn.textToArray(code, "urls");
		},
		button: [4],
		insertImg: [
			[".zjimg", 1, ".zjimg"], 2
		],
		customTitle: "#comicName",
		category: "hcomic"
	}, {
		name: "ACG糖",
		host: ["acgotang.com"],
		url: {
			e: "//div[@class='content']//a[text()='ACG糖']",
			p: /^\/\w+\/\w+\.html$/
		},
		imgs: () => fn.getImgO(".manga-picture img", fn.gt("//a[text()='下一页']", 2) || 1, 5),
		button: [4],
		insertImg: [".manga-page", 2],
		autoDownload: [0],
		next: ".next-toon a",
		prev: ".pre-toon a",
		customTitle: ".title",
		category: "hcomic"
	}, {
		name: "Roku Hentai",
		host: ["rokuhentai.com"],
		reg: /^https?:\/\/rokuhentai\.com\/\w+$/,
		include: [".site-manga-info", ".site-page-card__media"],
		box: [".site-manga-info+.mdc-layout-grid", 2, 1280],
		imgs: () => {
			fn.sm5();
			let url = fn.url + "/0";
			return fn.fetchDoc(url).then(dom => fn.getImgSrcArr(".site-reader__image", dom));
		},
		button: [4],
		insertImgBF: () => {
			let card = ge(".mdc-card");
			let a = ge(".site-popunder-ad-slot").cloneNode();
			card.after(a);
			a.append(card);
		},
		insertImg: [
			["box", 0, ".site-manga-info+.mdc-layout-grid"], 2
		],
		customTitle: () => fn.getText(["h6.site-manga-info__title-text+h6.site-manga-info__title-text", "h6.site-manga-info__title-text"]),
		hide: ".site-bottom-ad-slot",
		category: "hcomic"
	}, {
		name: "Roku Hentai",
		host: ["rokuhentai.com"],
		reg: /^https?:\/\/rokuhentai\.com\/\w+\/\d+$/,
		imgs: ".site-reader__image",
		button: [4],
		insertImg: [".site-reader", 2],
		customTitle: () => fn.title(" - Roku Hentai"),
		css: ".site-reader--right-to-left,.site-reader--left-to-right{overflow-x:auto !important;overflow-y:auto !important}.site-reader{padding-bottom:0px !important}.site-reader{display:block !important}",
		hide: ".site-bottom-ad-slot",
		category: "hcomic"
	}, {
		name: "177 漫画/XXIAV寫真館",
		url: {
			h: [/177pic/, "www.xxiav.com"],
			p: /^\/html\/\d+\/\d+\/\d+\.html$/
		},
		imgs: () => fn.getImg(".single-content img[data-lazy-src]", (fn.gt(".page-links>*:last-child", 2) || 1), 10),
		button: [4],
		insertImg: [".single-content", 2],
		autoDownload: [0],
		next: "a[rel=prev]",
		prev: "a[rel=next]",
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		name: "18H 宅宅愛動漫",
		host: ["18h.animezilla.com"],
		reg: /^https?:\/\/18h\.animezilla\.com\/manga\/\d+/,
		imgs: () => {
			let max = Number(fn.gu(".last")?.split("/")?.at(-1)) || 1;
			return fn.getImgO("#comic", max, "4", null, 0, ".entry-title,.wp-pagenavi", siteUrl, 0);
		},
		button: [4],
		insertImg: ["#page-current", 1],
		customTitle: () => fn.dt({
			s: "h1.entry-title",
			d: /\s?\[\d+P\](\s?-\s?\d+\/\d+\s?)?/i
		}),
		category: "hcomic"
	}, {
		name: "色漫網",
		host: ["www.cartoon18.com", "www.cartoon18.org"],
		url: {
			h: "cartoon18",
			p: "/v/",
			e: ".title+div>a.btn-info"
		},
		box: [".row.mb-4", 2],
		imgs: () => {
			fn.sm5();
			let urls = fn.gau(".title+div>a.btn-info");
			return fn.getImgA("img[data-src],#lightgallery a,.gallary a", urls, 2000);
		},
		button: [4],
		insertImg: ["box", 3],
		hide: "#chromeModal,.modal-backdrop,#_iconsTop,#_iconsBottom,#_imageBottom",
		category: "hcomic"
	}, {
		name: "色漫網",
		url: {
			h: "cartoon18",
			p: "/v/",
			e: ".title+div>a>i.fa-play"
		},
		imgs: () => {
			fn.sm5();
			let url = fn.gu(".title+div>a");
			return fn.fetchDoc(url).then(dom => fn.ge("img[data-src]", dom) ? fn.gae("img[data-src]", dom) : fn.gae("#lightgallery a,.gallary a", dom));
		},
		button: [4],
		insertImg: ["//div[a[img]]", 2],
		insertImgAF: (parent) => {
			parent.className = "";
			let modalOpen = fn.ge(".modal-open");
			if (modalOpen) modalOpen.classList.remove("modal-open");
		},
		hide: "#chromeModal,.modal-backdrop,#_iconsTop,#_iconsBottom,#_imageBottom",
		category: "hcomic"
	}, {
		name: "色漫网",
		host: ["www.cartoon18.com"],
		reg: /^https?:\/\/www\.cartoon18\.com\/([\w-]+\/)?story\/\d+\/full/,
		imgs: () => fn.ge("img[data-src]") ? fn.gae("img[data-src]") : fn.gae("#lightgallery a,.gallary a"),
		button: [4],
		insertImg: ["#lightgallery,.gallary", 2],
		autoDownload: [0],
		next: "//a[text()='下一話']",
		prev: "//a[text()='上一話']",
		hide: "#_iconsTop,#_iconsBottom,#_imageBottom",
		category: "hcomic"
	}, {
		name: "H漫/禁漫岛",
		host: ["hman91.com", "jmd8.com"],
		url: {
			t: ["H漫", "禁漫岛"],
			p: ["/manga-read/", "/manga/"],
			ee: ".page-title"
		},
		imgs: "#main .content img",
		button: [4],
		insertImg: [".content center:has(>div>img)", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][@href]",
		prev: "//a[text()='上一章'][@href]",
		chapters: {
			url: "//a[text()='章节目录']",
			target: ".module-tab~.module-blocklist a"
		},
		customTitle: ["#main h1", "#main h2"],
		category: "hcomic"
	}, {
		name: "开心看漫画",
		host: ["kxmanhua.com"],
		url: {
			t: "开心看漫画",
			p: "/detail/"
		},
		imgs: ".blog__details__content img",
		button: [4],
		insertImg: [".blog__details__content", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='下一话'][@href]",
		prev: "//a[text()='上一话'][@href]",
		chapters: {
			url: ".view-fix-top-bar a",
			target: ".chapter_list a",
			sort: "r"
		},
		customTitle: () => fn.ge("meta[name='manga-name']").content + " - " + fn.ge("meta[name='chap-title']").content,
		hide: ".fixed-ads,.ad-banner,.blog__details__content~*",
		category: "hcomic"
	}, {
		name: "肉肉漫画/凹凸漫/X漫/肉漫天堂/天堂禁漫/大鸟禁漫",
		host: ["18rouman.org", "atm166.org", "xman8.org", "rmtt7.com", "ttjm7.com", "daniao8.com"],
		url: {
			t: ["肉肉漫画", "凹凸漫", "X漫", "肉漫天堂", "天堂禁漫", "大鸟禁漫"],
			p: "read/",
			e: ["center>h1", "center>h2"]
		},
		init: () => fn.clearAllTimer(),
		imgs: "img.lazyload[data-original]",
		button: [4],
		insertImg: ["center:has(>div>img.lazyload[data-original])", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: "//a[text()='章节目录']",
			target: ".stui-content__playlist a,#playlistbox .content_playlist a,.episode-list a"
		},
		customTitle: async () => fn.dt({
			t: await getTitle(["center>h1", "center>h2"]),
			d: " - 全集"
		}),
		category: "hcomic"
	}, {
		name: "漫畫大濕",
		host: ["mhdashi.com", "mhds8.com"],
		url: {
			t: "漫畫大濕",
			p: "/manhua/"
		},
		box: [".gm-read center:has(h2)", 2],
		imgs: ".gm-read>img",
		button: [4],
		insertImg: [
			["box", 0, ".gm-read>img"], 2
		],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: "//a[text()='章節目錄']",
			target: ".title+.list a",
			sort: "r"
		},
		customTitle: ".gm-read h2",
		category: "hcomic"
	}, {
		name: "韓漫射/绅士同人H漫",
		url: {
			h: ["h-webtoon.com", "h-doujinshi.xyz"]
		},
		init: "setTimeout(()=>{fn.gae('.g1-nav-single a').forEach(e=>{e.removeAttribute('target')})},2000)",
		imgs: ".g1-content-narrow p img",
		button: [4],
		insertImg: [".g1-content-narrow", 2],
		autoDownload: [0],
		next: "#content .g1-teaser-next",
		prev: "#content .g1-teaser-prev",
		customTitle: "h1.entry-title",
		hide: "#simple-banner,.touchy-wrapper,.touchy-wrapper~*:not([id^='Full'],[class^='Full'],[id^='pv-'],[class^='pv-'],[id^='pagetual'],[class^='pagetual'],#comicRead,#fab,*[class^=fancybox]),.code-block,#secondary",
		category: "hcomic"
	}, {
		name: "拷贝漫画/爱漫画/韩漫之家",
		url: {
			h: ["kaobeimanhua.com", "love-mh.com", "hmzhijia.com"],
			p: "/chapter",
			s: "Id="
		},
		imgs: "#cp_img img,.showimg img,.lazyimg",
		button: [4, 3],
		insertImg: ["#cp_img,.showimg,.center:has(.lazyimg)", 2],
		autoDownload: [0],
		np: (s) => {
			let url = fn.gu(s);
			if (isString(url) && fn.url != url) {
				return url;
			}
			return null;
		},
		next: () => _this.np("a[href]:has(>img[alt^=下]),a.next[href*=chapter],a:has(i.icon-108)"),
		prev: () => _this.np("a[href]:has(>img[alt^=上]),a.prev[href*=chapter],a:has(i.icon-109)"),
		chapters: () => {
			if (fn.lh == "kaobeimanhua.com") {
				return fn.getChapters({
					url: "//a[p[text()='目录']]",
					target: "#detail-list-select a"
				});
			} else if (fn.lh == "love-mh.com") {
				return fn.getChapters({
					target: "#listtext~li[id]>a"
				});
			} else if (fn.lh == "hmzhijia.com") {
				return fn.getChapters({
					url: "//a[text()='返回目录']",
					target: "#a_link a",
					textNode: "p"
				});
			}
		},
		customTitle: () => fn.dt({
			s: ".view-fix-top-bar-title,.showimg h1,.center p",
			d: "当前漫画章节为:",
			r: [
				["漫画", " "]
			]
		}),
		css: "div:has(>.view-fix-top-bar),.view-fix-top-bar{z-index:100!important}",
		category: "hcomic"
	}, {
		name: "18H漫画",
		host: ["18hmanga.com", "18hmanga.cyou"],
		reg: /^https?:\/\/(18hmanga\.(com|cyou))\/[^\/]+\/$/,
		init: () => fn.remove(".code-block,#secondary,body>div[id][class][style]"),
		imgs: ".entry-content>img,.entry-content>p>img,.entry-content>div>img",
		button: [4],
		insertImg: [".entry-content", 2],
		autoDownload: [0],
		next: "#content .g1-teaser-prev",
		prev: "#content .g1-teaser-next",
		customTitle: ".entry-title",
		css: ".g1-column-2of3{width:100%!important}",
		category: "hcomic"
	}, {
		name: "18H漫画",
		url: {
			h: "18hmanga",
			e: "//a[contains(text(),'Read More')]"
		},
		init: () => fn.remove("body>div[id][class][style]"),
		imgs: () => {
			fn.sm1();
			let fetchNum = 0;
			let resArr = fn.gau("//a[contains(text(),'Read More')]").map((url, i, arr) => {
				return fn.fetchDoc(url).then(dom => {
					fn.showMsg(`${DL.str_02}${fetchNum+=1}/${arr.length}`, 0);
					return fn.gae(".entry-content>img,.entry-content>p>img,.entry-content>div>img", dom);
				});
			})
			return Promise.all(resArr).then(arr => arr.flat());
		},
		button: [4],
		insertImg: [
			["#primary", 0], 2
		],
		customTitle: ".g1-breadcrumbs-item>span[itemprop=name]",
		category: "hcomic"
	}, {
		name: "老司機禁漫",
		host: ["laosiji6.com", "laosijix.org"],
		url: {
			h: "laosiji",
			p: /^\/comic\/\d+\/\w+$/i
		},
		init: () => {
			let [, a] = fn.gae(".breadcrumb a");
			return fn.fetchDoc(a).then(dom => fn.gae(".vol-item a", dom).reverse()).then(chapters => (siteJson.chapters = chapters));
		},
		box: ["img.lazy", 1],
		imgs: "img.lazy",
		button: [4],
		insertImg: [
			["box", 0, "img.lazy"], 2
		],
		insertImgAF: () => {
			if (nextLink && !fn.ge("//a[text()='章節目錄']")) {
				fn.addUrlHtml(nextLink, ".container-fluid", 2);
				fn.css(".positionFooter{display:none!important;}");
			}
		},
		autoDownload: [0],
		np: (i) => {
			let id = fn.lp.split("/").at(-1);
			let ci = siteJson.chapters.findIndex(a => a.href.endsWith(id));
			let a = siteJson.chapters[ci + i];
			return isEle(a) ? a.href : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(a => ({
			text: a.text,
			url: a.href
		})),
		customTitle: [".breadcrumb-item:nth-child(2) a", ".breadcrumb-item.active"],
		category: "hcomic"
	}, {
		name: "COMIC18",
		host: ["www.comic18.cc"],
		reg: /^https?:\/\/www\.comic18\.cc\/\w+\/\d+\.html$/,
		init: () => fn.waitEle(".article-body>img").then(e => fn.createImgBox(e, 1)),
		imgs: ".article-body>img",
		button: [4],
		insertImg: [
			["box", 0, ".article-body>img"], 2
		],
		autoDownload: [0],
		next: "a.entry-page-prev[href$=html]",
		prev: "a.entry-page-next[href$=html]",
		customTitle: ".detail-title",
		category: "hcomic"
	}, {
		name: "18漫畫",
		host: ["18mh.org"],
		reg: [
			/^https?:\/\/badynews\.com\/[^\/]+$/i,
			/^https?:\/\/18mh\.org\/manga\/[\w-]+\/[\d-]+/
		],
		init: () => fn.waitEle(".touch-manipulation img").then(() => fn.remove(".flex.flex-row.space-x-2.px-2.py-4")),
		imgs: ".touch-manipulation img",
		button: [4],
		insertImg: [".touch-manipulation", 2],
		autoDownload: [0],
		next: "#nextChapterLink",
		prev: "#preChapterLink",
		chapters: {
			api: () => {
				let id = fn.ge("#chapterContent").dataset.ms;
				return `/manga/get?mid=${id}&mode=all`;
			},
			target: "#allchapterlist a",
			cb: (t, url, e) => ({
				text: e.dataset.ct,
				url
			})
		},
		customTitle: ["ol.inline-flex>li:nth-child(2) a", "ol.inline-flex>li:nth-child(3) a"],
		category: "hcomic"
	}, {
		name: "热漫画",
		url: {
			t: ["Rehanman", "rehanman"],
			h: "rehanman.com"
		},
		page: () => fn.clp("/webtoon/"),
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => {
			if (!_this.page()) return [];
			let [, , id] = fn.clp().split("/");
			let body = {
				query: "\n  query entry($id: ID, $inputs: InputEntries) {\n    entry (_id: $id, inputs: $inputs ){\n      _id, \n      title,\n      alt_title,\n      description,\n      title_normalized,\n      adult,\n      released_year,\n      status,\n      thumbnail,\n      type,\n      authors { name },\n      genres { name },\n      created_date,\n      modified_date,\n      rating,\n      rating_votes,\n      views,\n      volumes { id, chapters_count }\n      entries_data { _id, chapters {name, title, index, images}, volume_name }\n      entries_setting { _id, premium, entryId, isHide, countRead }\n    }\n  }\n",
				variables: {
					inputs: {
						title_normalized: id
					}
				}
			};
			fn.sm5();
			return fn.j("https://api.rehanman.com/manga-graphql", {
				"headers": {
					"content-type": "application/json"
				},
				"body": JSON.stringify(body),
				"method": "POST"
			}).then(json => {
				apiCustomTitle = json.data.entry.title;
				return json.data.entry.entries_data.chapters.map(e => e.images).flat().map(e => "https://img.rehanman.com/uploads/data/china18sky/" + e);
			});
		},
		capture: () => _this.imgs(),
		category: "hcomic"
	}, {
		name: "NyaHentai",
		url: {
			h: ["nyahentai.re", "shikotch.in", "doujinantena.top"],
			p: ["/re", "/comic/"]
		},
		imgs: "#post-comic img",
		button: [4],
		insertImg: ["#post-comic", 2],
		customTitle: "#post-data h1",
		hide: "[id*='_ad_'],div:has(>iframe),[id^='bnc_ad'],[class*='-ads-']",
		category: "hcomic"
	}, {
		name: "Hitomi.la",
		url: {
			h: ["hitomi.la"]
		},
		page: () => !!fn.ge("#read-online-button[href^='/reader/']:not([style])"),
		SPA: () => _this.page(),
		observeURL: "loop",
		MutationObserver: () => {
			document.body.removeAttribute("class");
			fn.remove(_this.hide);
		},
		imgs: () => _this.page() ? fn.sm5().then(() => fn.iframeVar(fn.gu("#read-online-button"), "galleryinfo").then(frame => {
			const {
				galleryinfo,
				url_from_url_from_hash,
				our_galleryinfo
			} = frame;
			apiCustomTitle = fn.dt({
				t: galleryinfo.title,
				d: "| Hitomi.la"
			});
			thumbnailSrcArray = fn.gae(".gallery-preview img").map(e => e.dataset.src ?? e.src);
			return galleryinfo.files.map((e, i) => url_from_url_from_hash(galleryinfo.id, our_galleryinfo[i], hitomi_img_type));
		})) : [],
		button: [4],
		insertImgBF: () => fn.createImgBox(".content", 2),
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".thumbnail-list,.simplePagerNav"),
		hide: [
			"body~*:not(#DownloadAppUIRoot,[id^=Full],.viewer-container)",
			"body>ins",
			"body>iframe[referrerpolicy]",
			"body>div:not(.container):has(>iframe)",
			"div:not(.container,.content):has(>ins)",
			"div:not(.container,.content):has(>div[id^=exo])",
			"div:not(.container,.content):has(>[data-cl-spot])",
			"div:not(.container,.content):has(>script):has(iframe)",
			"div:not(.container,.content):has(>[data-clickadilla-banner])"
		],
		category: "hcomic"
	}, {
		name: "NyaHentai/MoeImg/Hitomi/HitomiKR",
		url: {
			h: ["nyaa.fan", "moeimg.fan", "hitomi.si", "hitomikr.org", "hitomi.jp.net"]
		},
		page: () => ["/post/", "/g/", "/mangazine/"].some(p => fn.clp(p)),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.sm5().then(() => {
			let [id] = fn.clp().match(/\d+$/);
			let res_a = fn.j(`/spa/manga/${id}`);
			let res_b = fn.j(`/spa/manga/${id}/read`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b
				};
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				preview_imgs: {
					pages
				},
				chapter_detail: {
					server,
					chapter_content
				},
				detail: {
					manga_name
				}
			} = siteJson;
			thumbnailSrcArray = Object.values(pages).flat();
			let temp = fn.html(chapter_content);
			return fn.gae(".chapter-img canvas[data-srcset],.chapter-img img[data-url]", temp).map(e => server + (e.dataset.srcset || e.dataset.url));
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.detail.manga_name : null,
		category: "hcomic"
	}, {
		name: "HentaiCamp",
		url: {
			h: ["hentaicamp.com"]
		},
		page: () => fn.clp("/hc/") && fn.clp()?.split("/")?.length === 3,
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => {
			let url = `https://api.hentaicamp.com/api${fn.clp()}/load-more-images?show_all=true`;
			let res_a = fn.j(url).then(json => (siteJson = json));
			return Promise.all([res_a, fn.rd()]);
		},
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let s = "https://api.hentaicamp.com/storage/";
			thumbnailSrcArray = siteJson.images.map(e => s + e.small_image_path);
			return siteJson.images.map(e => s + e.image_path);
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.gt(".card-title", 1, doc) : null,
		category: "hcomic"
	}, {
		name: "Hentaiser",
		url: {
			h: ["app.hentaiser.com"]
		},
		page: () => fn.clp("/book/"),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.sm5().then(() => {
			let [, , id] = fn.clp().split("/");
			let res_a = fn.j("https://api.hentaiser.com/1.3/books/" + id);
			let res_b = fn.j("https://api.hentaiser.com/1.3/books/" + id + "/pages");
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b
				};
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				host,
				pages
			} = siteJson;
			return pages.map(e => host + e);
		},
		button: [4],
		insertImgBF: () => fn.waitEle("#detailsSection,.section--bg+.section").then(e => fn.createImgBox(e, 2)),
		insertImg: ["box", 2],
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.title : null,
		category: "hcomic"
	}, {
		name: "Ninekon",
		url: {
			h: ["app.ninekon.com"]
		},
		page: () => fn.clp("/chapter/"),
		SPA: () => _this.page(),
		observeURL: "nav",
		data: () => fn.sm5().then(() => {
			let [, , mid, , cid] = fn.clp().split("/");
			let res_a = fn.j(`https://api.ninekon.com/1.0/books/${mid}`);
			let res_b = fn.j(`https://api.ninekon.com/1.0/books/${mid}/chapters/${cid}/pages`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b,
					mid,
					cid
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				host,
				pages
			} = siteJson;
			return pages.map(e => host + e);
		},
		button: [4],
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let ci = siteJson.chapters.findIndex(e => e.gid == siteJson.cid);
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? fn.wurl(o.gid, fn.clp(), -2) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			gid,
			ordinal
		}) => ({
			text: `Chapter ${ordinal}`,
			url: fn.wurl(gid, fn.clp(), -2)
		})),
		customTitle: () => _this.page() ? `${siteJson.title} - Chapter ${siteJson.chapters.find(e => e.gid == siteJson.cid).ordinal}` : null,
		category: "comic"
	}, {
		name: "KOMI",
		url: {
			h: ["komi.la"]
		},
		page: () => fn.clp("/manga/"),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.sm5().then(() => {
			let [, , id] = fn.clp().split("/");
			let url = "/api/galleries/" + id;
			return fn.j(url).then(json => (siteJson = json) && fn.hm());
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.images.map(e => e.url);
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.title : null,
		category: "hcomic"
	}, {
		name: "리토미",
		url: {
			h: ["litomi.in"]
		},
		home: "/new/1",
		page: () => fn.clp(/\/manga\/\d+/),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.sm5().then(() => {
			let id = fn.clp().split("/").at(-1);
			let url = `/api/proxy/manga/${id}?`;
			return fn.j(url).then(json => (siteJson = json) && fn.hm());
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.images.map(e => e.original.url);
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.title : null,
		category: "hcomic"
	}, {
		name: "Doujin.sexy",
		url: {
			h: ["doujin.sexy"]
		},
		page: () => fn.clp("/read/"),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.sm5().then(() => {
			let [, , id] = fn.clp().split("/");
			let url = `https://api.doujin.sexy/v3/album/${id}/pages?token=OJ9X057amA`;
			return fn.j(url).then(json => (siteJson = json) && fn.hm());
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.data.pages.map(e => e.sizes.full);
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.data.title : null,
		category: "hcomic"
	}, {
		name: "app.rule34.dev",
		url: {
			h: ["app.rule34.dev"]
		},
		page: () => fn.clp("/manga/g/"),
		SPA: () => _this.page(),
		observeURL: "nav",
		data: () => fn.rd().then(() => {
			let code = fn.gst("pageProps", doc);
			let json = JSON.parse(code);
			siteJson = json.props.pageProps;
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				pages: {
					host,
					pages
				}
			} = siteJson
			return pages.map(e => host + e);
		},
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? fn.getText("#__next h1", doc) : null,
		category: "hcomic"
	}, {
		name: "Vinahentai",
		url: {
			h: ["www.vinahentai.com", "vinahentai.com"],
			p: "/chapter/"
		},
		init: () => fn.getChapters({
			url: "nav a[href^='/truyen-hentai/']",
			target: "#manga-description-section+div>.relative>div>a",
			textNode: "span",
			sort: "r"
		}).then(chapters => {
			siteJson = {
				chapters
			};
		}),
		imgs: () => {
			let code = fn.gst("enqueue");
			code = code.replace("window.__reactRouterContext.streamController.enqueue", "JSON.parse").replaceAll(";", "");
			let srcs = fn.run(code).filter(e => {
				if (isString(e)) {
					if (e.includes("/manga-images/")) {
						return true;
					}
				}
				return false;
			})
			return srcs;
		},
		capture: () => _this.imgs(),
		np: (i) => {
			let cs = siteJson.chapters;
			let ci = cs.findIndex(o => o.url == fn.url);
			let ti = ci + i;
			return isObject(cs[ti]) ? cs[ti].url : null;
		},
		autoDownload: [0],
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters,
		customTitle: ["nav>ol>li>a,nav>ol>li>span", 2, 4],
		category: "hcomic"
	}, {
		name: "HentaiVn",
		host: ["www.hentaivnx.com", "www.hentaivnx.net", "hentaivnx.vip"],
		url: {
			t: "HentaiVn",
			p: "/chapter"
		},
		imgs: ".page-chapter img",
		button: [4],
		insertImg: [".reading-detail", 2],
		autoDownload: [0],
		next: "a.next:not([href='#'])",
		prev: "a.prev:not([href='#'])",
		chapters: () => fn.j("/Comic/Services/ComicService.asmx/ProcessChapterList?comicId=" + fn.attr(".chapter-id", "data-cid")).then(json => json.chapters.map(({
			name,
			url
		}) => ({
			text: name,
			url
		})).reverse()),
		customTitle: [".breadcrumb span[itemprop=name]", 2, 3],
		hide: ".banners-all",
		category: "hcomic"
	}, {
		name: "PORN-COMIX.com",
		url: {
			h: "porn-comix.com",
			p: "/comics"
		},
		box: [".list_comic_book_pages", 1],
		imgs: ".list_comic_book_pages img",
		button: [4],
		insertImg: [
			["box", 0, ".list_comic_book_pages"], 2
		],
		customTitle: ".comic_information h1",
		category: "hcomic"
	}, {
		name: "SXKOMIX.com/SEXKOMIX2.com",
		url: {
			h: ["sxkomix.com", "sexkomix2.com"],
			p: "/comics"
		},
		home: "/home/",
		box: ["#comix_pages_ul", 1],
		imgs: "#comix_pages_ul img",
		button: [4],
		insertImg: [
			["box", 0, "#comix_pages_ul"], 2
		],
		customTitle: () => fn.dt({
			s: "#comix_description h1",
			d: "by sexkomix2.com."
		}),
		category: "comic"
	}, {
		name: "porncomicsworld.com",
		url: {
			h: ["porncomicsworld.com", "bonsporn.com", "sex-comixxx.com", "flash-porno.com", "porno-multiki.com"],
			p: "/comics"
		},
		box: ["#block-image-slide", 2],
		imgs: "#block-comix-grid img,#block-image-slide img",
		button: [4],
		insertImg: [
			["box", 0, "ul:has(#block-comix-grid),#block-image-slide"], 2
		],
		customTitle: "#block-comix-grid h1",
		category: "hcomic"
	}, {
		name: "хентай манга",
		host: ["a1.nude-moon.mom"],
		url: {
			e: "//div[text()='хентай манга']",
			p: "/online/"
		},
		imgs: ".page__player img",
		button: [4],
		insertImg: [".page__player", 2],
		customTitle: ".page__main h1",
		category: "hcomic"
	}, {
		name: "Хентай-тян!",
		host: ["hentaichan.live", "xxl.hentaichan.live", "hentaichan.pro", "x.hentaichan.pro", "hentai-chan.pro", "x4.h-chan.me"],
		url: {
			e: ["#thumbs img"],
			p: "/online/",
			s: "cacheId"
		},
		box: ["#thumbs", 1],
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr("#thumbs img");
			return thumbnailSrcArray.map(e => e.replace("_thumbs", ""));
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#thumbs"),
		customTitle: ".manga-title",
		category: "hcomic"
	}, {
		name: "Хентай-тян!",
		url: {
			h: "hentaichan.lat",
			p: "/online/"
		},
		imgs: ".page__player img",
		button: [4],
		insertImg: [".page__player", 2],
		customTitle: ".page__main h1",
		category: "hcomic"
	}, {
		name: "HentaiFC",
		url: {
			h: "hentaifc.com",
			p: /^\/e\/\d+$/
		},
		box: [".thumbs", 2],
		imgs: () => {
			fn.sm5();
			thumbnailSrcArray = fn.getImgSrcArr(".thumbs img");
			let url = fn.gu("//div[@class='thumbs']/a[text()=' Read Online']");
			return fn.iframe(url, {
				hide: true,
				wait: (_, frame) => {
					if (isArray(frame?.ytaw)) {
						let [e] = frame.ytaw;
						if (e?.startsWith("http")) return true;
					}
					return false;
				}
			}).then(({
				frame
			}) => frame?.ytaw || []);
		},
		button: [4],
		insertImg: ["box", 2],
		customTitle: ".info .meta .value",
		category: "hcomic"
	}, {
		name: "MangaXL",
		url: {
			h: "mangaxl.com",
			s: "read_manga"
		},
		init: () => fn.waitEle(".all-pages-dialog__content-list>.active"),
		imgs: () => fn.getImgA(".pages-slider__wrapper>img", ".all-pages-dialog__content-list>a:not(.active)"),
		button: [4],
		insertImg: [".pages-slider__wrapper", 2],
		customTitle: ".read-page__header-title",
		category: "hcomic"
	}, {
		name: "Doujin.li",
		url: {
			h: ["doujin.li"]
		},
		json: () => {
			fn.sm5();
			let gid = fn.clp().split("/").at(2);
			return fn.j(`https://backend.doujin.li/media?id=${gid}`).then(json => {
				siteJson = json;
				fn.hm();
			});
		},
		page: () => fn.clp("/manga/") && fn.clp().split("/").length == 4,
		init: () => _this.page() ? _this.json() : void 0,
		SPA: () => _this.page(),
		observeURL: "head",
		imgs: () => fn.arr(siteJson.pages_number, (v, i) => `https://media.doujin.li/doujins/${siteJson.id}/${i}.webp`),
		capture: () => _this.imgs(),
		customTitle: () => _this.page() ? siteJson.name : null,
		category: "hcomic"
	}, {
		name: "TruyenHentaiVN",
		host: ["truyenhentaivn.club"],
		url: {
			e: [".site-logo img[alt=TruyenHentaiVN]", ".chapter-content", "h1.name"]
		},
		imgs: ".chapter-content img",
		button: [4],
		insertImg: [".chapter-content", 2],
		autoDownload: [0],
		next: "//a[text()='Chap sau ']",
		prev: "//a[text()=' Chap trước']",
		chapters: {
			url: ".rank-math-breadcrumb a",
			urlIndex: 1,
			target: ".chap-list a",
			textNode: ".name",
			sort: "r"
		},
		customTitle: () => fn.dt({
			s: "h1.name",
			d: " - Oneshot"
		}),
		hide: "body>div[style]:has(a[href$=go])",
		category: "hcomic"
	}, {
		name: "TruyenHentaiVN AD",
		url: {
			e: ".site-logo img[alt=TruyenHentaiVN]"
		},
		hide: "body>div[style]:has(a[href$=go])",
		category: "ad"
	}, {
		name: "HentaiThai",
		url: {
			h: "hentaithai.com"
		},
		imgs: "#part-image img",
		button: [4],
		insertImg: ["#part-image", 2],
		customTitle: "#doujin-detail h1",
		category: "hcomic"
	}, {
		name: "เทพโดจิน",
		url: {
			h: "lnwdoujin.com",
			e: "#comic-reader-zone"
		},
		imgs: () => Object.values(JSON.parse(document.querySelector("#comic-reader-zone").getAttribute("img-code"))).map(e => {
			if (e?.sizes?.full?.includes("hentaithai")) {
				return "https://lnwdoujin.com/showimg.php?url=" + e.sizes.full;
			}
			return e?.sizes?.full;
		}),
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: "#main h1",
		category: "hcomic"
	}, {
		name: "HO5HO",
		url: {
			h: "www.ho5ho.com",
			st: "chapter_preloaded_images"
		},
		imgs: () => _unsafeWindow.chapter_preloaded_images,
		button: [4],
		insertImg: [".entry-content", 2],
		customTitle: ".breadcrumb>li:nth-child(2)",
		category: "hcomic"
	}, {
		name: "H漫画",
		host: ["a.123548.xyz"],
		url: {
			e: "//div[@class='logo']/a[text()='H漫画']",
			p: "/e/action/ShowInfo.php"
		},
		imgs: ".entry img",
		button: [4],
		insertImg: [".entry", 1],
		autoDownload: [0],
		next: "//p[contains(text(),'上一')]/a",
		prev: "//p[contains(text(),'下一')]/a",
		customTitle: ".contitle",
		category: "hcomic"
	}, {
		name: "JComic",
		host: ["jcomic.net"],
		reg: /^https?:\/\/jcomic\.net\/page\/[^\/]+$/,
		imgs: ".comic-view,.comic-thumb",
		button: [4],
		insertImg: ["//div[img[@class='img-responsive comic-thumb']]", 2],
		customTitle: "//ol/li[2]/a",
		category: "hcomic"
	}, {
		name: "JComic",
		host: ["jcomic.net"],
		reg: /^https?:\/\/jcomic\.net\/page\/[^\/]+\/[0-9\.]+$/,
		imgs: ".comic-view,.comic-thumb",
		button: [4],
		insertImg: ["//div[img[@class='img-responsive comic-thumb']]", 2],
		next: "//a[button[text()='下一章']]",
		prev: "//a[button[text()='上一章']]",
		customTitle: ["//ol/li[2]/a", "//ol/li[3]"],
		category: "hcomic"
	}, {
		name: "哇嘎哒/一之涩/哈塔兹/布罗塔/物二/奥特",
		host: ["www.wgada.com", "1zse.com", "hatazi.com", "www.bulota.com", "aotem.org", "522160.xyz"],
		url: {
			t: ["一之涩", "哈塔兹", "布罗塔", "物二", "奥特", "哇嘎哒"],
			p: /^\/index\.php\/\d+\.html/
		},
		init: () => {
			fn.addMutationObserver(() => fn.remove("#eruda,.__chobitsu-hide__,#lightboxOverlay,#lightbox"));
			fn.clearAllTimer();
		},
		imgs: () => fn.getImg(".context img", fn.gt(".pages")?.match(/\d+/g)[1] || fn.gt(".pagelist a:last-child"), 7),
		button: [4],
		insertImg: [".context", 2],
		autoDownload: [0],
		next: ".post-previous a",
		prev: ".post-next a",
		customTitle: () => fn.dt({
			s: "#content h1",
			d: /\[\d+P\]|〈|〉/gi
		}),
		hide: "body>*:not(#head,.container,#footer,#tbox,[id^='Full'],[class^='Full'],[id^='pv-'],[class^='pv-'],#comicRead,#fab,*[class^=fancybox])",
		category: "hcomic"
	}, {
		name: "杜牙/那露/勇吉拉/汉库克",
		host: ["www.duteya.com", "naluhd.com", "www.yojila.com", "www.hakuk.com"],
		url: {
			t: ["杜牙", "那露", "勇吉拉", "汉库克"],
			p: /^\/index\.php\/\d+\.html/
		},
		imgs: () => fn.getImgA(".article-content img", "a.post-page-numbers", 300),
		button: [4],
		insertImg: [".article-content", 2],
		autoDownload: [0],
		next: "//a[p[text()='上一篇'] and not(starts-with(@href,'java'))]",
		prev: "//a[p[text()='下一篇'] and not(starts-with(@href,'java'))]",
		customTitle: ".article-title>a",
		category: "hcomic"
	}, {
		name: "韩漫库/H萌漫画",
		host: ["se8.us", "comic.hmgal.com"],
		url: {
			t: ["韩漫库", "H萌漫画"],
			p: ["/chapter/"]
		},
		imgs: ".rd-article-wr img,.comic-list img",
		button: [4],
		insertImg: [".rd-article-wr,.comic-list", 1],
		autoDownload: [0],
		next: ".j-rd-next[_href*='/chapter/'],.next-chapter[_href*='/chapter/']",
		prev: ".j-rd-prev[_href*='/chapter/'],.prev-chapter[_href*='/chapter/']",
		chapters: () => isPC ? fn.getChapters({
			target: ".catalog__list a",
			textNode: ".comic-title"
		}) : fn.getChapters({
			url: "a:has(>.i-rd-mid)",
			target: ".catalog-list a"
		}),
		customTitle: () => {
			if (isPC) {
				return getTitle([".read__crumb a", 1, 2]);
			}
			let code = fn.gst("shareArr");
			let s = code.indexOf("《");
			let e = code.indexOf("》", s);
			let mn = code.slice(s + 1, e);
			return mn + " - " + fn.gt(".comic-name");
		},
		hide: "body>ins,div[id^='show'],a[onclick],.download-button",
		category: "hcomic"
	}, {
		name: "TIBIU漫画",
		host: ["comic.tibiu.net"],
		url: {
			t: "TIBIU漫画",
			p: "/chapter/"
		},
		init: () => {
			let [, , mid, cid] = fn.lp.split("/");
			let apis = [
				"/index.php/api/data/chapter?mid=" + mid,
				"/index.php/api/data/pic?cid=" + cid
			];
			let resArr = apis.map(api => fn.j(api));
			return Promise.all(resArr).then(([a, b]) => {
				siteJson = {
					mid,
					cid,
					title: fn.dt({
						s: ".j-comic-title,.comicname-info"
					}),
					chapters: a.data.sort((a, b) => a.xid - b.xid),
					images: b.data.sort((a, b) => a.id - b.id),
				};
			});
		},
		imgs: () => siteJson.images.map(e => e.img),
		button: [4, 3],
		insertImg: [".rd-article-wr,#maincomiccontainer", 1],
		autoDownload: [0],
		current: () => {
			let data = siteJson.chapters.find(o => o.id == siteJson.cid);
			let index = siteJson.chapters.findIndex(o => o.id == siteJson.cid);
			return {
				data,
				index
			};
		},
		np: (i) => {
			let o = siteJson.chapters[_this.current().index + i];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			name,
			id
		}) => ({
			text: name,
			url: `/chapter/${siteJson.mid}/${id}`
		})),
		customTitle: () => siteJson.title + " - " + _this.current().data.name,
		category: "hcomic"
	}, {
		name: "爱漫画",
		url: {
			h: ["aicomic.org"],
			p: "/chapter/"
		},
		init: () => fn.addMutationObserver(() => fn.remove("//div[div[text()='x']]")),
		imgs: ".rd-article-wr img,.comic-list img:not([src$='empty.png'])",
		button: [4],
		insertImg: [".rd-article-wr,.comic-list", 2],
		autoDownload: [0],
		next: ".j-rd-next[_href^='/index'],.next-chapter[_href^='/index']",
		prev: ".j-rd-prev[_href^='/index'],.prev-chapter[_href^='/index']",
		chapters: () => isPC ? fn.getChapters({
			target: ".catalog__list a",
			textNode: ".comic-title"
		}) : fn.getChapters({
			url: "a:has(>.i-rd-mid)",
			target: ".chapter-item a",
			sort: "r"
		}),
		customTitle: () => {
			if (isPC) {
				let [, mn, cn] = fn.gat(".read__crumb a");
				return mn + " - " + cn;
			}
			let code = fn.gst("shareArr");
			let s = code.indexOf("《");
			let e = code.indexOf("》", s);
			let mn = code.slice(s + 1, e);
			return mn + " - " + fn.gt(".comic-name");
		},
		hide: ".image-container",
		category: "hcomic"
	}, {
		name: "91禁漫",
		host: ["www.91jinman.com"],
		reg: /^https?:\/\/www\.91jinman\.com\/\d+\.html/,
		imgs: ".wp-posts-content img",
		button: [4],
		insertImg: [".wp-posts-content", 2],
		autoDownload: [0],
		next: "//a[p[text()='上一篇']]",
		prev: "//a[p[text()='下一篇']]",
		customTitle: ".article-title",
		css: ".wp-posts-content{max-height:unset!important}",
		category: "hcomic"
	}, {
		name: "鸟鸟韩漫",
		host: ["nnhanman6.com"],
		url: {
			h: "nnhanman",
			p: "chapter",
			e: ".BarTit>h1"
		},
		imgs: "img[data-original]",
		button: [4],
		insertImg: ["//td[img] | //div[@class='view-imgBox']", 2],
		autoDownload: [0],
		next: "#k_Pic_nextArr",
		prev: "#k_Pic_upArr",
		chapters: {
			url: "#k_Pic_backArr",
			target: "#list a",
			sort: "r"
		},
		customTitle: () => fn.gt(".BarTit>h1").replace(" - 第1章", ""),
		category: "hcomic"
	}, {
		name: "A漫/大人漫画/肉漫屋/小鸟禁漫/龙禁漫",
		host: ["aman8.org", "darenmh.org", "rman8.com", "xiaoniao6.org", "xiaoniao2.xyz", "long6.org"],
		url: {
			t: ["A漫", "大人漫画", "肉漫屋", "小鸟禁漫", "龙禁漫"],
			p: ["/manhuaview/", "/comics-reading/", "/readbooks/", "/mg/", "/manhua/"]
		},
		imgs: "center:has(>div>img) img",
		button: [4],
		insertImg: ["center:has(>div>img)", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: "//a[text()='章节目录']",
			target: "#hl-plays-list a,.module-play-list-link"
		},
		customTitle: ["h1", "h2"],
		category: "hcomic"
	}, {
		name: "韩漫之家",
		host: ["www.aammhh.com"],
		url: {
			t: "韩漫之家",
			p: /^\/comic\/\d+\/\d+\.html$/
		},
		imgs: ".images img",
		button: [4],
		insertImg: [".images", 2],
		autoDownload: [0],
		next: "//a[text()='下一话'][contains(@href,'.html')]",
		prev: "//a[text()='上一话'][contains(@href,'.html')]",
		chapters: {
			url: "//a[text()='返回目录']",
			target: ".book-chapter a"
		},
		customTitle: async () => fn.dt({
			t: await getTitle([".breadcrumbs a,.breadcrumbs span", 1, 2]),
			d: [" - 韩国漫画"]
		}),
		category: "hcomic"
	}, {
		name: "欲漫乐园",
		host: ["www.sexacg.xyz"],
		url: {
			t: "欲漫乐园",
			p: "/vodplay",
			st: "imglist_string"
		},
		init: () => {
			fn.waitVar("MfXKwV").then(() => {
				setTimeout(() => {
					fn.clearAllTimer();
				}, 2000);
			});
			return fn.wait((d, w) => isArray(w?.imgscroll?.options?.img_list));
		},
		imgs: () => _unsafeWindow.imgscroll.options.img_list.map(e => e.url).filter(e => !e.includes("/themes/")),
		button: [4],
		insertImg: ["#conch-content", 2],
		autoDownload: [0],
		next: "#hl-plays-list li:has(.active)+li>a",
		prev: "//ul[@id='hl-plays-list']/li[a[@class='hl-text-conch active']]/preceding-sibling::li[1]/a",
		chapters: {
			target: ".hl-plays-list a"
		},
		customTitle: () => fn.ge("#hl-plays-list") ? getTitle([".hl-mob-name", "#hl-plays-list .active"]) : fn.gt(".hl-mob-name"),
		category: "hcomic"
	}, {
		name: "口工动漫网/邪的恶了鸟",
		url: {
			h: ["m.684c.com", "m.acg81.com"],
			p: [/^\/\d+_0\.html$/, /^\/\d+\.html$/]
		},
		clearEvent: true,
		imgs: () => {
			let [id] = fn.lp.match(/\d+/);
			let max = fn.gt("a[title=总数]>b", 1, doc);
			let links = fn.arr(max, (v, i) => `/${id}_${i}.html`);
			return fn.getImgA("div[id^=img] img", links);
		},
		button: [4],
		insertImg: [".c_box.box", 2],
		next: () => fn.gu("#pre", doc) || null,
		prev: () => fn.gu("#next", doc) || null,
		customTitle: () => fn.gt(".ptitle", 1, doc),
		category: "hcomic"
	}, {
		name: "口工动漫网/邪的恶了鸟",
		url: {
			h: ["m.684c.com", "m.acg81.com"]
		},
		clearEvent: true,
		category: "none"
	}, {
		name: "漫画精灵",
		url: {
			h: "www.manhuajl.com",
			p: /^\/\w+\/\d+\/$/
		},
		box: [".mnlt", 1],
		imgs: () => {
			let pages = fn.ge(".pagelist a");
			if (pages) {
				let [max] = fn.gt(pages).match(/\d+/);
				let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}index_${i + 1}.html`);
				return fn.getImgA("#imgshow img", links);
			}
			return fn.gae("#imgshow img");
		},
		button: [4],
		insertImg: [
			["box", 0, ".mnlt,.dede_pages_all"], 2
		],
		next: "#next[href]",
		prev: "#pre[href]",
		customTitle: "h1",
		category: "hcomic"
	}, {
		name: "漫画精灵M",
		url: {
			h: ["m.manhuajl.com"],
			p: /^\/\w+\/\d+\/$/
		},
		clearEvent: true,
		imgs: () => {
			let [max] = fn.gt(".showpage>a", 1, doc).match(/\d+/);
			let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : `${fn.lp}index_${i + 1}.html`);
			return fn.getImgA("#imgString img", links);
		},
		button: [4],
		insertImg: ["#imgString", 2],
		next: () => fn.gu("//a[text()='上一话']", doc) || null,
		prev: () => fn.gu("//a[text()='下一话']", doc) || null,
		customTitle: () => fn.gt(".ptitle", 1, doc),
		category: "hcomic"
	}, {
		name: "漫画精灵M",
		url: {
			h: ["m.manhuajl.com"]
		},
		clearEvent: true,
		category: "none"
	}, {
		name: "韩漫网",
		host: ["www.hanmanwang.com", "hanmanwang.com"],
		url: {
			t: "韩漫网",
			p: /^\/hanman-\d+\/\d+\.html$/
		},
		imgs: ".module img",
		button: [4],
		insertImg: [".module", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='详情']",
			target: ".module-play-list-link"
		},
		customTitle: ["nav div>div", 1, 2],
		category: "hcomic"
	}, {
		name: "楠楠漫画",
		host: ["nnmh.cc", "ttmh99.com", "nnmh.info", "nnboook.com"],
		url: {
			t: "楠楠漫画",
			p: /\/inforedit\/\d+\/\d+$/
		},
		imgs: ".item img",
		button: [4],
		insertImg: [".item", 2],
		autoDownload: [0],
		next: () => {
			let url = fn.gu(".next a");
			return /\/\d+\/\d+$/.test(url) ? url : null;
		},
		prev: ".prev a",
		chapters: async () => {
			let p = 1;
			let loop = true;
			let html = "";
			let id = fn.lp.split("/").at(-2);
			const get = () => {
				let params = fn.cp({
					type: "mh",
					id,
					p,
					sort: 0
				});
				return fn.j("/index.php?m=&c=book&a=getjino", {
					"headers": {
						"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
						"x-requested-with": "XMLHttpRequest"
					},
					"body": params,
					"method": "POST"
				}).then(json => {
					html += json.info;
					if (json.status == 0) {
						loop = false;
					}
				});
			};
			while (loop) {
				await get();
				p++;
			}
			html = fn.html(html);
			return fn.gae(".item a", html).map(a => {
				let text = a.outerText;
				if (text.includes("第")) {
					let i = text.indexOf("第");
					text = text.slice(i);
				}
				return {
					text,
					url: a.href
				};
			});
		},
		customTitle: () => {
			let text = fn.ge("meta[property='og\\:title']").content.split("/").at(-1);
			let m, c;
			if (text.includes("-")) {
				[m, c] = text.split("-");
			} else {
				[m, c] = text.split(" ");
			}
			m = m.split("/").at(0);
			return m + " - " + c;
		},
		hide: ".read-article>img",
		category: "hcomic"
	}, {
		name: "漫香阁",
		host: ["xn--wgv69rba1382b.com", "韩漫日漫.com"],
		url: {
			t: "漫香阁",
			p: /^\/content-[\w-]+\.html$/
		},
		imgs: "#contentimg img",
		button: [4],
		insertImg: ["#contentimg", 2],
		customTitle: ".services-desc",
		category: "hcomic"
	}, {
		name: "亲亲漫画",
		host: ["m.qinqinmanhua.xyz"],
		reg: /^https?:\/\/m\.qinqinmanhua\.xyz\/view\/\d+\.html/,
		imgs: ".showimg img",
		autoDownload: [0],
		next: ".BtnBox>.next[href*=view]",
		prev: ".BtnBox>.prev[href*=view]",
		customTitle: () => document.title.match(/《(.+)》/)[1],
		category: "hcomic"
	}, {
		name: "18H汉化漫画 詳情頁",
		host: ["manhua.sexbook.top", "18manga.top", "mt91.top", "kk4.top", "9xh.top", "v-m.top", "cr8.top"],
		url: {
			e: "//ul[@class='nav-main']//a[text()='18H汉化漫画'] | //a[text()='很色情的漫画'] | //a[text()='涩涩汉化漫画']",
			p: "/cont.php",
			s: "?id="
		},
		init: () => fn.waitEle(".article-content>h3,.article-title"),
		imgs: () => {
			let [max] = fn.gt("#td-Act+#td-Series,.meta+.meta .rounded-button99").match(/\d+/);
			let [, dir, , ex] = fn.gu("#content-id a,.article-tabs-content a:has(img)").match(/^(.+\/)(\d+)(\.\w+)$/);
			return fn.arr(max, (v, i) => dir + (i + 1) + ex);
		},
		button: [4],
		insertImg: [
			[".content", 0, ".article-content>a,.article-tabs-content a:has(img)"], 2
		],
		endColor: "white",
		customTitle: () => {
			let text = fn.gt(".article-content>h3,.article-title");
			if (text.includes("|")) {
				text = text.split("|")[1];
			}
			return fn.dt({
				t: text,
				d: "很色情的漫画-"
			});
		},
		css: ".single .content{margin-right:0px!important;}",
		hide: ".sidebar,.modown-ad",
		category: "hcomic"
	}, {
		name: "hanime1",
		host: ["hanime1.biz", "hanime1biz.github.io", "hanime1me.github.io"],
		info: "ani02.xyz不同模板",
		url: {
			e: [{
				s: "a.h1",
				t: "Hanime1.biz"
			}, ".blog_div"],
			p: /^\/book\/\d+$/
		},
		init: () => fn.waitEle(".blog_div a[href^='/book/'] img:not([src*='/cover'])"),
		imgs: () => {
			thumbnailSrcArray = fn.getImgSrcArr(".blog_div a[href^='/book/'] img:not([src*='/cover'])");
			return thumbnailSrcArray.map(e => e.replace(/t(\d+\.\w+)$/, "$1"));
		},
		capture: () => _this.imgs(),
		customTitle: ".blog_div h3",
		hide: ".container,.blog:has(h2.blog__title),.blog_div>a:not([href^='/book/'])",
		category: "hcomic"
	}, {
		name: "hanime1 AD",
		url: {
			e: [{
				s: "a.h1",
				t: "Hanime1.biz"
			}]
		},
		init: () => fn.addMutationObserver(() => {
			for (let e of fn.gae(".blog")) {
				if (["熱門推薦", "成人遊戲區"].some(k => e.textContent.includes(k))) {
					e.remove();
				}
			}
		}),
		observerClick: "button[aria-label=Close]",
		hide: ".container:not(:has(ul)),.blog:has(.blog_div.rounded),.blog a:not(.doujin,.blog__title):not(:has(span))",
		category: "ad"
	}, {
		name: "有色漫画网",
		host: ["yousemanhua.com"],
		reg: /^https?:\/\/yousemanhua\.com\/index\.php\/chapter\/\d+$/i,
		imgs: "img[data-original]:not([data-original*='empty.png'])",
		button: [4],
		insertImg: [".rd-article-wr,.chapter_content", 2],
		autoDownload: [0],
		next: "//a[contains(@class,'j-rd-next')][@_href] | //a[div[span[contains(text(),'下一篇')]]]",
		prev: "//a[contains(@class,'j-rd-prev')][@_href] | //a[div[span[contains(text(),'上一篇')]]]",
		chapters: () => isPC ? fn.getChapters({
			target: ".catalog__list a",
			textNode: ".comic-title"
		}) : fn.getChapters({
			url: ".nav_left a",
			target: ".catalog_list a",
			textNode: ".name"
		}),
		customTitle: () => isPC ? getTitle([".read__crumb a", 1, 2]) : fn.fetchDoc(fn.gu(".nav_left>a")).then(dom => fn.gt(".comic_name", 1, dom) + " - " + fn.gt(".chapter_title")),
		category: "hcomic"
	}, {
		name: "XXcomic",
		url: {
			h: "www.xxcomic.com",
			p: "/album/"
		},
		button: [4],
		imgs: () => {
			fn.sm5();
			let fetchNum = 0;
			let [id] = fn.lp.match(/\d+/);
			let max = fn.attr(".pager a", "title").match(/\d+/g).at(-1);
			let resArr = fn.arr(max, (v, i) => {
				if (i == 0) {
					return fn.fetchDoc(fn.lp).then(dom => {
						fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
						return fn.ge(".entry-content", dom).innerHTML;
					});
				} else {
					return fn.j(`/wp-admin/admin-ajax.php?action=theme_page_nagination_ajax&post-id=${id}&page=${i + 1}`).then(json => {
						fn.showMsg(`${DL.str_06}${fetchNum+=1}/${max}`, 0);
						return json.content;
					});
				}
			});
			return Promise.all(resArr).then(htmls => {
				let dom = fn.doc(htmls.join(""));
				return [...dom.images];
			});
		},
		insertImg: [".entry-content", 2],
		customTitle: ".entry-title",
		category: "hcomic"
	}, {
		host: ["kkcomic.vip", "51man.vip", "www.51comic.org", "book.51comic.org", "18comic.top", "www.18comic.bar", "www.yumanse.com", "91manwu.com", "maozhuamcn.com", "fumanwu.org"],
		url: () => {
			let check = fn.checkUrl({
				e: [".hl-logo-black", ".hl-logo-white"],
				p: "/artdetail"
			});
			return check ? fn.waitEle(".hl-article-title,.hl-show").then(() => !fn.ge(".hl-comic-box.hl-show")) : false;
		},
		init: () => fn.remove(".container:has(>#homeBannerWrap)"),
		imgs: ".hl-article-box img",
		button: [4],
		insertImg: [".hl-article-box", 2],
		autoDownload: [0],
		next: "//a[@class='hl-next'] | //a[span[text()='下一話']]",
		prev: "//a[@class='hl-prev'] | //a[span[text()='上一話']]",
		customTitle: () => fn.ge(".hl-mob-title") ? fn.gt(".conch-head-1>.hl-mob-title") + " - " + fn.gt(".conch-head-2>.hl-mob-title") : fn.gt(".hl-article-title"),
		hide: ".hl-banner-list,.hl-app-list,.hl-hidden-md",
		category: "hcomic"
	}, {
		name: "污污漫畫",
		host: ["www.55comic.com", "www.wu55comic.live", "www.comicbox.xyz", "www.wucomic.art"],
		url: {
			t: "污污漫畫",
			p: "/chapter/",
			e: "script[src*='merge_split_file']"
		},
		init: () => fn.remove("//div[div[@class='CarouselView center']]"),
		imgs: async () => {
			let p_arr = [];
			await fn.aotoScrollEles({
				scale: ".comiclist,#cp_img",
				ele: ".comiclist div[data-src],.cropped[data-src]",
				cb: (ele) => {
					let canvas = fn.ge("canvas", ele);
					if (isEle(canvas)) {
						if (["id", "class", "width", "height"].every(k => canvas.hasAttribute(k))) {
							p_arr.push(new Promise(resolve => canvas.toBlob((blob) => resolve(URL.createObjectURL(blob)), "image/jpeg", 0.9)));
							return true;
						}
					}
					return false;
				},
				top: 1
			});
			return Promise.all(p_arr);
		},
		button: [4],
		insertImg: [".comicpage,#cp_img", 0],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: () => isPC ? fn.getChapters({
			target: ".mCustomScrollBox a"
		}) : fn.getChapters({
			url: "//a[p[text()='目錄']]",
			target: ".chapter-list a"
		}),
		customTitle: ".title",
		customTitle: () => isPC ? fn.gt(".title") : fn.title(" - 污污漫畫"),
		hide: ".global-navbar",
		category: "hcomic"
	}, {
		name: "污漫天堂",
		host: ["wumtt.com"],
		url: {
			e: ".logo>a[title='污漫天堂']",
			p: "/mangaread/"
		},
		imgs: ".content>center>div>img",
		button: [4],
		insertImg: [".content>center>div:has(>img)", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: "//a[text()='章节目录']",
			target: ".module-play-list-link"
		},
		customTitle: [".content h1", ".content h2"],
		category: "hcomic"
	}, {
		name: "污污漫书",
		host: "www.55comics.com",
		url: {
			t: "污污漫书",
			p: /\/\d+\.html$/,
			e: ".scramble-page img"
		},
		imgs: () => {
			if (fn.ge(".pagination li.active")) {
				let max = fn.gt("//li[a[text()='下一页»' or text()='下一頁»' or text()='Next»']]", 2);
				let links = fn.arr(max, (v, i) => i == 0 ? fn.url : fn.url + "?p=" + (i + 1));
				return fn.getImgA(".scramble-page img", links);
			}
			return fn.getNP(".scramble-page", "//li/a[text()='下一页»' or text()='下一頁»' or text()='Next»']", null, ".pagination").then(() => fn.gae(".scramble-page img"));
		},
		button: [4],
		insertImg: [
			[".scramble-page", 2, ".scramble-page"], 2
		],
		insertImgAF: () => {
			let arr = ["//div[div[@class='ads']]", "//div[ul[ul[@class='pagination']]]"];
			fn.remove(arr);
		},
		autoDownload: [0],
		next: "//a[text()='下一话»' or text()='下一話»']",
		prev: "//a[text()='上一话»' or text()='上一話»']",
		chapters: {
			url: ".chapter-left a",
			urlIndex: 2,
			target: ".episode a"
		},
		customTitle: () => {
			let str = fn.gt(".chapter-left h1");
			let strArr = str.split(">");
			strArr = strArr.map(str => str.trim());
			if (strArr[3] == "全集阅读") {
				return strArr[2]
			}
			return strArr[2] + " - " + strArr[3];
		},
		observerClick: "#chk_cover",
		hide: ".row:has(>.ads),.row:has(>.stui_md)",
		category: "hcomic"
	}, {
		name: "污污漫书",
		url: {
			t: "污污漫书",
			h: /www\.55comics\./
		},
		observerClick: "#chk_cover",
		hide: ".row:has(>.ads)",
		category: "ad"
	}, {
		name: "涩涩漫画",
		host: ["sscomic.top"],
		url: {
			t: "涩涩漫画",
			p: "/chapter/",
			e: "#comic-data"
		},
		imgs: () => JSON.parse(document.getElementById("comic-data").textContent).filter(Boolean),
		button: [4],
		insertImg: ["#pic-list", 2],
		autoDownload: [0],
		np: (key) => {
			let code = fn.gst(`var ${key}link`);
			let a = code.indexOf(`var ${key}link`);
			let b = code.indexOf("=", a);
			let c = code.indexOf(";", b);
			code = code.slice(b + 1, c);
			return code.includes("chapter") ? code.replace(/[\s'"]/g, "") : null;
		},
		next: () => _this.np("x"),
		prev: () => _this.np("s"),
		chapters: {
			url: "a:has(.button-image-category)",
			target: ".chapter-list a"
		},
		customTitle: () => {
			let url = fn.gu("a:has(.button-image-category)");
			let id = fn.lp.split("/").at(-1);
			return fn.fetchDoc(url).then(dom => {
				let n = dom.querySelector(".comic_name").innerText;
				let c = [...dom.querySelectorAll(".chapter-list a")].find(a => a.href.endsWith(id)).innerText;
				return n + " - " + c;
			});
		},
		hide: ".exoAds,.exoAdb,.exoAdl,ins",
		category: "hcomic"
	}, {
		name: "涩涩漫画",
		url: {
			t: "涩涩漫画",
			h: ["sscomic.top"]
		},
		hide: ".exoAds,.exoAdb,.exoAdl,ins",
		category: "ad"
	}, {
		name: "MangaTaro",
		url: {
			h: "mangataro.org",
			p: "/read/"
		},
		home: "/home",
		imgs: ".comic-image-container img",
		button: [4],
		insertImg: ["#reader-media", 2],
		next: "//a[div[div[div[text()='Next Chapter']]]]",
		prev: "//a[div[div[div[text()='Prev Chapter']]]]",
		chapters: {
			target: "#chapter-select option"
		},
		customTitle: ["span[itemprop=name]", 2, 3],
		hide: "#pageCounter",
		category: "comic"
	}, {
		name: "Mangago",
		host: ["mangago.me", "mangago.zone", "youhim.me"],
		url: {
			h: /mangago|youhim/,
			p: /^\/read-manga\/|^\/chapter\//,
			st: "imgsrcs"
		},
		update: "/list/latest/all/1/",
		decrypt: str => {
			let CryptoJS = _unsafeWindow.CryptoJS;
			let key = CryptoJS.enc.Hex.parse("e11adc3949ba59abbe56e057f20f883e");
			let iv = CryptoJS.enc.Hex.parse("1234567890abcdef1234567890abcdef");
			let opinion = {
				iv,
				padding: CryptoJS.pad.ZeroPadding
			};
			return CryptoJS.AES.decrypt(str, key, opinion).toString(CryptoJS.enc.Utf8).split(",");
		},
		getSrcs: (scripts) => scripts.map(script => {
			let code = script.textContent;
			let s = code.indexOf("'") + 1;
			let e = code.indexOf("'", s);
			code = code.slice(s, e);
			return _this.decrypt(code);
		}).flat(),
		init: () => {
			fn.clearAllTimer();
			return fn.waitVar(["jQuery", "CryptoJS", "imgsrcs"]).then(() => _unsafeWindow.jQuery(document).off("keydown"));
		},
		box: ["#pic_container", 1, 1000],
		imgs: () => {
			if (fn.lp.startsWith("/chapter/")) {
				let links = fn.gau("#pagenavigation a,#dropdown-menu-page a");
				links = links.filter((url, i) => {
					if (i == 0) return true;
					let p = url.split("/").at(-2);
					return ["1", "6"].some(n => p.endsWith(n));
				});
				return fn.getEle(links, "//script[contains(text(),'imgsrcs')]").then(scripts => _this.getSrcs(scripts));
			} else if ((isMobileDeviceUA || isM) && fn.lp.startsWith("/read-manga/")) {
				return fn.sm5().then(() => fn.xhrDoc(fn.url, {
					headers: {
						"User-Agent": PC_UA
					}
				}).then(dom => {
					let script = fn.ge("//script[contains(text(),'imgsrcs')]", dom);
					let scripts = [script];
					return _this.getSrcs(scripts);
				}));
			}
			return _this.decrypt(_unsafeWindow.imgsrcs);
		},
		button: [4],
		insertImg: [
			["box", 0, "#pic_container"], 2
		],
		insertImgAF: (parent) => {
			fn.remove(".addtoalbum,.page_select,#pagenavigation,div:has(>img[onclick]),.btn-group:has(#dropdown-menu-page),.subnav-wrapper .pager");
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 9);
			}
		},
		endColor: "white",
		autoDownload: [0],
		getNext: id => {
			let chapters = fn.gae(".chapter a");
			let c_chapter = chapters.find(a => a.href.includes(`/${id}/`));
			let next = c_chapter?.parentElement?.nextElementSibling?.firstElementChild;
			return next ? next.href : null;
		},
		next: () => {
			if ("next_c_url" in _unsafeWindow) {
				if (["/read-manga/", "/chapter/"].some(s => _unsafeWindow.next_c_url.includes(s))) {
					return _unsafeWindow.next_c_url;
				}
			}
			if (fn.lp.startsWith("/chapter/")) {
				let cid = fn.lp.split("/").at(-2);
				return _this.getNext(cid);
			} else {
				if (isM) {
					let cid = fn.lp.split("/").at(-3);
					return _this.getNext(cid);
				}
				return fn.gu("//p[contains(text(),'Next Chapter:')]/a");
			}
		},
		prev: 1,
		chapters: {
			target: "ul.chapter a"
		},
		customTitle: () => isM ? getTitle(["#series", "#series+a"]) : getTitle(["#series,span:has(>#series)~span", 0, 2]),
		css: "#FullPictureLoadMainImgBox img[id^=page]{width:auto;height:auto;max-width:100%}",
		fancybox: {
			blacklist: 1
		},
		category: "comic"
	}, {
		name: "MangaDex",
		url: {
			h: "mangadex.org",
			e: "link[title=MangaDex]",
			d: "pc"
		},
		page: () => fn.clp("/chapter/"),
		update: "/titles/latest",
		wait: () => fn.wait((d) => d.title != "" && !d.title.includes("Loading")),
		json: () => fn.sm5().then(() => fn.clp().split("/").at(2)).then(id => fn.j(`https://api.mangadex.org/at-home/server/${id}?forcePort443=false`).then(json => (siteJson = json) && fn.hm())),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json().then(() => _this.wait()).then(() => fn.sm4()).then(() => fn.waitEle("#chapter-selector li[data-value]")).then(() => fn.hm()) : _this.wait(),
		imgs: () => {
			if (!_this.page()) return [];
			let {
				baseUrl,
				chapter: {
					data,
					hash
				}
			} = siteJson;
			return data.map(e => baseUrl + "/data/" + hash + "/" + e);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: async () => {
			if (_this.page()) {
				let id = fn.clp().split("/").at(-1);
				let chapters = await fn.waitEle(["#chapter-selector li[data-value]"]);
				let c_chapter = chapters.find(e => e.dataset.value == id);
				let next = c_chapter?.previousElementSibling;
				return next ? fn.wurl(next.dataset.value) : null;
			}
			return null;
		},
		prev: 1,
		chapters: {
			target: "#chapter-selector li[data-value]",
			cb: (text, e) => ({
				text,
				url: fn.wurl(e.dataset.value)
			}),
			sort: "r"
		},
		customTitle: async () => {
			if (!_this.page()) return null;
			await _this.wait();
			let text = fn.dt({
				d: [
					/^[\d\s\|]+/,
					" - MangaDex"
				]
			});
			let textArr = text.split(" - ");
			return textArr[1] + " - " + textArr[0];
		},
		category: "comic"
	}, {
		name: "NamiComi",
		url: {
			h: "namicomi.com",
			e: "meta[content=NamiComi]",
			d: "pc"
		},
		page: () => fn.clp("/chapter/"),
		c_id: () => fn.clp().split("/").at(3),
		json: () => fn.sm5().then(() => fn.j(`https://api.namicomi.com/images/chapter/${_this.c_id()}?newQualities=true`).then(json => (siteJson = json) && fn.hm())),
		SPA: () => _this.page(),
		observeURL: "head",
		id: () => fn.clp().split("/").at(-1),
		init: () => _this.page() ? _this.json().then(() => fn.sm4()).then(() => fn.waitEle(`select.relative option[value="${_this.id()}"]`)).then(() => fn.hm()) : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let chapter_id = _this.c_id();
			let {
				data: {
					baseUrl,
					hash,
				}
			} = siteJson;
			let data;
			let quality;
			let keys = ["source", "high", "medium", "low"];
			for (let k of keys) {
				if (Array.isArray(siteJson.data[k])) {
					data = siteJson.data[k];
					quality = k;
					break;
				}
			}
			return data.map(e => baseUrl + "/chapter/" + chapter_id + "/" + hash + `/${quality}/` + e.filename);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: async () => {
			if (_this.page()) {
				let id = _this.id();
				let chapters = await fn.waitEle(["select.relative option"]);
				let c_chapter = chapters.find(e => e.value == id);
				let next = c_chapter?.previousElementSibling;
				return next ? fn.wurl(next.value) : null;
			}
			return null;
		},
		prev: 1,
		chapters: {
			target: "//div[h2[text()='Chapter']]//option",
			cb: (text, v) => ({
				text,
				url: fn.wurl(v)
			}),
			sort: "r"
		},
		customTitle: () => {
			if (!_this.page()) return null;
			let text = fn.dt({
				d: / - NamiComi.+$/
			});
			let textArr = text.split(" - ");
			return textArr[1] + " - " + textArr[0];
		},
		category: "comic"
	}, {
		name: "BATOTO V2",
		link: "https://bato.si/mirrors",
		url: {
			e: "meta[property='og:site_name'][content=Batoto]",
			p: "/chapter/",
			st: "imgHttps"
		},
		update: "/latest?langs=zh_tw,zh,en,zh_hk",
		imgs: () => {
			let ss = ["n00.", "n01.", "n02.", "n03.", "n04.", "n05.", "n06.", "n07.", "n08.", "n09.", "n10.", "n11.", "n12.", "n14.", "n15.", "n16.", "n17.", "n18.", "n19.", "n20.", "n21.", "n22.", "n23.", "n24.", "n25.", "n26.", "n27.", "n28.", "n29.", "n30."];
			let code = fn.gst("imgHttps");
			return fn.textToArray(code, "imgHttps").map(src => src.replace(/[a-z]+\d+\./, fn.arrayOne(ss)));
		},
		button: [4],
		insertImg: ["#viewer", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[span[text()='Next Chapter ▶']]",
		prev: "//a[span[text()='◀ Prev Chapter']]",
		chapters: {
			node: "optgroup[label=Chapters]",
			target: "option",
			cb: (t, v) => ({
				text: t,
				url: fn.wurl(v)
			})
		},
		customTitle: () => {
			let id = fn.lp.split("/").at(-1);
			let chapters = fn.gae("optgroup[label=Chapters] option");
			let chapterName = chapters.find(e => e.value == id).innerText;
			let magaName = fn.gt(".nav-title>a");
			return magaName + " - " + chapterName.replaceAll("\n", "").replace(/\s{2,10}/, "");
		},
		category: "comic"
	}, {
		name: "BATOTO V3",
		url: {
			t: "Bato.To",
			p: "/title/",
			e: "astro-island[props*=imageFiles]"
		},
		imgs: () => {
			let ss = ["n00.", "n01.", "n02.", "n03.", "n04.", "n05.", "n06.", "n07.", "n08.", "n09.", "n10.", "n11.", "n12.", "n14.", "n15.", "n16.", "n17.", "n18.", "n19.", "n20.", "n21.", "n22.", "n23.", "n24.", "n25.", "n26.", "n27.", "n28.", "n29.", "n30."];
			let srcs = JSON.parse(JSON.parse(fn.attr("astro-island[props*=imageFiles]", "props")).imageFiles.find(isString)).map(([, url]) => url);
			return srcs.map(src => src.replace(/[a-z]+\d+\./, fn.arrayOne(ss)));
		},
		button: [4],
		insertImgBF: () => fn.waitEle("div[name='image-item'] img"),
		insertImg: ["div[name='image-item']", 2],
		autoDownload: [0],
		next: "//a[span[text()='Next Chapter ▶']]",
		prev: "//a[span[text()='◀ Prev Chapter']]",
		chapters: {
			node: "optgroup[label=Chapters]",
			target: "option"
		},
		customTitle: () => fn.title(" - Read Free Manga Online at Bato.To"),
		hide: ".max-w-screen-2xl:has(button.btn-info)",
		category: "comic"
	}, {
		name: "BATOTO",
		host: ["bato.si"],
		url: {
			e: ["//p[contains(text(),'BATO.TO')]", "script[type='qwik/json']", ".select.select-sm"],
			p: "/title/"
		},
		box: [".grid:has(div[data-name='image-item'])", 1],
		imgs: () => {
			let ss = ["n00.", "n01.", "n02.", "n03.", "n04.", "n05.", "n06.", "n07.", "n08.", "n09.", "n10.", "n11.", "n12.", "n14.", "n15.", "n16.", "n17.", "n18.", "n19.", "n20.", "n21.", "n22.", "n23.", "n24.", "n25.", "n26.", "n27.", "n28.", "n29.", "n30."];
			return fn.getImgSrcArr("div[data-name='image-item'] img").map(src => src.replace(/[a-z]+\d+\./, fn.arrayOne(ss)));
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".grid:has(div[data-name='image-item'])"),
		autoDownload: [0],
		next: "//a[span[text()='Next Chapter']]",
		prev: "//a[span[text()='Prev Chapter']]",
		chapters: {
			wait: () => fn.waitEle(`.select.select-sm option[value="${fn.lp}"]`),
			node: ".select.select-sm",
			target: "option"
		},
		customTitle: () => fn.title(" - Read Free Manga Online"),
		category: "comic"
	}, {
		name: "MangaPark",
		host: ["mangapark.net", "mangapark.com", "mangapark.to", "parkmanga.com"],
		url: {
			t: "Share Any Manga on MangaPark",
			p: ["chapter", "/title/"],
			e: "select.select",
			st: "image_server"
		},
		update: "/latest",
		imgs: () => {
			let ss = ["s00.", "s01.", "s03.", "s04."];
			return fn.getImgSrcArr("div[data-name='image-item'] img").map(src => src.replace(/[a-z]+\d+\./, fn.arrayOne(ss)));
		},
		button: [4],
		insertImgBF: () => fn.waitEle("[data-name='image-item'] img"),
		insertImg: ["div:has(>div[data-name='image-item'])", 2],
		autoDownload: [0],
		next: "//a[span[text()='Next Chapter']]",
		prev: "//a[span[text()='Prev Chapter']]",
		chapters: {
			wait: "select[on\\:change] option[value^='/title/']",
			node: "select[on\\:change]",
			target: "option"
		},
		customTitle: () => fn.title(" - Share Any Manga on MangaPark"),
		category: "comic"
	}, {
		name: "Dynasty Reader",
		url: {
			h: "dynasty-scans.com",
			p: "/chapters/",
			e: "#reader"
		},
		imgs: () => _unsafeWindow.pages.map(e => fn.lo + e.image),
		button: [4],
		insertImg: ["#reader", 2],
		insertImgAF: (parent) => {
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 4);
			}
		},
		autoDownload: [0],
		next: "#next_link",
		prev: 1,
		chapters: {
			url: "#chapter-title a",
			target: ".chapter-list a.name"
		},
		customTitle: () => fn.title("Dynasty Reader » "),
		category: "comic"
	}, {
		name: ".reading-content single-chapter-select",
		url: {
			h: [
				"manhuatop.org",
				"www.topmanhua.fan",
				"toonily.com",
				"manhwaz.com",
				"manhwahub.net",
				"toonclash.com",
				"mangagg.com",
				"asurascan.me",
				"manhuaplus.com",
				"kissmanga.in",
				"mangalector.com",
				"cocomic.co",
				"kunmanga.com",
				"likemanga.in",
				"manhwaclan.com",
				"manhwaclub.net",
				/hentaivn/,
				"lectorhades.latamtoon.com",
				"yaoiscan.com",
				"dragontea.ink",
				"hiperdex.com",
				"www.mangaread.org",
				"lhtranslation.net",
				"manhuaus.com",
				"www.toongod.org",
				"manytoon.com",
				"harimanga.me",
				"reset-scans.org",
				"mangadistrict.com",
				"apcomics.org",
				"manga18free.com",
				"hiper.cool",
				"ero18x.com",
				"manhwa-latino.com",
				"manhwa-es.com",
				"gedecomix.com",
				"hentaixyuri.com",
				"hentaixcomic.com",
				"hentaixdickgirl.com",
				"allporncomics.co",
				"anycomics.com",
				"novelcrow.com",
				"manhwahentai.io",
				"mangayy.org",
				"www.shonenmangaz.com",
				"www.zinmanga.net",
				"www.zazamanga.com",
				"www.likemanga.vip",
				"lilymanga.net",
				"www.isekaiscan.top",
				"mangago.io",
				"aquareader.net",
				"manhuahot.com",
				"coffeemanga.ink",
				"mangasushi.org",
				"madaradex.org",
				"www.pornhwaz.com",
				"freemangatop.com",
				"manhwatop.com",
				"mangazin.org",
				"www.manhwatoon.me",
				"hentai20.online",
				"mangator.com",
				"manhwa18.org",
				"manhwabuddy.com",
				"www.manhwaden.com",
				"flamescans.lol",
				"manhuarmmtl.com"
			],
			p: ["/read/", "/chapter", "-chapter-", "/glava", "/c-", "/ch-", "/episode", "/capitulo", "-capitulo-", "oneshot", "/tmo/", "/porncomic", /^\/(manhwa|manga|comic|webtoon|serie)\//, "/gl/"],
			e: ".reader-image-block,.reading-content img,.wp-manga-chapter-img,.chapter-image img"
		},
		imgs: () => fn.waitEle([".reading-content img,.wp-manga-chapter-img,.chapter-image img"]).then(eles => eles.filter(e => !e.closest("a[href*='/t.me/'],.banner"))),
		button: [4],
		box: [".read-container,#chapter_content,.reader-image-block,.reading-img", 2],
		insertImg: ["box", 2],
		insertImgAF: () => {
			fn.hideEle(".read-container,#chapter_content,.reader-image-block,.reading-img");
			fn.addMutationObserver(() => fn.remove("div[style*='2147483647']:not(#DownloadAppUIRoot),iframe[style*='none'],.body-top-ads,.body-bottom-ads"));
		},
		endColor: () => fn.ge(".text-ui-light") ? "white" : "black",
		autoDownload: [0],
		next: "a.next_page",
		prev: "a.prev_page",
		chapters: {
			wait: ".single-chapter-select option[data-redirect],.single-chapter-select option[value],.chapter-dropdown-content a",
			node: "select.single-chapter-select,.chapter-dropdown-content",
			target: "option,a",
			cb: (t, v, e) => ({
				text: e.text,
				url: fn.rt(("redirect" in e.dataset) ? e.dataset.redirect : v, "?style=list", "")
			}),
			sort: "r"
		},
		customTitle: () => fn.ge(".breadcrumb") ? getTitle([".breadcrumb li", -2, -1]) : fn.gt("#chapter-heading,#chapter_header h1"),
		css: "body{overflow:auto!important;height:max-content!important}",
		hide: "#pageloader,[id^=teaser],body>div[id]:not(:has(*)):not([id^=Full]),body>div[id]:not(#body,#footer):has(p),.amg-ad-container,#body>.widget-adxx,.modal-backdrop",
		referer: "url",
		category: "comic"
	}, {
		name: "Terco Scans/Rizz Fables/Lectormiau/Mangagojo/Cosmic Scans Indonesia/KumoPoi/Mangakita/Manhuascan.us/tooncn/Komik Dewasa/Doujindesu/Doujin89",
		url: {
			h: [
				"tecnoxmoon.xyz",
				"rizzfables.com",
				"leemiau.com",
				"mangagojo.com",
				/^lc\d\.cosmicscans\.asia$/,
				"kumopoi.org",
				"mangakita.id",
				"manhuascan.us",
				"tooncn.net",
				"komikdewasa.id",
				"doujindesu.cv",
				"doujin89.com",
				"www.silentquill.net",
				"hentai20.io",
				"galaxymanga.io",
				"kingofshojo.com",
				"erosxsun.xyz"
			],
			p: [/^\/[\w-]+\/$/, "/chapter-", "-chapter-", "-capitulo-", "-Ep-", "-ch-"],
			e: "#readerarea,.bg-black"
		},
		init: () => fn.addMutationObserver(() => fn.remove("#radio_content,#teaserbottom")),
		imgs: () => fn.waitEle(["#readerarea img[class*='wp-image'],#readerarea .ts-main-image,#readerarea img[loading],#readerarea .chapter-img,#readerarea.rdminimal>img,#readerarea>p>img[alt][title]:not([alt='1 2'],[alt='2 2']),#readerarea img[src*='/chapter'],#readerarea img[src*='/Chapter'],#readerarea img[alt$=jpg],.chapter-image-anchor+img"]),
		button: [4],
		insertImg: ["#readerarea,.bg-black", 2],
		endColor: () => fn.ge(".darkmode") ? "white" : "black",
		autoDownload: [0],
		next: "a.ch-next-btn:not(.disabled),.section_button a:has(>.fa-angle-right)",
		prev: "a.ch-prev-btn:not(.disabled),.section_button a:has(>.fa-angle-left)",
		chapters: {
			wait: "#chapter option[data-id],#chapter option[value^=http]",
			node: "#chapter",
			target: "option[data-id],option[value^=http]",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => {
			let ct = fn.gt("#chapter [selected]");
			return ct == text;
		},
		hide: ".ver-src.chapter,.blox,div[style]:has(>div>script),div:has(.adblock_title),div:has(.vast-blocker),#floating-top-banner,#floating-bottom-banner,#inpage-float-ad,.kln",
		customTitle: ".entry-title,#chapter-title",
		category: "comic"
	}, {
		name: "Like Manga",
		url: {
			h: ["likemanga.ink"],
			p: ["/chapter-"]
		},
		init: () => (document.onkeydown = null),
		imgs: () => fn.waitEle([".reading-detail>.page-chapter>img"]),
		button: [4],
		insertImg: [".reading-detail", 2],
		autoDownload: [0],
		next: "a.a_next:not(.disabled)",
		prev: "a.a_prev:not(.disabled)",
		chapters: () => {
			let pages = fn.ge("#nav_list_chapter_id_modal a");
			if (pages) {
				let mid = fn.attr("#title-detail-manga", "data-manga");
				let max = fn.um("#nav_list_chapter_id_modal a,#nav_list_chapter_id_modal .current:not(:has(*))");
				let links = fn.arr(max, (v, i) => `/?act=ajax&code=load_list_chapter_modal&manga_id=${mid}&page_num=${i + 1}`);
				let resArr = links.map(fn.j);
				return Promise.all(resArr).then(jsons => {
					let html = jsons.map(j => j.list_chap).join("");
					let node = fn.html(html);
					return fn.gae("a", node).map(a => ({
						text: a.text.trim(),
						url: a.href
					})).reverse();
				});
			}
			return fn.getChapters({
				target: "#list_chapter_id_modal a",
				sort: "r"
			}).reverse();
		},
		customTitle: "#title-detail-manga",
		category: "comic"
	}, {
		name: "WebtoonRaw",
		url: {
			h: ["webtoonraw.com"],
			p: ["/chapter-"]
		},
		box: ["#chapter_boxImages", 1],
		imgs: () => _unsafeWindow.slides_p_path.map(e => atob(e)),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#chapter_boxImages"),
		autoDownload: [0],
		next: () => {
			let next = fn.ge("button[onclick]:has(>.ti-angle-left):not([disabled])");
			return next ? fn.attr(next, "onclick").split("'").at(1) : null;
		},
		prev: () => {
			let prev = fn.ge("button[onclick]:has(>.ti-angle-right):not([disabled])");
			return prev ? fn.attr(prev, "onclick").split("'").at(1) : null;
		},
		chapters: {
			target: ".form-control>option",
			sort: "r"
		},
		customTitle: [".breadcrumb>li", -2, -1],
		category: "comic"
	}, {
		name: "Manhwa18",
		url: {
			h: ["manhwa18.com"],
			p: ["/chapter-"]
		},
		box: ["#chapter-content", 1],
		imgs: "#chapter-content>img",
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#chapter-content"),
		autoDownload: [0],
		next: "a.chapter-nav-item:has(>.fa-forward):not(.disabled)",
		prev: "a.chapter-nav-item:has(>.fa-backward):not(.disabled)",
		chapters: {
			target: "#chap_list a",
			sort: "r"
		},
		customTitle: [".breadcrumb>li", -2, -1],
		category: "hcomic"
	}, {
		name: "MangaBTT",
		url: {
			h: ["manhwabtt.cc"],
			p: ["/chapter-"]
		},
		imgs: () => fn.waitEle([".reading-detail>.page-chapter>img:not([style])"]),
		button: [4],
		insertImg: [".reading-detail", 2],
		autoDownload: [0],
		next: "a.a_next:not(.disabled)",
		prev: "a.a_prev:not(.disabled)",
		chapters: {
			target: ".select-chapter option",
			sort: "r"
		},
		customTitle: ".top>.breadcrumb+h1",
		category: "comic"
	}, {
		name: "MangaCherri",
		url: {
			h: "mangacherri.com"
		},
		imgs: ".reading-container>img",
		button: [4],
		insertImg: [".reading-container", 2],
		autoDownload: [0],
		np: (i) => {
			let cid = fn.lp.split("/").at(-1);
			let cs = fn.gae("#top_chapter_selection>option");
			let ci = cs.findIndex(e => e.value == cid);
			let ti = ci + i;
			return isEle(cs[ti]) ? fn.wurl(cs[ti].value) : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: {
			target: "#top_chapter_selection>option",
			cb: (t, u) => ({
				text: "Chapter " + t,
				url: fn.wurl(u)
			}),
			sort: "r"
		},
		customTitle: () => fn.ge(".breadcrumb-container a[title]:nth-of-type(2)").title + " - Chapter " + fn.ge(".breadcrumb-container a[title]:nth-of-type(3)").innerText,
		category: "comic"
	}, {
		name: "ManhwaSusu",
		url: {
			h: "manhwasusu.com",
			p: "/chapter-"
		},
		imgs: ".min-h-screen .min-h-screen>div[q\\:key]>img",
		button: [4],
		insertImg: [".min-h-screen .min-h-screen", 2],
		autoDownload: [0],
		next: "//a[contains(text(),'Next')]",
		prev: "//a[contains(text(),'Prev')]",
		chapters: {
			url: "a:has(>h1[itemprop=name])",
			target: "h1+div.flex>a",
			textNode: "div>p",
			sort: "r"
		},
		customTitle: ["a:has(>h1[itemprop=name])", "a:has(>h1[itemprop=name])+h2"],
		category: "comic"
	}, {
		name: "巴卡漫画",
		host: ["bakamh.app", "bakamh.com", "bakamh.ru"],
		url: {
			t: "bakamh巴卡漫画",
			p: "/c-"
		},
		imgs: ".read-container img",
		button: [4],
		insertImg: [".read-container", 2],
		endColor: () => fn.ge(".text-ui-light") ? "white" : "black",
		autoDownload: [0],
		next: "a.next_page",
		prev: "a.prev_page",
		chapters: {
			wait: ".single-chapter-select option[data-redirect]",
			node: ".single-chapter-select",
			target: "option[data-redirect]",
			cb: (t, v, e) => ({
				text: e.text,
				url: e.dataset.redirect
			}),
			sort: "r"
		},
		customTitle: [".breadcrumb li", -2, -1],
		category: "comic"
	}, {
		name: "scanita",
		url: {
			h: ["scanita.org"],
			p: "/scan/"
		},
		init: () => fn.fetchDoc(fn.ge("//a[text()='Torna al manga']")).then(dom => (siteJson.chapterList = fn.gae(".chapters-list a", dom).reverse())),
		box: [".row:has(.book-page):not(.justify-content-center)", 1],
		imgs: () => fn.getNP(".row:has(.book-page):not(.justify-content-center)", ".btn-navigation.btn-next", null, ".row:has(.btn-navigation):not(.justify-content-center)").then(() => fn.gae(".book-page img")),
		insertImg: [
			["box", 0, ".row:has(.book-page):not(.justify-content-center)"], 2
		],
		np: (i) => {
			let id = fn.lp.split("/").at(-1);
			let urls = siteJson.chapterList.map(a => a.href);
			let index = urls.findIndex(u => u.endsWith(id));
			let u = urls[index + i];
			return isString(u) ? u : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapterList.map(a => ({
			text: fn.dt({
				t: a.firstElementChild.firstElementChild.firstChild.textContent
			}),
			url: a.href
		})),
		button: [4],
		customTitle: () => fn.dt({
			s: ".container h3",
			d: " - page 1"
		}),
		category: "comic"
	}, {
		name: "KaliScan/MGJinx",
		host: ["kaliscan.io", "kaliscan.com", "kaliscan.me", "mgjinx.com"],
		url: {
			t: ["KaliScan", "MGJinx"],
			p: "/chapter",
			st: "chapterId"
		},
		imgs: () => fn.sm5().then(() => fn.fetchDoc("/service/backend/chapterServer/?server_id=1&chapter_id=" + _unsafeWindow.chapterId).then(dom => fn.gae(".chapter-image", dom))),
		button: [4],
		insertImg: ["#chapter-images", 2],
		autoDownload: [0],
		next: "#btn-next",
		prev: "#btn-prev",
		chapters: {
			api: () => "/service/backend/chapterList/?manga_id=" + _unsafeWindow.bookId,
			target: "#chapter-list option",
			sort: "r"
		},
		customTitle: () => fn.ge(".chapter-info h1").textContent,
		category: "comic"
	}, {
		name: "MangaBuddy/MangaCute/MangaMonk/MangaFab/MangaSaga/BoxManhwa/MangaXYZ",
		host: ["mangabuddy.com", "mangacute.com", "mangamonk.com", "mangamonk.com", "mangasaga.com", "boxmanhwa.com", "mangaxyz.com"],
		url: {
			t: ["MangaBuddy", "MangaCute", "MangaMonk", "MangaFab", "MangaSaga", "BoxManhwa", "MangaXYZ"],
			p: "/chapter",
			st: "chapImages"
		},
		imgs: () => {
			let code = fn.gst("chapImages");
			return code.split("'").at(1).split(",").map(src => fn.rt(src, [
				[new URL(src).host, "sb.mbbcdn.com"],
				["/res/", "/"]
			]));
		},
		button: [4],
		insertImg: ["#chapter-images", 2],
		autoDownload: [0],
		next: "#btn-next",
		prev: "#btn-prev",
		chapters: {
			url: ".breadcrumbs-item:nth-child(2) a",
			target: "#chapter-list a",
			textNode: ".chapter-title",
			sort: "r"
		},
		customTitle: () => fn.ge(".chapter-info h1").textContent,
		category: "comic"
	}, {
		name: "TooniTube/Toonily/BeeHentai",
		host: ["toonitube.com", "toonily.me", "beehentai.com"],
		url: {
			t: ["TooniTube", "Toonily", "BeeHentai"],
			p: "/chapter"
		},
		imgs: ".chapter-image>img[data-src]",
		button: [4],
		insertImg: ["#chapter-images", 2],
		autoDownload: [0],
		next: "#btn-next",
		prev: "#btn-prev",
		chapters: {
			url: ".breadcrumbs-item:nth-child(2) a",
			target: "#chapter-list a",
			textNode: ".chapter-title",
			sort: "r"
		},
		customTitle: () => fn.ge(".chapter-info h1").textContent,
		category: "hcomic"
	}, {
		name: "MangaPub",
		host: ["mangapub.com"],
		url: {
			t: ["MangaPub"],
			p: "/chapter",
			st: "var bookId"
		},
		imgs: () => {
			let code = fn.gst("var bookId = ");
			return fn.textVar(code, "indicators", '"').split(",");
		},
		button: [4],
		insertImg: [".chapter-image", 3],
		autoDownload: [0],
		next: "#btn-next",
		prev: "#btn-prev",
		chapters: {
			url: ".breadcrumbs-item:nth-child(2) a",
			target: "#chapter-list a",
			textNode: ".chapter-title",
			sort: "r"
		},
		customTitle: () => fn.ge(".chapter-info h1").textContent + " - " + fn.ge(".chapter-info h2").textContent,
		category: "comic"
	}, {
		name: "Manga-Bay",
		url: {
			h: "manga-bay.org",
			p: "/reader/",
			st: "window.__DATA__"
		},
		update: "/comix/",
		init: () => {
			let code = fn.gst("__DATA__");
			let s = code.indexOf("{");
			let e = code.lastIndexOf("}") + 1;
			code = code.slice(s, e);
			siteJson = fn.run(code);
		},
		imgs: () => siteJson.images,
		button: [4],
		insertImg: [".reader-view", 2],
		insertImgAF: (parent) => {
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 8);
			}
		},
		autoDownload: [0],
		next: () => {
			let next = String(siteJson.next);
			return next.includes("/reader/") ? next : null;
		},
		prev: () => {
			let prev = String(siteJson.prev);
			return prev.includes("/reader/") ? prev.replace(/#.+$/, "") : null;
		},
		chapters: () => siteJson.chapters.map(({
			id,
			title
		}) => ({
			text: title,
			url: fn.wurl(id)
		})).reverse(),
		customTitle: () => fn.dt({
			d: ["Read", "manga online for free"]
		}),
		hide: ".nav__pages,.nav__paginate",
		category: "comic"
	}, {
		name: "MangaHub",
		url: {
			h: ["mangahub.io", "mangahub.us", "1manga.co", "mangareader.site", "manganel.me", "onemanga.info", "mangahere.onl", "mangaonline.fun", "mangafox.fun", "mangatoday.fun", "mangakakalot.fun"],
		},
		page: () => fn.clp("/chapter/"),
		update: "/updates",
		json: () => fn.sm5().then(() => {
			let x = "m01";
			if (fn.lh == "mangaonline.fun") x = "m02";
			if (fn.lh == "mangatoday.fun") x = "m03";
			if (fn.lh == "mangahub.us") x = "m04";
			if (fn.lh == "mangafox.fun") x = "mf01";
			if (fn.lh == "mangahere.onl") x = "mh01";
			if (fn.lh == "mangakakalot.fun") x = "mn01";
			if (fn.lh == "onemanga.info") x = "mn02";
			if (fn.lh == "1manga.co") x = "mn03";
			if (fn.lh == "manganel.me") x = "mn05";
			if (fn.lh == "mangareader.site") x = "mr01";
			let mhub_access = fn.cookie("mhub_access");
			let [, , slug, number] = fn.clp().split("/");
			number = number.replace("chapter-", "");
			let api = "https://api.mghcdn.com/graphql";
			let headers = {
				"content-type": "application/json",
				"x-mhub-access": mhub_access
			};
			let data = {
				query: `{chapter(x:${x},slug:"${slug}",number:${number}){id,title,mangaID,number,slug,pages,manga{id,title,slug}}}`,
			};
			return fn.j(api, {
				headers,
				"body": JSON.stringify(data),
				"method": "POST"
			}).then(json => {
				data = {
					query: `{chaptersByManga(mangaID:${json.data.chapter.mangaID}){number,title}}`,
				};
				return fn.j(api, {
					headers,
					"body": JSON.stringify(data),
					"method": "POST"
				}).then(chaptersJson => {
					json = json.data.chapter;
					Reflect.set(json, "chapters", chaptersJson.data.chaptersByManga);
					return (siteJson = json) && fn.hm();
				});
			});
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				p,
				i: images
			} = JSON.parse(siteJson.pages);
			return images.map(e => `https://imgx.mghcdn.com/${p + e}`);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (i) => {
			if (!_this.page()) return null;
			let index = siteJson.chapters.findIndex(e => e.number == siteJson.number);
			let o = siteJson.chapters[index + i];
			return isObject(o) ? fn.rt(fn.clp(), /[\d\.]+$/, o.number) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: {
			wait: ["ul[aria-labelledby='select-chapter'] a"]
		},
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				manga: {
					title: mt
				},
				title: ct,
				number
			} = siteJson;
			return `${mt} - Chapter ${number} ${ct}`;
		},
		category: "comic"
	}, {
		name: "VyManga",
		host: ["vymanga.com"],
		url: {
			h: ["summonersky.com", "burgerpixel.net"]
		},
		update: "https://vymanga.com/search?sort=updated_at",
		imgs: ".carousel-item img",
		autoDownload: [0],
		next: "a#navbar-chapter-control-next",
		prev: "a#navbar-chapter-control-prev",
		chapters: {
			node: ".select-chapter",
			target: "option",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => {
			let c_t = fn.gt(".select-chapter [selected]");
			return c_t == text;
		},
		customTitle: () => fn.ge("#chapter-info")?.textContent,
		category: "comic"
	}, {
		name: "MangaNato/MangaKakalot/MangaNelo/Mangabat",
		host: ["www.natomanga.com", "www.nelomanga.com", "www.nelomanga.net", "www.manganato.gg", "www.mangabats.com", "www.mangakakalove.com", "www.mangakakalot.gg", "www.mangakakalot.fan"],
		url: {
			t: ["MangaNato", "MangaKakalot", "MangaNelo", "Mangabat"],
			p: "/chapter",
			st: "chapterImages"
		},
		update: "/manga-list/latest-manga",
		imgs: () => {
			let {
				cdns,
				chapterImages
			} = _unsafeWindow;
			[cdns] = cdns;
			return chapterImages.map(e => cdns + "/" + e);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".btn-navigation-chap a.next",
		prev: ".btn-navigation-chap a.back",
		chapters: {
			node: ".navi-change-chapter",
			target: "option",
			cb: (t, v, e) => ({
				text: t,
				url: e.dataset.c
			}),
			sort: "r"
		},
		customTitle: ".info-top-chapter h2",
		hide: ".banner-cus",
		category: "comic"
	}, {
		name: "ReadComicOnline",
		url: {
			h: "readcomiconline.li",
			p: "/Comic/",
			s: "id=",
			st: "[cImgIndex]",
			d: "pc"
		},
		update: "/ComicList/LatestUpdate",
		init: () => (siteJson = {
			cid: fn.getUSP("id"),
			chapters: fn.gae("#selectEpisode option")
		}),
		imgs: () => {
			let max = fn.gae("#selectPage option").length;
			let code = fn.gst("[cImgIndex]");
			let vi = code.lastIndexOf("[cImgIndex]");
			let si = code.lastIndexOf("+", vi) + 1;
			let ei = code.indexOf("+", vi);
			let str = code.slice(si, ei).trim();
			return fn.arr(max, (v, i) => fn.run(str.replace("cImgIndex", i)));
		},
		button: [4],
		insertImg: ["#divImage", 2],
		insertImgAF: () => fn.hideEle("#selectQuality+.lbl,#selectReadType,#selectEpisode+.lbl,#selectPage,div:has(>#btnPrevious),.btnZoom-container"),
		autoDownload: [0],
		np: (i) => {
			let ci = siteJson.chapters.findIndex(o => (o.value.match(/\d+$/).at(0) == siteJson.cid));
			let o = siteJson.chapters[ci + i];
			return isEle(o) ? o.value : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: {
			target: "#selectEpisode option"
		},
		checkCurrentChapter: (url) => siteJson.cid == url.match(/\d+$/).at(0),
		customTitle: () => fn.dt({
			d: /- Read.+$/
		}),
		hide: "#adbWarnContainer",
		category: "comic"
	}, {
		name: "ReadComicOnline",
		url: {
			h: "readcomiconline.li",
			p: "/Comic/",
			s: "id=",
			st: "[currImage]",
			d: "m"
		},
		update: "/ComicList/LatestUpdate",
		init: () => (siteJson = {
			cid: fn.getUSP("id"),
			chapters: fn.gae("option", fn.ge(".selectEpisode"))
		}),
		box: ["#divImage", 1],
		imgs: () => {
			let max = Number(fn.gt("#totalPages"));
			let code = fn.gst("[currImage]");
			let vi = code.lastIndexOf("[currImage]");
			let si = code.lastIndexOf(",", vi) + 1;
			let ei = code.indexOf(")", vi);
			let str = code.slice(si, ei).trim();
			return fn.arr(max, (v, i) => fn.run(str.replace("currImage", i)));
		},
		button: [4],
		insertImg: [
			["box", 0, "#divImage,#pager,#imgLoader"], 2
		],
		np: (i) => {
			let ci = siteJson.chapters.findIndex(o => (o.value.match(/\d+$/).at(0) == siteJson.cid));
			let o = siteJson.chapters[ci + i];
			return isEle(o) ? o.value : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: {
			node: ".selectEpisode",
			target: "option"
		},
		checkCurrentChapter: (url) => siteJson.cid == url.match(/\d+$/).at(0),
		customTitle: () => fn.dt({
			d: /- Read.+$/
		}),
		category: "comic"
	}, {
		name: "ZipComic.com",
		url: {
			h: "www.zipcomic.com",
			e: ".block-content:has(#images)"
		},
		imgs: "#images img",
		insertImg: [".block-content:has(#images)", 2],
		autoDownload: [0],
		next: "a:has(>.fa-angle-double-right)",
		prev: "a:has(>.fa-angle-double-left)",
		chapters: {
			node: ".page-nav",
			target: "option"
		},
		customTitle: ".block-content h1",
		category: "comic"
	}, {
		name: "Mangakakalot",
		host: ["mangakakalot.to"],
		url: {
			t: "Mangakakalot",
			p: "/read/",
			e: "#reading"
		},
		update: "/latest",
		imgs: () => {
			let id = fn.attr("#reading", "data-reading-id");
			let type = fn.attr("#reading", "data-reading-type");
			return fn.fetchDoc(`/ajax/manga/images?id=${id}&type=${type}`).then(dom => fn.gae(".card-wrap[data-url]", dom));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (k) => {
			let c = fn.ge(".select-reading [selected]");
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			node: ".select-reading",
			target: "option",
			sort: "r"
		},
		customTitle: ".reading-info h2",
		category: "comic"
	}, {
		name: "Слив манги для вас",
		url: {
			h: "mangabuff.ru",
			p: "/manga/"
		},
		imgs: async () => {
			let srcs = fn.getImgSrcArr(".reader__pages img");
			let [src] = srcs;
			fn.showMsg(DL.str_56, 0);
			let status = await fn.xhrHEAD(src).then(res => res.status);
			fn.hm();
			if (status === 200) {
				return srcs;
			}
			let host = new URL(src).origin;
			let newHost;
			if (src.includes("https://custom.mangabuff.ru")) {
				newHost = "https://c3.mangabuff.ru";
			} else if (src.includes("https://c2.mangabuff.ru")) {
				newHost = "https://custom.mangabuff.ru";
			} else if (src.includes("https://img.mangabuff.ru")) {
				newHost = "https://img2.mangabuff.ru";
			} else if (src.includes("https://img2.mangabuff.ru")) {
				newHost = "https://img.mangabuff.ru";
			}
			return newHost ? srcs.map(e => e.replace(host, newHost)) : srcs;
		},
		button: [4],
		insertImg: [".reader__pages", 2],
		autoDownload: [0],
		next: "//a[contains(text(),'След.')]",
		prev: "//a[contains(text(),'Пред.')]",
		chapters: {
			node: ".reader-chapters",
			target: "a",
			sort: "r"
		},
		customTitle: ".reader__controls",
		hide: ".reader__top-a",
		category: "comic"
	}, {
		name: "MangaMen",
		url: {
			h: "mangamen.ru",
			st: ["__DATA__", "__pg"]
		},
		init: () => {
			let code = fn.gst("__DATA__");
			let a = code.indexOf("__DATA__");
			let b = code.indexOf("{", a);
			let c = code.indexOf(";", b);
			siteJson.data = fn.run(code.slice(b, c));
			a = code.indexOf("__info");
			b = code.indexOf("{", a);
			c = code.indexOf(";", b);
			siteJson.info = fn.run(code.slice(b, c));
			code = fn.gst("__pg");
			siteJson.pg = fn.textToArray(code, "__pg");
		},
		imgs: () => siteJson.pg.map(e => e.u),
		button: [4],
		insertImgBF: () => fn.waitEle(".reader-view div[page] img[alt]"),
		insertImg: [".reader-view", 2],
		autoDownload: [0],
		next: () => {
			let next = siteJson?.info?.next?.url;
			return String(next)?.split("/")?.length > 2 ? next : null;
		},
		prev: () => {
			let prev = siteJson?.info?.prev?.url;
			return String(prev)?.split("/")?.length > 2 ? prev.replace(/\?.+$/, "") : null;
		},
		chapters: {
			target: ".reader-chapters-list a",
			sort: "r"
		},
		customTitle: () => siteJson.info.current.title + " - " + siteJson.data.chapters.find(e => e.id == siteJson.info.current.id).title,
		hide: ".ads,.comment__dropdown",
		category: "comic"
	}, {
		name: "Manga-shi",
		url: {
			h: "manga-shi.org",
			p: "/glava"
		},
		imgs: ".chapter-images img",
		button: [4],
		insertImg: [".reading-content", 2],
		autoDownload: [0],
		next: ".nav-next .next_page",
		prev: ".nav-previous .prev_page",
		chapters: () => {
			let url = fn.gu(".chap-item a");
			let api = url + "ajax/chapters/?t=1";
			return fn.fetchDoc(api, {
				"headers": {
					"x-requested-with": "XMLHttpRequest"
				},
				"body": null,
				"method": "POST"
			}).then(dom => fn.gae(".listing-chapters_wrap a").map(a => ({
				text: fn.dt({
					t: a.text
				}),
				url: a.href
			})).reverse());
		},
		customTitle: () => {
			let m = fn.gt(".chap-item h3").split("/").at(0).trim();
			let c = fn.gt("#chapter-heading");
			return m + " - " + c;
		},
		hide: ".reading-content::before",
		category: "comic"
	}, {
		name: "Mangahub",
		url: {
			h: "mangahub.ru",
			p: "/read/"
		},
		update: "/feed",
		imgs: ".reader-viewer-img",
		autoDownload: [0],
		next: "a[data-target='reader-area.chapterNext']",
		prev: "a[data-target='reader-area.chapterPrev']",
		chapters: {
			api: () => {
				let m_id = fn.attr("history-progress", "object-id");
				let c_id = fn.attr("history-progress", "item-id");
				return `/read/${m_id}/chapters?translationId=${c_id}`;
			},
			target: "a",
			sort: "r"
		},
		customTitle: () => fn.gt(".reader-info a.text-truncate").split("/")[0] + " - " + fn.gt(".reader-header .text-truncate"),
		category: "comic"
	}, {
		name: "Mangahub",
		url: {
			h: "mangahub.cc"
		},
		box: [".pages_placer", 1],
		imgs: ".chapter_page_image",
		button: [4],
		insertImg: [
			["box", 0, ".pages_placer"], 2
		],
		autoDownload: [0],
		np: (k) => {
			let a = fn.gae("a.main_text_animate:has(svg)").find(a => a.text.includes(k));
			return a.pathname.split("/").length > 3 ? a.href : null;
		},
		next: () => _this.np("Следующая глава"),
		prev: () => _this.np("Предыдущая глава"),
		chapters: {
			url: "#texted_to_title",
			target: "a:has(.chapter_number)",
			textNode: ".chapter_number",
			sort: "r"
		},
		customTitle: () => fn.dt({
			d: " | Mangahub"
		}),
		hide: ".HelpBlockTop",
		category: "comic"
	}, {
		name: "ReManga",
		url: {
			h: ["remanga.org"]
		},
		page: () => fn.clp(/^\/manga\/[^\/]+\/\d+/),
		json: () => fn.rd().then(() => {
			let code = [...doc.scripts].find(s => !s.textContent.includes("self.__next_f.push") && ["chapter", "content_type", "pages", "server"].every(key => s.textContent.includes(key)))?.textContent;
			//debug("code", code);
			let a_i = code.indexOf("({") + 1;
			let b_i = code.lastIndexOf("})") + 1;
			let key_code = code.slice(a_i, b_i);
			//debug("key_code", key_code);
			let json = JSON.parse(key_code).queries.find(({
				queryHash
			}) => queryHash?.includes("chapter-detail")).state.data.json;
			siteJson = json;
			debug("\n此頁JSON資料\n", siteJson);
			if (siteJson?.pages?.length == 0) return;
			return fn.sm4().then(() => fn.waitEle("div[data-sentry-element=ReaderContainer] img", 600).then(e => {
				if (isEle(e)) {
					siteJson.host = new URL(e.src).host;
				}
			})).then(() => fn.hm());
		}),
		SPA: () => _this.page() ? true : (siteJson.host = null) && false,
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page() || !isArray(siteJson.pages)) return [];
			let srcs = siteJson.pages.flat().map(e => e.link);
			if (!siteJson.host) return srcs;
			let [src] = srcs;
			let host = new URL(src).host;
			return srcs.map(e => e.replace(host, siteJson.host));
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let o = siteJson[key];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np("next"),
		prev: () => _this.np("previous"),
		chapters: () => fn.j(`https://api.remanga.org/api/titles/chapters/?branch_id=${siteJson.branch_id}&user_data=0`).then(json => {
			let chapters = json.content.sort((a, b) => a.index - b.index);
			return chapters.map(({
				chapter,
				id
			}) => ({
				text: `Глава ${chapter}`,
				url: fn.wurl(id)
			}));
		}),
		category: "comic"
	}, {
		name: "MangaLib",
		url: {
			h: ["mangalib.org", "mangalib.me"],
			p: "/read/"
		},
		init: () => {
			const ajaxHooker = addAjaxHookerLibrary();
			ajaxHooker.filter([{
				type: "xhr",
				url: "/chapter?"
			}]);
			ajaxHooker.hook(request => {
				request.response = res => {
					if (!("srcs" in siteJson)) {
						siteJson.srcs = res.response.data.pages.map(e => e.url);
					}
				};
			});
			return fn.sm4().then(() => fn.waitEle("main div[data-page] img", 200, doc, ".vk_cm").then(() => fn.hm()));
		},
		imgs: () => {
			if (fn.ge(".vk_cm")) return [];
			let [src] = fn.getImgSrcArr("main div[data-page] img");
			let host = new URL(src).origin;
			return siteJson.srcs.map(e => host + e);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => fn.gu("a:has(.fa-chevron-right):not([aria-current])"),
		prev: () => fn.gu("a:has(.fa-chevron-left):not([aria-current])"),
		chapters: () => {
			let [, , id] = fn.clp().split("/");
			return fn.j(`https://api.cdnlibs.org/api/manga/${id}/chapters`, {
				"headers": {
					"client-time-zone": "Asia/Taipei",
					"content-type": "application/json"
				}
			}).then(json => json.data.map(({
				volume,
				number
			}) => ({
				text: `Том ${volume} Глава ${number}`,
				url: `/ru/${id}/read/v${volume}/c${number}`
			})));
		},
		customTitle: () => getTitle(["#app header a div", 1, 2]),
		category: "comic"
	}, {
		name: "МангаПоиск",
		url: {
			h: ["mangap.ru"]
		},
		page: () => fn.clp("/chapter/"),
		json: () => fn.rd().then(() => {
			let pageData = fn.ge("#app[data-page]", doc).dataset.page;
			let json = JSON.parse(pageData);
			siteJson = {
				manga: json.props.manga.data,
				chapter: json.props.chapter.data
			}
			debug("\n此頁JSON資料\n", siteJson);
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.chapter.pages.map(e => e.link) : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => _this.page() && siteJson?.chapter?.nextChapter?.link ? siteJson.chapter.nextChapter.link : null,
		prev: 1,
		chapters: () => fn.j(`/manga/${fn.clp().split("/").at(2)}/chapterSelector/${siteJson.chapter.id}`).then(json => json.chapters.map(({
			title,
			link
		}) => ({
			text: title,
			url: link
		})).reverse()),
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				manga: {
					title: n
				},
				chapter: {
					title: c
				},
			} = siteJson;
			return n + " - " + c;
		},
		category: "comic"
	}, {
		name: "YomiRaw",
		url: {
			h: ["yomiraw.com"]
		},
		page: () => fn.clp("/chapters/"),
		update: "/manga?sort=latest",
		json: () => fn.rd().then(() => {
			try {
				let pageData = fn.ge("#app[data-page]", doc).dataset.page;
				let json = JSON.parse(pageData);
				siteJson = json.props;
				debug("\n此頁JSON資料\n", siteJson);
			} catch (e) {
				siteJson = {};
			}
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: async () => {
			if (!_this.page()) return [];
			let img = await fn.waitEle("img[alt^='Page'][src^='http']");
			if (!img) return [];
			let dir = fn.dir(img.src);
			let file_name = img.src.split("/").at(-1);
			let [num_str] = file_name.match(/\d+/);
			let num_str_length = num_str.length;
			let file_name_templet = file_name.replace(num_str, "{num}");
			return fn.arr(siteJson.pages.length, (v, i) => {
				if (num_str_length > 1) {
					return `${dir}${file_name_templet.replace("{num}", String(i + 1).padStart(num_str_length, "0"))}`;
				}
				return `${dir}${file_name_templet.replace("{num}", i + 1)}`;
			});
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let o = siteJson[key];
			return isObject(o) ? fn.wurl(o.slug) : null;
		},
		next: () => _this.np("nextChapter"),
		prev: () => _this.np("previousChapter"),
		chapters: () => siteJson.allChapters.map(({
			title,
			slug
		}) => ({
			text: title,
			url: fn.wurl(slug)
		})),
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				chapter: {
					manga: {
						name
					},
					title
				}
			} = siteJson;
			return name + " - " + title;
		},
		category: "comic"
	}, {
		name: "Weeb Central",
		url: {
			h: "weebcentral.com",
			p: "/chapters/"
		},
		init: () => {
			let chapters_url = fn.attr("button[hx-get]", "hx-get");
			let p_a = fn.fetchDoc(chapters_url).then(dom => {
				let button = fn.ge("#selected_chapter", dom);
				siteJson.next = button?.previousElementSibling;
				siteJson.prev = button?.nextElementSibling;
				siteJson.chapterList = fn.gae("button,a", dom);
			});
			let p_b = fn.waitEle("main section img[alt^=Page]").then(() => fn.createImgBox("section:has(img[alt^=Page])", 1));
			return Promise.all([p_a, p_b]);
		},
		imgs: () => fn.gae("main section img[alt^=Page]"),
		button: [4],
		insertImg: [
			["box", 0, "section:has(img[alt^=Page])"], 2
		],
		endColor: "white",
		autoDownload: [0],
		next: () => {
			let next = siteJson.next;
			return isEle(next) ? next.href : null;
		},
		prev: () => {
			let prev = siteJson.prev;
			return isEle(prev) ? prev.href : null;
		},
		chapters: () => siteJson.chapterList.map(e => {
			let url;
			if (e.tagName == "BUTTON") {
				url = fn.curl();
			} else {
				url = e.href;
			}
			return {
				text: e.innerText.trim(),
				url
			}
		}).reverse(),
		customTitle: () => fn.title(" | Weeb Central"),
		category: "comic"
	}, {
		name: "Manga Ball",
		url: {
			h: ["mangaball.net"],
			p: "/chapter-detail/"
		},
		init: () => {
			fn.sm5();
			let code = fn.gst("const titleId");
			let titleId = fn.textVar(code, "titleId");
			let chapterId = fn.textVar(code, "titleId");
			let chapterLanguage = fn.textVar(code, "chapterLanguage");
			let images = fn.textToArray(code, "JSON.parse");
			let formData = new FormData();
			formData.append("title_id", titleId);
			formData.append("lang", chapterLanguage);
			return fn.j("/api/v1/chapter/chapter-listing-by-title-id/", {
				headers: {
					"x-csrf-token": fn.ge("meta[name='csrf-token']").content,
					"x-requested-with": "XMLHttpRequest"
				},
				body: formData,
				method: "POST"
			}).then(json => {
				siteJson = {
					...json,
					...{
						titleId,
						chapterId,
						chapterLanguage,
						images
					}
				}
				siteJson.chapters = siteJson.ALL_CHAPTERS.map(({
					number,
					translations
				}) => ({
					text: number,
					url: `/chapter-detail/${translations[0].id}/`
				})).reverse();
				fn.hm();
				debug("\n此頁JSON資料\n", siteJson);
			});
		},
		box: ["#mangaPages", 1],
		imgs: () => siteJson.images,
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#mangaPages"),
		np: (i) => {
			let ci = siteJson.chapters.findIndex(o => o.url.includes(fn.lp));
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? o.url : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters,
		customTitle: ["h6:has(+#chapterInfo)", "#chapterTitle"],
		category: "comic"
	}, {
		name: "YuKomik",
		url: {
			h: "yukomik.com",
		},
		imgs: ".min-h-screen div[q\\:key] img",
		button: [4],
		insertImg: [".min-h-screen .min-h-screen", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='Next ']",
		prev: "//a[text()=' Prev']",
		chapters: {
			url: "a:has(h1[itemprop])",
			target: "//div[h1[span[text()='Chapter']]]//a",
			textNode: "p",
			sort: "r"
		},
		customTitle: [".min-h-screen h1", ".min-h-screen h2"],
		category: "comic"
	}, {
		name: "MangaHere/Manga Fox 分頁模式",
		url: {
			h: ["www.mangahere.cc", "fanfox.net", "mangafox.la"],
			p: "/manga/",
			e: ".cp-pager-list span",
		},
		imgs: () => {
			let code = fn.gst("imagecount");
			let imagecount = fn.numVar(code, "imagecount");
			let croot = fn.dir(fn.lp);
			let chapterid = fn.numVar(code, "chapterid");
			let fetchNum = 0;
			let keyE = fn.ge("#dm5_key");
			let key = keyE.value;
			let resArr = fn.arr(imagecount, (v, i) => {
				let params = fn.cp({
					cid: chapterid,
					page: i + 1,
					key: key
				});
				let api = `${croot}chapterfun.ashx?${params}`;
				return fn.t(api).then(r_text => {
					fn.showMsg(`${DL.str_06}(${fetchNum+=1}/${imagecount})`, 0);
					let text = fn.parseCode(r_text);
					let pix = fn.textVar(text, "pix");
					let pvalue = fn.textToArray(text, "pvalue");
					return pix + pvalue[0];
				});
			});
			return Promise.all(resArr);
		},
		button: [4],
		insertImg: [".reader-main", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='Next Chapter']",
		prev: "//a[text()='Pre chapter']",
		chapters: {
			target: ".reader-header-title-list a"
		},
		customTitle: () => fn.ge("meta[name='og:title']")?.content?.split(" - ")[1]?.replace(/Read | Online/g, ""),
		hide: ".ad-reader,.pager-list-left>span",
		category: "comic"
	}, {
		name: "MangaHere/Manga Fox 條漫模式",
		url: {
			h: ["www.mangahere.cc", "fanfox.net", "mangafox.la"],
			p: "/manga/",
			e: ".cp-pager-list",
		},
		init: () => fn.waitEle(".reader-main img"),
		imgs: () => fn.gae(".reader-main img"),
		button: [4],
		insertImg: [".reader-main", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='Next Chapter']",
		prev: "//a[text()='Pre chapter']",
		chapters: {
			target: ".reader-header-title-list a"
		},
		customTitle: () => fn.ge("meta[name='og:title']")?.content?.split(" - ")[1]?.replace(/Read | Online/g, ""),
		hide: ".ad-reader",
		category: "comic"
	}, {
		name: "MangaHere/Manga Fox M",
		url: {
			h: ["m.mangahere.cc", "m.fanfox.net"],
			p: ["/manga/", "/roll_manga/"],
			e: "#viewer"
		},
		init: () => {
			let url = fn.url.replace("/manga/", "/roll_manga/");
			return fn.fetchDoc(url).then(dom => {
				siteJson.srcs = fn.getImgSrcArr("#viewer img", dom);
				let btn = fn.ge(".roll-pagebtn", dom);
				if (btn) {
					tempEles.push(btn);
					let next = fn.ge("//a[text()='Next Chapter']", btn);
					if (next) {
						tempNextLink = next.href;
					}
				}
			});
		},
		imgs: () => siteJson.srcs,
		button: [4, 1],
		insertImg: ["#viewer", 2],
		endColor: "white",
		insertImgAF: (parent) => {
			if (tempEles.length > 0 && !fn.ge(".roll-pagebtn")) {
				parent.after(...tempEles);
			}
			fn.remove(".pager,.mangaread-page");
		},
		next: () => tempNextLink,
		prev: 1,
		customTitle: () => {
			if (fn.lh.includes("fanfox")) {
				return document.title + fn.gt(".mangaread-title");
			}
			let code = fn.gst("addHistory");
			let json = fn.textToObject(code, "addHistory");
			let ch = fn.gt(".return-title");
			return json.name + " - " + ch;
		},
		category: "comic"
	}, {
		name: "MangaHere/Manga Fox M",
		url: {
			h: ["newm.mangahere.cc", "newm.fanfox.net"],
			p: "/manga/",
			e: ".read-bottom-bar"
		},
		imgs: () => {
			if (fn.ge(".read-bottom-bar-block.control-right")) {
				let code = fn.gst("imagecount");
				let imagecount = fn.numVar(code, "imagecount");
				let croot = fn.dir(fn.lp);
				let chapterid = fn.numVar(code, "chapterid");
				let fetchNum = 0;
				let resArr = fn.arr(imagecount, (v, i) => {
					let params = fn.cp({
						cid: chapterid,
						page: i + 1,
						key: ""
					});
					let api = `${croot}chapterfun.ashx?${params}`;
					return fn.t(api).then(r_text => {
						fn.showMsg(`${DL.str_06}(${fetchNum+=1}/${imagecount})`, 0);
						let text = fn.parseCode(r_text);
						let pix = fn.textVar(text, "pix");
						let pvalue = fn.textToArray(text, "pvalue");
						return pix + pvalue[0];
					});
				});
				return Promise.all(resArr);
			}
			return fn.gae(".read-img-bar img");
		},
		button: [4],
		insertImg: [".read-img-bar", 2],
		insertImgAF: (parent) => {
			fn.run("jQuery('.read-img-bar').off()")
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 5);
			}
		},
		next: "//a[div[p[text()='Next Chapter']]][not(starts-with(@href,'java'))]",
		prev: "//a[div[p[text()='Last Chapter' or text()='Prev Chapter']]][not(starts-with(@href,'java'))]",
		customTitle: () => fn.ge("meta[name='og:title']")?.content?.split(" - ")[1]?.replace(/Read | Online/g, ""),
		css: "#FullPictureLoadOptionsButtonParentDiv{margin-top:50px;}",
		hide: "div:has(>[id^=mc])",
		category: "comic"
	}, {
		name: "MangaFire",
		url: {
			h: ["mangafire.to"]
		},
		page: () => fn.clp("/read/"),
		SPA: () => _this.page(),
		observeURL: "head",
		home: "/home",
		init: () => {
			siteJson.images = null;
			if (!isAddAjaxHooker) {
				isAddAjaxHooker = true;
				const ajaxHooker = addAjaxHookerLibrary();
				ajaxHooker.filter([{
					url: "/ajax/read/chapter/"
				}]);
				ajaxHooker.hook(request => {
					request.response = res => {
						let json = JSON.parse(res.responseText);
						siteJson.images = json?.result?.images;
					}
				});
			}
			return _this.page() ? fn.sm5().then(() => fn.wait(() => isArray(siteJson.images))).then(() => fn.hm()) : void 0;
		},
		imgs: () => siteJson?.images?.map(arr => arr.find(e => e.startsWith("http"))) || [],
		capture: () => _this.imgs(),
		customTitle: () => {
			if (_this.page()) {
				return fn.rt(document.title, [
					[" - Read Manga Online", ""],
					[" chapter", " - Chapter"]
				]);
			}
			return null;
		},
		category: "comic"
	}, {
		name: "Mangapill",
		url: {
			h: ["www.mangapill.com", "mangapill.com"],
			p: "/chapters/"
		},
		update: "/chapters",
		imgs: "chapter-page img",
		button: [4],
		insertImg: ["div:has(>chapter-page)", 2],
		autoDownload: [0],
		next: "a[data-hotkey=ArrowRight]",
		prev: "a[data-hotkey=ArrowLeft]",
		chapters: {
			api: () => {
				let [id] = fn.lp.match(/\d+/);
				return `/manga/${id}/chapters`;
			},
			target: "a",
			sort: "r"
		},
		customTitle: "h1#top",
		hide: ".flex.items-center.justify-between:has(svg[data-remove-flyer])",
		category: "comic"
	}, {
		name: "TodayManga",
		url: {
			h: ["todaymanga.com"],
			p: "/ch-"
		},
		update: "/category/recent",
		imgs: ".chapter-content>img[data-src]",
		button: [4],
		insertImg: [".chapter-content", 2],
		autoDownload: [0],
		next: "a:has(>.icon-ic_arw_right)",
		prev: "a:has(>.icon-ic_arw_left)",
		chapters: {
			api: () => fn.attr("button[data-url]", "data-url"),
			target: "a",
			sort: "r"
		},
		customTitle: [".chapter-name>a", ".chapter-name>span"],
		category: "comic"
	}, {
		name: "MangaTown",
		url: {
			h: ["www.mangatown.com", "m.mangatown.com"],
			p: "/manga/",
			e: "#top_chapter_list"
		},
		update: "/latest/",
		init: async () => {
			if (fn.lh.startsWith("m.")) {
				await fn.waitEle("#top_chapter_list option");
				for (let e of fn.gae("#top_chapter_list option")) {
					let url = e.value;
					if (url.includes("//manga")) {
						url = url.replace("https://m.mangatown.com/", "");
					}
					if (!url.endsWith("/")) {
						url = url + "/";
					}
					e.value = url;
				}
			}
		},
		imgs: () => {
			if (fn.ge("#viewer .image")) {
				return fn.gae("#viewer .image");
			}
			let max;
			if (fn.lh.startsWith("m.")) {
				max = fn.gae(".ch-select option").length;
			} else {
				max = _unsafeWindow.total_pages;
			}
			let links = fn.arr(max, (v, i) => i == 0 ? fn.lp : fn.lp + `${i + 1}.html`);
			return fn.getImgA("#image", links);
		},
		button: [4],
		insertImg: ["#viewer", 2],
		endColor: "white",
		insertImgAF: (parent) => {
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 6);
			}
			document.onkeyup = null;
		},
		autoDownload: [0],
		np: (k) => {
			let chapters = fn.gae("#top_chapter_list option");
			let c = chapters.find(e => e.value == fn.lp);
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("nextElementSibling"),
		prev: () => _this.np("previousElementSibling"),
		chapters: {
			target: "#top_chapter_list option"
		},
		customTitle: () => {
			if (fn.lh.startsWith("m.")) {
				return fn.dt({
					s: ".title>a",
					d: " Page 1"
				});
			}
			return fn.dt({
				d: [
					/.+- Read/,
					"Online - Page 1",
				]
			});
		},
		hide: ".page_select,div[style]:has(>.page_select),.ch-select,#pager",
		category: "comic"
	}, {
		name: "MangaHome",
		url: {
			h: "www.mangahome.com",
			p: "/manga/",
			e: "#viewer"
		},
		update: "/latest/shoujo",
		init: () => fn.waitEle("#readChapterLists a"),
		imgs: () => {
			const {
				imagecount,
				chapter_id
			} = _unsafeWindow;
			let fetchNum = 0;
			let resArr = fn.arr(imagecount, (v, i) => {
				let params = fn.cp({
					cid: chapter_id,
					page: i + 1,
					key: ""
				});
				let api = `chapterfun.ashx?${params}`;
				return fn.t(api).then(r_text => {
					fn.showMsg(`${DL.str_06}(${fetchNum+=1}/${imagecount})`, 0);
					let text = fn.parseCode(r_text);
					let [, pix] = text.match(/pix="([^"]+)/);
					let [, pvalue] = text.match(/pvalue=([^;]+)/);
					pvalue = JSON.parse(pvalue);
					return pix + pvalue[0];
				});
			});
			return Promise.all(resArr);
		},
		button: [4],
		insertImg: ["#viewer", 2],
		endColor: "white",
		insertImgAF: () => fn.run("$('body').off()"),
		autoDownload: [0],
		next: "//a[text()='Next Chapter']",
		prev: "//a[text()='Prev Chapter']",
		chapters: {
			target: "#readChapterLists a"
		},
		customTitle: () => fn.dt({
			d: [
				/.+- Read/,
				"Online - Page 1",
			]
		}),
		hide: ".mangaread-pagenav",
		category: "comic"
	}, {
		name: "Asura Scans",
		url: {
			h: "asuracomic.net",
			p: "/chapter/"
		},
		update: "/series",
		init: () => fn.waitEle("img[alt*='chapter']"),
		imgs: () => fn.gae("img[alt*='chapter']"),
		button: [4],
		insertImg: ["div:has(>div>div>img[alt*='chapter'])", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[div[h2[text()='Next']]]",
		prev: "//a[div[h2[text()='Prev']]]",
		chapters: {
			url: "h2+p a",
			target: "//div[a[div[h3[text()='First Chapter']]]]/following-sibling::div//a",
			textNode: "h3",
			cb: (text, u) => ({
				text,
				url: [...new Set(u.split("/"))].join("/")
			}),
			sort: "r"
		},
		customTitle: "h2.text-xl",
		hide: "#header-ads,.bg-gradient-to-br,.backdrop-blur-sm",
		category: "comic"
	}, {
		name: "Comick",
		h: ["comick.art", "comick.live"],
		url: {
			t: "ComicK",
			p: "/comic/",
			e: "#sv-data"
		},
		home: "/home",
		init: () => (siteJson = JSON.parse(document.querySelector("#sv-data").innerHTML)),
		imgs: () => siteJson.chapter.images.map(e => e.url),
		button: [4],
		insertImg: [".overflow-scroll", 2],
		insertImgAF: (parent) => parent.classList.remove("overflow-scroll", "remove-scroll-bar"),
		autoDownload: [0],
		chapter_url: (i) => {
			let {
				chapter,
				chapterList
			} = siteJson;
			let c_i = chapterList.findIndex(d => d.hid == chapter.hid);
			let next_prev = chapterList[c_i + i];
			if (isObject(next_prev)) {
				let dir = fn.dir(fn.url);
				let {
					chap,
					hid,
					lang
				} = next_prev;
				return `${dir}${hid}-chapter-${chap}-${lang}`;
			}
			return null;
		},
		next: () => _this.chapter_url(-1),
		prev: () => _this.chapter_url(1),
		chapters: () => siteJson.chapterList.map(({
			chap,
			hid,
			lang
		}) => ({
			text: `Ch ${chap}`,
			url: `${fn.dir(fn.url)}${hid}-chapter-${chap}-${lang}`
		})).reverse(),
		customTitle: () => siteJson.chapter.comic.title + " - Chapter " + siteJson.chapter.chap,
		hide: ".ads-banner-container",
		category: "comic"
	}, {
		name: "Project Suki",
		url: {
			h: ["www.projectsuki.com", "projectsuki.com"],
			p: "/read/"
		},
		box: [".strip-reader", 1, 1280],
		imgs: () => {
			let [, , mid, cid] = fn.lp.split("/");
			return fn.j("/callpage", {
				"body": JSON.stringify({
					bookid: mid,
					chapterid: cid,
					first: true
				}),
				"method": "POST"
			}).then(json => {
				let html = fn.ge(".strip-reader").innerHTML;
				html += json.src;
				let dom = fn.doc(html);
				return [...dom.images];
			});
		},
		button: [4],
		insertImg: [
			["box", 0, ".strip-reader"], 2
		],
		autoDownload: [0],
		next: "a[title='Next chapter']",
		prev: "a[title='Previous chapter']",
		chapters: {
			target: "#chapter-select>option",
			cb: (t, u) => ({
				text: "Chapter " + t.match(/[\d\.]+/).at(0),
				url: fn.wurl(u, fn.lp, 3)
			}),
			sort: "r"
		},
		customTitle: () => fn.title(" | Project Suki"),
		category: "comic"
	}, {
		name: "MangaDemon",
		url: {
			h: ["www.demonicscans.org", "demonicscans.org"],
			p: "/chapter/"
		},
		update: "/lastupdates.php",
		box: [".main-width .chapter-info", 1],
		imgs: ".imgholder:not([src*='free_ads'])",
		button: [4],
		insertImg: [
			["box", 0, ".main-width>*:not(#FullPictureLoadMainImgBox,.chapter-info,center)"], 2
		],
		autoDownload: [0],
		next: "a.nextchap",
		prev: "a.prevchap",
		chapters: {
			node: ".chapters-nav select",
			target: "option"
		},
		checkCurrentChapter: (url) => {
			let cid = fn.lp.split("/").at(-2);
			let uid = fn.getUSP("chapter", location.origin + url);
			return cid == uid;
		},
		hide: "#teaser3",
		category: "comic"
	}, {
		name: "Sektekomik",
		url: {
			h: ["sektekomik.id"]
		},
		update: "/manga?sort=updated",
		imgs: ".read-img>img",
		button: [4],
		insertImg: [".read-img", 2],
		autoDownload: [0],
		next: ".text-right a.nav-chap",
		prev: ".text-left a.nav-chap",
		chapters: {
			url: ".breadcrumb__links a",
			urlIndex: 1,
			target: "#chapterList a"
		},
		customTitle: ".container h3",
		category: "comic"
	}, {
		name: "BaoTangTruyen",
		host: ["baotangtruyen36.top"],
		url: {
			t: "BaoTangTruyen",
		},
		page: () => fn.clp("/chapter-"),
		SPA: () => _this.page(),
		observeURL: "head",
		ah: "https://api.chilltruyentranh.site",
		json: () => fn.sm5().then(() => {
			let [, , mid, cid] = fn.clp().split("/");
			let res_a = fetch(`${_this.ah}/comic/${mid}/${cid}`).then(res => res.json());
			let res_b = fetch(`${_this.ah}/api/comics/${mid}/chapters`).then(res => res.json());
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b,
					mid,
					cid
				};
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.images.map(e => _this.ah + e) : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (i) => {
			let cs = siteJson.chapters;
			let ci = cs.findIndex(o => o.slug == siteJson.cid);
			let ti = ci + i;
			return isObject(cs[ti]) ? fn.wurl(cs[ti].slug) : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: () => siteJson.chapters.map(o => ({
			text: o.name,
			url: fn.wurl(o.slug)
		})).reverse(),
		customTitle: () => _this.page() ? siteJson.comic_name + " - " + siteJson.chapter_name : null,
		category: "comic"
	}, {
		name: "TruyenSieuHay",
		url: {
			h: ["truyensieuhay.com"],
			p: "-chapter-",
			e: "#btn_report_chap"
		},
		update: "/danhsach/index.html?status=0&sort=2",
		decrypt: (des, id) => {
			const CryptoJS = addCryptoJSLibrary();
			const key = CryptoJS.enc.Utf8.parse(id.substring(2, id.length - 3).toLowerCase());
			const iv = CryptoJS.enc.Utf8.parse('gqLOHUioQ0QjhuvI');
			return CryptoJS.AES.decrypt(des, key, {
				iv: iv,
				mode: CryptoJS.mode.CBC,
			}).toString(CryptoJS.enc.Utf8);
		},
		box: ["#contentchap", 1],
		imgs: () => {
			fn.sm5();
			let [, sID, , chuc] = fn.attr("#btn_report_chap", "onclick").split("'");
			return fn.j("/Service.asmx/getContentChap", {
				headers: {
					"content-type": "application/json; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				body: `{ sID: '${sID}', chuc:'${chuc}' }`,
				method: "POST"
			}).then(json => {
				let {
					id,
					des
				} = JSON.parse(json.d);
				let html = _this.decrypt(des, id);
				let dom = fn.doc(html);
				return [...dom.images];
			});
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#contentchap"),
		autoDownload: [0],
		next: ".nav-read-page .next-chap.pull-left>a",
		prev: ".nav-read-page .pre-chap.pull-left>a",
		chapters: {
			target: "#ddl_listchap>option",
			cb: (text, u) => ({
				text,
				url: `${fn.dir(fn.url)}${u}.html`
			}),
			sort: "r"
		},
		customTitle: ".title-header",
		hide: "#popup-giua-man-hinh",
		category: "comic"
	}, {
		name: "TruyenQQ",
		host: ["truyenqqno.com"],
		url: {
			e: "meta[property='og:site_name'][content^=TruyenQQ]",
			p: "-chap-"
		},
		init: () => {
			fn.wait((_, w) => isFn(w?.jQuery?.fn?.isInViewport)).then(() => fn.rjk());
		},
		box: [".chapter_control", 1],
		imgs: ".chapter_content .page-chapter>img[data-original]",
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.remove(".chapter_content>*:not([id^=Full],.chapter_control)"),
		autoDownload: [0],
		next: "a[href]:has(>.fa-arrow-right)",
		prev: "a[href]:has(>.fa-arrow-left)",
		chapters: {
			target: ".chapter_list>option",
			sort: "r"
		},
		customTitle: ".detail-title",
		category: "comic"
	}, {
		name: "FoxTruyen",
		host: ["foxtruyen.com"],
		url: {
			e: "meta[property='og:site_name'][content=FoxTruyen]",
			p: "-chap-"
		},
		init: () => {
			fn.wait((_, w) => isFn(w?.jQuery?.lazy)).then(() => fn.rjk());
		},
		imgs: ".content_detail_manga>img",
		button: [4],
		insertImg: [".content_detail_manga", 2],
		autoDownload: [0],
		next: ".button-next-prev>a[href]:has(>.bi-arrow-right-short)",
		prev: ".button-next-prev>a[href]:has(>.bi-arrow-left-short)",
		chapters: {
			url: ".title-detail a",
			target: ".list_chap a",
			sort: "r"
		},
		customTitle: ".title-detail>h1",
		category: "comic"
	}, {
		name: "TopTruyen",
		host: ["www.toptruyentv11.com"],
		url: {
			e: "meta[property='og:site_name'][content=TopTruyenVN]",
			p: "/chapter-"
		},
		init: () => {
			fn.wait((_, w) => isFn(w?.reloadImg)).then(() => fn.rjk());
		},
		imgs: () => fn.gae(".list-image-detail>[id^=page]>img").map(e => e.src),
		button: [4],
		insertImg: [".list-image-detail", 2],
		autoDownload: [0],
		next: "a.next-chapter",
		prev: "a.previous-chapter",
		chapters: {
			target: "#select_chapter>option",
			sort: "r"
		},
		customTitle: [".breadcrumb>li", 1, 2],
		category: "comic"
	}, {
		name: "NewTruyenTranh",
		host: ["newtruyentranh5.com"],
		url: {
			t: "NewTruyenTranh",
			p: "/chapter-"
		},
		init: () => {
			fn.wait((_, w) => isFn(w?.getlistCmt)).then(() => fn.rjk());
		},
		imgs: ".reading-detail>.page-chapter>img",
		button: [4],
		insertImg: [".reading-detail", 2],
		autoDownload: [0],
		next: "#nextChapter:not(.disabled)",
		prev: "#prevChapter:not(.disabled)",
		chapters: {
			target: ".select-chapter>option",
			sort: "r"
		},
		customTitle: ".breadcrumb+h1",
		category: "comic"
	}, {
		name: "Kingsmanga",
		url: {
			h: "www.kingsmanga.net"
		},
		imgs: ".post-content img",
		button: [4],
		insertImg: [".post-content", 2],
		autoDownload: [0],
		next: ".reader-content a[rel=next]",
		prev: ".reader-content a[rel=prev]",
		chapters: {
			url: "#breadcrumbs a",
			urlIndex: 2,
			target: ".table-bordered a",
			cb: (t, u) => ({
				text: t.trim().match(/[\d\.]+$/)[0],
				url: u
			}),
			sort: "r"
		},
		customTitle: "h1.entry-title",
		category: "comic"
	}, {
		name: "MangaToons",
		url: {
			h: "mangatoon.mobi",
			p: "/watch/",
			e: ".episode",
			ee: ".new-episode-lock"
		},
		init: () => fn.waitEle(".pictures img:not(.cover)"),
		imgs: ".pictures img:not(.cover)",
		button: [4],
		insertImg: [".pictures", 2],
		autoDownload: [0],
		next: ".page-icons-next",
		prev: ".page-icons-prev",
		chapters: {
			url: ".top-left a",
			target: ".episode-content-asc .episodes-wrap-new a.episode-item-new",
			textNode: ".episode-title-new:not(.episode-number)"
		},
		customTitle: [".title", ".episode"],
		category: "comic"
	}, {
		name: "Assorted Scans",
		url: {
			h: "assortedscans.com",
			p: "/reader/"
		},
		box: ["#dropdowns", 2],
		imgs: () => fn.getImgA("#page-image", ".dropdown-list:has(.page-details)>li:not(:first-child)>a"),
		button: [4],
		insertImg: [
			["box", 0, "#page-image"], 2
		],
		autoDownload: [0],
		np: (i) => {
			let cs = fn.gae(".chapter-details");
			let ci = cs.findIndex(e => !!e.dataset?.current);
			let ti = ci + i;
			return isEle(cs[ti]) ? fn.gu("a", cs[ti]) : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: {
			target: ".chapter-details a",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => url.split("/").at(-2) == location.href.split("/").at(-3),
		customTitle: () => fn.dt({
			t: fn.ge("#content>h1>a").textContent
		}) + " - " + fn.gt(".dropdown-title+a>span"),
		category: "comic"
	}, {
		name: "NovaManga",
		url: {
			h: "novamanga.com",
			p: "/read/"
		},
		imgs: ".content>img[id^=img][data-src]",
		button: [4],
		insertImg: [".content", 2],
		autoDownload: [0],
		next: "//a[span[text()='Next']]",
		prev: "//a[p[text()='Previous']]",
		chapters: {
			node: "//div[div[p[text()='Select Episode']]]//following-sibling::div[@data-select-content]",
			target: "a"
		},
		customTitle: [".items-center.justify-center a", 2, 3],
		category: "comic"
	}, {
		name: "Read Manga",
		url: {
			h: "readmanga.cc",
			p: "/chapter-"
		},
		imgs: "div.justify-center>img[alt][loading=eager]",
		button: [4],
		insertImg: ["div.justify-center:has(>img[alt][loading=eager])", 2],
		autoDownload: [0],
		next: "//a[contains(text(),'Next')]",
		prev: "//a[contains(text(),'Previous')]",
		chapters: {
			target: "#chapter-select option",
			cb: (text, u) => ({
				text,
				url: fn.url.replace(/[\d\.]+$/, u)
			}),
			sort: "r"
		},
		customTitle: ["nav>ol>li", 1, 2],
		category: "comic"
	}, {
		name: "MangaSail",
		url: {
			h: "www.sailmg.com",
			p: "/content/"
		},
		box: ["#images>.mnav", 1],
		imgs: "#images>img",
		button: [4],
		insertImg: [
			["box", 0, "#images>*:not(.mnav,[id])"], 2
		],
		autoDownload: [0],
		next: ".mnav>.mna-r",
		prev: ".mnav>.mna-l",
		chapters: {
			target: "#edit-select-node option",
			cb: (t, u) => ({
				text: "Chapter " + t.match(/[\d\.]+$/).at(0),
				url: "/node/" + u
			}),
			sort: "r"
		},
		checkCurrentChapter: (_, t) => fn.url.match(/[\d\.]+$/).at(0) == t.match(/[\d\.]+$/).at(0),
		customTitle: () => fn.rt(fn.gt(".page-header>a"), /([\d+\.]+)$/, "- Chapter $1"),
		category: "comic"
	}, {
		name: "Manga-Doom",
		url: {
			h: ["manga-doom.com"],
			p: "/all-pages"
		},
		imgs: ".inner-page img",
		button: [4],
		insertImg: [".post-footer+div", 2],
		autoDownload: [0],
		np: (k) => {
			let e = fn.ge("option[selected]");
			return isEle(e[k]) ? e[k].value + "/all-pages" : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			node: ".chapterSelect>select",
			target: "option",
			cb: (t, url) => ({
				text: "Chapter " + t.match(/[\d\.]+$/).at(0),
				url: url + "/all-pages"
			}),
			sort: "r"
		},
		customTitle: () => fn.rt(fn.gt("option[selected]"), /([\d\.\s]+)$/, " Chapter$1"),
		category: "comic"
	}, {
		name: "MangaPanda/MangaReader",
		url: {
			h: ["www.mangapanda.in", "mangareader.in"],
			p: "-chapter-",
			e: "#arraydata"
		},
		imgs: () => fn.ge("#arraydata").textContent.split(","),
		button: [4],
		insertImg: [".chapter-content-inner", 2],
		autoDownload: [0],
		next: "a.RightArrow",
		prev: "a.LeftArrow.prev",
		chapters: {
			api: () => {
				let code = fn.gst("load_chapters_selectbox");
				let args = fn.textToObject(code, "args");
				return `/ajax-load-chapters-selectbox?mangaID=${args.mangaID}`;
			},
			target: "option",
			sort: "r"
		},
		customTitle: ["h2.chapter-title", 1, 0],
		category: "comic"
	}, {
		name: "MangaMob",
		url: {
			h: "mangamob.com",
			p: "/chapter/"
		},
		update: "/browse-comics/?filter=Updated",
		imgs: "#chapter-images img",
		button: [4, 4],
		insertImg: ["#chapter-images", 2],
		autoDownload: [0],
		next: ".sticky-chaps>a:has(.fa-arrow-right)",
		prev: ".sticky-chaps>a:has(.fa-arrow-left)",
		chapters: () => fn.gae("#nav-chapter-select>option").map(o => ({
			text: o.text,
			url: fn.wurl(o.value, fn.url, -2)
		})).reverse(),
		customTitle: () => fn.title("Read Chapter "),
		category: "comic"
	}, {
		name: "MangaGeko",
		url: {
			h: "www.mgeko.cc",
			p: "/reader/"
		},
		update: "/jumbo/manga/",
		init: () => fn.addMutationObserver(() => fn.remove("#radio_content")),
		imgs: "#chapter-reader img",
		button: [4],
		insertImg: ["#chapter-reader", 2],
		autoDownload: [0],
		next: ".chnav.next[href^='/reader/']",
		prev: ".chnav.prev[href^='/reader/']",
		chapters: {
			node: ".chapternav select",
			target: "option",
			cb: (t, v, e) => ({
				text: t.replace("-eng-li", ""),
				url: e.value ? v : fn.lp
			}),
			sort: "r"
		},
		customTitle: () => fn.title("Manga: "),
		hide: "center:has(>#chapter-reader)>*:not(#chapter-reader),.chapternav+div[style]",
		category: "comic"
	}, {
		name: "Qi Scans",
		url: {
			h: ["qiscans.org"]
		},
		page: () => fn.clp("/chapter-"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let code = fn.__next_f(doc);
			code = fn.stringSlicer(code, '"images":[', "]");
			if (!code) return [];
			return JSON.parse("[" + code).map(e => e.url);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let e = fn.ge(`//a[button[text()='${key}']]`);
			return isEle(e) ? e.pathname : null;
		},
		next: () => _this.np("Next"),
		prev: () => _this.np("Previous"),
		chapters: () => fn.j(`https://api.qiscans.org/api/post/chapters?postSlug=${fn.clp().split("/").at(-2)}`).then(array => array.map(({
			slug,
			number
		}) => ({
			text: `Chapter ${number}`,
			url: fn.wurl(slug)
		}))),
		category: "comic"
	}, {
		name: "SetsuScans",
		url: {
			h: ["manga.saytsu.com"]
		},
		page: () => fn.clp("/chapter-"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			fn.sm5();
			let res_a = fn.j(`https://api.saytsu.com/${fn.clp().replace(/\/chapter[\d\.\_\-]+$/, "")}`);
			let res_b = fn.j(`https://api.saytsu.com/${fn.clp()}`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...b,
					...a
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			fn.sm5();
			let fetchNum = 0;
			let resArr = siteJson.full_image_paths.map((path, i, arr) => fn.b(location.origin + "/" + path, {
				headers: {
					"accept": "image/webp, human/ok",
				}
			}).finally(() => {
				fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
			}));
			return Promise.all(resArr).then(blobs => blobs.map(blob => URL.createObjectURL(blob)));
		},
		autoDownload: [0],
		np: (i) => {
			if (!_this.page()) return null;
			let slug = fn.clp().split("/").at(-1);
			let chapters = siteJson.chapters.sort((a, b) => a.index - b.index);
			let ci = chapters.findIndex(o => o.slug == slug);
			let o = chapters[ci + i];
			return isObject(o) ? fn.wurl(o.slug) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.sort((a, b) => a - b).map(({
			slug,
			chapter_number
		}) => ({
			text: `Chapter ${chapter_number}`,
			url: fn.wurl(slug)
		})),
		customTitle: () => _this.page() ? `${siteJson.title} - Chapter ${siteJson.chapter_number}` : null,
		category: "comic"
	}, {
		name: "Comix",
		url: {
			h: ["comix.to"]
		},
		home: "/home",
		page: () => fn.clp("-chapter-"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd().then(() => fn.wait(() => {
			let e = fn.ge("#syncData");
			if (isEle(e)) {
				return e.textContent?.includes('"chapter"');
			}
			return false;
		}).then(() => {
			siteJson = JSON.parse(fn.ge("#syncData").textContent);
			debug("\n此頁JSON資料\n", siteJson);
		})) : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let code = fn.gst('\\"images\\"', doc);
			if (!code) return [];
			code = code.replaceAll("\\", "");
			return fn.textToArray(code, '"images":').map(e => {
				if (isObject(e)) {
					return e.url;
				}
				return e;
			});
		},
		capture: () => _this.imgs(),
		np: (k) => {
			if (k in siteJson) {
				return siteJson[k];
			}
			return null;
		},
		next: () => _this.np("next_chapter_url"),
		prev: () => _this.np("prev_chapter_url"),
		chapters: () => {
			let filter = (array) => {
				let temp = new Set();
				return array.filter(o => {
					if (temp.has(o.number)) {
						return false;
					} else {
						temp.add(o.number);
						return true;
					}
				}).map(({
					chapter_id,
					number
				}) => ({
					text: `Chapter ${number}`,
					url: `${siteJson.manga_url}/${chapter_id}-chapter-${number}`
				}));
			};
			return fetch(`/api/v2/manga/${siteJson.manga_id}/chapters?limit=100&page=1&order[number]=asc`).then(res => res.json()).then(json => {
				if (json.result.pagination.last_page > 1) {
					let pages = Array.from({
						length: json.result.pagination.last_page - 1
					}, (v, i) => fetch(`/api/v2/manga/${siteJson.manga_id}/chapters?limit=100&page=${i + 2}&order[number]=asc`).then(res => res.json()));
					return Promise.all(pages).then(data => {
						let items = [json, ...data].map(j => j.result.items).flat();
						return filter(items);
					});
				}
				return filter(json.result.items);
			});
		},
		checkCurrentChapter: (url, text) => text.split(" ").at(-1) == fn.clp().split("-").at(-1),
		customTitle: () => _this.page() ? `${siteJson.name} - Chapter ${siteJson.number}` : null,
		category: "comic"
	}, {
		name: "WeebDex",
		url: {
			h: ["weebdex.org"]
		},
		page: () => fn.clp("/chapter/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => fn.sm5().then(() => {
			return fn.j(`https://api.weebdex.org/chapter/${fn.clp().split("/").at(2)}`).then(json => {
				siteJson = json;
				return fn.j(`https://api.weebdex.org/manga/${json.relationships.manga.id}/aggregate?tlang=${json.language}`).then(json => {
					siteJson = {
						...siteJson,
						...json
					};
					debug("\n此頁JSON資料\n", siteJson);
					fn.hm();
				});
			});
		}),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				id,
				data,
				data_optimized,
				node,
			} = siteJson;
			return (data ?? data_optimized).map(o => `${node}/data/${id}/${o.name}`);
		},
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let ci = siteJson.chapters.findIndex(o => (siteJson.id in o.entries));
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? `https://weebdex.org/chapter/${Object.keys(o.entries).at(-1)}/1` : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: () => siteJson.chapters.map(({
			chapter,
			entries
		}) => ({
			text: `Chapter ${chapter}`,
			url: `/chapter/${Object.keys(entries).at(-1)}/1`
		})).reverse(),
		customTitle: () => {
			if (_this.page()) {
				let str;
				if ("volume" in siteJson) {
					str = `${siteJson.relationships.manga.title} - Volume ${siteJson.volume} Chapter ${siteJson.chapter}`;
				} else {
					str = `${siteJson.relationships.manga.title} - Chapter ${siteJson.chapter}`;
				}
				if ("title" in siteJson) {
					str += ` - ${siteJson.title}`;
				}
				return str;
			}
			return null;
		},
		category: "comic"
	}, {
		name: "Atsumaru",
		url: {
			h: ["atsu.moe"]
		},
		page: () => fn.clp("/read/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => fn.sm5().then(() => {
			let [, , mid, cid] = fn.clp().split("/");
			let res_a = fn.j(`/api/manga/info?mangaId=${mid}`);
			let res_b = fn.j(`/api/read/chapter?mangaId=${mid}&chapterId=${cid}`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b,
					mid,
					cid
				}
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.readChapter.pages.map(o => o.image);
		},
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let ci = siteJson.chapters.findIndex(o => o.id == siteJson.cid);
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			title,
			id
		}) => ({
			text: title,
			url: fn.wurl(id)
		})),
		customTitle: () => _this.page() ? siteJson.title + " - " + siteJson.readChapter.title : null,
		category: "comic"
	}, {
		name: "MangaCloud",
		url: {
			h: ["mangacloud.org"]
		},
		page: () => fn.clp("/chapter/"),
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => fn.sm5().then(() => {
			let [, , mid, , cid] = fn.clp().trim().split("/");
			let res_a = fn.j(`https://api.mangacloud.org/comic/${mid}`);
			let res_b = fn.j(`https://api.mangacloud.org/chapter/${cid}`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a.data,
					...b.data,
					mid,
					cid
				}
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		}),
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.images.map(o => `https://pika.mangacloud.org/${siteJson.mid}/${siteJson.cid}/${o.id}.${o.f}`);
		},
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let ci = siteJson.chapters.findIndex(o => o.id == siteJson.cid);
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: () => siteJson.chapters.map(({
			number,
			id
		}) => ({
			text: "Chapter " + number,
			url: fn.wurl(id)
		})).reverse(),
		customTitle: () => _this.page() ? siteJson.title + " - Chapter " + siteJson.number : null,
		category: "comic"
	}, {
		name: "All Manga",
		url: {
			h: ["allmanga.to"]
		},
		page: () => fn.clp("/chapter-"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd().then(dom => {
			let code = fn.gst("__NUXT__", dom);
			let data = fn.parseCode(code);
			siteJson = data.fetch["chapter:0"];
			siteJson.chapterList = siteJson.chapterSelectionOptions.map(({
				chapterString
			}) => ({
				text: `Chapter ${chapterString}`,
				url: fn.wurl(`chapter-${chapterString}-sub`)
			})).reverse();
			debug("\n此頁JSON資料\n", siteJson);
		}) : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			return siteJson.chapters[0].pictureUrls.map(o => "https://ytimgf.youtube-anime.com/" + o.url);
		},
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let ci = siteJson.chapterList.findIndex(o => o.url == fn.clp());
			let o = siteJson.chapterList[ci + i];
			return isObject(o) ? o.url : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapterList,
		customTitle: () => _this.page() ? siteJson.manga.name + " - Chapter " + siteJson.chapters[0].chapterString : null,
		category: "comic"
	}, {
		name: "Flame Comics",
		url: {
			h: ["flamecomics.xyz"]
		},
		json: () => fn.rd().then(() => {
			let code = fn.gt("#__NEXT_DATA__", 1, doc);
			let json = JSON.parse(code);
			siteJson = json.props.pageProps;
			debug("\n此頁JSON資料\n", siteJson);
		}),
		page: () => fn.clp(/^\/series\/\w+\/\w+/),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let cdn = "https://cdn.flamecomics.xyz/uploads/images/series";
			let {
				chapter: {
					series_id,
					images,
					token,
					release_date,
					title,
					chapter_title,
					chapter
				}
			} = siteJson;
			apiCustomTitle = title + " - " + (chapter_title ?? "Chapter " + Number(chapter));
			return Object.values(images).map(({
				name
			}) => `${cdn}/${series_id}/${token}/${name}?${release_date}`);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let {
				chapter: {
					series_id
				}
			} = siteJson;
			let o = siteJson[key];
			return isString(o) ? `/series/${series_id}/${o}` : null;
		},
		next: () => _this.np("next"),
		prev: () => _this.np("previous"),
		chapters: {
			api: () => `/series/${siteJson.chapter.series_id}`,
			target: ".mantine-ScrollArea-viewport a",
			textNode: "p",
			sort: "r"
		},
		hide: "div:has(>iframe[allow=autoplay]),div[class^='Radio_radio_content'],div:not([id],[class],[style]):has(iframe)",
		category: "comic"
	}, {
		name: "Hive Toon/Vortex Scans",
		url: {
			h: ["www.hivetoons.org", "hivetoons.org", "www.vortexscans.org", "vortexscans.org"]
		},
		page: () => fn.clp("/chapter"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.rd() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let code = fn.gst('\\"images\\"', doc);
			if (!code) return [];
			code = code.replaceAll("\\", "");
			return fn.textToArray(code, '"images":').map(e => e.url);
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let code = fn.gst(`\\"${key}\\":{`, doc);
			if (!code) return null;
			code = code.replaceAll("\\", "");
			let {
				slug
			} = fn.textToObject(code, key);
			return fn.wurl(slug);
		},
		next: () => _this.np("nextChapter"),
		prev: () => _this.np("previousChapter"),
		chapters: () => fn.fetchDoc(fn.ge("main a", doc).pathname).then(dom => {
			let code = fn.gst('\\"chapters\\"', dom);
			code = code.replaceAll("\\", "");
			let a = code.indexOf('"chapters"');
			let b = code.indexOf("[", a);
			let c = code.indexOf("],", b) + 1;
			code = code.slice(b, c);
			return JSON.parse(code).map(({
				slug,
				number
			}) => ({
				text: `Chapter ${number}`,
				url: fn.wurl(slug)
			})).reverse();
		}),
		customTitle: () => _this.page() ? fn.dt({
			d: [
				" - Void Scans hivetoon",
				" - Vortex Scans"
			]
		}, doc) : null,
		hide: "#radio_content",
		category: "comic"
	}, {
		name: "M440.in",
		url: {
			h: ["m440.in"],
			p: "/manga/"
		},
		update: "/releases",
		imgs: "#all img",
		button: [4],
		insertImg: ["#ppp", 2],
		autoDownload: [0],
		next: () => _unsafeWindow.next_chapter ? _unsafeWindow.next_chapter : null,
		prev: () => _unsafeWindow.prev_chapter ? _unsafeWindow.prev_chapter : null,
		chapters: {
			target: "#chapter-list .dropdown-menu a",
			sort: "r"
		},
		checkCurrentChapter: (url) => {
			let cid = fn.url.split("/").at(5);
			let uid = url.split("/").at(5);
			return cid == uid;
		},
		customTitle: () => fn.dt({
			d: [
				" - Pág. 1",
				" - M440.in"
			]
		}),
		category: "comic"
	}, {
		name: "HotComics",
		host: ["w1.hotcomics.me"],
		url: {
			t: "HotComics",
			p: "/episode"
		},
		box: ["#viewer-img", 1, 800],
		imgs: "#viewer-img img",
		button: [4],
		insertImg: [
			["box", 0, "#viewer-img"], 2
		],
		autoDownload: [0],
		next: "a.vnext:not(.disabled)",
		prev: "a.vprev:not(.disabled)",
		chapters: {
			url: "a.vlist",
			target: "#tab-chapter a",
			textNode: ".num",
			cb: (t, url, a) => {
				url = a.getAttribute("onclick").split("'").at(1);
				return {
					text: "Episode " + url.split("-").at(-2),
					url
				}
			}
		},
		customTitle: () => fn.ge(".viewer-title a").firstChild.textContent + " - " + fn.gt(".viewer-title a>em"),
		category: "comic"
	}, {
		name: "Heytoon/Webtooni",
		host: ["heytoon.net", "webtooni.net"],
		url: {
			t: ["Heytoon", "Webtooni"],
			p: "/episode"
		},
		box: ["#comicContent", 1, 800],
		imgs: "#comicContent img",
		button: [4, 2],
		insertImg: [
			["box", 0, "#comicContent"], 2
		],
		autoDownload: [0],
		next: "a:has(>img[alt=next]):not([href='#'])",
		prev: "a:has(>img[alt=prev]):not([href='#'])",
		chapters: {
			target: ".read_episode a",
			cb: (t, url, a) => ({
				text: a.nextElementSibling.innerText,
				url
			})
		},
		customTitle: [".subj_stit", ".subj_tit"],
		category: "comic"
	}, {
		name: "ReadComicsOnline",
		url: {
			h: ["readcomicsonline.ru"],
			p: "/comic/"
		},
		update: "/latest-release",
		imgs: "#all img",
		button: [4],
		insertImg: [".imagecnt", 2],
		autoDownload: [0],
		next: () => _unsafeWindow.next_chapter ? _unsafeWindow.next_chapter : null,
		prev: () => _unsafeWindow.prev_chapter ? _unsafeWindow.prev_chapter : null,
		chapters: {
			target: "#chapter-list .dropdown-menu a",
			cb: (t, url) => ({
				text: t.slice(0, t.indexOf(":")),
				url
			}),
			sort: "r"
		},
		customTitle: () => fn.dt({
			d: " - Page 1"
		}),
		category: "comic"
	}, {
		name: "Omega Scans",
		url: {
			h: ["omegascans.org"]
		},
		page: () => fn.clp("/chapter"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? fn.waitEle("#content .container img:not(.rounded)") : void 0,
		imgs: () => _this.page() ? fn.gae("#content .container img:not(.rounded)") : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a:has(>button>.fa-chevron-right)",
		prev: "a:has(>button>.fa-chevron-left)",
		chapters: () => fn.j(`https://api.omegascans.org/chapter/all/${fn.clp().split("/").at(2)}`).then(array => array.map(({
			chapter_name,
			chapter_slug
		}) => ({
			text: chapter_name,
			url: fn.wurl(chapter_slug)
		})).reverse()),
		customTitle: () => _this.page() ? fn.dt({
			d: [" - Reaper Scans", " - Omega Scans"]
		}) : null,
		category: "comic"
	}, {
		name: "ZeroScans",
		url: {
			h: ["zscans.com"]
		},
		page: () => fn.clp(/^\/comics\/[\w-]+\/\d+$/),
		json: () => fn.rd().then(() => {
			let code = fn.gst("__ZEROSCANS__", doc);
			let json = fn.parseCode(code);
			[siteJson] = json.data;
			debug("\n此頁JSON資料\n", siteJson);
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.current_chapter.high_quality : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let o = siteJson.nav[key];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np("next"),
		prev: () => _this.np("prev"),
		chapters: () => siteJson.chapter_list.map(({
			id,
			name
		}) => ({
			text: `Chapter ${name}`,
			url: fn.wurl(id)
		})),
		customTitle: () => _this.page() ? fn.waitEle(".v-breadcrumbs").then(e => fn.dt({
			t: fn.gt(e),
			d: "Comics"
		})) : null,
		category: "comic"
	}, {
		name: "Danke fürs Lesen/Hachirumi",
		url: {
			h: ["danke.moe", "hachirumi.com"]
		},
		page: () => fn.clp("/read/") && fn.clp().split("/").length == 7,
		json: () => {
			fn.sm5();
			let [, , , mid, cid] = fn.clp().split("/");
			return fetch(`/api/series/${mid}/`).then(res => res.json()).then(json => {
				siteJson = {
					...json,
					mid,
					cid
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (_this.page()) {
				let chapter = siteJson.chapters[siteJson.cid];
				let [k, images] = Object.entries(chapter.groups).at(0);
				return images.map(p => `/media/manga/${siteJson.slug}/chapters/${chapter.folder}/${k}/${p}`);
			}
			return [];
		},
		capture: () => _this.imgs(),
		np: (i) => {
			let chapterArray = Object.entries(siteJson.chapters);
			let ci = chapterArray.findIndex(([k, v]) => k == siteJson.cid);
			let ti = ci + i;
			if (ti >= 0 && ti < chapterArray.length) {
				return `/read/manga/${siteJson.slug}/${chapterArray[ti][0]}/1/`;
			}
			return null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => Object.keys(siteJson.chapters).map(k => ({
			text: `Chapter ${k}`,
			url: `/read/manga/${siteJson.slug}/${k}/1/`
		})),
		customTitle: () => _this.page() ? siteJson.title + " - Chapter " + siteJson.cid : null,
		category: "comic"
	}, {
		name: "Danke fürs Lesen/Hachirumi",
		url: {
			h: ["danke.moe", "hachirumi.com"]
		},
		page: () => fn.clp("/read/") && fn.clp().split("/").length == 7,
		json: () => {
			fn.sm5();
			let [, , , mid, cid] = fn.clp().split("/");
			return fetch(`/api/series/${mid}/`).then(res => res.json()).then(json => {
				siteJson = {
					...json,
					mid,
					cid
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (_this.page()) {
				let chapter = siteJson.chapters[siteJson.cid];
				let [k, images] = Object.entries(chapter.groups).at(0);
				return images.map(p => `/media/manga/${siteJson.slug}/chapters/${chapter.folder}/${k}/${p}`);
			}
			return [];
		},
		capture: () => _this.imgs(),
		np: (i) => {
			let chapterArray = Object.entries(siteJson.chapters);
			let ci = chapterArray.findIndex(([k, v]) => k == siteJson.cid);
			let ti = ci + i;
			if (ti >= 0 && ti < chapterArray.length) {
				return `/read/manga/${siteJson.slug}/${chapterArray[ti][0]}/1/`;
			}
			return null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => Object.keys(siteJson.chapters).map(k => ({
			text: `Chapter ${k}`,
			url: `/read/manga/${siteJson.slug}/${k}/1/`
		})),
		customTitle: () => _this.page() ? siteJson.title + " - Chapter " + siteJson.cid : null,
		category: "comic"
	}, {
		name: "Kagane",
		url: {
			h: ["kagane.org"]
		},
		update: "/series/recently-updated",
		page: () => fn.clp("/reader/"),
		json: () => {
			fn.sm5();
			let [, , mid, , cid] = fn.clp().split("/");
			let p = {
				headers: {
					"X-Rsch-Did": localStorage.getItem("rsch_did")
				}
			};
			let res_a = fn.j(`https://api.kagane.org/api/v1/series/${mid}`, p);
			let res_b = fn.j(`https://api.kagane.org/api/v1/books/${mid}`, p);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					mid,
					cid,
					...a,
					...b
				}
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: async (s = ".blob-image-page img[alt^=Page][src^=blob]") => {
			if (_this.page()) {
				fn.sm4();
				await fn.waitEle(s);
				await _this.scrollEle();
				return fn.gae(s);
			}
			return [];
		},
		scrollEle: () => fn.aotoScrollEles({
			//scale: ".reader-content",
			ele: ".page-container[data-page]",
			time: 60000,
			cb: (ele) => isEle(fn.ge("img[alt^=Page][src^=blob]", ele))
		}),
		autoDownload: [0],
		current: () => {
			let data = siteJson.content.find(o => o.id == siteJson.cid);
			let index = siteJson.content.findIndex(o => o.id == siteJson.cid);
			return {
				data,
				index
			};
		},
		np: (i) => {
			if (!_this.page()) return null;
			let o = siteJson.content[_this.current().index + i];
			return isObject(o) ? fn.wurl(o.id) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.content.map(({
			id,
			title
		}) => ({
			text: title,
			url: fn.wurl(id)
		})),
		customTitle: () => _this.page() ? siteJson.name + " - " + _this.current().data.title : null,
		gallery: 1,
		category: "comic"
	}, {
		name: "RawUwU/Rawdevart",
		url: {
			h: ["rawuwu.net", "rawdevart.art"]
		},
		update: "/latest",
		page: () => fn.clp("/read/"),
		SPA: () => _this.page(),
		observeURL: "head",
		data: () => fn.rd().then(() => {
			let mid = fn.ge("#manga-id", doc).value;
			let [cid] = fn.clp().match(/[\d\.]+$/);
			return fn.j(`/spa/manga/${mid}/${cid}`).then(json => {
				siteJson = json;
				debug("\n此頁JSON資料\n", siteJson);
			});
		}),
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let {
				chapter_detail: {
					server,
					chapter_content
				}
			} = siteJson;
			let f = fn.html(chapter_content);
			return fn.gae(".chapter-img canvas[data-srcset]", f).map(e => server + e.dataset.srcset);
		},
		button: [4],
		insertImg: [".chapter-imgs", 2],
		autoDownload: [0],
		np: (key) => {
			if (!_this.page()) return null;
			let o = siteJson[key];
			return o?.startsWith("/read/") ? o : null;
		},
		next: () => _this.np("next"),
		prev: () => _this.np("prev"),
		chapters: () => fn.gae("option", fn.html(siteJson.options)).map(o => ({
			text: o.innerText.trim(),
			url: o.value
		})).reverse(),
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				chapter_detail: {
					manga_name,
					chapter_number
				}
			} = siteJson;
			return manga_name.trim() + " - Chapter " + chapter_number;
		},
		category: "comic"
	}, {
		name: "Kiryuu",
		url: {
			t: "Kiryuu",
			p: "/chapter-"
		},
		imgs: "section[data-image-data]>img",
		button: [4],
		insertImg: ["section[data-image-data]", 2],
		autoDownload: [0],
		next: "//a[div[p[text()='Next']]][not(starts-with(@href,'#'))]",
		prev: "//a[div[p[text()='Prev']]][not(starts-with(@href,'#'))]",
		chapters: () => {
			let url = fn.attr("div[hx-get]", "hx-get");
			let mid = fn.getUSP("manga_id", url);
			let cid = fn.getUSP("chapter_id", url);
			return fn.fetchDoc(`/wp-admin/admin-ajax.php?manga_id=${mid}&chapter_id=${cid}&type=manga&action=chapter_selects`).then(dom => fn.gae("#chapter-lists--manga a", dom).map(a => ({
				text: a.innerText.trim(),
				url: a.href
			})).reverse());
		},
		customTitle: "main h1",
		category: "comic"
	}, {
		name: "AnimeBbg",
		url: {
			h: ["animebbg.net"],
			p: "/capitulo/link/"
		},
		update: "/comics/?order=resource_date&direction=desc",
		imgs: ".itemList .js-lbImage",
		button: [4],
		insertImg: [".itemList", 2],
		autoDownload: [0],
		next: ".albumLinksNav-right a:has(.fa-arrow-right)",
		prev: ".albumLinksNav-left a:has(.fa-arrow-left)",
		chapters: () => {
			let a = fn.ge("//a[contains(text(),'Capítulos')]");
			return fn.fetchDoc(a).then(dom => {
				const get = (_dom) => fn.gae(".structItem-title a", _dom).map(a => ({
					text: a.innerText.trim().replace(".00", "").replace(".50", ".5").replace(".60", ".6"),
					url: a.href
				}));
				let pages = fn.ge(".pageNav-jump--next", dom);
				if (pages) {
					let doms = [dom];
					let max = Number(pages.previousElementSibling.lastElementChild.innerText) - 1;
					let links = fn.arr(max, (v, i) => `${a.href}?page=${i + 2}`);
					let resArr = links.map(fn.fetchDoc);
					return Promise.all(resArr).then(res => {
						doms = [...doms, ...res];
						return doms.map(get).flat();
					});
				}
				return get(dom);
			});
		},
		customTitle: () => {
			let text = fn.gt(".p-title-value");
			let [c, m] = text.split("-").map(e => e.trim());
			return m + " - " + c.replace(".00", "").replace(".50", ".5").replace(".60", ".6");
		},
		fetch: 0,
		category: "comic"
	}, {
		name: "InManga",
		url: {
			h: "inmanga.com",
			p: /^\/ver\/manga\//,
			e: ".ChapterDescriptionContainer"
		},
		init: async () => {
			await fn.waitVar("pageController");
			await fn.waitEle("#ChapList option:checked");
			_unsafeWindow.jQuery(document).off();
			_unsafeWindow.jQuery(document.body).off();
		},
		imgs: () => {
			let options = fn.gae("#PageList option");
			return options.map((e, i) => _unsafeWindow.pageController._containers.pageUrl.replace("pageNumber", i).replace("identification", e.value));
		},
		button: [4],
		insertImg: ["div:has(>a.NextPage)", 2],
		insertImgAF: () => {
			fn.ge(".chapterControlsContainer.hidden")?.classList.remove("hidden");
			fn.remove(".pageSourceContainer");
		},
		autoDownload: [0],
		chapterUrl: (option) => _unsafeWindow.pageController._containers.chapterUrl.replace("chapterNumber", option.innerText.replace(".", "-")).replace("identification", option.value),
		current: () => fn.ge("#ChapList option:checked"),
		next: () => {
			let next = _this.current()?.nextElementSibling;
			return next ? _this.chapterUrl(next) : null;
		},
		prev: () => {
			let prev = _this.current()?.previousElementSibling;
			return prev ? _this.chapterUrl(prev) : null;
		},
		chapters: {
			node: "#ChapList",
			target: "option",
			cb: (text, v, e) => ({
				text,
				url: _this.chapterUrl(e)
			})
		},
		checkCurrentChapter: (url, text) => {
			let ct = fn.gt("#ChapList [selected]");
			return ct == text;
		},
		customTitle: () => fn.dt({
			d: " Online - InManga"
		}),
		category: "comic"
	}, {
		name: "Mangakawaii",
		url: {
			h: "www.mangakawaii.io",
			p: "/manga/",
			st: "chapter_slug"
		},
		box: ["#ppp", 2],
		imgs: () => {
			let {
				pages,
				chapter_server,
				oeuvre_slug,
				applocale,
				chapter_slug,
			} = _unsafeWindow;
			return pages.map(({
				page_image,
				page_version
			}) => `https://${chapter_server}.mangakawaii.io/uploads/manga/${oeuvre_slug}/chapters_${applocale}/${chapter_slug}/${page_image}?${page_version}`);
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#ppp,.reader-page__page-nav>div:has(#page-list)"),
		autoDownload: [0],
		next: () => {
			let {
				oeuvre_url,
				next_chapter
			} = _unsafeWindow;
			return next_chapter == oeuvre_url ? null : next_chapter;
		},
		prev: () => {
			let {
				oeuvre_url,
				prev_chapter
			} = _unsafeWindow;
			return prev_chapter == oeuvre_url ? null : prev_chapter;
		},
		chapters: {
			target: ".chapter-pager .dropdown-menu a",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => url.split("/").at(6) == location.href.split("/").at(6),
		customTitle: () => fn.dt({
			d: " | Mangakawaii",
			r: [
				[" Chapter ", " - Chapter "]
			]
		}),
		category: "comic"
	}, {
		name: "MangaOni",
		url: {
			h: ["manga-oni.com"],
			p: "/lector/"
		},
		update: "/recientes/",
		init: async () => {
			await fn.waitVar("hojas");
			await fn.waitEle("#c_list option:checked");
			fn.ge("#c_list")?.dispatchEvent(new Event("mouseover"));
			await fn.delay(1000, 0);
			await fn.waitEle("#c_list option:checked");
			document.body.onkeydown = null;
		},
		imgs: () => {
			let {
				dir,
				hojas
			} = _unsafeWindow;
			return hojas.map(e => dir + e);
		},
		button: [4],
		insertImg: ["#slider", 2],
		endColor: "white",
		insertImgAF: (parent) => {
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 6);
			}
			fn.remove("#right")
		},
		autoDownload: [0],
		np: (k) => {
			let chapters = fn.gae("#c_list option");
			let c = chapters.find(e => e.value == _unsafeWindow.url_lector);
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			target: "#c_list option",
			sort: "r"
		},
		checkCurrentChapter: (url) => {
			let cid = fn.url.split("/").at(5);
			let uid = url.split("/").at(5);
			return cid == uid;
		},
		customTitle: () => fn.dt({
			d: " — Manga en línea | MangaOni"
		}),
		category: "comic"
	}, {
		name: "Raw Lazy/Raw FREE",
		host: ["rawlazy.io", "rawfree.ax"],
		url: {
			t: "Manga Raw",
			p: ["/manga-chapter/", "/manga-raw/", "-raw-"]
		},
		imgs: async () => {
			if (fn.ge(".z_content img")) {
				return fn.gae(".z_content img");
			} else if (fn.gst("chapter_id")) {
				fn.sm5();
				let code = fn.gst("data:");
				let obj_a = fn.textToObject(code, "data:", 2);
				code = fn.gst("var zing") || fn.gst("const zing");
				let obj_b = fn.textToObject(code, "zing");
				let data = {
					...obj_a,
					...obj_b
				};
				let {
					nonce,
					nonce_a,
					action,
					_action,
					p,
					chapter_id
				} = data;
				let page = 1;
				let img_index = 0;
				let loop = true;
				let html = "";
				const get = () => {
					let params = fn.cp({
						nonce,
						nonce_a,
						action,
						_action,
						p,
						img_index,
						chapter_id
					});
					return fn.j("/wp-admin/admin-ajax.php", {
						"headers": {
							"content-type": "application/x-www-form-urlencoded; charset=UTF-8"
						},
						"body": params,
						"method": "POST"
					}).then(json => {
						fn.showMsg(`${DL.str_06}${page}/???`, 0);
						img_index = json.img_index;
						html += json.mes;
						if (json?.going != 1) {
							loop = false;
						}
					});
				};
				while (loop) {
					await get();
					page++;
				}
				return [...fn.doc(html).images];
			}
			return [];
		},
		button: [4],
		insertImg: [".entry-content,div:has(>.go-open-popup-wrap)", 2],
		insertImgAF: () => fn.hideEle(".br-content"),
		autoDownload: [0],
		next: "//a[text()='次の章 →'] | //a[text()='次に ']",
		prev: "//a[text()='← 前の章'] | //a[text()=' 以前']",
		chapters: () => {
			if (fn.ge(".chapters-list")) {
				return fn.getChapters({
					target: ".chapters-list a",
					textNode: "span",
					sort: "r"
				});
			} else if (fn.ge(".entry-chapter")) {
				return fn.getChapters({
					target: ".entry-chapter a",
					sort: "r"
				});
			} else {
				return fn.getChapters({
					wait: ".single-chapter-select option[data-redirect]",
					node: ".single-chapter-select",
					target: "option[data-redirect]",
					cb: (t, v, e) => ({
						text: e.text,
						url: e.dataset.redirect
					})
				});
			}
		},
		customTitle: ".post-title",
		category: "comic"
	}, {
		name: "KUMARAW",
		url: {
			h: ["kumaraw.com"],
			p: "/chapter"
		},
		box: [".detail_chapterMenu", 2],
		imgs: () => _unsafeWindow.slides_p_path.map(e => atob(e)),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".chapter_boxImages,.go-to-B-wrap"),
		np: (k) => {
			let chapters = fn.gae("#slcChapter option");
			let c = chapters.find(e => e.value == fn.url);
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			node: "#slcChapter",
			target: "option",
			sort: "r"
		},
		customTitle: ".story_name>h1",
		category: "comic"
	}, {
		name: "コミックシーモア",
		url: {
			h: ["hachiraw.win"],
			p: "/chapter/"
		},
		imgs: ".entry-content img",
		button: [4],
		insertImg: [".entry-content", 2],
		endColor: "white",
		next: ".nextchapter",
		prev: ".prevchapter",
		chapters: {
			node: ".chaplist",
			target: "option",
			sort: "r"
		},
		customTitle: () => fn.dt({
			s: ".entry-title",
			d: "&#40;MANGA&#41; "
		}),
		category: "comic"
	}, {
		name: "KLManga",
		host: ["klz9.com", "klto9.com", "jestful.net"],
		url: {
			t: [" - KL", " - KT9", " - JF"],
			st: "load_image"
		},
		update: "/manga-list.html?listType=pagination&sort=last_update&sort_type=DESC",
		box: ["#list-imga", 2],
		imgs: () => {
			fn.sm5();
			let code = fn.gst("load_image");
			let cid = Number(code.match(/\d+/));
			return fn.fetchDoc(`/${fn.generateRandomString(30, 1)}.iog?cid=${cid}`).then(dom => fn.gae("img[alt^=Page]", dom));
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#list-imga"),
		endColor: "white",
		autoDownload: [0],
		np: (k) => {
			let c = fn.ge(".select-chapter option[selected]");
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? fn.wurl(e.value) : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			wait: "#chap_list .current",
			target: "#chap_list a",
			sort: "r"
		},
		customTitle: () => fn.dt({
			s: ".breadcrumb",
			d: "Home Manga List"
		}),
		category: "comic"
	}, {
		name: "Weloma/WeloveManga",
		url: {
			h: ["weloma.art", "welovemanga.one"],
			e: ".chapter-content"
		},
		box: [".chapter-content:not([id])", 1, 1280],
		imgs: () => fn.rd().then(() => fn.gae(".chapter-content img[data-img]", doc).map(e => atob(e.dataset.img))),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".chapter-content:not([id])"),
		endColor: "white",
		autoDownload: [0],
		np: (k) => {
			let c = fn.ge(".select-chapter option[selected]");
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? fn.wurl(e.value) : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			wait: "#chap_list .current",
			target: "#chap_list a",
			sort: "r"
		},
		customTitle: () => fn.dt({
			s: ".breadcrumb",
			d: "Home List manga"
		}),
		category: "comic"
	}, {
		name: "NicoManga",
		url: {
			h: ["nicomanga.com"],
		},
		page: () => fn.clp("/read-"),
		update: "/manga-list.html",
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? fn.rd() : void 0,
		loop: () => {
			fn.remove("body~iframe,a[id^='dl-banner'],.ph-inpage-widget,center:has(#unlock-overlay),div:has(>h2)");
		},
		imgs: () => {
			if (_this.page()) {
				fn.sm5();
				let code = fn.gst("loadWebtoonImages", doc);
				if (!code) return [];
				let content = fn.textVar(code, "content");
				return atob(content).replace(/\r/g, "").split("\n");
			}
			return [];
		},
		button: [4],
		insertImgBF: () => fn.waitEle("#listImgs img").then(() => fn.createImgBox("center:has(#listImgs)", 2)),
		insertImg: [
			["box", 0], 2
		],
		autoDownload: [0],
		np: (s) => {
			if (_this.page()) {
				let a = fn.ge(s, doc);
				return a ? a.pathname : null;
			}
			return null;
		},
		next: () => _this.np("a.nav-button.next:not([disabled])"),
		prev: () => _this.np("a.nav-button.prev:not([disabled])"),
		chapters: (b = "#chapterListContainer button") => {
			if (!fn.ge(b, doc)) return [];
			let url_templet = fn.clp().replace(/([\d\.]+)(\.html)$/, "{num}$2");
			return fn.gae(b, doc).map(b => ({
				text: b.innerText.trim(),
				url: url_templet.replace("{num}", b.dataset.chapter)
			})).reverse();
		},
		customTitle: () => _this.page() ? getTitle([".breadcrumb-item", -2, -1], doc) : null,
		hide: ".ph-inpage-widget,center:has(#unlock-overlay),div:has(>h2)",
		category: "comic"
	}, {
		name: "NihonKuni",
		url: {
			h: ["nihonkuni.com"],
			p: "-chapter-"
		},
		box: ["#imgChapter", 1],
		imgs: () => {
			let node = fn.html(_unsafeWindow.chapterImages);
			return fn.gae("img[data-srcset]", node).map(e => e.dataset.srcset);
		},
		button: [4],
		insertImg: [
			["box", 0, "#imgChapter"], 2
		],
		autoDownload: [0],
		next: "a[title='Next Chapter']",
		prev: "a[title='Previous Chapter']",
		chapters: {
			target: ".chapters-list-sidebar a",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => url.split("-").at(-1) == location.href.split("-").at(-1),
		customTitle: [".breadcrumb-item", -2, -1],
		category: "comic"
	}, {
		name: "RawINU",
		url: {
			h: ["rawinu.com"],
			p: "-chapter-"
		},
		init: () => fn.rd(),
		box: ["#imgsList", 1],
		imgs: () => fn.gae("#imgsList img[data-img]", doc).map(e => atob(e.dataset.img)),
		button: [4],
		insertImg: [
			["box", 0, "#imgsList"], 2
		],
		autoDownload: [0],
		np: (s) => {
			let a = fn.ge(s, doc);
			return a ? a.pathname : null;
			return null;
		},
		next: () => _this.np("a:has(i.next:not([disabled]))"),
		prev: () => _this.np("a:has(i.prev:not([disabled]))"),
		chapters: {
			url: ".breadcrumb-item:nth-child(3)>a",
			target: ".list-chapters a",
			textNode: ".chapter-name",
			sort: "r"
		},
		customTitle: () => getTitle([".breadcrumb-item", -2, -1], doc),
		category: "comic"
	}, {
		name: "RawKuro",
		url: {
			h: ["rawkuro.net", "mangakoma.net", "www.manhuaplus.org", "manhuaplus.org", "mangakoma01.top", "mangakoma01.net", "raw1001.net"],
			st: "CHAPTER_ID"
		},
		box: ["#chapterContent,#image_container", 2],
		imgs: () => {
			fn.sm5();
			let code = fn.gst("CHAPTER_ID");
			let cid = fn.numVar(code, "CHAPTER_ID");
			return fn.t(`/ajax/image/list/chap/${cid}`, {
				"headers": {
					"x-requested-with": "XMLHttpRequest"
				},
				"method": "POST"
			}).then(text => {
				text = text.replace("The requested URL returned error: 403", "");
				let json = JSON.parse(text);
				let dom = fn.doc(json.html);
				if (fn.ge(".separator", dom)) {
					let divs = fn.gae(".separator", dom).sort((a, b) => a.dataset.index - b.dataset.index);
					return divs.map(e => e.firstElementChild.href).filter(e => !e.includes("rawwkuro.jpg"));
				}
				return fn.gae(".page-chapter img:not([data-original$='rawwkuro.jpg'])", dom);
			});
		},
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#chapterContent,#image_container"),
		endColor: "white",
		autoDownload: [0],
		next: "a.nextBtn[href*='/'],a.a_next[href*='/']",
		prev: "a.prevBtn[href*='/'],a.a_prev[href*='/']",
		chapters: {
			node: ".nPL_select",
			target: "option",
			sort: "r"
		},
		customTitle: "main h1",
		category: "comic"
	}, {
		name: "RawOtaku/JManga/MangaReader",
		host: ["rawotaku.com", "rawotaku.org", "jmanga.wtf"],
		url: {
			t: ["Otaku", "jmanga", "Read"],
			h: [/^rawotaku/, /^jmanga/, "mangareader.to"]
		},
		page: () => fn.clp("/read/"),
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? fn.waitEle(["#images-content .page-read", ".chapter-item.active"]) : void 0,
		imgs: () => {
			if (!_this.page()) return [];
			let id = fn.ge(".chapter-item.active").dataset.id;
			fn.sm5();
			let api = fn.lh.includes("mangareader") ? `/ajax/image/list/chap/${id}?mode=vertical&quality=high&hozPageSize=1` : `/json/chapter?mode=vertical&id=${id}`;
			return fetch(api).then(res => res?.json()).then(json => {
				fn.hm();
				if (fn.lh.includes("mangareader")) {
					let node = fn.html(json.html);
					return fn.gae(".iv-card[data-url]", node);
				}
				return [...fn.doc(json.html).images];
			});
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//li[contains(@class,'chapter-item active')]/preceding-sibling::li[1]/a",
		prev: ".chapter-item.active+li>a",
		chapters: {
			target: "#ja-chapters a,.reading-list a",
			textNode: ".name",
			sort: "r"
		},
		customTitle: () => _this.page() ? fn.dt({
			t: fn.gt(".manga-name") + " - " + fn.gt("#dropdown-chapters button")
		}) : null,
		category: "comic"
	}, {
		name: "ZonaTMO",
		url: {
			h: ["zonatmo.com"],
			p: ["/viewer/", "/news/"]
		},
		update: "/latest_uploads",
		init: () => (document.onkeydown = null),
		imgs: () => {
			if (!!fn.gst("dirPath")) {
				let {
					dirPath,
					images
				} = _unsafeWindow;
				return images.map(e => dirPath + e);
			}
			return fn.gae(".viewer-container .viewer-img");
		},
		button: [4],
		insertImg: [".viewer-container", 2],
		insertImgAF: () => fn.remove(".container:has(#viewer-pages-select)"),
		autoDownload: [0],
		np: (s) => {
			let a = fn.ge(s);
			return a ? fetch(a).then(res => res.url) : null;
		},
		next: () => _this.np(".chapter-next a"),
		prev: () => _this.np(".chapter-prev a"),
		chapters: {
			url: "a[title=Volver]",
			target: ".list-group-item[data-index]",
			textNode: "h4",
			urlNode: "a.btn",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => {
			let [h2t_num] = fn.gt("#app h2").match(/[\d\.]+/);
			let [ct_num] = text.match(/[\d\.]+/);
			return h2t_num == ct_num;
		},
		customTitle: () => {
			let text = fn.gt("h1") + " - " + fn.gt("h2");
			return fn.dt({
				t: text,
				d: /Subido por:.+$/
			});
		},
		category: "comic"
	}, {
		name: "ManhwaWeb",
		url: {
			h: ["www.manhwaweb.com", "manhwaweb.com"],
			p: "/leer/"
		},
		update: "/latest-chapters",
		init: () => {
			let slug = fn.lp.replace("/leer", "");
			let res_a = fn.j(`https://manhwawebbackend-production.up.railway.app/chapters/see${slug}`);
			let res_b = fn.j(`https://manhwawebbackend-production.up.railway.app/chapters/seeprevpost${slug}`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					...a,
					...b
				};
				debug("\n此頁JSON資料\n", siteJson);
			});
		},
		imgs: () => siteJson.chapter.img,
		button: [4],
		insertImgBF: () => fn.waitEle(".flex-col.justify-center.items-center img"),
		insertImg: [".flex-col.justify-center.items-center", 2],
		insertImgAF: () => fn.remove("//div[div[div[span[text()='AD']]]]"),
		endColor: "white",
		autoDownload: [0],
		next: () => siteJson.chapterSiguiente?.startsWith("http") ? siteJson.chapterSiguiente : null,
		prev: () => siteJson.chapterAnterior?.startsWith("http") ? siteJson.chapterAnterior : null,
		chapters: () => fn.j(`https://manhwawebbackend-production.up.railway.app/manhwa/see/${siteJson.real_id}`).then(json => json.chapters.map(({
			chapter,
			link
		}) => ({
			text: `Capitulo ${chapter}`,
			url: link
		}))),
		customTitle: () => fn.dt({
			d: " manhwa - ManhwaWeb"
		}),
		category: "comic"
	}, {
		name: "MangaKatana",
		url: {
			h: ["mangakatana.com"],
			p: "/manga/"
		},
		update: "/latest",
		init: () => fn.waitVar("dimension_imgs").then(() => _unsafeWindow.jQuery(document).off()),
		box: ["#imgs", 1],
		imgs: "#imgs div[id^=page] img",
		button: [4],
		insertImg: [
			["box", 0, "#imgs"], 2
		],
		endColor: "white",
		autoDownload: [0],
		next: "a.nav_button.next[href^=http]",
		prev: "a.nav_button.prev[href^=http]",
		chapters: {
			node: "select[name=chapter_select]",
			target: "option",
			cb: (text, v) => ({
				text,
				url: fn.wurl(v)
			}),
			sort: "r"
		},
		customTitle: () => fn.dt({
			s: ".uk-breadcrumb",
			d: "Home"
		}),
		category: "comic"
	}, {
		name: "MangaFreak",
		url: {
			t: "MangaFreak",
			p: "/Read"
		},
		box: [".slideshow-container", 1],
		imgs: ".slideshow-container img",
		button: [4],
		insertImg: [
			["box", 0, ".slideshow-container"], 2
		],
		autoDownload: [0],
		next: "//div[text()='Next Chapter:']/following-sibling::span[1]/a",
		prev: "//div[text()='Previous Chapter:']/following-sibling::span[1]/a",
		chapters: {
			target: ".chapter_list option"
		},
		customTitle: () => fn.dt({
			d: [
				"Read ",
				" - MangaFreak"
			]
		}),
		category: "comic"
	}, {
		name: "LeerCapitulo",
		host: ["www.leercapitulo.co"],
		url: {
			e: ".chapter-title>a[title=Leercapitulo]",
			p: "/leer/"
		},
		init: () => fn.waitEle("#page_select"),
		imgs: () => fn.gae("#page_select option").map(e => e.value),
		button: [4],
		insertImg: [".each-page", 2],
		autoDownload: [0],
		next: "a.next",
		prev: "a.pre",
		chapters: {
			node: "select[rel='chap-select']",
			target: "option",
			sort: "r"
		},
		customTitle: ".bodycontainer h1",
		category: "comic"
	}, {
		name: "OlympusBiblioteca",
		url: {
			h: ["olympusbiblioteca.com"],
		},
		page: () => fn.clp("/capitulo/") && fn.clp("/comic-"),
		update: "/capitulos",
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			fn.sm5();
			let [, , c_id, m_id] = fn.clp().split("/");
			m_id = m_id.replace("comic-", "");
			return fn.j(`/api/capitulo/${m_id}/${c_id}?type=comic`).then(json => {
				siteJson = json;
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.chapter.pages : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		chapter_url: (id) => fn.clp().split("/").with(2, id).join("/"),
		next: () => {
			let next = siteJson?.next_chapter?.id;
			return next ? _this.chapter_url(next) : null;
		},
		prev: () => {
			let prev = siteJson?.prev_chapter?.id;
			return prev ? _this.chapter_url(prev) : null;
		},
		chapters: () => {
			let m_id = fn.clp().split("/").at(-1).replace("comic-", "");
			const get_json = (id, p) => fn.j(`https://dashboard.olympusbiblioteca.com/api/series/${id}/chapters?page=${p}&direction=asc&type=comic`);
			const get_c = (json) => json.data.map(({
				id,
				name
			}) => ({
				text: `Capítulo ${name}`,
				url: `/capitulo/${id}/comic-${m_id}`
			}));
			return get_json(m_id, 1).then(json => {
				if (json.meta.last_page > 1) {
					let jsons = [json];
					let resArr = fn.arr(json.meta.last_page - 1, (v, i) => get_json(m_id, i + 2));
					return Promise.all(resArr).then(res => {
						jsons = [...jsons, ...res];
						return jsons.map(j => get_c(j)).flat();
					});
				}
				return get_c(json);
			});
		},
		customTitle: () => {
			if (_this.page()) {
				let {
					comic: {
						name: m
					},
					chapter: {
						name: c
					}
				} = siteJson;
				return `${m} - Capítulo ${c}`;
			}
			return null;
		},
		category: "comic"
	}, {
		name: "KuManga",
		url: {
			h: "www.kumanga.com",
			p: "/manga/leer/"
		},
		imgs: () => fn.waitEle(["div[x-data^=imageGallery] img"]),
		button: [4],
		insertImg: ["div[x-data^=imageGallery]", 2],
		autoDownload: [0],
		next: ".chapter_next:not(.disabled)",
		prev: ".chapter_prev:not(.disabled)",
		customTitle: [".t_manga", ".t_cap"],
		category: "comic"
	}, {
		name: "Temple Scan",
		url: {
			h: ["templetoons.com"],
			p: "/chapter-"
		},
		imgs: () => fn.textToArray(fn.__next_f(), '"images":').filter(fn.isImage),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//a[contains(text(),'Next')]",
		prev: "//a[contains(text(),'Prev')]",
		chapters: {
			url: "//a[text()='Home']",
			target: ".grid>a:has(h1):not(:has(span>svg))",
			textNode: "h1",
			sort: "r"
		},
		checkCurrentChapter: (url, text) => url.split("-").at(-1) == location.href.split("-").at(-1),
		customTitle: () => fn.title(" - Temple Scan"),
		category: "comic"
	}, {
		name: "Dream-Manga",
		url: {
			h: "dream-manga.com",
			p: "/reader/"
		},
		init: () => fn.waitEle([".header__post-title", ".chapter__selector-trigger__title"]),
		box: [".reader-view", 2, 1200],
		imgs: () => _unsafeWindow.__DATA__.images,
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle(".reader-view,.nav"),
		autoDownload: [0],
		next: () => {
			let next = _unsafeWindow?.__DATA__?.next;
			return next?.includes("/reader/") ? next : null;
		},
		prev: () => {
			let prev = _unsafeWindow?.__DATA__?.prev;
			return prev?.includes("/reader/") ? prev.replace(/#.+$/, "") : null;
		},
		chapters: () => _unsafeWindow?.__DATA__?.chapters.map(({
			id,
			title
		}) => ({
			text: title,
			url: fn.wurl(id)
		})).reverse(),
		customTitle: [".header__post-title", ".chapter__selector-trigger__title"],
		category: "comic"
	}, {
		name: "N站模板無變數圖名隨機",
		url: {
			h: ["hentaivsmanga.com", "savehentai.info", "www.hentaihardcore.net", "hentai4all.com"],
			e: "#thumbnail-container"
		},
		imgs: () => {
			let links = fn.gau("#thumbnail-container a");
			return fn.getImgA("#image-container img", links);
		},
		thums: "#thumbnail-container img",
		button: [4],
		insertImg: ["#thumbnail-container", 2],
		customTitle: () => fn.getText(["#info h2", "#info h1"]),
		category: "hcomic"
	}, {
		name: "N站模板無變數無縮略圖",
		host: ["multi-manga.today", "hmanga.today", "w1.multi-manga.com"],
		url: {
			h: /multi|manga/,
			e: ".logo img[src*='hitomila']"
		},
		imgs: "#thumbnail-container img",
		button: [4],
		insertImg: ["#thumbnail-container", 2],
		customTitle: () => fn.getText(["#info h2", "#info h1"]),
		category: "hcomic"
	}, {
		name: "N站模板無變數無縮略圖",
		host: ["nhentai.online", "hentaiyaoi.net", "nhentaiyaoi.net", "hentaibl.com", "nhentai.net.br"],
		url: {
			h: "hentai",
			e: ".post-titulo,.tituloOriginal"
		},
		imgs: ".post-fotos img",
		button: [4],
		insertImg: [".post-fotos", 2],
		customTitle: () => fn.getText([".tituloOriginal", ".post-titulo"]),
		hide: ".anuncios,#onesignal-slidedown-container,.floating-button",
		category: "hcomic"
	}, {
		name: "嗨皮漫畫閱讀",
		//enable: 0,
		url: {
			h: ["m.happymh.com", "hihimanga.com"],
			p: "/mangaread/",
			ee: ".captcha-area"
		},
		update: "/latest",
		getHeaders: () => ({
			"headers": {
				"x-requested-id": new Date().getTime(),
				"x-requested-with": "XMLHttpRequest"
			}
		}),
		fetchJson: (url = siteUrl) => {
			let mangaCode = new URL(url).pathname.split("/").at(-1);
			let api = `/v2.0/apis/manga/reading?code=${mangaCode}&v=v3.1818134`;
			return fn.j(api, _this.getHeaders());
		},
		init: async () => {
			let json = await _this.fetchJson();
			debug("\n此頁JSON資料\n", json);
			siteJson = json;
			fn.picPreload(_this.imgs(json), _this.customTitle(json));
			return fn.waitEle("#root footer button[data-href^='/manga']");
		},
		imgs: (json = siteJson) => {
			if (json.status == 0) {
				let srcs = json.data.scans.map(({
					url
				}) => url.replace(/\?q=\d+$/, ""));
				if (srcs.length == 2 && ("next_cid" in json.data)) {
					srcs = srcs.slice(0, -1);
				}
				if (srcs.length > 2 && ("next_cid" in json.data)) {
					srcs = srcs.slice(0, -2);
				}
				return srcs;
			}
			return [];
		},
		referrerpolicy: "origin",
		button: [4],
		insertImg: ["//article[div[contains(@id,'imageLoader')]]", 3],
		autoDownload: [0],
		np: (k) => {
			let b = fn.ge(`//article//button[text()='${k}一话' or text()='${k}一話'][starts-with(@data-href,'/mangaread/')]`);
			return b ? b.dataset.href : null;
		},
		next: () => _this.np("下"),
		prev: () => _this.np("上"),
		chapters: () => new Promise(resolve => {
			let dir = fn.dir(fn.url);
			let chapterListData = [];
			let page = 1;
			const get = () => {
				const params = fn.cp({
					code: siteJson.data.manga_code,
					cid: siteJson.data.id,
					page,
					order: "desc"
				});
				return fn.j("/v2.0/apis/manga/chapterByPage?" + params, _this.getHeaders()).then(json => {
					if (json?.msg === "success") {
						chapterListData = chapterListData.concat(json.data.items);
						if (json?.data?.isEnd == 1 || chapterListData.length >= json?.data?.total) {
							chapterListData = chapterListData.map(({
								chapterName,
								codes
							}) => ({
								text: chapterName.trim(),
								url: dir + codes
							})).reverse();
							resolve(chapterListData);
						} else {
							page++;
							return get();
						}
					} else {
						resolve([]);
						console.error("獲取章節列表資料錯誤");
					}
				}).catch(error => {
					resolve([]);
					console.error("獲取章節列表資料錯誤", error);
				});
			};
			get();
		}),
		preloadNext: async () => {
			let json = await _this.fetchJson(nextLink);
			json.status == 0 ? fn.picPreload(_this.imgs(json), _this.customTitle(json), "next") : debug("預讀下一頁失敗");
		},
		customTitle: (json = siteJson) => json.data.manga_name + " - " + json.data.chapter_name,
		category: "comic"
	}, {
		name: "COLAMANHUA",
		url: {
			h: "www.colamanga.com",
			p: /^\/manga-.+\.html$/,
			ee: ".app-download-prompt",
			d: "pc"
		},
		init: async () => {
			await fn.waitEle(".mh_comicpic img[src]");
			const {
				__cr,
				__cad,
				mh_info
			} = _unsafeWindow;
			const [value_a, value_b] = __cad.getCookieValue();
			const pageCountKey = value_b + String(mh_info.pageid);
			const pageCount = Number(fn.cookie(pageCountKey) || "0");
			siteJson.images = fn.arr(pageCount, (v, i) => __cr.getPicUrl(i + 1));
			debug("images", siteJson.images);
			fn.clearAllTimer(1);
			const [src] = siteJson.images;
			if (autoScrollAllElement === 1 && src.includes(".enc.")) _this.scrollEle();
		},
		imgs: async () => {
			let [src] = siteJson.images;
			if (src.includes(".enc.")) {
				let insufficient_quantity = false;
				let current_total = fn.gae(".mh_comicpic img[src]").length;
				if (current_total < siteJson.images.length) {
					insufficient_quantity = true;
				}
				if (insufficient_quantity || options.autoDownload == 1 || options.shadowGallery == 1 || options.mobileGallery == 1) {
					await _this.scrollEle();
				}
				return fn.imgBlobUrlArr(".mh_comicpic img[src^=blob]");
			}
			return siteJson.images;
		},
		button: [4],
		insertImg: ["#mangalist", 0],
		scrollEle: () => fn.aotoScrollEles({
			scale: "#mangalist",
			ele: ".mh_comicpic",
			cb: (ele) => isEle(fn.ge("img[src]", ele)),
			time: 10000,
			top: 1,
			end: (sn) => sn > siteJson.images.length
		}),
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')]",
		chapters: {
			url: ".mh_readtitle .read_page_link",
			target: ".all_data_list a",
			sort: "r"
		},
		customTitle: () => fn.attr({
			s: ".read_page_link",
			t: "返回目录"
		}, "title") + " - " + fn.gt(".mh_readtitle h1"),
		fetch: 1,
		css: ".mh_wrap{width:100%!important;min-width:100%!important}",
		category: "comic"
	}, {
		name: "8Comic無限動漫",
		host: ["www.8comic.com"],
		url: {
			t: "無限動漫 8comic.com",
			p: "/online/",
			i: 0
		},
		update: "https://www.8comic.com/comic/u-1.html",
		frameCode: `
if ("xx" in window) {
    const {
        su,
        ti,
        nn,
        ni,
        mm,
        xx
    } = window;
    const getSrc = (code) => {
        const a = code.substring(15);
        const b = window[code.substring(0, 5)];
        const c = window[code.substring(5, 10)];
        const d = window[code.substring(10, 15)];
        const src = "https://img" + su(b, 0, 1) + ".8comic.com/" + su(b, 1, 1) + "/" + ti + "/" + c + "/" + nn(a) + "_" + su(d, mm(a), 3) + ".jpg";
        return src;
    };
    const html = decodeURIComponent(xx);
    const codes = html.matchAll(/\\ss="([^"]+)"/g);
    const srcs = [...codes].map(([, code]) => {
        if (code.startsWith("//")) {
            return window.location.protocol + code;
        } else if (code.length >= 16 && code.length <= 18 && /\\d{1,3}/.test(code.substring(15))) {
            return getSrc(code);
        }
        return null;
    });
    window.newImgs = srcs;
    const url = reurl("ch", ni);
    if (url == document.URL) {
        window.nextLink = null;
    } else {
        window.nextLink = url;
    }
}
        `,
		init: async () => {
			await fn.waitVar(["xx", "su", "ti", "nn", "mm", "reurl"]);
			await fn.waitEle("#comics-pics img");
			fn.script(_this.frameCode);
			fn.createImgBox(".pinch-zoom-container", 2);
		},
		imgs: (frame = _unsafeWindow) => frame.newImgs,
		button: [4],
		insertImg: [
			["box", 0, ".pinch-zoom-container"], 2
		],
		autoDownload: [0],
		next: () => _unsafeWindow.nextLink,
		prev: "#prevvol",
		chapters: {
			url: ".view-back",
			mode: "g",
			target: "#chapters a[onclick]",
			textNode: "font",
			cb: (text, u, a) => {
				let [mid, ch] = fn.attr(a, "onclick").split("'").at(1).replace(".html", "").split("-");
				return {
					text,
					url: `/online/new-${mid}.html?ch=${ch}`
				}
			}
		},
		checkCurrentChapter: (url, text) => {
			let cid = fn.getUSP("ch");
			let uid = fn.getUSP("ch", location.origin + url);
			return cid == uid;
		},
		customTitle: (dom = doc) => fn.dt({
			s: "#pt"
		}, dom),
		frame: "#comics-pics img",
		preloadNext: () => fn.iframe(_unsafeWindow.nextLink, {
			waitVar: ["xx", "su", "ti", "nn", "mm"],
			cb: (dom, frame) => {
				fn.picPreload(_this.imgs(frame), _this.customTitle(dom), "next");
			}
		}),
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "8Comic無限動漫 自動翻頁",
		url: {
			t: "無限動漫 8comic.com",
			p: "/online/",
			i: 1
		},
		frameCode: `
if ("xx" in window) {
    const {
        su,
        ti,
        nn,
        ni,
        mm,
        xx
    } = window;
    const getSrc = (code) => {
        const a = code.substring(15);
        const b = window[code.substring(0, 5)];
        const c = window[code.substring(5, 10)];
        const d = window[code.substring(10, 15)];
        const src = "https://img" + su(b, 0, 1) + ".8comic.com/" + su(b, 1, 1) + "/" + ti + "/" + c + "/" + nn(a) + "_" + su(d, mm(a), 3) + ".jpg";
        return src;
    };
    const html = decodeURIComponent(xx);
    const codes = html.matchAll(/\\ss="([^"]+)"/g);
    const srcs = [...codes].map(([, code]) => {
        if (code.startsWith("//")) {
            return window.location.protocol + code;
        } else if (code.length >= 16 && code.length <= 18 && /\\d{1,3}/.test(code.substring(15))) {
            return getSrc(code);
        }
        return null;
    });
    window.newImgs = srcs;
    const url = reurl("ch", ni);
    if (url == document.URL) {
        window.nextLink = null;
    } else {
        window.nextLink = url;
    }
}
        `,
		init: async () => {
			await fn.waitVar(["xx", "su", "ti", "nn", "mm", "reurl"]);
			await fn.waitEle("#comics-pics img");
			fn.script(_this.frameCode);
			let s = ".pinch-zoom-container";
			await fn.caae(fn.createImgBox(s, 1), fn.createImgArray(frameWindow.newImgs), s);
		},
		autoPager: {
			mode: 1,
			waitEle: "#comics-pics img",
			ele: () => fn.createImgArray(frameWindow.newImgs),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: () => frameWindow.nextLink,
			title: (dom, frame) => isM ? "第" + frame.ch + "集" : fn.dt({
				s: "#pt"
			}, dom),
			re: "#pt",
			aF: () => (_unsafeWindow.ch = frameWindow.ch),
			preloadNextPage: () => {
				if (!!frameWindow.nextLink) {
					fn.iframe(frameWindow.nextLink, {
						waitVar: ["xx", "su", "ti", "nn", "mm"],
						cb: (dom, frame) => {
							fn.picPreload(frame.newImgs, _this.autoPager.title(dom, frame), "next");
						}
					});
				}
			},
			chapters: {
				url: ".view-back",
				mode: "g",
				target: "#chapters a[onclick]",
				textNode: "font",
				cb: (text, u, a) => {
					let [mid, ch] = fn.attr(a, "onclick").split("'").at(1).replace(".html", "").split("-");
					return {
						text,
						url: `/online/new-${mid}.html?ch=${ch}`
					}
				}
			},
			home: "https://www.8comic.com/",
			update: "https://www.8comic.com/comic/u-1.html",
			list: ".view-back",
			background: "#1d79b1"
		},
		category: "comic autoPager"
	}, {
		name: "Mangabz",
		url: {
			h: "mangabz.com",
			p: "/m",
			e: ".container",
			ee: ".mh-list",
			st: "MANGABZ",
			d: "pc",
			i: 0
		},
		update: "/manga-list-0-0-2/",
		init: () => fn.MangabzUI(),
		imgs: (dom = document, msg = 1) => fn.MXY_getSrcs(dom, msg),
		button: [4],
		insertImg: ["#cp_img", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[img[contains(@src,'xiayizhang')]][starts-with(@href,'/m')]",
		prev: "//a[img[contains(@src,'shangyizhang')]][starts-with(@href,'/m')]",
		chapters: {
			url: ".top-title a",
			target: "#chapterlistload a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title("_", 2, dom).replace("漫畫", ""),
		preloadNext: async (nextDoc) => fn.picPreload(await fn.MXY_getSrcs(nextDoc, 0), _this.customTitle(nextDoc), "next"),
		css: "body{overflow:unset!important}",
		hide: "a[href^='j']",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "Mangabz 自動翻頁",
		url: {
			h: "mangabz.com",
			p: "/m",
			e: ".container",
			ee: ".mh-list",
			st: "MANGABZ",
			d: "pc",
			i: 1
		},
		getSrcs: (dom, msg = 0) => fn.MXY_getSrcs(dom, msg),
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: () => {
			fn.MangabzUI();
			return fn.showMsg(DL.str_135, 0).then(() => _this.getImgs()).then(imgs => fn.caae("#cp_img", imgs) && fn.hm());
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#cp_img", 0],
			observer: "#cp_img>img",
			next: "//a[img[contains(@src,'xiayizhang')]][starts-with(@href,'/m')]",
			re: ".container",
			title: (dom) => {
				let code = fn.gst("MANGABZ_CTITLE", dom);
				return fn.textVar(code, "MANGABZ_CTITLE");
			},
			preloadNextPage: 1,
			update: "/manga-list-0-0-2/",
			list: ".top-title a",
			chapters: {
				url: ".top-title a",
				target: "#chapterlistload a",
				sort: "r"
			}
		},
		css: "body{overflow:unset!important}",
		hide: "a[href^='j']",
		category: "comic autoPager"
	}, {
		name: "Xmanhua",
		url: {
			h: "xmanhua",
			p: "/m",
			st: "XMANHUA",
			ee: ".mh-list",
			d: "pc",
			i: 0
		},
		update: "/manga-list-0-0-2/",
		init: () => fn.XmanhuaUI(),
		imgs: (dom = document, msg = 1) => fn.MXY_getSrcs(dom, msg),
		button: [4],
		insertImg: ["#cp_img", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[img[contains(@src,'reader-bottom-right-2')]][starts-with(@href,'/m')]",
		prev: "//a[img[contains(@src,'reader-bottom-right-1')]][starts-with(@href,'/m')]",
		chapters: {
			url: ".reader-title a[title]",
			target: "#chapterlistload a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title("_", 2, dom).replace("漫畫", ""),
		preloadNext: async (nextDoc) => fn.picPreload(await fn.MXY_getSrcs(nextDoc, 0), _this.customTitle(nextDoc), "next"),
		css: ".reader-img-con{padding:64px 0 50px !important;}",
		hide: ".relative>a",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "Xmanhua 自動翻頁",
		url: {
			h: "xmanhua",
			p: "/m",
			st: "XMANHUA",
			ee: ".mh-list",
			d: "pc",
			i: 1
		},
		getSrcs: (dom, msg = 0) => fn.MXY_getSrcs(dom, msg),
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: () => {
			fn.XmanhuaUI();
			return fn.showMsg(DL.str_135, 0).then(() => _this.getImgs()).then(imgs => fn.caae("#cp_img", imgs) && fn.hm());
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#cp_img", 0],
			observer: "#cp_img>img",
			next: "//a[img[contains(@src,'reader-bottom-right-2')]][starts-with(@href,'/m')]",
			re: ".container",
			title: (dom) => {
				let code = fn.gst("XMANHUA_CTITLE", dom);
				return fn.textVar(code, "XMANHUA_CTITLE");
			},
			preloadNextPage: 1,
			update: "/manga-list-0-0-2/",
			list: ".reader-title a:nth-child(2)",
			chapters: {
				url: ".reader-title a[title]",
				target: "#chapterlistload a",
				sort: "r"
			}
		},
		css: ".reader-img-con{padding:64px 0 50px !important;}",
		hide: ".relative>a",
		category: "comic autoPager"
	}, {
		name: "YYMANGA",
		url: {
			h: "yymanhua.com",
			p: "/m",
			e: ".reader-bottom-page-list",
			d: "pc",
			i: 0
		},
		update: "/manga-list-0-0-2/",
		init: () => fn.XmanhuaUI(),
		imgs: (dom = document, msg = 1) => fn.MXY_getSrcs(dom, msg),
		button: [4],
		insertImg: ["#cp_img", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[img[contains(@src,'reader-bottom-right-2')]][starts-with(@href,'/m')]",
		prev: "//a[img[contains(@src,'reader-bottom-right-1')]][starts-with(@href,'/m')]",
		chapters: {
			url: ".reader-title a[title]",
			target: "#chapterlistload a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title("_", 2, dom).replace("漫畫", ""),
		preloadNext: async (nextDoc) => fn.picPreload(await fn.MXY_getSrcs(nextDoc, 0), _this.customTitle(nextDoc), "next"),
		css: ".reader-img-con{padding:64px 0 50px !important;}",
		hide: ".relative>a",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "YYMANGA 自動翻頁",
		url: {
			h: "yymanhua.com",
			p: "/m",
			e: ".reader-bottom-page-list",
			d: "pc",
			i: 1
		},
		getSrcs: (dom, msg = 0) => fn.MXY_getSrcs(dom, msg),
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: () => {
			fn.XmanhuaUI();
			return fn.showMsg(DL.str_135, 0).then(() => _this.getImgs()).then(imgs => fn.caae("#cp_img", imgs) && fn.hm());
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#cp_img", 0],
			observer: "#cp_img>img",
			next: "//a[img[contains(@src,'reader-bottom-right-2')]][starts-with(@href,'/m')]",
			re: ".container",
			title: (dom) => {
				let code = fn.gst("YYMANHUA_CTITLE", dom);
				return fn.textVar(code, "YYMANHUA_CTITLE");
			},
			preloadNextPage: 1,
			update: "/manga-list-0-0-2/",
			list: ".reader-title a:nth-child(2)",
			chapters: {
				url: ".reader-title a[title]",
				target: "#chapterlistload a",
				sort: "r"
			}
		},
		css: ".reader-img-con{padding:64px 0 50px !important;}",
		hide: ".relative>a",
		category: "comic autoPager"
	}, {
		name: "DM5/極速 分頁模式",
		host: ["www.dm5.com", "m.dm5.com", "www.dm5.cn", "m.dm5.cn", "en.dm5.com", "cnc.dm5.com", "hk.dm5.com", "cnc.dm5.com", "www.1kkk.com", "m.1kkk.com", "tel.1kkk.com", "en.1kkk.com", "cnc.1kkk.com", "hk.1kkk.com", "www.hkmanga.com"],
		url: {
			h: [/dm5/, /1kkk/, /hkmanga/],
			p: /^\/(m|ch|vol|other)/,
			e: "#chapterpager",
			i: 0
		},
		update: "/manhua-new/",
		imgs: (dom = document, msg = 1) => fn.DM5_getSrcs(dom, msg),
		button: [4],
		insertImg: ["#cp_img", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: ".view-btn-back",
			target: ".view-win-list a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title("_", 2, dom),
		topButton: true,
		css: "body{overflow:unset!important}",
		hide: ".view-ad,.view-mask",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "DM5/極速 分頁模式 自動翻頁",
		url: {
			h: [/dm5/, /1kkk/, /hkmanga/],
			p: /^\/(m|ch|vol|other)/,
			e: "#chapterpager",
			i: 1
		},
		getSrcs: (dom, msg = 0) => fn.DM5_getSrcs(dom, msg),
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: () => fn.showMsg(DL.str_135, 0).then(() => _this.getImgs()).then(imgs => fn.caae("#cp_img", imgs) && fn.hm()),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#cp_img", 0],
			observer: "#cp_img>img",
			next: "//a[text()='下一章']",
			re: ".active.right-arrow,.view-paging",
			title: (dom) => fn.gt(".title", 1, dom).replace("首页 ", "").replace(/\s+/g, " ").trim(),
			hide: ".view-comment",
			update: "/manhua-new/",
			list: ".view-btn-back",
			chapters: {
				url: ".view-btn-back",
				target: ".view-win-list a",
				sort: "r"
			}
		},
		css: "body{overflow:unset!important}",
		hide: "a[href^='javascript:Show'],.chapterpager,.view-ad,.view-mask",
		category: "comic autoPager"
	}, {
		name: "DM5/極速 條漫模式",
		url: {
			h: [/dm5/, /1kkk/, /hkmanga/],
			p: /^\/(m|ch|vol|other)/,
			i: 0
		},
		update: "/manhua-new/",
		imgs: "#barChapter>img",
		button: [4],
		insertImg: ["#barChapter", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: ".view-btn-back",
			target: ".view-win-list a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title("_", 2, dom),
		css: "body{overflow:unset!important}",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "DM5/極速 條漫模式 自動翻頁",
		url: {
			h: [/dm5/, /1kkk/, /hkmanga/],
			p: /^\/(m|ch|vol|other)/,
			e: "#barChapter",
			i: 1
		},
		getSrcs: (dom) => fn.gae("img.load-src[data-src]", dom).map(e => e.dataset.src),
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.caae("#barChapter", _this.getImgs()),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#barChapter", 0],
			observer: "#barChapter>img",
			next: "//a[text()='下一章']",
			re: ".view-paging",
			title: (dom) => fn.gt(".title", 1, dom).replace("首页 ", "").replace(/\s+/, " ").trim(),
			hide: ".view-comment",
			update: "/manhua-new/",
			list: ".view-btn-back",
			chapters: {
				url: ".view-btn-back",
				target: ".view-win-list a",
				sort: "r"
			}
		},
		css: "body{overflow:unset!important}",
		category: "comic autoPager"
	}, {
		name: "DM5/極速/Mangabz/Xmanhua/yymanhua/漫画人/漫本 手機版",
		host: ["m.dm5.com", "m.1kkk.com", "www.mangabz.com", "mangabz.com", "www.xmanhua.com", "xmanhua.com", "www.yymanhua.com", "yymanhua.com", "www.manben.com", "www.manhuaren.com"],
		url: {
			h: /dm5|1kkk|mangabz|xmanhua|yymanhua|manhuaren|manben/,
			p: /^\/(m|ch|vol|other)?[-_0-9]+\//,
			//st: "newImgs",
			d: "m",
			i: 0
		},
		init: async () => {
			await fn.waitVar("newImgs");
			if (fn.gae(".view-bottom-bar>li").length == 4) {
				fn.css(".view-bottom-bar>li:nth-child(n+2):nth-child(-n+3){display:none!important}.view-bottom-bar li{width:50%!important}");
			}
			let b = fn.ge("body.viewbody");
			if (fn.lh.includes("mangabz") && b) {
				b.innerHTML = b.innerHTML.replace("<!--", "").replace("-->", "");
				fn.ge(".top-bar-tool").removeAttribute("style");
				fn.ge(".bottom-bar").removeAttribute("style");
				const showtoolbar = () => document.body.classList.toggle("toolbar");
				document.addEventListener('click', showtoolbar);
			}
		},
		imgs: () => _unsafeWindow.newImgs,
		button: [4],
		insertImg: ["#cp_img,.main_img,#comicContain,.comic-list", 2],
		autoDownload: [0],
		np: (k) => {
			let e = fn.ge(`//a[text()='${k}一章'] | //a[img[@alt='${k}一章']]`);
			if (e) {
				if (e?.href?.includes("void(0)") || e?.href?.includes("-end")) return null;
				return /pushHistory/.test(e.href) ? location.origin + e.href.split("'")[1] : e.href;
			};
			return null;
		},
		next: () => _this.np("下"),
		prev: () => _this.np("上"),
		chapters: {
			url: "//a[p[text()='目录']]",
			target: ".detail-list-select a",
			sort: "r"
		},
		customTitle: (dom = document) => {
			let host = fn.lh;
			if (/dm5|manhuaren|1kkk|mangabz|xmanhua|yymanhua/.test(host)) {
				return fn.title("_", 2, dom);
			} else if (/manben/.test(host)) {
				if (fn.ge("#comicTitle")) {
					return fn.gt("#chapter", 1, dom) + " " + fn.gt(".title-comicHeading", 1, dom);
				}
				return fn.title(" ", 2, dom);
			}
		},
		preloadNext: (nextDoc) => {
			if (!/dm5|1kkk|manhuaren/.test(fn.lh)) {
				let code = fn.gst("newImgs", nextDoc);
				fn.script(code);
				fn.picPreload(_unsafeWindow.newImgs, _this.customTitle(nextDoc), "next");
			}
		},
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "DM5/極速/Mangabz/Xmanhua/yymanhua/漫画人/漫本 手機版 自動翻頁",
		url: {
			h: /dm5|1kkk|mangabz|xmanhua|yymanhua|manhuaren|manben/,
			p: /^\/(m|ch|vol|other)?[-_0-9]+\//,
			//st: "newImgs",
			d: "m",
			i: 1
		},
		getSrcs: (dom) => {
			let code = fn.gst("newImgs", dom);
			let text = fn.parseCode(code);
			return fn.textToArray(text, "newImgs");
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: async () => {
			await fn.caae("#cp_img", _this.getImgs());
			if (fn.gae(".view-bottom-bar>li").length == 4) {
				fn.css(".view-bottom-bar>li:nth-child(n+2):nth-child(-n+3){display:none!important}.view-bottom-bar li{width:50%!important}");
			}
			let b = fn.ge("body.viewbody");
			if (fn.lh.includes("mangabz") && b) {
				b.innerHTML = b.innerHTML.replace("<!--", "").replace("-->", "");
				fn.ge(".top-bar-tool").removeAttribute("style");
				fn.ge(".bottom-bar").removeAttribute("style");
				const showtoolbar = () => document.body.classList.toggle("toolbar");
				document.addEventListener('click', showtoolbar);
			}
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#cp_img", 0],
			observer: "#cp_img>img",
			next: (dom) => {
				let next = fn.ge("//a[text()='下一章'] | //a[img[@alt='下一章']]", dom, dom);
				if (next) {
					let url = /pushHistory/.test(next.href) ? fn.lo + next.href.split("'")[1] : next.href;
					if (!/-end/.test(url)) {
						return url;
					}
				}
				return null;
			},
			re: ".view-fix-top-bar-title,.top-title,.view-bottom-bar,.view-fix-bottom-bar,.bottom-bar-tool",
			title: (dom) => {
				let tt = fn.gt(".top-title", 1, dom);
				if (fn.lh.includes("xmanhua") && tt) {
					return tt.replaceAll("?", "-").replace("XManhua-", "");
				} else if (fn.lh.includes("mangabz") && tt) {
					return tt.replaceAll("?", "-").replace("Mangabz-", "");
				} else if (fn.lh.includes("yymanhua") && tt) {
					return tt.replaceAll("?", "-").replace("YYManhua-", "");
				}
				return dom.title.replace(/,?_在线漫画.+/, "").replace("漫画", "").replace(/^[^_]+_/, "");
			},
			bF: (dom) => {
				let b = fn.ge("body.viewbody", dom);
				if (fn.lh.includes("mangabz") && b) {
					b.innerHTML = b.innerHTML.replace("<!--", "").replace("-->", "");
				}
			},
			preloadNextPage: (dom) => {
				if (!/dm5|1kkk/.test(fn.lh)) {
					let next = _this.autoPager.next(dom);
					if (next) {
						fn.fetchDoc(next).then(_dom => fn.picPreload(_this.getSrcs(_dom), _this.autoPager.title(_dom), "next"));
					}
				}
			},
			list: "//a[p[text()='目录']]",
			chapters: {
				url: "//a[p[text()='目录']]",
				target: ".detail-list-select a",
				sort: "r"
			}
		},
		category: "comic autoPager"
	}, {
		name: "再漫画",
		url: {
			h: "manhua.zaimanhua.com",
			d: "pc"
		},
		page: () => fn.dlp("/view/"),
		update: "/update",
		SPA: () => _this.page(),
		observeURL: "head",
		json: () => {
			fn.sm5();
			let [, , , comic_id, chapter_id] = fn.clp().split("/");
			siteJson.comic_id = comic_id;
			siteJson.chapter_id = chapter_id;
			let res_a = fn.j(`/api/v1/comic2/chapter/detail?comic_id=${comic_id}&chapter_id=${chapter_id}`).then(json => {
				let {
					page_url,
					page_url_hd,
					title: chapter_title
				} = json.data.chapterInfo;
				siteJson.srcs = page_url_hd ?? page_url;
				siteJson.chapter_title = chapter_title;
			});
			let res_b = fn.j(`/api/v1/comic2/comic/detail?id=${comic_id}`).then(json => {
				let _chapters = [];
				let {
					id,
					chapterList,
					title: comic_title
				} = json.data.comicInfo;
				siteJson.comic_id = id;
				siteJson.comic_title = comic_title;
				for (let e of chapterList) {
					if (e.title == "单行本") {
						_chapters[0] = e;
					} else if (e.title == "连载") {
						_chapters[1] = e;
					} else if (e.title == "番外篇") {
						_chapters[2] = e;
					} else {
						_chapters[3] = e;
					}
				}
				_chapters = _chapters.filter(Boolean);
				siteJson.chapters = _chapters.map(e => e.data.reverse()).flat();
			});
			return Promise.all([res_a, res_b]).then(() => {
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.srcs : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		np: (i) => {
			if (!_this.page()) return null;
			let index = siteJson.chapters.findIndex(e => e.chapter_id == siteJson.chapter_id);
			let o = siteJson.chapters[index + i];
			return isObject(o) ? fn.wurl(o.chapter_id) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			chapter_id,
			chapter_title
		}) => ({
			text: chapter_title,
			url: fn.wurl(chapter_id)
		})),
		customTitle: () => _this.page() ? siteJson.comic_title + " - " + siteJson.chapter_title : null,
		preloadNext: () => {
			let [, , , comic_id, chapter_id] = nextLink.split("/");
			fn.j(`/api/v1/comic2/chapter/detail?comic_id=${comic_id}&chapter_id=${chapter_id}`).then(json => {
				let {
					page_url,
					page_url_hd,
					title
				} = json.data.chapterInfo;
				fn.picPreload(page_url_hd ?? page_url, title, "next");
			});
		},
		category: "comic"
	}, {
		name: "再漫画M",
		url: {
			h: "m.zaimanhua.com",
			d: "m"
		},
		page: () => fn.clp("/pages/comic/page"),
		json: () => {
			fn.sm5();
			let url = fn.curl();
			let comic_id = fn.getUSP("comic_id", url);
			let chapter_id = fn.getUSP("chapter_id", url);
			siteJson.comic_id = comic_id;
			siteJson.chapter_id = chapter_id;
			let res_a = fn.j(`/api/app/v1/comic/chapter/${comic_id}/${chapter_id}?_v=15`).then(json => {
				let {
					page_url,
					page_url_hd,
					title: chapter_title
				} = json.data.data;
				siteJson.srcs = page_url_hd ?? page_url;
				siteJson.chapter_title = chapter_title;
			});
			let res_b = fn.j(`/api/app/v1/comic/detail/${comic_id}?_v=15`).then(json => {
				let _chapters = [];
				let {
					id,
					chapters,
					title: comic_title
				} = json.data.data;
				siteJson.comic_id = id;
				siteJson.comic_title = comic_title;
				for (let e of chapters) {
					if (e.title == "单行本") {
						_chapters[0] = e;
					} else if (e.title == "连载") {
						_chapters[1] = e;
					} else if (e.title == "番外篇") {
						_chapters[2] = e;
					} else {
						_chapters[3] = e;
					}
				}
				_chapters = _chapters.filter(Boolean);
				siteJson.chapters = _chapters.map(e => e.data.reverse()).flat();
			});
			return Promise.all([res_a, res_b]).then(() => {
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.srcs : [],
		capture: () => _this.imgs(),
		np: (i) => {
			if (!_this.page()) return null;
			let index = siteJson.chapters.findIndex(e => e.chapter_id == siteJson.chapter_id);
			let o = siteJson.chapters[index + i];
			return isObject(o) ? `/pages/comic/page?comic_id=${siteJson.comic_id}&chapter_id=${o.chapter_id}&chapter_name=${o.chapter_title}` : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(({
			chapter_id,
			chapter_title
		}) => ({
			text: chapter_title,
			url: `/pages/comic/page?comic_id=${siteJson.comic_id}&chapter_id=${chapter_id}&chapter_name=${chapter_title}`
		})),
		checkCurrentChapter: (url) => {
			let cid = fn.getUSP("chapter_id", fn.curl());
			let uid = fn.getUSP("chapter_id", location.origin + url);
			return cid == uid;
		},
		customTitle: () => _this.page() ? siteJson.comic_title + " - " + siteJson.chapter_title : null,
		preloadNext: () => {
			let url = location.origin + nextLink;
			let chapter_id = fn.getUSP("chapter_id", url);
			fn.j(`/api/app/v1/comic/chapter/${siteJson.comic_id}/${chapter_id}?_v=15`).then(json => {
				let {
					page_url,
					page_url_hd,
					title
				} = json.data.data;
				fn.picPreload(page_url_hd ?? page_url, title, "next");
			});
		},
		css: ".top_nav{z-index: 999999999!important}",
		category: "comic"
	}, {
		name: "漫畫狗",
		url: {
			h: "dogemanga.com",
			p: "/p/",
			e: ".site-reader"
		},
		imgs: () => fn.gae(".site-reader__image").map(e => e.dataset.pageImageUrl),
		button: [4, 1],
		insertImgBF: () => fn.ge(".site-reader").setAttribute("class", "imgBox"),
		insertImg: [".imgBox", 2],
		insertImgAF: () => {
			fn.addUrlHtml(location.origin, ".imgBox", 1, "首頁");
			if (nextLink) fn.addUrlHtml(nextLink, ".imgBox", 1);
		},
		autoDownload: [0],
		np: (k) => {
			let c = fn.ge(".site-selector[data-kind=publication] [selected]");
			let e = null;
			if (isEle(c)) {
				if (k in c) {
					e = c[k];
				}
			}
			return isEle(e) ? e.value : null;
		},
		next: () => _this.np("previousElementSibling"),
		prev: () => _this.np("nextElementSibling"),
		chapters: {
			url: ".site-navbar__title",
			target: "#site-manga__tab-pane-all a",
			sort: "r"
		},
		customTitle: () => fn.title(" - 漫畫狗"),
		preload: 0,
		css: ".imgBox{height:auto!important}",
		hide: ".fixed-bottom",
		category: "comic"
	}, {
		name: "Manhuagui看漫画M",
		url: {
			h: "m.manhuagui.com",
			p: /^\/comic\/\d+\/\d+.html/,
			i: 0
		},
		update: "/update/",
		json: (dom = document) => fn.manhuaguiJson(dom),
		init: () => {
			siteJson = _this.json();
			let nextE = fn.ge("a[data-action='chapter.next']");
			let prevE = fn.ge("a[data-action='chapter.prev']");
			let c_url = fn.ge("#mangaTitle a").href;
			if (siteJson.nextId == 0) {
				nextE.innerText = "目录";
				nextE.href = c_url;
			} else {
				nextE.href = c_url + siteJson.nextId + ".html";
			}
			if (siteJson.prevId == 0) {
				prevE.innerText = "目录";
				prevE.href = c_url;
			} else {
				prevE.href = c_url + siteJson.prevId + ".html";
			}
		},
		box: ["#manga", 2],
		imgs: (json = siteJson) => json.images.map(e => `https://${manhuagui_img_serv}.hamreus.com${e}?e=${json.sl.e}&m=${json.sl.m}`),
		button: [4],
		insertImg: ["box", 2],
		insertImgBF: () => fn.waitEle("#manga img[src*=hamreus]"),
		insertImgAF: () => fn.css("#manga{display:none!important;}"),
		autoDownload: [0],
		next: () => siteJson.nextId == 0 ? null : fn.gu("#mangaTitle a") + siteJson.nextId + ".html",
		prev: "//a[text()='上一章']",
		chapters: () => fn.MHG_M_C(),
		customTitle: (dom = document) => fn.gt("#mangaTitle", 1, dom),
		preloadNext: (nextDoc) => {
			let json = _this.json(nextDoc);
			let arr = _this.imgs(json);
			fn.picPreload(arr, _this.customTitle(nextDoc), "next");
		},
		css: ".action-list li{width:50% !important}",
		hide: "#action>ul>li:nth-child(n+2):nth-child(-n+3),.manga-page,.clickforceads",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "Manhuagui看漫画M 自動翻頁",
		url: {
			h: "m.manhuagui.com",
			p: /^\/comic\/\d+\/\d+.html/,
			i: 1
		},
		json: (dom = document) => fn.manhuaguiJson(dom),
		getSrcs: (dom) => {
			let json = _this.json(dom);
			return json.images.map(e => `https://${manhuagui_img_serv}.hamreus.com${e}?e=${json.sl.e}&m=${json.sl.m}`);
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.waitEle("#manga img[src*=hamreus]").then(() => fn.caae("#manga", _this.getImgs())),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#manga", 0],
			observer: "#manga>img",
			next: (dom, r = 1) => {
				let json = _this.json(dom);
				if (json.nextId == 0) {
					if (r === 1) {
						let e = fn.ge("a[data-action='chapter.next']");
						e.href = fn.ge("#mangaTitle a").href;
						e.innerText = "返回目录";
					}
					return null;
				}
				return fn.gu("#mangaTitle a") + json.nextId + ".html";
			},
			re: "#mangaTitle",
			title: (dom) => fn.ge("#mangaTitle>a", dom)?.nextSibling?.data?.replace(/\s+/g, " ")?.trim(),
			aF: (dom) => {
				let json = _this.json(dom);
				let cUrl = fn.gu("#mangaTitle a");
				let ne = fn.ge("a[data-action='chapter.next']");
				ne.href = cUrl + json.nextId + ".html";
				let pe = fn.ge("a[data-action='chapter.prev']");
				pe.href = cUrl + json.prevId + ".html";
			},
			preloadNextPage: 1,
			list: "#mangaTitle a",
			chapters: () => fn.MHG_M_C(),
			update: "/update/",
			background: "#0077d1"
		},
		css: ".action-list li{width:50% !important}",
		hide: "#action>ul>li:nth-child(n+2):nth-child(-n+3),.manga-page,.clickforceads",
		category: "comic autoPager"
	}, {
		name: "Manhuagui看漫画M 点击查看下20条记录",
		url: {
			h: "m.manhuagui.com",
			p: /^\/(update|list|rank|user)\//
		},
		loadMore: "#more:not([style*=none])>.more-go",
		openInNewTab: "#detail a:not([target=_blank])",
		category: "autoPager"
	}, {
		name: "Manhuagui看漫画",
		host: ["www.manhuagui.com", "tw.manhuagui.com", "www.mhgui.com"],
		url: {
			h: /manhuagui|mhgui/,
			p: /^\/comic\/\d+\/\d+.html/,
			i: 0
		},
		update: "/update/",
		init: () => fn.waitVar(["SMH", "pVars"]).then(() => fn.run("$(document).unbind('keydown')")),
		imgs: (dom = document) => {
			let json = fn.manhuaguiJson(dom);
			let {
				files,
				path,
				sl: {
					e,
					m
				}
			} = json;
			return files.map(f => `https://${manhuagui_img_serv}.hamreus.com${path}${f}?e=${e}&m=${m}`);
		},
		button: [4],
		insertImg: ["#tbBox", 2],
		autoDownload: [0],
		next: () => {
			const {
				cInfo
			} = _unsafeWindow;
			return cInfo.nextId == 0 ? null : location.origin + "/comic/" + cInfo.bid + "/" + cInfo.nextId + ".html";
		},
		prev: "//a[text()='上一章']",
		chapters: () => fn.MHG_PC_C(),
		customTitle: (dom = document) => fn.gt("h1>a", 1, dom) + " - " + fn.gt("h2", 1, dom),
		preloadNext: true,
		css: ".tbCenter{max-width:1400px!important;width:auto!important;height:auto!important}",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "Manhuagui看漫画 自動翻頁",
		url: {
			h: /manhuagui|mhgui/,
			p: /^\/comic\/\d+\/\d+.html/,
			i: 1
		},
		json: (dom = document) => fn.manhuaguiJson(dom),
		getSrcs: (dom) => {
			let json = _this.json(dom);
			let {
				files,
				path,
				sl: {
					e,
					m
				}
			} = json;
			return files.map(f => `https://${manhuagui_img_serv}.hamreus.com${path}${f}?e=${e}&m=${m}`);
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.caae("#tbBox", _this.getImgs()).then(() => fn.run("$(document).unbind('keydown')")),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#tbBox", 0],
			observer: "#tbBox img",
			next: (dom, r = 1) => {
				let json = _this.json(dom);
				let n = json.nextId;
				if (n == 0) {
					if (r === 1) {
						fn.ge("#pagination").outerHTML = fn.ge(".main-btn").outerHTML;
					}
					return null;
				}
				return fn.url.replace(/\d+\.html$/, "") + n + ".html";
			},
			re: ".title h2",
			title: (dom) => _this.json(dom).cname,
			preloadNextPage: 1,
			list: "#viewList",
			chapters: () => fn.MHG_PC_C(),
			update: "/update/",
			background: "#0077d1"
		},
		css: ".tbCenter{max-width:1400px!important;width:auto!important;height:auto!important}",
		hide: "#prev,#pageSelect,#next,.pager>*:not([onclick])",
		category: "comic autoPager"
	}, {
		name: "包子漫画 閱讀",
		host: ["cn.baozimh.com", "cn.webmota.com", "tw.baozimh.com", "tw.webmota.com", "www.baozimh.com", "www.webmota.com", "cn.kukuc.co", "tw.kukuc.co", "www.kukuc.co", "tw.czmanga.com", "cn.czmanga.com", "www.czmanga.com", "tw.dzmanga.com", "cn.dzmanga.com", "www.dzmanga.com", "tw.dociy.net", "cn.dociy.net", "www.dociy.net", "tw.twmanga.com", "cn.twmanga.com", "www.twmanga.com"],
		url: {
			t: "包子",
			p: /^\/comic\/chapter\/[^/]+\/\w+\.html/i,
			i: 0
		},
		init: async () => {
			fn.addMutationObserver(() => fn.remove("div[id*='ads'],div[id='interstitial_fade'],iframe:not([id^=Full])"));
			fn.run("document.onkeydown=null");
			await fn.getNP(".comic-contain>div:not(.mobadsq)", "//a[contains(text(),'下一頁') or contains(text(),'下一页')]", null, ".comic-chapter>.next_chapter,.bottom-bar-tool");
		},
		imgs: (dom = document) => [...new Set(fn.gae(".comic-contain amp-img", dom).map(e => e.dataset.src ?? e.getAttribute("src")))],
		button: [4],
		insertImg: [".comic-contain", 2],
		autoDownload: [0],
		next: "//div[@class='next_chapter']/a[contains(text(),'下一話') or contains(text(),'下一话')]",
		prev: 1,
		chapters: () => fn.BZMH_C(),
		customTitle: (dom = document) => fn.title(" - ", 3, dom).replace(/\(\d+\/\d+\)/, ""),
		preloadNext: true,
		hide: ".baozi-ad,div[id*='ads'],div[id='interstitial_fade'],iframe:not([id^=Full]),.chapter-main.scroll-mode~*:not(.next_chapter):not(.bottom-bar)",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "包子漫画 閱讀 自動翻頁",
		url: {
			t: "包子",
			p: /^\/comic\/chapter\/[^/]+\/\w+\.html/i,
			i: 1
		},
		getSrcs: (dom) => fn.gae(".comic-contain amp-img", dom).map(e => e.dataset.src ?? e.getAttribute("src")),
		getImgs: (dom = document) => {
			let srcs = _this.getSrcs(dom);
			if (fn.ge(".FullPictureLoadImage")) {
				let currentLastSrc = fn.gae(".FullPictureLoadImage").at(-1).dataset.src;
				let nextFirstNum = Number(srcs[0].match(/(\d)\.\w+$/)[1]);
				if (/\/(50|100|150|200|250|300)\.[a-z]{3,5}$/i.test(currentLastSrc) && nextFirstNum == 7 && nextFirstNum != 1) {
					srcs = srcs.slice(4);
				}
			}
			return fn.createImgArray(srcs);
		},
		init: () => {
			fn.addMutationObserver(() => fn.remove("div[id*='ads'],div[id='interstitial_fade'],iframe"));
			fn.run("document.onkeydown=null");
			return fn.caae(".comic-contain", _this.getImgs());
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".comic-contain", 0],
			observer: ".comic-contain img",
			next: (dom) => {
				let next = fn.ge("a#next-chapter", dom);
				return next ? fn.lo + next.pathname : null;
			},
			re: "//div[@class='text']/span[@class='title'] | //div[@class='comic-chapter']/div[@class='next_chapter'] | //div[@class='bottom-bar-tool']",
			title: (dom) => {
				let titleText = fn.gt("span.title", 1, dom).replace(/\(\d\/\d+\)/, "");
				return {
					ok: /\/\d+_\d+\.html$/.test(nextLink),
					text: titleText
				}
			},
			skipHistory: (url) => url.split("/").at(-1).split("_").length > 2,
			hide: ".comic-chapter>.l-content",
			preloadNextPage: 1,
			list: "a.goto",
			chapters: () => fn.BZMH_C(),
		},
		css: ".comic-contain{width: 100%;margin: 0 auto;max-width:970px;}",
		hide: ".baozi-ad,div[id*='ads'],div[id='interstitial_fade'],iframe,.chapter-main.scroll-mode~*:not(.next_chapter,.bottom-bar,.l-content),.mobadsq",
		category: "comic autoPager"
	}, {
		name: "包子漫画 展開目錄",
		icon: 0,
		key: 0,
		url: {
			t: "包子",
			p: /^\/comic\/[-\w]+$/i
		},
		autoClick: ["#button_show_all_chatper", 1000],
		category: "comic"
	}, {
		name: "包子漫画,連結新分頁開啟",
		icon: 0,
		key: 0,
		url: {
			t: "包子",
			e: ".comics-card,.bookshelf-items"
		},
		openInNewTab: ".comics-card a:not([target=_blank]),.bookshelf-items a:not(.remove-img):not([target=_blank])",
		category: "comic"
	}, {
		name: "Komiic",
		enable: 0,
		url: {
			h: ["komiic.com"]
		},
		page: () => fn.clp("/chapter/"),
		json: () => {
			fn.sm5();
			let [, , comicId, , chapterId] = fn.clp().split("/");
			let options = (b) => ({
				"headers": {
					"content-type": "application/json"
				},
				"body": JSON.stringify(b),
				"method": "POST"
			});
			let res_a = fn.j("/api/query", options({
				operationName: "imagesByChapterId",
				variables: {
					chapterId
				},
				query: "query imagesByChapterId($chapterId: ID!) {\n  imagesByChapterId(chapterId: $chapterId) {\n    id\n    kid\n    height\n    width\n    __typename\n  }\n}\n"
			}));
			let res_b = fn.j("/api/query", options({
				operationName: "chapterByComicId",
				variables: {
					comicId
				},
				query: "query chapterByComicId($comicId: ID!) {\n  chaptersByComicId(comicId: $comicId) {\n    id\n    serial\n    type\n    dateCreated\n    dateUpdated\n    size\n    __typename\n  }\n}\n"
			}));
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				let chapterList = b.data.chaptersByComicId;
				let vols = chapterList.filter(e => e.type == "book");
				let chs = chapterList.filter(e => e.type != "book");
				chapterList = [...vols, ...chs];
				siteJson = {
					comicId,
					chapterId,
					chapterList,
					images: a.data.imagesByChapterId
				};
				debug("\n此頁JSON資料\n", siteJson);
				fn.hm();
			});
		},
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.images.map(e => "https://komiic.com/api/image/" + e.kid) : [],
		capture: () => _this.imgs(),
		chapter_url: (id) => `/comic/${siteJson.comicId}/chapter/${id}/images/all`,
		np: (i) => {
			if (!_this.page()) return null;
			let {
				chapterList
			} = siteJson;
			let ci = chapterList.findIndex(e => e.id == siteJson.chapterId);
			let o = chapterList[ci + i];
			return isObject(o) ? _this.chapter_url(o.id) : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapterList.map(({
			id,
			serial,
			type
		}) => ({
			text: `第${serial}${type == "book" ? "卷" : "話"}`,
			url: _this.chapter_url(id)
		})),
		customTitle: (s = ".v-breadcrumbs .breadcrumbs__item") => {
			if (!_this.page()) return null;
			return fn.waitEle(s).then(() => getTitle([s, 1, 2]));
		},
		referer: "url",
		category: "comic"
	}, {
		name: "LINE WEBTOON / 咚漫",
		host: ["www.webtoons.com", "www.dongmanmanhua.cn"],
		enable: 0,
		url: {
			h: /webtoons|dongmanmanhua/,
			p: /^\/[^&]+&episode/
		},
		imgs: "._images[data-url]",
		autoDownload: [0],
		next: "//div[@class='episode_cont']//li[a[starts-with(@class,'on')]]/following-sibling::li[1]/a",
		prev: "//div[@class='episode_cont']//li[a[starts-with(@class,'on')]]/preceding-sibling::li[1]/a",
		customTitle: () => fn.title("|", 3).replace(/ - \d+/, "").replace("|", " - "),
		category: "comic"
	}, {
		name: "LINE WEBTOON 目錄聚集所有章節",
		enable: 0,
		icon: 0,
		key: 0,
		url: {
			h: "www.webtoons.com",
			p: "/list"
		},
		init: "fn.getNP('._episodeItem',\"//div[@class='paginate']/a[span[@class='on']]/following-sibling::a[1]\",null,'.paginate',0,null,0)",
		category: "comic"
	}, {
		name: "動漫啦",
		enable: 0,
		url: {
			h: "www.dongman.la",
			p: "/chapter/"
		},
		imgs: (link = siteUrl, msg = 1, request = 0) => {
			let links = [link.replace("all.html", "") + "all.html"];
			return fn.getImgA(".imgListBox img", links, 0, null, msg, request);
		},
		button: [4],
		insertImg: [".imgListBox", 2],
		autoDownload: [0],
		next: "//a[label[text()='下一章']][contains(@href,'chapter')]",
		prev: "//a[label[text()='上一章']][contains(@href,'chapter')]",
		chapters: {
			url: ".mdui-typo-headline",
			target: ".cy_plist a",
			sort: "r"
		},
		customTitle: (dom = document) => getTitle(["a[title]", 0, 1], dom),
		preloadNext: async (nextDoc) => fn.picPreload(await _this.imgs(nextLink, 0, 1), await _this.customTitle(nextDoc), "next"),
		css: ".mdui-col-xs-4{width:50%!important}",
		hide: ".mdui-container .mdui-col-xs-4:nth-child(2)",
		category: "comic"
	}, {
		name: "動漫啦M",
		enable: 0,
		url: {
			h: "m.dongman.la",
			p: "/chapter/",
		},
		imgs: ".chapter-images img",
		button: [4],
		insertImg: [".chapter-images", 2],
		next: "//a[label[text()='下一章']][contains(@href,'chapter')]",
		prev: "//a[label[text()='上一章']][contains(@href,'chapter')]",
		chapters: {
			url: "a[title='查看章节列表']",
			target: "#tab-chapters a",
			sort: "r"
		},
		customTitle: (dom = document) => getTitle(["span[title]", 0, 1], dom),
		preloadNext: true,
		category: "comic"
	}, {
		name: "漫画456",
		host: ["www.manhua456.com", "m.manhua456.com"],
		enable: 0,
		url: {
			h: ".manhua456.com",
			p: /^\/manhua\/\w+\/\d+\.html/
		},
		init: () => fn.rd().then(() => {
			isPC ? fn.run("setTimeout(()=>$(document).unbind('keyup') && $(document).unbind('keydown'),4000)") : void 0;
			let code = fn.gst("comicUrl", doc);
			let comicUrl = fn.textVar(code, "comicUrl");
			return fn.fetchDoc(new URL(comicUrl).pathname).then(dom => {
				let chapters = fn.gae("ul[id^=chapter-list] a", dom);
				let index = chapters.findIndex(a => a.href.includes(fn.lp));
				let next = chapters[index + 1];
				let prev = chapters[index - 1];
				siteJson = {
					chapters: chapters.map(a => ({
						text: fn.dt({
							t: a.text
						}),
						url: a.href
					})),
					next: isEle(next) ? next.href : null,
					prev: isEle(prev) ? prev.href : null
				}
			});
		}),
		imgs: (dom = doc) => {
			let code = fn.gst("chapterImages", dom);
			let chapterImages = fn.textToArray(code, "chapterImages");
			let chapterPath = fn.textVar(code, "chapterPath");
			return chapterImages.map(e => ["http", "//"].some(s => e.startsWith(s)) ? e : "http://res456.kingwar.cn/" + chapterPath + e);
		},
		button: [4],
		insertImgBF: () => fn.waitEle("#images img"),
		insertImg: ["#images", 2],
		insertImgAF: () => fn.run("jQuery('#images').unbind('click')"),
		autoDownload: [0],
		next: () => isString(siteJson.next) ? siteJson.next : null,
		prev: () => isString(siteJson.prev) ? siteJson.prev : null,
		chapters: () => siteJson.chapters,
		customTitle: (dom = doc) => {
			let code = fn.gst("pageTitle", dom);
			let pageTitle = fn.textVar(code, "pageTitle");
			let [chapterName, comicName] = pageTitle.split(" - ");
			return comicName + " - " + chapterName;
		},
		preloadNext: true,
		mcss: ".action-list li{width:50% !important}",
		hide: ".img_land_prev,.img_land_next,#action>ul>li:nth-child(n+2):nth-child(-n+3),.img_land_prev,.img_land_next,body>div[id]:has(>div[class][style]>div[style]),body>div:has(.swiper-slide)",
		category: "comic"
	}, {
		name: "漫画1234",
		host: ["www.amh1234.com", "b.amh1234.com"],
		enable: 0,
		url: {
			t: "漫画1234",
			p: /^\/comic\/\d+\/\d+\.html/,
			st: "chapterImages"
		},
		init: () => {
			let res_a = fn.t("/js/config.js").then(text => {
				let domain = String(fn.textToArray(text, "domain"));
				siteJson.domain = domain;
			});
			let res_b = fn.rd().then(() => {
				let code = fn.gst("comicUrl", doc);
				let comicUrl = fn.textVar(code, "comicUrl");
				return fn.fetchDoc(new URL(comicUrl).pathname).then(dom => {
					let chapters = fn.gae("ul[id^=chapter-list] a", dom);
					if (fn.lh.startsWith("b.")) {
						chapters = chapters.reverse();
					}
					let index = chapters.findIndex(a => a.href.includes(fn.lp));
					let next = chapters[index + 1];
					let prev = chapters[index - 1];
					let obj = {
						chapters: chapters.map(a => ({
							text: fn.dt({
								t: a.text
							}),
							url: a.href
						})),
						next: isEle(next) ? next.href : null,
						prev: isEle(prev) ? prev.href : null
					};
					siteJson = {
						...siteJson,
						...obj
					}
				});
			});
			return Promise.all([res_a, res_b]).then(() => fn.run("$(document).unbind('keydown') && $(document).unbind('keyup')"));
		},
		imgs: (dom = doc) => {
			let code = fn.gst("chapterImages", dom);
			let chapterImages = fn.textToArray(code, "chapterImages");
			let chapterPath = fn.textVar(code, "chapterPath");
			return chapterImages.map(e => ["http", "//"].some(s => e.startsWith(s)) ? e : siteJson.domain + "/" + chapterPath + e);
		},
		button: [4],
		insertImg: ["#images", 2],
		insertImgAF: (parent) => {
			fn.run("$('#images').unbind('click')");
			if (nextLink) {
				fn.addUrlHtml(nextLink, parent, 1, DL.str_143, 3);
			}
		},
		autoDownload: [0],
		next: () => isString(siteJson.next) ? siteJson.next : null,
		prev: () => isString(siteJson.prev) ? siteJson.prev : null,
		chapters: () => siteJson.chapters,
		customTitle: (dom = doc) => {
			let code = fn.gst("SinMH.initChapter", dom);
			let [, chapterName, , comicName, ] = code.match(/SinMH.initChapter\(([^\)]+)\)/)[1].replaceAll('"', "").split(",");
			return comicName + " - " + chapterName;
		},
		preloadNext: true,
		css: ".action-list li{width:50% !important}",
		hide: ".globalPadding,.img_info,#imgLoading,#loading,#action>ul>li:nth-child(n+2):nth-child(-n+3)",
		category: "comic"
	}, {
		name: "92漫画/31漫画",
		enable: 0,
		url: {
			h: ["www.92mh.com", "www.31mh.cc"],
			p: [/^\/manhua\/\d+\/\d+\.html$/, /^\/comic\/\w+\/\d+\.html$/]
		},
		init: () => fn.rd().then(() => {
			if (isPC) {
				try {
					fn.run("$(document).unbind('keydown') && $(document).unbind('keyup') && $('#images').unbind('click')");
				} catch {}
			}
			let code = fn.gst("comicUrl", doc);
			let comicUrl = fn.textVar(code, "comicUrl");
			return fn.fetchDoc(new URL(comicUrl).pathname).then(dom => {
				let chapters = fn.gae("ul[id^=chapter-list] a", dom);
				let index = chapters.findIndex(a => a.href.includes(fn.lp));
				let next = chapters[index + 1];
				let prev = chapters[index - 1];
				siteJson = {
					chapters: chapters.map(a => ({
						text: fn.dt({
							t: a.text
						}),
						url: a.href
					})),
					next: isEle(next) ? next.href : null,
					prev: isEle(prev) ? prev.href : null
				}
			});
		}),
		imgs: (dom = doc) => {
			let code = fn.gst("chapterImages", dom);
			let chapterImages = fn.textToArray(code, "chapterImages");
			let chapterImageHost = fn.textVar(code, "chapterImageHost");
			return chapterImages.map(e => ["http", "//"].some(s => e.startsWith(s)) ? e : chapterImageHost + e);
		},
		button: [4],
		insertImg: ["#images", 2],
		autoDownload: [0],
		next: () => isString(siteJson.next) ? siteJson.next : null,
		prev: () => isString(siteJson.prev) ? siteJson.prev : null,
		chapters: () => siteJson.chapters,
		customTitle: (dom = doc) => {
			let code = fn.gst("SinMH.initChapter", dom);
			let [, chapterName, , comicName, ] = code.match(/SinMH.initChapter\(([^\)]+)\)/)[1].replaceAll('"', "").split(",");
			return comicName + " - " + chapterName;
		},
		preloadNext: true,
		hide: ".img_land_prev,.img_land_next",
		category: "comic"
	}, {
		name: "92漫画M/31漫画M",
		enable: 0,
		url: {
			h: ["m.92mh.com", "m.31mh.cc"],
			p: [/^\/manhua\/\d+\/\d+\.html$/, /^\/comic\/\w+\/\d+\.html$/]
		},
		imgs: (url = fn.url, msg = 1) => {
			if (msg == 1) fn.sm5();
			url = url.replace("/m.", "/www.");
			return fn.xhrDoc(url, {
				headers: {
					"Referer": url,
					"User-Agent": PC_UA
				}
			}).then(dom => {
				let code = fn.gst("chapterImages", dom);
				let chapterImages = fn.textToArray(code, "chapterImages");
				let chapterImageHost = fn.textVar(code, "chapterImageHost");
				return chapterImages.map(e => ["http", "//"].some(s => e.startsWith(s)) ? e : chapterImageHost + e);
			});
		},
		button: [4],
		insertImg: ["#images", 2],
		autoDownload: [0],
		next: {
			s: "a[href$='.html']",
			t: "下一章"
		},
		prev: {
			s: "a[href$='.html']",
			t: "上一章"
		},
		customTitle: (dom = document) => fn.rt(fn.title("在线", 1, dom), "第", " - 第"),
		preloadNext: async nextDoc => fn.picPreload(await _this.imgs(nextLink, 0), _this.customTitle(nextDoc), "next"),
		css: "body{padding:0!important}.action-list li{width:50% !important}",
		hide: "div[style*='text-align: left;'],.UnderPage~*:not([id^='Full'],[class^='Full'],[id^='pv-'],[class^='pv-'],[id^='pagetual'],[class^='pagetual'],#comicRead,#fab,[class^=fancybox]),.action-list>ul>li:nth-child(n+2):nth-child(-n+3)",
		category: "comic"
	}, {
		name: "优酷漫画",
		host: ["www.ykmh.net", "m.ykmh.net"],
		enable: 0,
		url: {
			h: ".ykmh.",
			p: /^\/manhua\/\w+\/\d+\.html$/
		},
		init: () => {
			let res_a = fn.t("/js/config.js").then(text => {
				let domain = String(fn.textToArray(text, "domain"));
				siteJson.domain = domain;
			});
			let res_b = fn.rd().then(() => {
				if (isPC) {
					fn.run("$(document).unbind('keydown') && $(document).unbind('keyup') && $('#images').unbind('click')");
				}
				let code = fn.gst("comicUrl", doc);
				let comicUrl = fn.textVar(code, "comicUrl");
				return fn.fetchDoc(new URL(comicUrl).pathname).then(dom => {
					let chapters = fn.gae("ul[id^=chapter-list] a", dom);
					if (fn.lh.startsWith("m.")) {
						chapters = chapters.reverse();
					}
					let index = chapters.findIndex(a => a.href.includes(fn.lp));
					let next = chapters[index + 1];
					let prev = chapters[index - 1];
					let obj = {
						chapters: chapters.map(a => ({
							text: fn.dt({
								t: a.text
							}),
							url: a.href
						})),
						next: isEle(next) ? next.href : null,
						prev: isEle(prev) ? prev.href : null
					};
					siteJson = {
						...siteJson,
						...obj
					}
				});
			});
			return Promise.all([res_a, res_b]);
		},
		imgs: (dom = doc) => {
			let code = fn.gst("chapterImages", dom);
			let chapterImages = fn.textToArray(code, "chapterImages");
			let chapterPath = fn.textVar(code, "chapterPath");
			return chapterImages.map(e => ["http", "//"].some(s => e.startsWith(s)) ? e : siteJson.domain + e);
		},
		button: [4],
		insertImg: ["#images", 2],
		autoDownload: [0],
		next: () => isString(siteJson.next) ? siteJson.next : null,
		prev: () => isString(siteJson.prev) ? siteJson.prev : null,
		chapters: () => siteJson.chapters,
		customTitle: (dom = doc) => {
			let code = fn.gst("pageTitle", dom);
			let pageTitle = fn.textVar(code, "pageTitle");
			let [chapterName, comicName] = pageTitle.split(" - ");
			return comicName + " - " + chapterName;
		},
		preloadNext: true,
		mcss: ".action-list li{width:50% !important}",
		hide: ".img_land_prev,.img_land_next,.letchepter>div,.letchepter>section,#action>ul>li:nth-child(n+2):nth-child(-n+3),#loading,.control_panel",
		category: "comic"
	}, {
		name: "来漫画",
		host: ["www.laimanhua88.com", "www.comemh8.com"],
		url: {
			h: [/^www\.(laimanhua|comemh)/],
			p: "/kanmanhua/",
			d: "pc",
			i: 0
		},
		update: "/kanmanhua/zaixian_recent.html",
		init: () => fn.clearAllTimer(),
		box: ["#pic-list", 2],
		imgs: () => {
			const {
				base64_decode,
				picTree,
				getpicdamin
			} = _unsafeWindow;
			return base64_decode(picTree).split("$qingtiandy$").map(e => getpicdamin() + e);
		},
		button: [4],
		insertImg: [
			["box", 0, "#pic-list"], 2
		],
		endColor: "white",
		autoDownload: [0],
		next: () => {
			const {
				nextUrlid
			} = _unsafeWindow;
			return nextUrlid == "" ? null : fn.gu("a#cartoon_url") + nextUrlid + ".html";
		},
		prev: ".btn-prev",
		chapters: {
			url: "a.big-link-back",
			target: ".plist a",
			sort: "r"
		},
		customTitle: (dom = document) => fn.title(",", 1, dom).replace("漫画", "").trim(),
		preloadNext: (nextDoc) => {
			let code = fn.gst("picTree", nextDoc);
			fn.script(code);
			fn.picPreload(_this.imgs(), _this.customTitle(nextDoc), "next");
		},
		hide: "#loading,#pre-loading,.img_info,.blank20,#udbsdk_login",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "来漫画 自動翻頁",
		url: {
			h: /^www\.(laimanhua|comemh)/,
			p: "/kanmanhua/",
			e: "#pic-list",
			d: "pc",
			i: 1
		},
		getSrcs: (dom) => {
			const {
				base64_decode,
				getpicdamin
			} = _unsafeWindow;
			let code = fn.gst("picTree", dom);
			let base64Text = fn.textVar(code, "picTree");
			return base64_decode(base64Text).split("$qingtiandy$").map(e => getpicdamin() + e);
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => {
			fn.clearAllTimer();
			return fn.caae(fn.createImgBox("#pic-list", 1), _this.getImgs(), "#pic-list,#pre-loading,#loading");
		},
		autoPager: {
			script: "//script[contains(text(),'picTree')]",
			ele: (dom) => _this.getImgs(dom),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: (dom) => {
				let code = fn.gst("nextUrlid", dom);
				let comicURL = fn.gu("#position a");
				let [, cidText] = code.match(/nextUrlid[\s\=]+([^,;]+)/);
				if (/\d+/.test(cidText)) {
					let [cid] = cidText.match(/\d+/);
					return comicURL + cid + ".html";
				}
				return null;
			},
			re: "#bottom_chapter",
			title: (dom) => fn.gt("#position", 1, dom).replaceAll("\n", "").replaceAll(">", "").replace("漫画", "").trim(),
			preloadNextPage: 1,
			update: "/kanmanhua/zaixian_recent.html",
			list: "a.big-link-back",
			chapters: {
				url: "a.big-link-back",
				target: ".plist a",
				sort: "r"
			}
		},
		css: ".subNav{margin: 4px auto!important;float:unset!important}",
		hide: "#loading,#pre-loading,.img_info,.blank20,#udbsdk_login",
		category: "comic autoPager"
	}, {
		name: "来漫画M",
		host: ["m.laimanhua8.com", "m.laimanhua88.com", "m.comemh.com", "m.comemh8.com"],
		url: {
			h: [/^m\.(laimanhua|comemh)/],
			p: "/kanmanhua/",
			e: "#manga",
			d: "m",
			i: 0
		},
		update: "/kanmanhua/zaixian_recent.html",
		init: () => fn.clearAllTimer(),
		imgs: () => {
			const {
				mhInfo,
				realurl
			} = _unsafeWindow;
			return mhInfo.images.map(e => realurl + mhInfo.path + e);
		},
		button: [4],
		insertImg: ["#manga", 2],
		autoDownload: [0],
		next: () => {
			const {
				mhInfo
			} = _unsafeWindow;
			return mhInfo.nextUrlid == "" ? null : fn.gu("#mangaTitle>a") + mhInfo.nextUrlid + ".html";
		},
		prev: "//a[text()='上一章']",
		customTitle: (dom = document) => fn.gt("#mangaTitle", 1, dom).replace(/\n/g, "").trim(),
		chapters: {
			url: "#mangaTitle a",
			target: "#chapterList a",
			sort: "r"
		},
		preloadNext: (nextDoc) => {
			let code = fn.gst("mhInfo", nextDoc);
			fn.script(code);
			fn.picPreload(_this.imgs(), _this.customTitle(nextDoc), "next");
		},
		css: ".action-list li{width:50% !important}",
		hide: "#jusha1,#action>ul>li:nth-child(n+2):nth-child(-n+3)",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "来漫画M 自動翻頁",
		url: {
			h: [/^m\.(laimanhua|comemh)/],
			p: "/kanmanhua/",
			e: "#manga",
			d: "m",
			i: 1
		},
		json: (dom) => {
			let code = fn.gst("mhInfo", dom);
			return fn.textToObject(code, "mhInfo");
		},
		getSrcs: (dom) => {
			let json = _this.json(dom);
			return json.images.map(e => _unsafeWindow.realurl + json.path + e);
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => {
			fn.clearAllTimer();
			return fn.caae("#manga", _this.getImgs());
		},
		autoPager: {
			script: "//script[contains(text(),'mhInfo')]",
			ele: (dom) => _this.getImgs(dom),
			pos: ["#manga", 0],
			observer: "#manga>img",
			next: (dom, r = 1) => {
				let json = _this.json(dom);
				let cUrl = fn.gu("#mangaTitle>a");
				if (json.nextUrlid == "") {
					if (r === 1) {
						fn.remove("//li[a[text()='下一章']]");
						let html = `<li><a href="${cUrl}">返回目录</a></li>`;
						fn.ge("#action>ul").insertAdjacentHTML("beforeend", html);
					}
					return null;
				}
				return cUrl + json.nextUrlid + ".html";
			},
			title: (dom) => _this.json(dom).chapterTitle,
			hide: "#slider",
			preloadNextPage: 1,
			update: "/kanmanhua/zaixian_recent.html",
			list: "#mangaTitle a",
			chapters: {
				url: "#mangaTitle a",
				target: "#chapterList a",
				sort: "r"
			}
		},
		css: ".action-list li{width:50% !important}",
		hide: "#jusha1,#action>ul>li:nth-child(n+2):nth-child(-n+3)",
		category: "comic autoPager"
	}, {
		name: "漫客栈",
		enable: 0,
		url: {
			h: "www.mkzhan.com",
			p: /^\/\d+\/\d+\.html/
		},
		fetchJson: async (lp = new URL(siteUrl).pathname) => {
			let lps = lp.split("/");
			let comic_id = lps[1];
			let [chapter_id] = lps[2].match(/\d+/);
			let apiUrl = `https://comic.mkzcdn.com/chapter/content/v1/?chapter_id=${chapter_id}&comic_id=${comic_id}&format=1&quality=1&type=1`;
			return fn.j(apiUrl);
		},
		init: async () => {
			let json = await _this.fetchJson();
			debug("\n此頁JSON資料\n", json);
			siteJson = json;
		},
		imgs: (json = siteJson) => json.code == 302 ? [] : json.data.page.map(e => e.image),
		insertImg: ["#pages-tpl", 2],
		autoDownload: [0],
		next: ".rd-aside a.j-rd-next",
		prev: ".rd-aside a.j-rd-prev",
		autoClick: "//div[@class='rd-aside__item j-rd-mod'][span[text()='卷轴']]",
		customTitle: (dom = document) => fn.title(" - ", 1, dom),
		preloadNext: async (nextDoc) => {
			let json = await _this.fetchJson(new URL(nextLink).pathname);
			fn.picPreload(_this.imgs(json), _this.customTitle(nextDoc), "next");
		},
		category: "comic"
	}, {
		name: "漫画屋格式",
		enable: 0,
		url: {
			h: ["www.mhua5.com", /www\.mhw\d?\.com/, "www.mh5.xyz", "www.umh5.com", "www.biqu8.xyz", "www.benzhu.cc"],
			p: ["/chapter/", "/chapter-", ".html"],
			e: [".rd-article-wr", ".read__crumb"],
			d: "pc"
		},
		init: "document.onkeydown=null",
		imgs: (dom = document) => fn.getImgSrcArr("img[data-original]:not([data-original*='/template/pc/default/']),.lazy-read:not([data-original*='/template/pc/default/']),img[data-src]", dom),
		referrerpolicy: "no-referrer",
		button: [4],
		insertImg: [".rd-article-wr", 2],
		endColor: "white",
		autoDownload: [0],
		next: "a.j-rd-next[_href*='/chapter']",
		prev: "a.j-rd-prev[_href*='/chapter']",
		chapters: {
			target: ".catalog__list a",
			textNode: ".comic-title"
		},
		customTitle: (dom = document) => {
			let [, mn, cn] = fn.gat(".read__crumb a", dom);
			return mn + " - " + cn;
		},
		preloadNext: true,
		category: "comic"
	}, {
		name: "漫画屋M格式",
		host: ["m.mkzhan.com", "www.mhua5.com", "www.mhw1.com", "www.mh5.xyz", "www.umh5.com", "www.bq888.net"],
		enable: 0,
		reg: [
			/^https?:\/\/m\.mkzhan\.com\/\d+\/\d+\.html$/i,
			/^https?:\/\/(www\.mhua5\.com|www\.mhw\d?\.com|www\.mh5\.xyz|www\.umh5\.com)\/index\.php\/chapter\/\d+/i,
			/^https?:\/\/www\.biqu8\.xyz\/index\.php\/chapter-\d+.html$/i
		],
		imgs: (dom = document) => fn.getImgSrcArr(".comic-page img,img[data-src],img[data-original]", dom),
		autoDownload: [0],
		next: async () => {
			if (fn.ge(".next-chapter[_href]")) {
				let next = fn.attr(".next-chapter", "_href");
				return next !== "" ? location.origin + next : null;
			} else if (/m\.mkzhan\.com/.test(fn.lh)) {
				await fn.waitEle(".next-chapter[data-href]", 10)
				let next = fn.ge(".next-chapter").dataset.href;
				return next !== "" || next != 0 ? location.origin + next : null;
			}
			let next = fn.ge("//a[text()='下一章']");
			return next ? next.href : null;
		},
		prev: 1,
		customTitle: (dom = document) => {
			if (/m\.mkzhan\.com/.test(fn.lh)) {
				return fn.title(" - 漫客栈", 0, dom).trim();
			} else if (fn.gst("shareArr")) {
				let code = fn.gst("shareArr");
				let s = code.indexOf("《");
				let e = code.indexOf("》", s);
				let mn = code.slice(s + 1, e);
				return mn + " - " + fn.gt(".comic-name", 1, dom);
			}
			return fn.title(/下拉|在线/, 1, dom).trim().replace("-", " - ");
		},
		preloadNext: true,
		hide: "body>ins,#mainView>.read,.chapter-end .read,#chapter1,#chapter3,.cnt-4,.comic-list a,.chapter-end>a,div[style^=height],body>div[id][style]:has(>div[style]),.comic-list>div[id][style]:has(>div[style]),#mainView>div[id][style]:has(>div[style]),.chapter-end>div[id][style]:has(>div[style])",
		category: "comic"
	}, {
		name: "GodaComic 英文漫画",
		url: {
			h: ["manhuascans.org"],
			p: /^\/manga\/[\w-]+\/[\w-]+$/i,
			e: "#chapterContent",
			i: 0
		},
		xhrOptions: {
			cache: "no-cache"
		},
		init: () => fn.waitEle(".touch-manipulation img"),
		imgs: () => fn.gae(".touch-manipulation img"),
		button: [4],
		insertImg: [".touch-manipulation", 2],
		autoDownload: [0],
		next: "#nextChapterLink[href^='/manga/']",
		prev: "#preChapterLink",
		chapters: {
			api: () => {
				let id = fn.ge("#chapterContent").dataset.ms;
				return `/manga/get?mid=${id}&mode=all`;
			},
			target: "#allchapterlist a",
			cb: (t, url, e) => ({
				text: e.dataset.ct,
				url
			})
		},
		customTitle: (dom = document) => fn.gt("ol.inline-flex>li:nth-child(2) a", 1, dom) + " - " + fn.gt("ol.inline-flex>li:nth-child(3) a", 1, dom),
		preloadNext: (dom) => {
			let dataE = fn.ge("#chapterContent", dom);
			let {
				ms,
				cs,
				ct,
				host
			} = dataE.dataset;
			let api = `${host}/chapter/getcontent?m=${ms}&c=${cs}`;
			fn.fetchDoc(api).then(nextDom => {
				let srcs = fn.getImgSrcArr(".touch-manipulation img", nextDom);
				fn.picPreload(srcs, ct, "next");
			});
		},
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "GodaComic 英文漫画 自動翻頁",
		url: {
			h: ["manhuascans.org"],
			p: /^\/manga\/[\w-]+\/[\w-]+$/i,
			e: "#chapterContent",
			i: 1
		},
		xhrOptions: {
			cache: "no-cache"
		},
		getSrcs: (dom) => {
			let dataE = fn.ge("#chapterContent", dom);
			let {
				ms,
				cs,
				ct,
				host
			} = dataE.dataset;
			let api = `${host}/chapter/getcontent?m=${ms}&c=${cs}`;
			return fn.fetchDoc(api).then(apitDom => fn.getImgSrcArr(".touch-manipulation img", apitDom));
		},
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: () => fn.waitEle(".touch-manipulation img").then(() => fn.remove("//div[ins[@class='adsbygoogle']]")).then(() => _this.getImgs().then(imgs => {
			let s = ".touch-manipulation";
			return fn.caae(fn.createImgBox(s, 1), imgs, s);
		})),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			observer: "#FullPictureLoadMainImgBox>img",
			pos: ["#FullPictureLoadMainImgBox", 0],
			next: "#nextChapterLink[href^='/manga/']",
			title: (dom) => fn.ge("#chapterContent", dom).dataset.ct,
			history: 0,
			hide: ".pb-14",
			preloadNextPage: 1,
			update: "/newss/",
			list: "nav[aria-label=Breadcrumb] li:not([class]) a",
			chapters: {
				api: () => {
					let id = fn.ge("#chapterContent").dataset.ms;
					return `/manga/get?mid=${id}&mode=all`;
				},
				target: "#allchapterlist a",
				cb: (t, url, e) => ({
					text: e.dataset.ct,
					url
				})
			}
		},
		category: "comic autoPager"
	}, {
		name: "GODA漫畫/包子漫畫",
		url: {
			h: [
				"www.cocolamanhua.com",
				"n.cocolamanhua.com",
				"godamh.com",
				"m.godamh.com",
				"g-mh.org",
				"m.g-mh.org",
				"baozimh.org",
				"m.baozimh.org",
				"baozimh.one",
				"m.baozimh.one",
				"bzmh.org",
				"m.bzmh.org",
				"manhuafree.com"
			],
			p: /^\/manga\/[\w-]+\/[\w-]+$/i,
			e: "#chapterContent",
			i: 0
		},
		init: async () => {
			fn.addMutationObserver(() => fn.remove("iframe,.bannersUite"));
			await fn.waitEle(".touch-manipulation img");
			fn.remove(["#noad-button,.absolute,.adshow", "//div[ins[@class='adsbygoogle']]"]);
			let chapterDataE = fn.ge("#chapterContent");
			let ms = chapterDataE.dataset.ms;
			let cs = chapterDataE.dataset.cs;
			let api = `https://api-get-v3.mgsearcher.com/api/chapter/getinfo?m=${ms}&c=${cs}`;
			let fetchJson = await fn.j(api, {
				cache: "no-cache"
			});
			siteJson = fetchJson;
		},
		imgs: (json = siteJson) => {
			let {
				line,
				images
			} = json.data.info.images;
			let host = line === 2 ? "https://f40-1-4.g-mh.online" : "https://t40-1-4.g-mh.online";
			return images.map(e => host + e.url);
		},
		button: [4],
		insertImg: [".touch-manipulation", 2],
		autoDownload: [0],
		next: "#nextchaptera[href*='/manga/']",
		prev: "#prevchaptera[href*='/manga/']",
		chapters: () => fn.GODA_A_BZ_C(),
		customTitle: (json = siteJson) => json.data.info.mangatitle + " - " + json.data.info.title,
		preloadNext: () => {
			let next = siteJson.data.info?.next;
			if (!!next) {
				let chapterDataE = fn.ge("#chapterContent");
				let ms = chapterDataE.dataset.ms;
				let api = `https://api-get-v3.mgsearcher.com/api/chapter/getinfo?m=${ms}&c=${next}`;
				fn.j(api, {
					cache: "no-cache"
				}).then(json => {
					let srcs = _this.imgs(json);
					let text = _this.customTitle(json);
					fn.picPreload(srcs, text, "next");
				});
			}
		},
		hide: "iframe,.bannersUite,.w-full:has(>amp-ad),#noad-button,.absolute,.adshow",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "GODA漫畫/包子漫畫 自動翻頁",
		url: {
			h: [
				"www.cocolamanhua.com",
				"n.cocolamanhua.com",
				"godamh.com",
				"m.godamh.com",
				"g-mh.org",
				"m.g-mh.org",
				"baozimh.org",
				"m.baozimh.org",
				"baozimh.one",
				"m.baozimh.one",
				"bzmh.org",
				"m.bzmh.org",
				"manhuafree.com"
			],
			p: /^\/manga\/[\w-]+\/[\w-]+$/i,
			e: "#chapterContent",
			i: 1
		},
		getApi: (mode = "current") => {
			let chapterDataE = fn.ge("#chapterContent");
			let ms = chapterDataE.dataset.ms
			let cs = chapterDataE.dataset.cs
			if (mode === "next") {
				return `https://api-get-v3.mgsearcher.com/api/chapter/getinfo?m=${ms}&c=${siteJson.data.info.next}`;
			}
			return `https://api-get-v3.mgsearcher.com/api/chapter/getinfo?m=${ms}&c=${cs}`;
		},
		getSrcs: (json) => {
			let {
				line,
				images
			} = json.data.info.images;
			let host = line === 2 ? "https://f40-1-4.g-mh.online" : "https://t40-1-4.g-mh.online";
			return images.map(e => host + e.url);
		},
		getImgs: (json) => fn.createImgArray(_this.getSrcs(json)),
		init: async () => {
			fn.addMutationObserver(() => fn.remove("iframe,.bannersUite,.w-full:has(>amp-ad)"));
			await fn.waitEle(".touch-manipulation img");
			let api = _this.getApi();
			let fetchJson = await fn.j(api, {
				cache: "no-cache"
			});
			siteJson = fetchJson;
			fn.remove(["#noad-button,.absolute,.adshow,#loadimg", "//div[ins[@class='adsbygoogle']]"]);
			let s = ".touch-manipulation";
			await fn.caae(fn.createImgBox(s, 1), _this.getImgs(fetchJson), s);
		},
		autoPager: {
			mode: "json",
			ele: (json) => _this.getImgs(json),
			observer: "#FullPictureLoadMainImgBox>img",
			pos: ["#FullPictureLoadMainImgBox", 0],
			next: async () => {
				let next = siteJson?.data?.info?.next;
				if (!!next) {
					currentURL = fn.lo + fn.wurl(siteJson.data.info.nextslug);
					return _this.getApi("next");
				}
				return null;
			},
			title: (json) => json.data.info.title,
			//history: 0,
			hide: ".pb-14",
			preloadNextPage: (json) => {
				let next = json?.data?.info?.next || siteJson?.data?.info?.next;
				if (next) {
					let api = _this.getApi("next");
					fn.j(api, {
						cache: "no-cache"
					}).then(json => {
						let srcs = _this.getSrcs(json);
						let text = _this.autoPager.title(json);
						fn.picPreload(srcs, text, "next");
					});
				}
			},
			list: "nav[aria-label=Breadcrumb] li:not([class]) a",
			chapters: () => fn.GODA_A_BZ_C(),
		},
		hide: "iframe,.bannersUite,.w-full:has(>amp-ad),#noad-button,.absolute,.adshow,.relative",
		category: "comic autoPager"
	}, {
		name: "ゼロサムオンライン",
		url: {
			h: "zerosumonline.com"
		},
		data: () => fn.rd().then(() => {
			let code = fn.gst("decodedChapterId", doc);
			let [, id] = code.match(/decodedChapterId[\\\s"':]+(\d+)/);
			return fn.t(`https://api.zerosumonline.com/api/v1/viewer?chapter_id=${id}`, {
				"method": "POST"
			}).then(text => (siteJson.data = text));
		}),
		page: () => fn.clp("/episode/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.data() : void 0,
		imgs: () => _this.page() ? siteJson.data.match(/https?:\/\/\w+\.\w+\.com\/\w+\/\d+\/\d+\.\w+/gi) : [],
		capture: () => _this.imgs(),
		customTitle: () => {
			if (!_this.page()) return null;
			let textArr = doc.title.split("|");
			return textArr[1] + " - " + textArr[0];
		},
		category: "comic"
	}, {
		name: "マンガMeets",
		url: {
			h: "manga-meets.jp",
			p: /^\/comics\/[\w-]+\/\d+$/i
		},
		init: () => {
			let [, , mid, cid] = fn.lp.split("/");
			let res_a = fn.j(`/api/comics/${mid}/episodes.json`);
			let res_b = fn.j(`/api/comics/${mid}/episodes/${cid}/viewer.json`);
			return Promise.all([res_a, res_b]).then(([a, b]) => {
				siteJson = {
					chapters: a.data,
					...b
				};
			});
		},
		imgs: () => siteJson.episode_pages.map(e => e.image.original_url.replace("f_auto", "w_1080")),
		capture: () => _this.imgs(),
		next: () => {
			let [, , mid, cid] = fn.lp.split("/");
			let {
				chapters,
				sort_volume
			} = siteJson;
			if (chapters[sort_volume]?.id) {
				return `/comics/${mid}/${(Number(cid) + 1)}`;
			}
			return null;
		},
		prev: 1,
		customTitle: () => {
			let {
				comic: {
					title
				},
				volume
			} = siteJson;
			return title + " - " + volume;
		},
		category: "comic"
	}, {
		name: "アルファポリス",
		url: {
			h: "www.alphapolis.co.jp",
			p: /^\/manga\/official\/\d+\/\d+$/,
			d: "pc"
		},
		init: () => fn.rd(),
		imgs: () => {
			let data = fn.attr("viewer-manga-horizontal", "v-bind:pages", doc);
			let array = JSON.parse(data);
			let srcs = array.filter(isString).filter(src => !src.includes("/white_page/"));
			return srcs.map(e => e.replace(/\d+x\d+\.jpg/, "1080x1536.jpg"));
		},
		capture: () => _this.imgs(),
		current: () => {
			let menu = fn.ge("template", doc).content;
			let episodes = fn.gae("template", menu).map(t => fn.gae(".episode-unit", t.content)).flat();
			let cid = fn.lp.split("/").at(-1);
			let c_episode = episodes.find(e => e.dataset.order == cid);
			return c_episode;
		},
		next: () => {
			let next = _this.current()?.previousElementSibling;
			return next ? fn.wurl(next.dataset.order) : null;
		},
		prev: () => {
			let prev = _this.current()?.nextElementSibling;
			return prev ? fn.wurl(prev.dataset.order) : null;
		},
		customTitle: () => {
			let menu = fn.ge("template", doc).content;
			let tag = fn.ge("menu-official-content", menu);
			return fn.attr(tag, "manga-title") + " - " + fn.attr(tag, "episode-title");
		},
		category: "comic"
	}, {
		name: "GANMA!(ガンマ)",
		url: {
			h: ["ganma.jp"]
		},
		page: () => fn.clp("/reader/"),
		json: () => fn.rd().then(() => {
			let code = fn.gst("singleModeDisplayUnits", doc).replaceAll("\\", "");
			let ai = code.indexOf("{");
			let ei = code.lastIndexOf("}") + 1;
			code = code.slice(ai, ei);
			siteJson = JSON.parse(code);
			debug("\n此頁JSON資料\n", siteJson);
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => _this.page() ? siteJson.singleModeDisplayUnits.map(e => e.url.replaceAll("u0026", "&")) : [],
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "//a[div[span[text()='次話']]]",
		prev: 1,
		customTitle: () => {
			if (_this.page()) {
				let {
					title: cn,
					magazine: {
						title: mn
					}
				} = siteJson;
				return mn + " - " + cn;
			}
			return null;
		},
		category: "comic"
	}, {
		name: "ガンガンONLINE",
		url: {
			h: ["www.ganganonline.com"]
		},
		page: () => fn.clp("/chapter/"),
		json: () => fn.rd().then(() => {
			let code = fn.gst("pageProps", doc);
			siteJson = JSON.parse(code);
			debug("\n此頁JSON資料\n", siteJson);
		}),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.json() : void 0,
		imgs: () => {
			if (_this.page()) {
				return siteJson.props.pageProps.data.pages.filter(obj => {
					if (isObject(obj)) {
						return ("image" in obj);
					}
					return false;
				}).map(e => e.image.imageUrl);
			}
			return [];
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => {
			if (_this.page()) {
				let {
					page,
					props: {
						pageProps: {
							data: {
								lastPage: {
									nextChapterId
								}
							}
						},
						titleId
					}
				} = siteJson;
				if (isNumber(nextChapterId)) {
					page = page.replace("[titleId]", titleId);
					page = page.replace("[chapterId]", nextChapterId);
					return page;
				}
				return null;
			}
			return null;
		},
		prev: 1,
		customTitle: () => {
			if (_this.page()) {
				let {
					titleName,
					chapterName
				} = siteJson.props.pageProps.data;
				return titleName + " - " + chapterName;
			}
			return null;
		},
		category: "comic"
	}, {
		name: "コミックDAYS 格式",
		url: {
			h: [
				"comic-days.com",
				"shonenjumpplus.com",
				"kuragebunch.com",
				"www.sunday-webry.com",
				"tonarinoyj.jp",
				"comic-gardo.com",
				"comic-zenon.com",
				"comic-trail.com",
				"comic-action.com",
				"magcomi.com",
				"viewer.heros-web.com",
				"feelweb.jp",
				"comicborder.com",
				"comic-ogyaaa.com",
				"comic-earthstar.com",
				"comic-seasons.com"
			]
		},
		data: () => fn.rd().then(() => {
			let json = JSON.parse(fn.ge("#episode-json", doc).dataset.value);
			siteJson = json.readableProduct;
			debug("\n此頁JSON資料\n", siteJson);
		}),
		page: () => fn.clp("/episode/"),
		SPA: () => _this.page(),
		observeURL: "head",
		init: () => _this.page() ? _this.data() : void 0,
		imgs: async () => {
			if (!_this.page() || !siteJson?.pageStructure?.pages) return [];
			let urls = siteJson.pageStructure.pages.filter(obj => {
				if (isObject(obj)) {
					return ("src" in obj);
				}
				return false;
			}).map(e => e.src);
			let [url] = urls;
			if (
				url.includes("/original/") ||
				isM && ["viewer.heros-web.com", "feelweb.jp"].some(h => fn.lh === h)
			) {
				return urls;
			}
			fn.showMsg(DL.str_53, 0);
			let arr = [];
			let fetchNum = 0;
			for (const [index, url] of urls.entries()) {
				let getRedraw = new Promise(async resolve => {
					let error = false;
					const blob = await fn.b(url);
					const img = new Image();
					await new Promise(load => {
						img.onload = load;
						img.onerror = () => {
							error = true;
							resolve(null);
						}
						img.src = URL.createObjectURL(blob);
					});
					if (error) return;

					const imgWidth = img.naturalWidth;
					const imgHeight = img.naturalHeight;
					const canvas = new OffscreenCanvas(imgWidth, imgHeight);
					const canvas_2d = canvas.getContext("2d");

					const DIVIDE_NUM = 4;
					const MULTIPLE = 8;
					const cellWidth = Math.floor(canvas.width / (DIVIDE_NUM * MULTIPLE)) * MULTIPLE;
					const cellHeight = Math.floor(canvas.height / (DIVIDE_NUM * MULTIPLE)) * MULTIPLE;

					for (let e = 0; e < DIVIDE_NUM * DIVIDE_NUM; e++) {
						const t = Math.floor(e / DIVIDE_NUM) * cellHeight;
						const i = e % DIVIDE_NUM * cellWidth;
						const r = Math.floor(e / DIVIDE_NUM);
						const n = e % DIVIDE_NUM * DIVIDE_NUM + r;
						const s = n % DIVIDE_NUM * cellWidth;
						const o = Math.floor(n / DIVIDE_NUM) * cellHeight;
						canvas_2d.drawImage(img, i, t, cellWidth, cellHeight, s, o, cellWidth, cellHeight);
					}

					URL.revokeObjectURL(img.src);
					canvas.convertToBlob({
						type: blob.type,
						quality: 0.95
					}).then(blob => {
						fn.showMsg(`DrawImage ${fetchNum+=1}/${urls.length}`, 0);
						resolve(URL.createObjectURL(blob));
					});
				});
				arr.push(getRedraw);
				await delay(100);
			}
			return arr;
		},
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: () => {
			if (!_this.page()) return null;
			let next = siteJson?.nextReadableProductUri;
			return next ? next : null;
		},
		prev: 1,
		customTitle: () => {
			if (!_this.page()) return null;
			let {
				series: {
					title: m
				},
				title: c
			} = siteJson
			return (m == c) ? m : m + " - " + c;
		},
		category: "comic"
	}, {
		name: "ヤンチャンWeb 格式",
		url: {
			h: [
				"youngchampion.jp",
				"younganimal.com",
				"bigcomics.jp",
				"comicride.jp",
				"kansai.mag-garden.co.jp",
				"championcross.jp",
				"comic.j-nbooks.jp",
				"comic-growl.com",
				"comicpash.jp",
				"rimacomiplus.jp"
			],
			p: "/episodes/"
		},
		init: async () => {
			let viewer = await fn.waitEle("#comici-viewer[comici-viewer-id]");
			let id = fn.attr("#comici-viewer", "comici-viewer-id");
			let apiDomain = viewer.dataset.apiDomain;
			let res_a = fn.j(`https://${apiDomain}/book/Info?comici-viewer-id=${id}`);
			let res_b = fn.j(`https://${apiDomain}/book/episodeInfo?comici-viewer-id=${id}`);
			return Promise.all([res_a, res_b]).then(([res_a, res_b]) => {
				siteJson = {
					...res_a.result,
					apiDomain,
					chapters: res_b.result,
					chapter: res_b.result.find(e => e.id === id)
				};
				debug("\n此頁JSON資料\n", siteJson);
			});
		},
		imgs: async () => {
			let userId = fn.gt("#login_user_id") || "0";
			let {
				id,
				apiDomain,
				chapter: {
					page_count
				}
			} = siteJson
			const pages = await fn.j(`https://${apiDomain}/book/contentsInfo?user-id=${userId}&comici-viewer-id=${id}&page-from=0&page-to=${page_count}`).then(json => json.result);
			fn.showMsg(DL.str_53, 0);
			let arr = [];
			let fetchNum = 0;
			for (const [index, page] of pages.entries()) {
				let getRedraw = new Promise(async resolve => {
					let error = false;
					const {
						imageUrl,
						scramble,
						height,
						width
					} = page;
					const blob = await fn.b(imageUrl);
					const img = new Image();
					await new Promise(load => {
						img.onload = load;
						img.onerror = () => {
							error = true;
							resolve(null);
						}
						img.src = URL.createObjectURL(blob);
					});
					if (error) return;

					const imgWidth = img.naturalWidth;
					const imgHeight = img.naturalHeight;
					const canvas = new OffscreenCanvas(imgWidth, imgHeight);
					const canvas_2d = canvas.getContext("2d");

					const dict = [];
					const dictTemplete = JSON.parse("[[0,0],[0,1],[0,2],[0,3],[1,0],[1,1],[1,2],[1,3],[2,0],[2,1],[2,2],[2,3],[3,0],[3,1],[3,2],[3,3]]");
					const scrambleOrders = JSON.parse(scramble);
					for (let i = 0; i < dictTemplete.length; i++) {
						dict.push(dictTemplete[scrambleOrders[i]]);
					}

					const pieceWidth = Math.floor(width / 4);
					const pieceHeight = Math.floor(height / 4);
					let dictCounter = 0;
					for (let i = 0; i < 4; i++) {
						for (let j = 0; j < 4; j++) {
							const x = dict[dictCounter][0];
							const y = dict[dictCounter][1];
							canvas_2d.drawImage(img, pieceWidth * x, pieceHeight * y, pieceWidth, pieceHeight, pieceWidth * i, pieceHeight * j, pieceWidth, pieceHeight);
							dictCounter++;
						}
					}

					URL.revokeObjectURL(img.src);
					canvas.convertToBlob({
						type: blob.type,
						quality: 0.95
					}).then(blob => {
						fn.showMsg(`DrawImage ${fetchNum+=1}/${pages.length}`, 0);
						resolve(URL.createObjectURL(blob));
					});
				});
				arr.push(getRedraw);
				await delay(100);
			}
			return arr;
		},
		capture: () => _this.imgs(),
		customTitle: () => {
			let {
				title,
				chapter: {
					name
				}
			} = siteJson;
			return title + " - " + name;
		},
		category: "comic"
	}, {
		name: "WEBコミックガンマぷらす 格式",
		url: {
			h: [
				"gammaplus.takeshobo.co.jp",
				"storia.takeshobo.co.jp",
				"webcomicgamma.takeshobo.co.jp",
				"comic-meteor.jp",
				"www.comic-valkyrie.com",
				"comic-polaris.jp",
				"televikun-super-hero-comics.com"
			],
			p: ["/_files/", "/ptdata/", "/samplebook/", "/rensai/"]
		},
		imgs: async () => {
			fn.sm5();

			const baseURL = fn.url;

			const datas = await fn.t(fn.url).then(text => {
				let urls = text.match(/data\/\d+\.ptimg\.json/gm).map(json => baseURL + json);
				let resArr = urls.map(url => fn.j(url));
				return Promise.all(resArr);
			});

			fn.showMsg(DL.str_53, 0);
			let arr = [];
			let fetchNum = 0;
			for (const [index, data] of datas.entries()) {
				let getRedraw = new Promise(async resolve => {
					let error = false;
					const {
						resources,
						views
					} = data;
					const img = new Image();
					await new Promise(load => {
						img.onload = load;
						img.onerror = () => {
							error = true;
							resolve(null);
						}
						img.src = `${baseURL}data/${resources.i.src}`;
					});
					if (error) return;

					const imgWidth = views[0].width;
					const imgHeight = views[0].height;
					const canvas = new OffscreenCanvas(imgWidth, imgHeight);
					const canvas_2d = canvas.getContext("2d");

					const coords = views[0].coords.map(coord => {
						const items = coord.match(/^([^:]+):(\d+),(\d+)\+(\d+),(\d+)>(\d+),(\d+)$/).map(Number);
						return items.slice(2);
					});

					for (const [srcX, srcY, width, height, destX, destY] of coords) {
						canvas_2d.drawImage(img, srcX, srcY, width, height, destX, destY, width, height);
					}

					URL.revokeObjectURL(img.src);
					canvas.convertToBlob({
						type: "image/jpeg",
						quality: 0.95
					}).then(blob => {
						fn.showMsg(`DrawImage ${fetchNum+=1}/${datas.length}`, 0);
						resolve(URL.createObjectURL(blob));
					});
				});
				arr.push(getRedraw);
				await delay(100);
			}
			return arr;
		},
		capture: () => _this.imgs(),
		category: "comic"
	}, {
		name: "COMICリュウ",
		url: {
			h: ["www.comic-ryu.jp", "unicorn.comic-ryu.jp"],
			p: /^\/\d+\/$/
		},
		imgs: () => fn.waitEle([".m-viewer-page-comic-img"]),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: async () => {
			await fn.waitEle(".m-viewer .m-viewer-page-comic-img");
			let next = fn.ge(".is-link-next");
			return next ? next.href : null;
		},
		prev: 1,
		customTitle: [".m-viewer .sakuhin-article-title", ".m-viewer-title"],
		gallery: 1,
		category: "comic"
	}, {
		name: "マンガボックス",
		url: {
			h: "www.mangabox.me",
			p: "/reader/"
		},
		imgs: () => fn.waitEle([".slides img:not(.link_page_image)"]).then(imgs => isM ? imgs.reverse() : imgs),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".lastSlider_nextButton",
		prev: 1,
		customTitle: () => fn.waitEle("header h2,.episode_header_title").then(e => fn.gt(e)),
		category: "comic"
	}, {
		name: "コミチ",
		url: {
			h: ["comici.jp"],
			p: "/episodes/"
		},
		imgs: ".manga-area img[id][alt]",
		autoDownload: [0],
		next: ".mode-next a.ep-f-nav-link",
		prev: ".mode-prev a.ep-f-nav-link",
		customTitle: [".a-series-title", ".title-line2"],
		category: "comic"
	}, {
		name: "少年エースplus",
		url: {
			h: ["web-ace.jp"],
			p: "/episode/"
		},
		imgs: () => fn.j(fn.lp + "json"),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: ".viewerbtn_toNext a",
		prev: ".viewerbtn_toBack a",
		customTitle: ["#viewerPc h2", "#viewerPc span"],
		category: "comic"
	}, {
		name: "やわらかスピリッツ",
		url: {
			h: ["yawaspi.com"],
			p: "/comic/"
		},
		imgs: () => fn.waitEle([".vertical__inner ul li img"]),
		capture: () => _this.imgs(),
		autoDownload: [0],
		next: "a.-next",
		prev: "a.-prev",
		customTitle: ["header h2", "header h3"],
		category: "comic"
	}, {
		name: "Comic Top",
		url: {
			h: "comic-top.com",
			p: "/viewer/",
			s: "cid="
		},
		imgs: () => {
			let code = fn.gst("chapter");
			let [, text] = code.match(/chapter[\s=]+({[^;]+)/);
			let json = JSON.parse(text);
			return Object.values(json).map(e => e.image);
		},
		capture: () => _this.imgs(),
		customTitle: [".manga-title", ".manga-episode"],
		category: "comic"
	}, {
		name: "漫畫屋",
		enable: 0,
		url: {
			h: "mh5.tw",
			p: /^\/(series|seriesvip)-\w+-\d+-\d+/
		},
		imgs: () => {
			let max;
			/seriesvip/.test(siteUrl) ? max = fn.gt("a.cur~a:last-child") - 2 : max = fn.gt("a.cur~a:last-child") - 1;
			return fn.getImgIframe(".ptview>img[alt]:not([style])", max, 13, ".setnmh-pagedos", 1000, 0);
		},
		button: [4],
		insertImg: [".ptview", 1, 0],
		autoDownload: [0],
		next: "//a[text()='下一話']",
		prev: "//a[text()='上一話']",
		customTitle: () => {
			let ele = fn.ge("h2");
			return ele ? fn.gt("h1") + " - " + fn.gt("h2") : fn.gt(".setnmh-bookname>a:nth-child(5)") + " - " + fn.gt(".setnmh-bookname>a:nth-child(7)");
		},
		css: ".ptview>img{width:100%!important;height:auto!important;max-width:1000px!important;border:none!important;box-shadow:none!important;padding:0!important;margin:0 auto!important}",
		category: "comic"
	}, {
		name: "山立漫畫/TVBS漫畫",
		enable: 0,
		url: {
			h: ["www.setnmh.com", "www.tvbsmh.com"],
			p: /^\/(series|seriesvip)-\w+-\d+-\d+-.+$/
		},
		imgs: () => {
			let max;
			/seriesvip/.test(siteUrl) ? max = fn.gt("a.cur~a:last-child") - 2 : max = fn.gt("a.cur~a:last-child") - 1;
			return fn.getImgIframe(".ptview>img[alt]:not([style])", max, 13, ".setnmh-pagedos,.pagedosw", 1000, 0);
		},
		button: [4],
		insertImg: [".ptview", 1, 0],
		autoDownload: [0],
		next: "//a[text()='下一話']",
		prev: "//a[text()='上一話']",
		customTitle: () => document.title.split(" - ")[0].replace(/正在觀看|(\d+P)/ig, "").replace(">", " - "),
		css: ".ptview>img{width:100%!important;height:auto!important;max-width:1000px!important;border:none!important;box-shadow:none!important;padding:0!important;margin:0 auto!important}",
		category: "comic"
	}, {
		name: "D漫画/顶漫画",
		url: {
			h: ["www.dmanhua.com", "www.dingmanhua.com"],
			p: "/chapter/",
			i: 0
		},
		update: "/new",
		imgs: (dom = document) => {
			let code = fn.gst("pasd", dom);
			let [num] = code.match(/\d+/);
			let [, pasd] = code.match(/pasd[\s="]+([^"]+)/);
			return fn.arr(num, (v, i) => pasd + (i + 1) + ".webp");
		},
		button: [4],
		insertImg: [".images", 2],
		autoDownload: [0],
		next: "#nextChapter[href]",
		prev: "//a[contains(@class,'nav-button')][contains(text(),'上')]",
		chapters: () => fn.D_A_DI_C(),
		customTitle: (dom = document) => {
			let textArr = fn.ge("meta[name=keywords]", dom).content.replaceAll("\n", "").split(",");
			return textArr[0] + " - " + textArr[1];
		},
		preloadNext: true,
		infiniteScroll: true,
		hide: "body>div[class][style^='position:fixed;'],.ads",
		mcss: "#content{margin-top:0!important}.card-main{margin:0!important;padding:0!important}",
		category: "comic"
	}, {
		name: "D漫画/顶漫画 自動翻頁",
		url: {
			h: ["www.dmanhua.com", "www.dingmanhua.com"],
			p: "/chapter/",
			i: 1
		},
		getSrcs: (dom = document) => {
			let code = fn.gst("pasd", dom);
			let [num] = code.match(/\d+/);
			let [, pasd] = code.match(/pasd[\s="]+([^"]+)/);
			return fn.arr(num, (v, i) => pasd + (i + 1) + ".webp");
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.caae(".images", _this.getImgs()),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".images", 0],
			observer: ".images>img",
			next: "#nextChapter[href]",
			re: "#leftNav,#rightNav,.footer-toolbar",
			title: (dom) => {
				let textArr = fn.ge("meta[name=keywords]", dom).content.replaceAll("\n", "").split(",");
				return isM ? textArr[1] : textArr[0] + " - " + textArr[1];
			},
			hide: "#leftNav,#rightNav",
			preloadNextPage: 1,
			update: "/new",
			list: "//a[text()='目录']",
			chapters: () => fn.D_A_DI_C()
		},
		css: ".autoPagerTitle{width:100%}",
		hide: "body>div[class][style^='position:fixed;'],.ads",
		mcss: "#content{margin-top:0!important}.card-main{margin:0!important;padding:0!important}",
		category: "comic autoPager"
	}, {
		name: "D漫画/顶漫画 AD",
		url: {
			h: ["www.dmanhua.com", "www.dingmanhua.com"],
		},
		hide: "body>div[class][style^='position:fixed;'],.ads",
		category: "ad"
	}, {
		name: "漫画网/漫画吧",
		host: ["www.manhua3.com", "www.manhuaba.com"],
		url: {
			e: ["div.logo>a[title=漫画网]>img[alt=漫画网],div.logo>a[title=漫画吧]>img[alt=漫画吧]", "#pics,#images"],
			p: [/^\/[\d-]+\.html$/, "/chapter/"]
		},
		init: () => fn.wait(() => isArray(_unsafeWindow?.params?.images)),
		box: ["#pics,#images", 1],
		imgs: (frame = _unsafeWindow) => frame.params.images.map(src => {
			if (
				!/^(https?:\/\/|\/\/)/.test(src) &&
				frame.params.source_id == 12
			) {
				src = "https://img1.baipiaoguai.org" + src;
			}
			return src;
		}),
		button: [4],
		insertImg: [
			["box", 0, "#pics,#images"], 2
		],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='返回详情']",
			mode: "g",
			target: ".module-play-list-content a"
		},
		customTitle: (dom = document) => fn.dt({
			d: ["在线阅读-漫画网", "在线漫画阅读_漫画吧"]
		}, dom).replace("_", " - "),
		preloadNext: () => fn.iframe(nextLink, {
			wait: (dom, frame) => isArray(frame?.params?.images),
			cb: (dom, frame) => {
				fn.picPreload(_this.imgs(frame), _this.customTitle(dom), "next");
			}
		}),
		hide: "body>div[id][style*='2147483646']:has(>div>a>img)",
		mcss: ".main{padding:20px 0px 0!important}",
		category: "comic"
	}, {
		name: "如漫画/读漫屋",
		host: ["www.rumanhua.com", "rumanhua.com", "m.rumanhua.com", "www.rumanhua1.com", "rumanhua1.com", "m.rumanhua1.com", "www.dumanwu.com", "dumanwu.com", "m.dumanwu.com", "www.dumanwu1.com", "dumanwu1.com", "m.dumanwu1.com"],
		url: {
			h: [/rumanhua\d?\.com$/, /dumanwu\d?\.com$/],
			p: /^\/\w+\/\w+\.html$/i,
			st: "__c0rst96"
		},
		init: () => fn.waitEle(".main_img img[data-src]"),
		imgs: (dom = document) => fn.getImgSrcArr(".main_img img", dom),
		button: [4, 3],
		insertImg: [".main_img", 2],
		endColor: () => ["dumanwu.com", "m.dumanwu.com"].some(h => fn.lh === h) ? "white" : "black",
		autoDownload: [0],
		next: "a[href$=html]:has(>.folat-next1),a[href$=html]:has(>.i-rd-next)",
		prev: "a[href$=html]:has(>.folat-prev1),a[href$=html]:has(>.i-rd-prev)",
		chapters: () => fn.RUDUMH_C(),
		customTitle: (dom = document) => {
			let text = fn.dt({
				d: ["漫画 - 如漫画", "漫画 - 读漫屋"]
			}, dom);
			let textArr = text.split("_");
			return textArr[1] + " - " + textArr[0];
		},
		frame: ".main_img img[data-src]",
		preloadNext: true,
		fancybox: {
			blacklist: 1
		},
		category: "comic"
	}, {
		name: "如漫画/读漫屋/漫画屋/囧次元/天天看漫画/风车漫画/扑飞漫画/51漫画网/追更漫画/追漫画/古風漫畫/漫士多/六漫画/奇漫屋/36漫画/来漫画/催漫画/无尽漫画",
		url: {
			h: [
				/^(www\.)?manhua55\.com$/,
				/^(www\.)?jiongcy\.com$/,
				"www.ttkmh.com",
				"www.fengchemh.com",
				"www.pufeimh.com",
				"www.zhuigeng.cc",
				"www.ycymh.com",
				/^(www\.)?gfmh\.app$/,
				"manshiduo.org",
				"www.liumanhua.com",
				"m.liumanhua.com",
				"www.cuimanhua.com",
				"kuman.wang",
				"qimanwu.org",
				"www.qimanwu.app",
				"m.qimanwu.app",
				"www.36mh.org",
				"m.36mh.org",
				"www.laimanhua.org",
				"m.laimanhua.org",
				"www.dumanwu.org",
				"m.dumanwu.org",
				"www.rumanhua.org",
				"m.rumanhua.org",
				"www.wujinmh.com",
				"m.wujinmh.com"
			],
			st: "params"
		},
		init: () => {
			fn.showMsg(DL.str_16, 0);
			let a = fn.ge([
				"//a[text()='章节目录' or text()='章節目錄']",
				"//div[@class='navtop']/a[text()='返回']",
				"//a[contains(text(),'详情')]",
				"//a[img[@alt='目录']]",
				"//a[text()='目录']",
				"//a[@class='crumb__title j-comic-title']",
				"//a[@class='iconback']",
				"//a[@class='back-btn']",
				"//a[img[@id='goBak']]"
			]);
			return fn.fetchDoc(a).then(dom => {
				fn.ge("span.grading", dom)?.remove();
				let title = fn.gt([
					".book-container__detail>.title",
					".detail-info-title",
					".comics-detail__title",
					".comic-detail>h1.name",
					".novel_info_title h1",
					".infobox .title",
					".comicInfo .info .title",
					".content>.info>.title",
					".vod-info .info a",
					".DramaDetail_bookName",
					".dramaDetail_bookName",
					".cy_title>h1",
					".data>h4",
					".comic-name",
					".book-name",
				], 1, dom);
				let chapters = fn.gae([
					"#chapter-items a",
					"#ul_all_chapters a",
					"#chapterlistload a",
					"#dataList a",
					".episode-box a",
					"ul.chapterList a",
					".j-chapter-list a",
					".chapter__item a",
					".catalog-list a",
					".list_block a",
					".listbox a",
					".playlist a",
					".cnxh-ul a",
				], dom);
				if (["liumanhua", "cuimanhua", "www.wujinmh.com"].some(k => fn.lh.includes(k))) {
					chapters = chapters.reverse();
				}
				siteJson = {
					title,
					chapters
				};
				fn.hm();
				return fn.wait(() => isArray(_unsafeWindow?.params?.images))
			});
		},
		box: [
			[
				".chpater-images",
				".chapter-main",
				"#newImgs",
				"#chapterPics",
				".vod-list .more-box:has(img)",
				".main-container",
				"#manga-imgs",
				"h1~#content",
				"h1~#contents",
				".rd-article-wr",
				"#cp_img",
				"#comic-list",
				".imgbox",
				"#images",
				"#mainView"
			],
			1, 1024
		],
		imgs: (frame = _unsafeWindow) => frame.params.images.map(src => {
			if (
				!/^(https?:\/\/|\/\/)/.test(src) &&
				frame.params.source_id == 12
			) {
				src = "https://img1.baipiaoguai.org" + src;
			}
			return src;
		}),
		button: [4, 3],
		insertImg: [
			["box", 0, ".chpater-images,.chapter-main,#newImgs,#chapterPics,.vod-list .more-box:has(img),.main-container,#manga-imgs,h1~#content,h1~#contents,.rd-article-wr,#cp_img,#comic-list,.imgbox,#images"], 2
		],
		insertImgAF: () => {
			if (fn.lh == "kuman.wang") {
				fn.remove(".imgbg,.mask");
				let lastScrollTop = 0;
				document.addEventListener("scroll", event => {
					let st = event.srcElement.scrollingElement.scrollTop;
					if (st > lastScrollTop) {
						fn.ge(".navtop").setAttribute("style", "top: -50px;");
						fn.ge(".control_bottom").setAttribute("style", "bottom: -70px;");
						lastScrollTop = st;
					} else if (st < lastScrollTop - 20) {
						fn.ge(".navtop").removeAttribute("style");
						fn.ge(".control_bottom").removeAttribute("style");
						lastScrollTop = st;
					}
				});
			};
		},
		autoDownload: [0],
		next: {
			s: [
				"a[href^='/chapter/']:not(.readTipForm):not(:has(img))",
				"a[href$=html]:has(>img[alt=下一章])",
				".toolBar a[href^='/chapter/']:has(img)",
				".toolBar a[href^='/manhua/']:has(img)",
				".toolBar a[href^='/show/']:has(img)",
				".toolBar a[href^='/comic/']:has(img)",
				".btn a[href^='/kan/']",
				"#next_url[href$=html]",
				".j-rd-next[_href^='/']",
				".next-btn[_href^='/']"
			],
			t: [
				"下一章",
				"下一話",
				"下一话",
				"下话"
			]
		},
		prev: {
			s: [
				"a[href^='/chapter/']:not(.readTipForm):not(:has(img))",
				"a[href$=html]:has(>img[alt=上一章])",
				".toolBar a[href^='/chapter/']:has(img)",
				".toolBar a[href^='/manhua/']:has(img)",
				".toolBar a[href^='/show/']:has(img)",
				".toolBar a[href^='/comic/']:has(img)",
				".btn a[href^='/kan/']",
				"#prev_url[href$=html]",
				".j-rd-prev[_href^='/']",
				".prev-btn[_href^='/']"
			],
			t: [
				"上一章",
				"上一話",
				"上一话",
				"上话"
			]
		},
		chapters: () => siteJson.chapters.map(a => ({
			text: fn.dt({
				t: a.text,
				d: siteJson.title
			}),
			url: a.href
		})),
		customTitle: (dom = document) => {
			let {
				title,
				chapters
			} = siteJson;
			let cn = fn.gt(".comic-name", 1, dom) || fn.gt(".comic-title>.last-crumb", 1, dom) || chapters.find(a => a.href.includes(dom.location.pathname))?.text;
			cn = fn.dt({
				t: String(cn),
				d: [
					title,
					/\d+-\d+-\d+/
				]
			});
			return title + " - " + cn;
		},
		preloadNext: () => fn.iframe(nextLink, {
			wait: (_, frame) => isArray(frame?.params?.images),
			cb: (dom, frame) => {
				fn.picPreload(_this.imgs(frame), _this.customTitle(dom), "next");
			}
		}),
		hide: "body>div[id][style]:has(img):not([id^=Full])",
		mcss: ".vod-list{padding:0!important;}",
		category: "comic"
	}, {
		name: "漫画100/漫蛙漫画/漫画鱼/奈斯漫画",
		host: ["www.manhua100.com", "m.manhua100.com", "www.manwamh5.com", "www.manhuayu8.com", "www.nicemh.com"],
		url: {
			t: ["漫蛙漫画", "漫画100", "漫画鱼", "奈斯漫画"],
			p: [/^\/\d+\/\d+\.html$/, /^\/\w+\/\d+$/i, /^\/manhua\/\w+\/\d+\.html$/i],
			st: "params"
		},
		imgs: (frame = _unsafeWindow) => {
			let {
				images_domain,
				images_base64,
				chapter_images
			} = frame.params;
			return chapter_images.map(src => {
				if (images_domain) {
					if (images_base64) {
						return images_domain + frame.CMS.base64.encode(src);
					} else if (!["http", "//"].some(k => src.startsWith(k))) {
						return images_domain + src;
					}
				}
				return src;
			});
		},
		button: [4, 1],
		insertImg: [".chapter-images", 2],
		autoDownload: [0],
		next: "//a[text()='下一章' or text()='下一话'] | id('next-chapter') | //a[span[text()='下一话' or text()='下话']][not(starts-with(@href,'javascript'))]",
		prev: "//a[text()='上一章' or text()='上一话'] | id('prev-chapter') | //a[span[text()='上一话' or text()='上话']][not(starts-with(@href,'javascript'))]",
		chapters: {
			url: "//a[text()='目录'] | //a[@class='back-btn'] | //li[a[text()='漫画']]/following-sibling::li[1]/a | //a[span[text()='目录']]",
			target: ".comic-chapter a,.comic-chapters a,.chapter-list a,#chapter-items a"
		},
		customTitle: (frame = _unsafeWindow) => {
			let {
				comic_name,
				chapter_title
			} = frame.params;
			return comic_name + " - " + chapter_title;
		},
		preloadNext: () => fn.iframe(nextLink, {
			wait: (_, frame) => isArray(frame?.params?.chapter_images),
			cb: (_, frame) => {
				fn.picPreload(_this.imgs(frame), _this.customTitle(frame), "next");
			}
		}),
		category: "comic"
	}, {
		name: "爱漫画",
		url: {
			h: "www.jingmingbg.com",
			p: /^\/\d+\/\d+\.html$/
		},
		update: "/category/?order=2",
		imgs: ".chapter-content img",
		button: [4],
		insertImg: [".chapter-content", 2],
		autoDownload: [0],
		next: "//a[span[text()='下一话']][contains(@href,'.html')]",
		prev: "//a[span[text()='上一话']][contains(@href,'.html')]",
		chapters: () => fn.j(`/modules/article/ajax.php?act=chapterlist&aid=${fn.lp.split("/").at(1)}`).then(json => json.result.map(({
			chaptername,
			chapter_url
		}) => ({
			text: chaptername,
			url: chapter_url
		}))),
		customTitle: [".header-center a,.header-center span", 1, 2],
		preloadNext: true,
		category: "comic"
	}, {
		name: "爱漫画M",
		url: {
			h: "m.jingmingbg.com",
			p: /^\/\d+\/\d+\.html$/
		},
		update: "/category/?order=2",
		init: () => (siteJson.mid = fn.lp.split("/").at(1)),
		imgs: ".lazy-img",
		button: [4, 3],
		insertImg: [".hide-scrollbars", 2],
		autoDownload: [0],
		next: "//a[p[text()='下一话']][contains(@href,'html')]",
		prev: "//a[p[text()='下一话']][contains(@href,'html')]",
		chapters: () => fn.j(`/ajax.php?chapter_list=1&aid=${siteJson.mid}`).then(array => array.map(({
			chaptername,
			chapterid
		}) => ({
			text: chaptername,
			url: `/${siteJson.mid}/${chapterid}.html`
		}))),
		customTitle: (dom = doc) => fn.attr("//a[p[text()='详情']]", "alt", dom) + " - " + fn.gt(".chapter-header h1", 1, dom),
		preloadNext: true,
		css: ".chapter-footer{z-index: 10!important}",
		category: "comic"
	}, {
		name: "天天漫画",
		host: ["www.ortzn.com", "m.ortzn.com"],
		url: {
			t: "天天漫画",
			p: /^\/ttmanhua\/\d+\/\d+\.html$/,
			i: 0
		},
		update: "/update/",
		imgs: (dom = document) => fn.getImgSrcArr(".chapter-content img,.hide-scrollbars img", dom),
		button: [4, 3],
		insertImg: [".chapter-content,.hide-scrollbars", 2],
		next: "a[href$='html']:has(>.icon-xiayihua),a[href$=html]:has(>.icon-chapter-right)",
		prev: "a[href$='html']:has(>.icon-shangyihua),a[href$=html]:has(>.icon-chapter-left)",
		chapters: () => fn.TTMH_C(),
		customTitle: (dom = document) => isPC ? getTitle(["a[title]", "span.active"], dom) : fn.attr(".chapter-tool-box a", "alt", dom) + " - " + fn.gt("h1.title", 1, dom),
		preloadNext: true,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "天天漫画 自動翻頁",
		url: {
			t: "天天漫画",
			p: /^\/ttmanhua\/\d+\/\d+\.html$/,
			i: 1
		},
		getSrcs: (dom) => fn.getImgSrcArr(".chapter-content img,.hide-scrollbars img", dom),
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.caae(".chapter-content,.hide-scrollbars", _this.getImgs()),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".chapter-content,.hide-scrollbars", 0],
			observer: ".chapter-content>img,.hide-scrollbars>img",
			next: "a[href$='html']:has(>.icon-xiayihua),a[href$=html]:has(>.icon-chapter-right)",
			re: ".title,a.tool-item",
			title: (dom) => isPC ? fn.gt("span.active", 1, dom) : fn.gt("h1.title", 1, dom),
			preloadNextPage: 1,
			update: "/update/",
			list: () => fn.dir(fn.clp()),
			chapters: () => fn.TTMH_C()
		},
		category: "comic autoPager"
	}, {
		name: "图库漫画",
		host: ["www.tuku.cc"],
		url: {
			t: "图库漫画",
			p: "/chapter",
			i: 0
		},
		update: "/update/",
		init: () => fn.tukuMangaUI(),
		imgs: ".content img,.container img",
		button: [4],
		insertImg: [".content,.container", 2],
		autoDownload: [0],
		next: "//a[p[text()='下一话']]",
		prev: "//a[p[text()='上一话']]",
		chapters: {
			target: ".calssify-list-wrap a,.chapter-item"
		},
		customTitle: () => isPC ? getTitle([".crumbs a", 1, 2]) : getTitle(["p.title", ".chapter-item.act"]),
		preloadNext: true,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "图库漫画 自動翻頁",
		url: {
			t: "图库漫画",
			p: "/chapter",
			i: 1
		},
		getSrcs: (dom) => fn.getImgSrcArr(".content img,.container img", dom),
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => {
			fn.tukuMangaUI();
			return fn.caae(".content,.container", _this.getImgs());
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".content,.container", 0],
			observer: ".content img,.container img",
			next: "//a[p[text()='下一话']]",
			re: ".crumbs,.chapter-wrap,.btn-left,.btn-right",
			title: (dom) => fn.dt({
				s: ".crumbs a:last-child,.chapter-item.act"
			}, dom),
			preloadNextPage: 1,
			update: "/update/",
			list: "a.f-left,a.read-header-left",
			chapters: {
				target: ".calssify-list-wrap a,.chapter-item"
			},
			scroll: ".read-doc-center,.app",
			color: "#000",
			background: "#ffd21a"
		},
		category: "comic autoPager"
	}, {
		name: "漫画站",
		url: {
			h: ["www.manhuazhan.com", "m.manhuazhan.com"],
			p: "/chapter/"
		},
		init: () => fn.waitVar("newImgs"),
		imgs: (w = _unsafeWindow) => w.newImgs.map(e => e.url),
		button: [4],
		insertImg: ["#ChapterContent,.chapter_content", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')] | //a[div[span[contains(text(),'下一篇')]]][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')] | //a[div[span[contains(text(),'上一篇')]]][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='目录'] | //a[div[span[contains(text(),'目录')]]]",
			target: ".looplist a,.catalog_list a",
			textNode: ".name"
		},
		customTitle: (dom = document) => fn.lh.startsWith("m.") ? fn.dt({
			d: ["漫画", "-漫画站"],
			r: [
				["_", " - "]
			]
		}, dom) : getTitle([".arthor", ".title"], dom),
		preloadNext: (nextDoc) => fn.iframeVar(nextLink, "newImgs").then(async frame => fn.picPreload(_this.imgs(frame), await _this.customTitle(nextDoc), "next")),
		hide: "body>div[id][style*='2147483646']:has(>div>a>img)",
		category: "comic"
	}, {
		name: "土豪漫画",
		url: {
			h: "www.tuhaomanhua.org",
			p: "/chapter"
		},
		imgs: "#ChapterContent img,.chapter_content img",
		button: [4],
		insertImg: ["#ChapterContent,.chapter_content", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')] | //a[div[span[contains(text(),'下一篇')]]][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')] | //a[div[span[contains(text(),'上一篇')]]][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='目录'] | //a[div[span[contains(text(),'目录')]]]",
			target: ".looplist a,.catalog_list a",
			textNode: ".name"
		},
		customTitle: (dom = document) => isM ? fn.ge(".chapter_content img", dom)?.alt + " - " + fn.gt(".chapter_title", 1, dom) : getTitle([".arthor", ".title"], dom),
		preloadNext: true,
		category: "comic"
	}, {
		name: "喵趣漫画",
		url: {
			h: ["www.miaoqumh.org", "m.miaoqumh.org"],
			p: ".html",
			e: "#manga-imgs",
			st: "DATA"
		},
		init: () => fn.waitVar("newImgs"),
		imgs: (w = _unsafeWindow) => w.newImgs.map(e => e.url),
		button: [4],
		insertImg: ["#manga-imgs", 2],
		autoDownload: [0],
		next: "//a[text()='下一话' or text()='下一章'][starts-with(@href,'/')]",
		prev: "//a[text()='上一话' or text()='上一章'][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='目录'] | //a[@class='iconback']",
			target: "#episodes a,.listbox a",
			cb: (t, url, e) => ({
				text: e?.title?.includes(":") ? e.title.split(":")[1] : t,
				url
			})
		},
		customTitle: (dom = document) => {
			let textArr = dom.title.replace("-妙趣漫画", "").split("_");
			return textArr[1] + " - " + textArr[0];
		},
		preloadNext: (nextDoc) => fn.iframeVar(nextLink, "newImgs").then(frame => fn.picPreload(_this.imgs(frame), _this.customTitle(nextDoc), "next")),
		hide: "body>div[id][style]:has([style]):not(#manga-imgs)",
		category: "comic"
	}, {
		name: "漫画160",
		host: ["www.mh160mh.com", "m.mh160mh.com"],
		url: {
			t: "漫画160",
			p: "/kanmanhua/",
			st: "qTcms_S_m_murl_e",
			i: 0
		},
		update: "/kanmanhua/zaixian_recent.html",
		init: () => fn.lh == "www.mh160mh.com" ? fn.wait(() => isFn(document?.onkeydown)).then(() => (document.onkeydown = null)) : void 0,
		imgs: (dom = document) => {
			const {
				base64_decode,
				f_qTcms_Pic_curUrl_realpic
			} = _unsafeWindow;
			let code = fn.gst("qTcms_S_m_murl_e", dom);
			let qTcms_S_m_murl_e = fn.textVar(code, "qTcms_S_m_murl_e");
			return base64_decode(qTcms_S_m_murl_e).split("$qingtiandy$").map(e => f_qTcms_Pic_curUrl_realpic(e));
		},
		button: [4],
		insertImg: ["//td[//img[@onclick]] | //div[@class='UnderPage']", 2],
		autoDownload: [0],
		next: "#k_Pic_nextArr[href$='html']",
		prev: "#k_Pic_backArr[href$='html']",
		chapters: {
			url: "#viewList,a.iconRet",
			target: ".cy_plist a,.chapters a",
			sort: "r"
		},
		customTitle: (dom = document) => {
			let code = fn.gst("qTcms_S_m_name", dom);
			let qTcms_S_m_name = fn.textVar(code, "qTcms_S_m_name");
			let qTcms_S_m_playm = fn.textVar(code, "qTcms_S_m_playm");
			return qTcms_S_m_name + " - " + qTcms_S_m_playm;
		},
		preloadNext: true,
		infiniteScroll: true,
		css: ".action-list li{width:50% !important}",
		mcss: ".container,.content-body{padding:0px !important}",
		hide: "body>a[target],#action>ul>li:nth-child(n+2):nth-child(-n+3)",
		category: "comic"
	}, {
		name: "漫画160 自動翻頁",
		url: {
			t: "漫画160",
			p: "/kanmanhua/",
			st: "qTcms_S_m_murl_e",
			i: 1
		},
		getSrcs: (dom) => {
			const {
				base64_decode,
				f_qTcms_Pic_curUrl_realpic
			} = _unsafeWindow;
			let code = fn.gst("qTcms_S_m_murl_e", dom);
			let qTcms_S_m_murl_e = fn.textVar(code, "qTcms_S_m_murl_e");
			return base64_decode(qTcms_S_m_murl_e).split("$qingtiandy$").map(e => f_qTcms_Pic_curUrl_realpic(e));
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: async () => {
			if (fn.lh == "www.mh160mh.com") {
				fn.wait(() => isFn(document?.onkeydown)).then(() => (document.onkeydown = null));
			}
			let s = "//td[//img[@onclick]] | //div[@class='UnderPage']";
			await fn.caae(fn.createImgBox(s, 1), _this.getImgs(), s);
		},
		autoPager: {
			script: "//script[contains(text(),'qTcms_S_m_murl_e')]",
			ele: () => _this.getImgs(),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: (dom, r = 1) => {
				let n = fn.ge("#k_Pic_nextArr[href$='html']", dom);
				if (n) {
					return n.href;
				} else {
					if (r === 1) {
						let n = fn.ge("#k_Pic_nextArr");
						if (n) {
							n.href = fn.lp.replace(/\d+\.html$/, "");
							n.innerText = "返回目录";
							if (fn.lh === "www.mh160mh.com") {
								n.remove();
							}
						}
					}
					return null;
				}
			},
			re: ".title,.main-btn,.breadcrumb,.BarTit,#action,.pager:not([id])",
			title: (dom) => {
				let code = fn.gst("qTcms_S_m_name", dom);
				let qTcms_S_m_name = fn.textVar(code, "qTcms_S_m_name");
				let qTcms_S_m_playm = fn.textVar(code, "qTcms_S_m_playm");
				return isM ? qTcms_S_m_playm : qTcms_S_m_name + " - " + qTcms_S_m_playm;
			},
			hide: "#m_r_bottom~.imgBox,.globalPadding",
			lazyload: 0,
			preloadNextPage: 1,
			update: "/kanmanhua/zaixian_recent.html",
			list: "#viewList,a.iconRet",
			chapters: {
				url: "#viewList,a.iconRet",
				target: ".cy_plist a,.chapters a",
				sort: "r"
			}
		},
		css: ".action-list li{width:50% !important}",
		mcss: ".container,.content-body{padding:0px !important}",
		hide: "body>a[target],.main-btn #prev,.main-btn #k_next,#k_pageSelect,#action>ul>li:nth-child(n+2):nth-child(-n+3),li:has(>#prev),li:has(>.curPage),li:has(>#k_next)",
		category: "comic autoPager"
	}, {
		name: "漫画大全/笨狗漫画",
		url: {
			h: ["www.yueman8.cc", "m.yueman8.cc", "www.bengou.co", "m.bengou.co"],
			p: /^\/\w+\/\w+\/\d+\.html$/,
			i: 0
		},
		init: "document.onkeydown=null",
		imgs: (dom = document) => {
			const {
				base64_decode,
				f_qTcms_Pic_curUrl_realpic
			} = _unsafeWindow;
			let code = fn.gst("qTcms_S_m_murl_e", dom);
			let qTcms_S_m_murl_e = fn.textVar(code, "qTcms_S_m_murl_e");
			return base64_decode(qTcms_S_m_murl_e).split("$qingtiandy$").map(src => {
				if (src.includes(".baozicdn.")) {
					return src;
				}
				return f_qTcms_Pic_curUrl_realpic(src);
			}).filter(src => !src.endsWith("reman.jpg"));
		},
		button: [4, 1],
		insertImg: ["//td[img[@id='qTcms_pic']]", 2],
		insertImgAF: () => fn.hideEle("a.prev,a.next,[id^=qTcms_select],#prev,#k_next,#k_pageSelect,#pager"),
		autoDownload: [0],
		next: () => {
			const {
				qTcms_Pic_nextArr
			} = _unsafeWindow;
			return (!/^java/.test(qTcms_Pic_nextArr) && qTcms_Pic_nextArr !== "" && qTcms_Pic_nextArr.split("/").length == 4) ? qTcms_Pic_nextArr : null;
		},
		prev: 1,
		chapters: () => {
			if (fn.lh.startsWith("m.")) {
				let a = fn.ge("a.iconRet");
				return fn.fetchDoc(a).then(dom => {
					let chapters = fn.gae("#list a", dom);
					if (chapters.length) {
						return chapters.map(a => ({
							text: a.text,
							url: a.href
						})).reverse();
					} else if (fn.gst("initIntroData", dom)) {
						let code = fn.gst("initIntroData", dom);
						let data = fn.textToObject(code, "initIntroData", 1, 1);
						return data.data.map(({
							chapter_name,
							h
						}) => ({
							text: chapter_name,
							url: h
						})).reverse();
					}
					return [];
				});
			} else {
				return fn.getChapters({
					url: "a.dir,#viewList",
					target: ".plist a",
					sort: "r"
				});
			}
		},
		customTitle: (dom = document) => {
			let code = fn.gst("qTcms_S_m_name", dom);
			let qTcms_S_m_name = fn.textVar(code, "qTcms_S_m_name");
			let qTcms_S_m_playm = fn.textVar(code, "qTcms_S_m_playm");
			return qTcms_S_m_name + " - " + qTcms_S_m_playm;
		},
		preloadNext: true,
		css: ".action-list li{width:50% !important}",
		hide: "[id^=mypic],#subNav,.action-list>ul>li:nth-child(n+2):nth-child(-n+3)",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "漫画大全/笨狗漫画 自動翻頁",
		url: {
			h: ["www.yueman8.cc", "m.yueman8.cc", "www.bengou.co", "m.bengou.co"],
			p: /^\/\w+\/\w+\/\d+\.html$/,
			i: 1
		},
		init: "document.onkeydown=null",
		getSrcs: (dom) => {
			const {
				base64_decode,
				f_qTcms_Pic_curUrl_realpic
			} = _unsafeWindow;
			let code = fn.gst("qTcms_S_m_murl_e", dom);
			let qTcms_S_m_murl_e = fn.textVar(code, "qTcms_S_m_murl_e");
			return base64_decode(qTcms_S_m_murl_e).split("$qingtiandy$").map(src => {
				if (src.includes(".baozicdn.")) {
					return src;
				}
				return f_qTcms_Pic_curUrl_realpic(src);
			}).filter(src => !src.endsWith("reman.jpg"));
		},
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: (s = ".tbCenter") => fn.caae(fn.createImgBox(s, 1), _this.getImgs(), s),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: (dom) => {
				let code = fn.gst("qTcms_Pic_nextArr", dom);
				let qTcms_Pic_nextArr = fn.textVar(code, "qTcms_Pic_nextArr");
				return (!/^java/.test(qTcms_Pic_nextArr) && qTcms_Pic_nextArr !== "" && qTcms_Pic_nextArr.split("/").length == 4) ? qTcms_Pic_nextArr : null;
			},
			title: (dom) => {
				let code = fn.gst("qTcms_S_m_playm", dom);
				let qTcms_S_m_playm = fn.textVar(code, "qTcms_S_m_playm");
				return qTcms_S_m_playm;
			},
			re: "h1:has(#qTcms_picID),.title,.main-btn,.BarTit,#action",
			hide: ".imgBox",
			preloadNextPage: 1,
			list: "a.dir,#viewList,a.iconRet"
		},
		css: ".action-list li{width:50% !important}",
		hide: "[id^=mypic],a.prev,a.next,[id^=qTcms_select],#subNav,#prev,#k_next,#k_pageSelect,#pager,.action-list>ul>li:nth-child(n+2):nth-child(-n+3)",
		category: "comic autoPager"
	}, {
		name: "SF在线漫画",
		enable: 0,
		url: {
			h: "manhua.sfacg.com",
			p: /^\/mh\/\w+\/\d+\/$/i
		},
		init: () => fn.waitVar("picAy").then(() => fn.run("document.onkeydown=null")),
		box: ["#PicArea", 1],
		imgs: () => _unsafeWindow.picAy,
		button: [4, 1],
		insertImg: [
			["box", 0, "#PicArea,.page_turning>a[href*='Page'],#pageSel,#Pages"], 2
		],
		autoDownload: [0],
		np: (k) => {
			let {
				comicFolder
			} = _unsafeWindow;
			let v = _unsafeWindow[k];
			return isNumber(v) && v > 0 ? "/mh/" + comicFolder + "/" + v + "/" : null;
		},
		next: () => _this.np("nextChap"),
		prev: () => _this.np("preChap"),
		chapters: {
			url: "//a[text()='目录列表']",
			target: ".comic_Serial_list a",
			sort: "r"
		},
		customTitle: () => {
			let text = fn.gt(".Reduction_left");
			let texts = text.split(">").map(t => t.trim());
			return texts.at(-2) + " - " + texts.at(-1);
		},
		category: "comic"
	}, {
		name: "SF在线漫画M",
		enable: 0,
		url: {
			h: "mm.sfacg.com"
		},
		init: () => fn.waitVar("picAy"),
		box: ["#PicArea", 1],
		imgs: () => _unsafeWindow.picAy,
		button: [4, 3],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#PicArea"),
		autoDownload: [0],
		np: (k) => {
			let e = fn.ge(`//a[contains(text(),'${k}一话')]`)
			return isEle(e) && e?.href?.split("/")?.length > 4 ? e.href : null;
		},
		next: () => _this.np("下"),
		prev: () => _this.np("上"),
		chapters: {
			url: "//a[span[text()='返回']]",
			target: ".comic_main_list a",
			sort: "r"
		},
		customTitle: ".menu_top_list li:nth-child(2)",
		category: "comic"
	}, {
		name: "哔咔漫画",
		enable: 0,
		url: {
			h: ["www.bikamanhua.com", "m.bikamanhua.com"],
			p: /^\/[\d-]+\.html$/
		},
		imgs: "img.lazy-read",
		button: [4],
		insertImg: ["div:has(>div>img.lazy-read),.episode-detail", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'] | //a[text()='下一话']",
		prev: "//a[text()='上一章'] | //a[text()='上一话']",
		chapters: {
			url: "//a[text()='目录' or contains(text(),'全集')]",
			target: ".cnxh-ul a,.episode-list a"
		},
		customTitle: (dom = document) => fn.title(" - ", 3, dom),
		preloadNext: true,
		hide: "body>div[id][style]:has(div[style]>a)",
		category: "comic"
	}, {
		name: "杰西漫画/皮皮漫画",
		url: {
			h: ["www.jiexi8.com", "www.pipimanhua.com"],
			p: "/read/",
			i: 0
		},
		imgs: ".comicpage img",
		button: [4],
		insertImg: [".comicpage", 2],
		autoDownload: [0],
		next: "#next_url:not([class])",
		prev: "#prev_url:not([class])",
		chapters: {
			url: "#info_url",
			target: "#ul_all_chapters a"
		},
		customTitle: [".text_info i.fa-book", ".style_h1"],
		preloadNext: true,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "杰西漫画/皮皮漫画 自動翻頁",
		url: {
			h: ["www.jiexi8.com", "www.pipimanhua.com"],
			p: "/read/",
			i: 1
		},
		getSrcs: (dom) => fn.getImgSrcArr(".comicpage img", dom),
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: () => fn.caae(".comicpage", _this.getImgs()),
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".comicpage", 0],
			observer: ".comicpage>img",
			next: "#next_url:not([class])",
			re: ".style_h1,.read_nav",
			title: (dom) => fn.dt({
				s: ".style_h1"
			}, dom),
			preloadNextPage: 1,
			list: "#info_url",
			chapters: {
				url: "#info_url",
				target: "#ul_all_chapters a"
			},
			background: "#3e3d43"
		},
		category: "comic autoPager"
	}, {
		name: "滴滴漫画网",
		url: {
			h: "www.didimh.com",
			p: /\/\d+\.html$/,
			e: ".rd-article-wr"
		},
		imgs: ".imgpic img",
		button: [4],
		insertImg: [".imgpic", 2],
		autoDownload: [0],
		next: ".j-rd-next[href$=html]",
		prev: ".j-rd-prev[href$=html]",
		chapters: {
			target: "#chapterrows a"
		},
		customTitle: (dom = doc) => getTitle([".read__crumb a", 1, 2], dom),
		preloadNext: true,
		category: "comic"
	}, {
		name: "滴滴漫画网M",
		url: {
			h: "www.didimh.com",
			p: /\/\d+\.html$/,
			e: "#cp_img"
		},
		update: "/update",
		imgs: ".imgpic img",
		insertImg: [".imgpic", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			url: ".mu_list",
			target: "#ncp3_ul a"
		},
		customTitle: () => fn.fetchDoc(fn.gu(".mu_list")).then(dom => fn.gt(".ncp1b_tit h1", 1, dom) + " - " + fn.gt("h1.h1")),
		category: "comic"
	}, {
		name: "次元漫画格式",
		host: ["2cycomic.com", "yemancomic.com", "www.ikmmh.com", "www.aymry.com"],
		url: {
			e: ["#reader-scroll", "#img-box", ".acgn-reader-chapter__item"],
			st: ["read=", "articlename", "chaptername"],
			d: "pc"
		},
		imgs: () => fn.getNP("div[chapter-pid]", "//a[div[text()='下一页']]", null, ".chapter-page-nav").then(() => fn.gae("div[chapter-pid] img")),
		button: [4, 4],
		insertImg: ["#img-box", 2],
		autoDownload: [0],
		next: "a:has(>.ift-read-chapter-next)",
		prev: "a:has(>.ift-read-chapter-prev)",
		chapters: {
			target: "#js_catalogList a"
		},
		customTitle: () => {
			let code = fn.gst("articlename");
			let object = fn.textToObject(code, "read", 2);
			let {
				articlename,
				chaptername
			} = object;
			if (articlename.includes("/")) {
				[articlename] = articlename.split("/");
			}
			return articlename + " - " + chaptername;
		},
		category: "comic"
	}, {
		name: "次元漫画M格式",
		url: {
			e: ["#reader-scroll", "#imgsec", ".imgbg", "//button[div[text()='目录'][@class='text']]"],
			st: ["read=", "articlename", "chaptername", "set_history"],
			d: "m"
		},
		init: () => fn.waitEle(".episode-side").then(() => {
			for (let e of fn.gae("div[style]:not(:has(#imgsec)),div:has(center):not(:has(#imgsec,.episode-side))")) {
				if (["腐", "客服", "公告", "升级VIP", "广告", "反馈", "删减"].some(k => e.innerText.includes(k))) {
					e.remove();
				}
			}
		}),
		imgs: "#imgsec img",
		button: [4],
		insertImg: ["#imgsec", 2],
		autoDownload: [0],
		next: "#next:not([href*='/book/'])",
		prev: "#prev:not([href*='/book/'])",
		chapters: {
			mode: "f",
			url: () => {
				let button = fn.ge("//button[div[text()='目录'][@class='text']]");
				let code = fn.attr(button, "onclick");
				return code.split("'").at(1);
			},
			target: "#js_chapter_list a,#dataList a"
		},
		customTitle: () => {
			let code = fn.gst("articlename");
			let object = fn.textToObject(code, "read", 2);
			let {
				articlename,
				chaptername
			} = object;
			if (articlename.includes("/")) {
				[articlename] = articlename.split("/");
			}
			return articlename + " - " + chaptername;
		},
		hide: ".down-app,.imgbg,.mask,.clearfix~br,body>*[style*='z-index: 100;']",
		category: "comic"
	}, {
		name: "酷看漫画/飞飞漫画/六漫画",
		host: ["www.kukanmanhua.org", "www.feifeimanhua.vip", "www.mh369.com", "www.un10000.net"],
		url: {
			t: ["酷看漫画", "飞飞漫画", "皮皮漫画", "六漫画"],
			p: "/chapter/"
		},
		update: "/update",
		imgs: ".comiclist img[data-original],.imgpic>img,#cp_img img",
		button: [4],
		insertImg: [".comicpage,#cp_img", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/chapter/')] | //div[@class='mCustomScrollBox']//li[@class='active']/following-sibling::li[1]/a",
		prev: "//a[text()='上一章'][starts-with(@href,'/chapter/')] | //div[@class='mCustomScrollBox']//li[@class='active']/preceding-sibling::li[1]/a",
		chapters: () => isPC ? fn.getChapters({
			target: ".mCustomScrollBox a"
		}) : fn.getChapters({
			url: "//a[p[text()='目录']]",
			target: "#detail-list-select a"
		}),
		customTitle: (dom = document) => {
			let code = fn.gst("bookInfo", dom);
			let bookInfo = fn.textToObject(code, "bookInfo");
			let {
				book_name,
				chapter_name
			} = bookInfo;
			return book_name.replace(/_\d+$/, "") + " - " + chapter_name.replaceAll(book_name, "").replace(/-\d+-/, "");
		},
		preloadNext: true,
		category: "comic"
	}, {
		name: "白菜漫画",
		url: {
			h: "baicaimanhua.com",
			p: "/mhread.php"
		},
		update: "/mhlist.php?t=3",
		box: [".view-paging", 2],
		imgs: ".comiclist img[data-original]",
		button: [4],
		insertImg: [
			["box", 0, ".comicpage>div[style^=width],.comicpage>img[data-original]"], 2
		],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		chapters: {
			target: ".mCustomScrollBox a"
		},
		customTitle: (dom = document) => fn.dt({
			s: "h1.title"
		}, dom),
		preloadNext: true,
		category: "comic"
	}, {
		name: "白菜漫画M",
		url: {
			h: "baicaimanhua.com",
			p: "/m/mh_read.php"
		},
		update: "/m/mh_hot.php?hot=5",
		imgs: ".imagecj img",
		button: [4],
		insertImg: [".imagecj", 2],
		insertImgAF: () => {
			let $ = _unsafeWindow.jQuery;
			$(".FullPictureLoadImage").click(() => {
				if ($(".crt-bar").hasClass("flt")) {
					$(".crt-bar").removeClass("flt");
					$(".crt-bar").css("position", "absolute");
				} else {
					$(".crt-bar").addClass("flt");
					$(".crt-bar").css("position", "fixed");
				}
				let node = $("#funcBox");
				if (node.is(":hidden")) {
					node.show();
				} else {
					node.hide();
				}
			});
		},
		autoDownload: [0],
		next: "//a[text()='下一章' or text()='下一话'][not(starts-with(@href,'javascript'))]",
		prev: "//a[text()='上一章' or text()='上一话'][not(starts-with(@href,'javascript'))]",
		customTitle: (dom = document) => {
			let textArr = dom.title.split("-");
			return textArr[1] + " - " + textArr[2];
		},
		preloadNext: true,
		fancybox: {
			blacklist: 1
		},
		hide: ".read-article>div:has(>div[style*=float]),div[style^=line]",
		category: "comic"
	}, {
		name: "readData&setComic 格式",
		host: ["say-on.com", "ahgwyd.com", "www.jianyu120.com", "www.jiasenongye.com", "www.one-uplus.com", "www.qize-airline.com"],
		url: {
			st: [/(R|r)eadData/, "setComic"],
			p: "/read/"
		},
		imgs: ".read-content img,#comicContainer img,.pic-ist img",
		autoDownload: [0],
		next: "//a[div[text()='下一话']][contains(@href,'/read/')] | //a[@class='page-next'][contains(@href,'/read/')] | //a[@id='nextButton'][contains(@href,'/read/')]",
		prev: "//a[div[text()='上一话']][contains(@href,'/read/')] | //a[@class='page-prev'][contains(@href,'/read/')] | //a[@id='prevButton'][contains(@href,'/read/')]",
		chapters: {
			target: ".chapter-sidebar a,.list-main a"
		},
		customTitle: () => {
			let code = fn.gst(/readdata/i);
			let object = fn.textToObject(code, "eadData");
			return object.comicName + " - " + object.readName;
		},
		category: "comic"
	}, {
		name: "我的漫畫",
		url: {
			h: "mycomic.com",
			p: "/chapters/",
			i: 0
		},
		update: "/comics?sort=-update",
		init: () => fn.MyComicUI(),
		box: ["div:has(>img.page)", 2],
		imgs: "img.page",
		button: [4],
		insertImg: [
			["box", 0, "div:has(>img.page)"], 2
		],
		insertImgAF: (p) => p.after(fn.ge("div:has(>div[data-flux-button-group])").cloneNode(true)),
		autoDownload: [0],
		next: {
			s: "a[href*='/chapters/']",
			t: "下一話"
		},
		prev: {
			s: "a[href*='/chapters/']",
			t: "上一話"
		},
		chapters: () => fn.MYC_C(),
		customTitle: (dom = document) => fn.ge("img.page", dom).alt.replace(/:.+$/, ""),
		preloadNext: true,
		infiniteScroll: true,
		hide: "div:has(>div>div>button[x-ref])",
		mcss: ".p-6{padding:1.5rem 0}",
		category: "comic"
	}, {
		name: "我的漫畫 自動翻頁",
		url: {
			h: "mycomic.com",
			p: "/chapters/",
			i: 1
		},
		getSrcs: (dom) => fn.getImgSrcArr("img.page", dom),
		getImgs: (dom = document) => fn.createImgArray(_this.getSrcs(dom)),
		init: async () => {
			fn.MyComicUI();
			let s = "div:has(>img.page)";
			let b = fn.createImgBox(s, 1);
			await fn.caae(b, _this.getImgs(), s);
			let e = fn.ge("div:has(>div[data-flux-button-group])").cloneNode(true);
			b.after(e);
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: ["#FullPictureLoadMainImgBox", 0],
			observer: "#FullPictureLoadMainImgBox>img",
			next: "//a[contains(text(),'下一話')][contains(@href,'/chapters/')]",
			title: (dom) => {
				let text = fn.ge("img.page", dom).alt.replace(/:.+$/, "");
				return isM ? text.split(" - ")[1] : text;
			},
			re: "div[data-flux-breadcrumbs]",
			aF: (dom) => {
				let ne = fn.ge("div:has(>div[data-flux-button-group])", dom);
				for (let ce of fn.gae("div:has(>div[data-flux-button-group])")) ce.innerHTML = ne.innerHTML;
			},
			preloadNextPage: 1,
			update: "/comics?sort=-update",
			list: "[data-flux-breadcrumbs-item] a:not([aria-label])",
			chapters: () => fn.MYC_C()
		},
		hide: "div:has(>div>div>button[x-ref])",
		mcss: ".p-6{padding:1.5rem 0}",
		category: "comic autoPager"
	}, {
		name: "漫蛙库",
		host: ["www.mwkk.cc", "www.mwdd.cc", "www.mhtmh.org"],
		url: {
			t: ["漫蛙漫画", "猕猴桃漫画"],
			p: /^\/comic\/\d+\/\d+$/,
			e: ".epContent",
			i: 0
		},
		update: "/cate/",
		data: (url = fn.lp) => {
			let [, , mid, cid] = url.split("/");
			let params = fn.cp({
				page: 1,
				page_size: 500,
				image_source: localStorage.getItem("comic_image_source") || _unsafeWindow.CURRENT_IMAGE_SOURCE || ""
			});
			let res_arr = [
				`/api/comic/chapter/info/${cid}`,
				`/api/comic/image/${cid}?${params}`,
				`/api/comic/${mid}`
			].map(api => fn.j(api));
			return Promise.all(res_arr).then(([a, b, c]) => ({
				...a.data,
				...b.data,
				...c.data
			}));
		},
		init: () => fn.sm5().then(() => _this.data().then(json => {
			siteJson = json;
			debug("\n此頁JSON資料\n", siteJson);
			fn.hm();
		})),
		imgs: (json = siteJson) => json.images.map(e => e.url),
		button: [4],
		insertImgBF: () => fn.waitEle(["#showimgcontent .cImg img", "#next-nav-container a", "#next-nav-mobile a"]),
		insertImg: [".epContent", 2],
		insertImgAF: () => {
			let next = _this.next();
			for (let a of fn.gae("#next-nav-container a,#next-nav-mobile a")) next ? (a.href = next) && (a.innerText = "下一章") : a.outerHTML = fn.ge("#directory-container a").outerHTML;
		},
		chapter_url: (key) => {
			let {
				id
			} = siteJson[key];
			return id > 0 ? fn.wurl(id) : null;
		},
		autoDownload: [0],
		next: () => _this.chapter_url("next"),
		prev: () => _this.chapter_url("prev"),
		chapters: {
			url: "#directory-container a",
			target: ".chapter-item",
			textNode: ".chapter-name"
		},
		customTitle: (json = siteJson) => {
			let {
				title: mn,
				current: {
					title: cn
				}
			} = json;
			return mn + " - " + cn;
		},
		preloadNext: () => _this.data(nextLink).then(json => fn.picPreload(_this.imgs(json), _this.customTitle(json), "next")),
		css: ".topMenu{margin-top:unset!important}.tooltip-bar.bottomMenu{z-index: 100!important}",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "漫蛙库 自動翻頁",
		url: {
			t: ["漫蛙漫画", "猕猴桃漫画"],
			p: /^\/comic\/\d+\/\d+$/,
			e: ".epContent",
			i: 1
		},
		json: (cid) => {
			let params = fn.cp({
				page: 1,
				page_size: 500,
				image_source: localStorage.getItem("comic_image_source") || _unsafeWindow.CURRENT_IMAGE_SOURCE || ""
			});
			let res_arr = [
				`/api/comic/chapter/info/${cid}`,
				`/api/comic/image/${cid}?${params}`
			].map(api => fn.j(api));
			return Promise.all(res_arr).then(([a, b]) => ({
				...a.data,
				...b.data
			}));
		},
		data: () => {
			let cid = new URL(document.URL).pathname.split("/").at(-1);
			return _this.json(cid).then(json => {
				_this.ui(json);
				let {
					images,
					current: {
						title
					},
					next
				} = json;
				images = images.map(e => e.url);
				next = next.id > 0 ? fn.wurl(next.id, document.URL) : null;
				siteJson = {
					images,
					title,
					next
				}
				console.log("\n漫蛙库_JSON\n", siteJson);
			});
		},
		ui: (json) => {
			let {
				current: {
					title
				},
				next,
				prev
			} = json;
			fn.ge("#current-title").innerText = title;
			let c_html = fn.ge("#directory-container a").outerHTML;
			next = next.id > 0 ? fn.wurl(next.id) : null;
			for (let a of fn.gae("#next-nav-container a,#next-nav-mobile a")) next ? (a.href = next) && (a.innerText = "下一章") : (a.outerHTML = c_html);
			prev = prev.id > 0 ? fn.wurl(prev.id) : null;
			for (let a of fn.gae("#prev-nav-container a,#prev-nav-mobile a")) prev ? (a.href = prev) && (a.innerText = "上一章") : (a.outerHTML = c_html);
		},
		init: () => fn.showMsg(DL.str_135, 0).then(() => fn.waitEle(["#showimgcontent .cImg img", "#next-nav-container a", "#next-nav-mobile a"])).then(() => _this.data()).then(() => fn.caae(".epContent", fn.createImgArray(siteJson.images)) && fn.hm()),
		autoPager: {
			ele: () => fn.createImgArray(siteJson.images),
			pos: [".epContent", 0],
			observer: ".epContent>img",
			next: () => siteJson.next,
			wait: () => _this.data(),
			title: () => siteJson.title,
			preloadNextPage: () => {
				if (!!siteJson.next) {
					let cid = siteJson.next.split("/").at(-1);
					_this.json(cid).then(json => {
						let {
							current: {
								title
							},
							images
						} = json;
						images = images.map(e => e.url);
						fn.picPreload(images, title, "next");
					});
				}
			},
			update: "/cate/",
			list: "#directory-container a",
			chapters: {
				url: "#directory-container a",
				target: ".chapter-item",
				textNode: ".chapter-name"
			}
		},
		css: ".topMenu{margin-top:unset!important}.tooltip-bar.bottomMenu{z-index: 100!important}",
		category: "comic autoPager"
	}, {
		name: "漫蛙漫画",
		host: ["manwa.xin", "manwa.la", "www.58hl.com", "www.manwatw.cc"],
		url: {
			t: "漫蛙",
			p: /^\/chapter\/\d+\/\d+\.html$/,
			e: ".epContent",
			d: "m"
		},
		data: (url = fn.lp) => {
			let [mid, cid] = url.match(/\d+/g);
			const getJson = async (url) => {
				let res;
				while (true) {
					res = await fetch(url, {
						"headers": {
							"x-requested-with": "XMLHttpRequest"
						}
					});
					if (res.ok) {
						break;
					} else {
						await fn.delay(1000, 0);
					}
				}
				const json = await res.json();
				return json;
			};
			let res_arr = [
				`/e/json/chapter/?zpid=${mid}&line=1000&orderby=asc`,
				`/e/json/img/?id=${cid}`
			].map(api => getJson(api));
			let get_doc = fn.fetchDoc(fn.lp).then(dom => (doc = dom));
			res_arr.push(get_doc);
			return Promise.all(res_arr);
		},
		init: () => fn.sm5().then(() => _this.data().then(([a, b]) => {
			siteJson = {
				chapters: a.length.sort((a, b) => Number(a.num) - Number(b.num)),
				images: b.sort((a, b) => Number(a.sortId) - Number(b.sortId))
			};
			debug("\n此頁JSON資料\n", siteJson);
			fn.hm();
		})),
		imgURL: (url) => {
			async function decryptAES(encryptedData, key) {
				const cryptoKey = await crypto.subtle.importKey("raw", key, {
					name: "AES-CBC"
				}, false, ["decrypt"]);
				const iv = key.slice(0, 16);
				const decryptedData = await crypto.subtle.decrypt({
					name: "AES-CBC",
					iv
				}, cryptoKey, encryptedData);
				return new Uint8Array(decryptedData);
			}
			async function loadAndDecryptImage(url, key) {
				let res;
				while (true) {
					res = await fetch(url);
					if (res.ok) {
						break;
					} else {
						await fn.delay(3000, 0);
					}
				}
				const encryptedData = await res.arrayBuffer();
				const decryptedArray = await decryptAES(encryptedData, key);
				const blob = new Blob([decryptedArray], {
					type: "image/jpeg"
				});
				return URL.createObjectURL(blob);
			}
			const key = new TextEncoder().encode("manwatupianjiami");
			return loadAndDecryptImage(url, key);
		},
		imgs: async (json = siteJson) => {
			fn.showMsg("图片解密中...", 0);
			let fetchNum = 0;
			return json.images.map(async (e, i) => {
				await fn.delay(200 * i, 0);
				return _this.imgURL(e.url).then((url) => {
					fn.showMsg(`图片解密中 ${fetchNum += 1}/${json.images.length}`, 0);
					return url;
				});
			});
		},
		button: [4],
		insertImg: [".epContent", 2],
		autoDownload: [0],
		next: () => fn.gp(".next a[href^='/chapter/']"),
		prev: () => fn.gp(".prev a[href^='/chapter/']"),
		chapters: () => siteJson.chapters.map(({
			name,
			url
		}) => ({
			text: name,
			url
		})),
		customTitle: () => fn.gae(".basetitle,.basechaptername", doc).map(e => _unsafeWindow.decodeBase64(fn.gt(e))).join(" - "),
		hide: "#app-download-tip,div[class^=floating]",
		category: "comic"
	}, {
		name: "奇漫屋",
		url: {
			h: "www.mqzjw.com",
			p: "/bookstt/",
			i: 0
		},
		update: "/custom/news",
		init: () => {
			fn.addMutationObserver(() => fn.remove([
				"//div[a[contains(text(),'下载')]]",
				"//div[contains(text(),'下载')]",
				"//div[contains(text(),'投诉邮箱')]",
				"#alertBox",
				"#xiazai"
			]));
			return fn.waitVar("CryptoJS");
		},
		imgs: () => fn.getMqzjwSrc(),
		button: [4],
		insertImg: [".comiclist", 2],
		insertImgAF: () => {
			let [id] = fn.gst("readPic").match(/\d+/);
			fn.ge(".back").href = `/book/${id}.html`;
			const {
				jQuery: $
			} = _unsafeWindow;
			fn.run("jQuery(window).off()");
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				const st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					$(".header").css("transform", "translateY(-100%)");
					$(".bottom-bar").css("transform", "translateY(100%)");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					$(".header").css("transform", "translateY(0%)");
					$(".bottom-bar").css("transform", "translateY(0%)");
					lastScrollTop = st;
				}
			});
			if (isString(nextLink)) {
				fn.addUrlHtml(nextLink, ".next_chapter", 1, "点击进入下一话");
			}
			fn.remove(".next_chapter");
		},
		autoDownload: [0],
		next: ".j-rd-next[_href^='/bookstt/']",
		prev: ".j-rd-prev[_href^='/bookstt/']",
		chapters: {
			target: "#chapter-items a",
			sort: "r"
		},
		customTitle: (dom = document) => {
			let text = dom.title.replace("漫画-免费在线看漫画-奇漫屋", "");
			let textArr = text.split("-");
			return textArr[1] + " - " + textArr[0];
		},
		preloadNext: async (nextDoc) => {
			let srcs = await fn.getMqzjwSrc(nextLink, 0);
			fn.picPreload(srcs, _this.customTitle(nextDoc), "next");
		},
		fancybox: {
			blacklist: 1
		},
		infiniteScroll: true,
		css: "html{cursor:auto!important}",
		category: "comic"
	}, {
		name: "奇漫屋 自動翻頁",
		url: {
			h: "www.mqzjw.com",
			p: "/bookstt/",
			i: 1
		},
		init: async () => {
			fn.addMutationObserver(() => fn.remove([
				"//div[a[contains(text(),'下载')]]",
				"//div[contains(text(),'下载')]",
				"//div[contains(text(),'投诉邮箱')]",
				"#alertBox",
				"#xiazai"
			]));
			await fn.waitVar("CryptoJS");
			fn.showMsg(DL.str_135, 0);
			await fn.getMqzjwSrc(fn.lp, 0).then(srcs => fn.createImgArray(srcs)).then(imgs => {
				fn.ge(".j-rd-prev").outerHTML = fn.ge(".j-rd-prev").outerHTML;
				fn.ge(".j-rd-next").outerHTML = fn.ge(".j-rd-next").outerHTML;
				fn.ge(".j-rd-prev").href = fn.attr(".j-rd-prev[_href]", "_href");
				fn.ge(".j-rd-next").href = fn.attr(".j-rd-next[_href]", "_href");
				let [id] = fn.gst("readPic").match(/\d+/);
				fn.ge(".back").href = `/book/${id}.html`;
				fn.hm();
				return fn.caae(".comiclist", imgs, ".next_chapter");
			});
			const {
				jQuery: $
			} = _unsafeWindow;
			fn.run("jQuery(window).off()");
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				const st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					$(".header").css("transform", "translateY(-100%)");
					$(".bottom-bar").css("transform", "translateY(100%)");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					$(".header").css("transform", "translateY(0%)");
					$(".bottom-bar").css("transform", "translateY(0%)");
					lastScrollTop = st;
				}
			});
		},
		autoPager: {
			ele: () => fn.getMqzjwSrc(nextLink, 0).then(srcs => fn.createImgArray(srcs)),
			pos: [".comiclist", 0],
			observer: ".comiclist>img",
			next: (dom) => {
				let next = fn.ge(".j-rd-next[_href^='/bookstt/']", dom);
				return next ? fn.lo + fn.attr(next, "_href") : null;
			},
			title: (dom) => {
				let text = dom.title.replace("漫画-免费在线看漫画-奇漫屋", "");
				let textArr = text.split("-");
				return isM ? textArr[0] : textArr[1] + " - " + textArr[0];
			},
			re: "span.title,.j-rd-prev[_href],.j-rd-next[_href]",
			aF: (dom) => {
				fn.ge(".j-rd-prev").href = fn.attr(".j-rd-prev[_href]", "_href", dom);
				let nextE = fn.ge(".j-rd-next");
				let next_url = fn.attr(".j-rd-next[_href]", "_href", dom);
				if (next_url == "") {
					nextE.href = fn.gu(".back");
					fn.ge("span", nextE).innerText = "返回";
				} else {
					nextE.href = next_url;
				}
			},
			preloadNextPage: async (dom) => {
				let next = _this.autoPager.next(dom);
				if (!!next) {
					let srcs = await fn.getMqzjwSrc(next, 0);
					fn.fetchDoc(next).then(nextDoc => fn.picPreload(srcs, _this.autoPager.title(nextDoc), "next"));
				}
			},
			update: "/custom/news",
			list: "a.back",
			chapters: {
				target: "#chapter-items a",
				sort: "r"
			}
		},
		css: "html{cursor:auto!important}",
		category: "comic autoPager"
	}, {
		name: "奇漫屋AD",
		url: {
			h: "www.mqzjw.com"
		},
		init: () => fn.addMutationObserver(() => fn.remove([
			"//div[div[contains(text(),'下载')]]",
			"//div[a[contains(text(),'下载')]]",
			"#alertBox",
			"#xiazai"
		])),
		category: "ad"
	}, {
		name: "嗶哩漫畫",
		url: {
			h: ["www.bilimanga.net", "www.bilicomic.net"],
			p: "/read/",
			st: "ReadParams"
		},
		imgs: "#acontentz img",
		button: [4],
		insertImg: ["#acontentz", 2],
		endColor: "white",
		autoDownload: [0],
		next: () => {
			let next = _unsafeWindow?.ReadParams?.url_next;
			return isString(next) && next?.includes("/read/") ? next : null;
		},
		prev: 1,
		chapters: {
			url: () => {
				let dir = fn.dir(fn.lp);
				return dir + "catalog";
			},
			target: ".volume-chapters a"
		},
		customTitle: () => document.title.trim().slice(0, -5),
		preload: 0,
		fancybox: {
			blacklist: 1
		},
		category: "comic"
	}, {
		name: "拷貝漫畫M SPA",
		url: {
			h: ["www.2025copy.com", "2025copy.com", "copy2000.site", "www.copy20.com", "copy20.com", "www.mangacopy.com", "mangacopy.com"],
			i: 0,
			d: "m"
		},
		page: () => fn.clp("/h5/comicContent/"),
		clearLoop: true,
		json: (url = fn.clp(), msg = 1) => {
			if (msg == 1) fn.sm5();
			let [name, id] = url.split("/").slice(3);
			let api_a = `https://api.2025copy.com/api/v3/comic/${name}/chapter/${id}`;
			//let api_b = `https://api.2025copy.com/api/v3/comic/${name}/chapter2/${id}`;
			return fn.xhr(api_a, {
				responseType: "json",
				headers: {
					"User-Agent": PC_UA,
					"Accept": "application/json",
					"platform": "1",
					"version": "2025.08.08",
					"webp": 1,
					"region": 1
				}
			});
		},
		SPA: () => _this.page(),
		observeURL: "nav",
		init: () => _this.page() ? _this.json().then(json => (siteJson = json) && fn.hm()) : (_unsafeWindow.aboutBlank = null),
		imgs: (json = siteJson) => {
			if (!_this.page()) return [];
			const {
				contents
			} = json.results.chapter;
			return contents.map(e => e.url);
			/**
			api_b 需要還原圖片順序
			const srcs = [];
			const {
			    words,
			    contents
			} = json.results.chapter;
			words.forEach((w, i) => (srcs[w] = contents[i].url));
			return srcs;
			 */
		},
		capture: () => _this.imgs(),
		button: [4],
		insertImgBF: () => fn.waitEle(".van-image__img").then(() => fn.createImgBox(".comicContentPopupImageList", 2)).then(() => fn.hideEle(".van-ovarlay,.van-toast:has(.van-loading)")),
		insertImg: [
			["box", 0, ".comicContentPopupImageList"], 2
		],
		insertImgAF: (p) => {
			const addHtml = (url, text) => {
				let str = `<div style="padding: 10px 0; text-align: center; font-size: initial !important;"><a href="${url}"style="width: 100%;font-size: 26px;line-height: 50px;height: 50px;text-align: center;">${text}</a></div>`;
				p.insertAdjacentHTML("afterend", str);
			};
			let s = fn.clp().split("/").at(-2);
			let url = `/h5/details/comic/${s}`;
			let hUrl = `/h5/index`;
			addHtml(hUrl, "首頁");
			addHtml(url, "目錄");
			if (nextLink) addHtml(nextLink, "點選進入下一話");
			fn.hideEle(".comicFixed");
		},
		next: () => {
			if (!_this.page()) return null;
			let next = siteJson.results.chapter.next;
			return next ? fn.wurl(next) : null;
		},
		prev: 1,
		chapters: () => fn.CPMH_M_C(),
		customTitle: (json = siteJson) => _this.page() ? json.results.comic.name + " - " + json.results.chapter.name : null,
		preloadNext: () => _this.json(nextLink, 0).then(json => {
			let srcs = _this.imgs(json);
			let title = _this.customTitle(json);
			fn.picPreload(srcs, title, "next");
		}),
		fancybox: {
			blacklist: 1
		},
		gallery: 0,
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "拷貝漫畫M 自動翻頁",
		url: {
			h: /2025copy|copy20|mangacopy/,
			p: /^\/h5\/comicContent\/\w+\//,
			i: 1
		},
		json: (name, id) => {
			let api = `https://api.2025copy.com/api/v3/comic/${name}/chapter/${id}`;
			return fn.xhr(api, {
				responseType: "json",
				headers: {
					"User-Agent": PC_UA,
					"Accept": "application/json",
					"platform": "1",
					"version": "2025.08.08",
					"webp": 1,
					"region": 1
				}
			});
		},
		data: () => {
			let [name, id] = new URL(document.URL).pathname.split("/").slice(-2);
			return _this.json(name, id).then(json => {
				let {
					contents,
					name,
					next
				} = json.results.chapter;
				const images = contents.map(e => e.url);
				if (!!next) {
					next = fn.wurl(next, document.URL);
				} else {
					next = null;
				}
				siteJson = {
					images,
					name,
					next
				}
				console.log("\n拷貝漫畫M_JSON\n", siteJson);
			});
		},
		init: async () => {
			fn.showMsg(DL.str_135, 0);
			await _this.data();
			fn.hideEle(".van-ovarlay,.van-toast:has(.van-loading)");
			await fn.caae(".comicContentPopupImageList", fn.createImgArray(siteJson.images));
			fn.clearAllTimer(3);
			if ("aboutBlank" in _unsafeWindow) _unsafeWindow.aboutBlank = null;
			fn.hm();
		},
		autoPager: {
			ele: () => fn.createImgArray(siteJson.images),
			pos: [".comicContentPopupImageList", 0],
			observer: ".comicContentPopupImageList>img",
			next: () => siteJson.next,
			wait: () => _this.data(),
			title: () => siteJson.name,
			preloadNextPage: () => {
				if (!!siteJson.next) {
					let [name, id] = new URL(siteJson.next).pathname.split("/").slice(-2);
					_this.json(name, id).then(json => {
						let {
							contents,
							name
						} = json.results.chapter;
						const images = contents.map(e => e.url);
						fn.picPreload(images, name, "next");
					});
				}
			},
			scroll: "#comicContentMain",
			list: () => "/h5/details/comic/" + fn.clp().split("/").at(-2),
			chapters: () => fn.CPMH_M_C(),
		},
		css: ".comicControlBottom a:-webkit-any-link{color:white!important}.comicContentPopup .comicControlBottom .comicControlBottomBottom span{margin:0 1rem!important}",
		hide: ".comicFixed,.comicControlBottom.hide",
		category: "comic autoPager"
	}, {
		name: "拷貝漫畫",
		url: {
			t: ["拷貝漫畫", "拷贝漫画"],
			p: /^\/comic\/\w+\/chapter\//,
			st: "contentKey",
			i: 0
		},
		update: "/comics",
		init: async () => {
			await fn.waitEle(".comicContent-list img[src^=http]");
			fn.copymangaUI();
			let readHistoryData = localStorage.getItem("copymangaReadHistory");
			let [, , comic, , chapter] = fn.lp.split("/");
			let json;
			readHistoryData ? json = JSON.parse(readHistoryData) : json = {};
			json[comic] = chapter;
			localStorage.setItem("copymangaReadHistory", JSON.stringify(json));
		},
		imgs: async (dom = document) => {
			let code = fn.gst("contentKey", dom);
			let [, key, , raw] = code.split("'");
			let images = await fn.copymanga_decrypt_A(raw, key);
			return images.map(({
				url
			}) => url.replace("800x.", "1500x."));
		},
		button: [4],
		insertImg: [".comicContent-list", 2],
		endColor: "white",
		autoDownload: [0],
		next: "//a[text()='下一話'][starts-with(@href,'/comic/')]",
		prev: "//a[text()='上一話'][starts-with(@href,'/comic/')]",
		chapters: () => fn.CPMH_PC_C(),
		customTitle: (dom = document) => fn.dt({
			d: / - 拷.+$/
		}, dom),
		preloadNext: true,
		hide: ".header+div[style],.comicContainerAds",
		infiniteScroll: true,
		category: "comic"
	}, {
		name: "拷貝漫畫 自動翻頁",
		url: {
			t: ["拷貝漫畫", "拷贝漫画"],
			p: /^\/comic\/\w+\/chapter\//,
			st: "contentKey",
			i: 1
		},
		getSrcs: async (dom) => {
			let code = fn.gst("contentKey", dom);
			let [, key, , raw] = code.split("'");
			let images = await fn.copymanga_decrypt_A(raw, key);
			return images.map(({
				url
			}) => url.replace("800x.", "1500x."));
		},
		getImgs: async (dom = document) => fn.createImgArray(await _this.getSrcs(dom)),
		init: async () => {
			await fn.waitEle(".comicContent-list img[src^=http]");
			fn.copymangaUI();
			await _this.getImgs().then(imgs => fn.caae(".comicContent-list", imgs));
			fn.addMutationObserver(() => {
				if (fn.ge("//li[img[@data-src]]")) {
					fn.remove("//li[img[@data-src]]");
				}
			});
		},
		autoPager: {
			ele: (dom) => _this.getImgs(dom),
			pos: [".comicContent-list", 0],
			observer: ".comicContent-list>img",
			next: "//a[text()='下一話'][starts-with(@href,'/comic/')]",
			re: ".header,.footer",
			title: (dom) => fn.dt({
				d: / - 拷.+$/
			}, dom),
			preloadNextPage: 1,
			update: "/comics",
			list: ".list a",
			chapters: () => fn.CPMH_PC_C(),
		},
		hide: ".header+div[style],.comicContainerAds",
		category: "comic autoPager"
	}, {
		name: "拷貝漫畫 目錄頁",
		url: {
			t: ["拷貝漫畫", "拷贝漫画"],
			p: /^\/comic\/\w+$/
		},
		init: async () => {
			await fn.waitEle(".tab-pane.show.active a");
			const updateLastChapter = () => {
				let [, , comic] = fn.lp.split("/");
				let readHistoryData = localStorage.getItem("copymangaReadHistory");
				if (!!readHistoryData) {
					let json = JSON.parse(readHistoryData);
					if (comic in json) {
						let selector = `.tab-content a[href$="${json[comic]}"]`;
						for (let a of fn.gae(".lastchapter")) a.classList.remove("lastchapter");
						for (let a of fn.gae(selector)) a.classList.add("lastchapter");
						setTimeout(() => {
							let lastReadUrl = fn.lp + "/chapter/" + json[comic];
							let lastText = fn.ge(".lastchapter").title;
							let lastE = fn.ge("#lastRead");
							if (!lastE && !fn.ge("//span[contains(text(),'最後閱讀')]")) {
								let a = fn.ce("a", {
									id: "lastRead",
									href: lastReadUrl,
									target: "_blank",
									innerText: lastText
								});
								let span = fn.ce("span", {
									innerText: "最後閱讀:"
								});
								let tableRight = fn.ge(".table-default-right");
								tableRight.insertAdjacentElement("afterbegin", a);
								tableRight.insertAdjacentElement("afterbegin", span);
							} else if (!!lastE) {
								let a = lastE;
								a.href = lastReadUrl;
								a.innerText = lastText;
							}
						}, 200);
					}
				}
			};
			updateLastChapter();
			document.addEventListener("visibilitychange", updateLastChapter);
			if ("aboutBlank" in _unsafeWindow) _unsafeWindow.aboutBlank = null;
			setTimeout(() => fn.clearAllTimer(3), 2000);
		},
		css: ".lastchapter{color:#fff !important;background:#1790E6}",
		hide: ".comicDetailAds",
		category: "none"
	}, {
		name: "樱花漫画",
		url: {
			h: "yinghuamh.net",
			p: /^\/comic\/\w+\/\d+\/\d+/
		},
		update: "/update",
		init: async () => {
			await fn.waitVar("x_tokens");
			fn.run("$(document).off()");
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					fn.ge(".view-title").style.top = "-60px";
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					fn.ge(".view-title").style.top = "0px";
					lastScrollTop = st;
				}
			});
		},
		imgs: () => {
			const {
				x_tokens,
				Gm
			} = _unsafeWindow;
			return x_tokens.map(e => Gm.getImgUrl(Gm.fitImgUrl(e)));
		},
		button: [4],
		insertImg: ["#all", 2],
		endColor: "white",
		autoDownload: [0],
		next: "a.next_part:not([href^=java])",
		prev: ".paginationContent>a:first-child:not([href^=java])",
		chapters: {
			url: "//a[text()='目录']",
			target: "#comic-book-list a[title]",
			sort: "r"
		},
		customTitle: () => {
			const {
				comic_name,
				part_name
			} = _unsafeWindow;
			return comic_name + " - " + part_name;
		},
		preloadNext: () => fn.iframeVar(nextLink, "x_tokens").then(frame => {
			const {
				x_tokens,
				Gm,
				comic_name,
				part_name
			} = frame;
			let srcs = x_tokens.map(e => Gm.getImgUrl(Gm.fitImgUrl(e)));
			let text = comic_name + part_name;
			fn.picPreload(srcs, text, "next");
		}),
		category: "comic"
	}, {
		name: "看漫画",
		host: ["www.kanman.com"],
		enable: 0,
		url: {
			h: "www.kanman.com",
			p: /^\/\d+\/[\w-]+\.html$/,
			d: "pc"
		},
		init: async () => {
			let [, comic_id, id] = fn.lp.split("/");
			id = id.replace(".html", "");
			let api = `/api/getchapterinfov2?product_id=1&productname=kmh&platformname=pc&comic_id=${comic_id}&chapter_newid=${id}&isWebp=1&quality=middle`;
			await fn.j(api).then(json => (siteJson = json));
			debug("\n此頁JSON資料\n", siteJson);
		},
		imgs: () => siteJson.data.current_chapter.chapter_img_list,
		next: () => {
			let {
				comic_id,
				next_chapter
			} = siteJson.data;
			if (next_chapter) {
				return "/" + comic_id + "/" + next_chapter.chapter_newid + ".html";
			}
			return null;
		},
		prev: 1,
		customTitle: () => siteJson.data.comic_name + " - " + siteJson.data.current_chapter.chapter_name,
		category: "comic"
	}, {
		name: "zero搬运网",
		host: ["www.zerobywtar.com"],
		url: {
			h: "www.zero",
			p: "/plugin",
			s: "a=read",
			st: "listimg"
		},
		imgs: () => {
			let code = fn.gst("listimg");
			let dataArr = fn.textToArray(code, "listimg");
			return dataArr.map(e => e.file);
		},
		button: [4],
		insertImg: [".uk-alert.uk-alert-danger.uk-text-center,.uk-zjimg", 3],
		autoDownload: [0],
		next: "//a[contains(text(),'下一章')]",
		prev: "//a[contains(text(),'上一章')]",
		chapters: {
			url: "//a[text()='目录']",
			target: "h3~[uk-grid] a"
		},
		customTitle: () => fn.title(" - zero搬运网"),
		category: "comic"
	}, {
		name: "zero搬运网M",
		url: {
			h: "www.zero",
			p: "/plugin",
			s: "a=read",
			d: "m"
		},
		imgs: () => {
			let i = ".zjimg img";
			if (fn.ge(i)) {
				return fn.gae(i);
			}
			fn.sm5();
			return fn.xhrDoc(fn.url, {
				headers: {
					"User-Agent": PC_UA
				}
			}).then(dom => {
				let code = fn.gst("listimg", dom);
				let dataArr = fn.textToArray(code, "listimg");
				return dataArr.map(e => e.file);
			});
		},
		button: [4],
		insertImg: [".areadiv", 3],
		autoDownload: [0],
		next: "//a[contains(text(),'下一章')]",
		prev: "//a[contains(text(),'上一章')]",
		customTitle: () => fn.title(/_ zero搬运网.+/),
		category: "comic"
	}, {
		name: "漫蛙漫画",
		host: ["manwa.me"],
		link: "https://fuwz.cc/maKapG",
		url: {
			t: "漫蛙漫画",
			p: /^\/chapter\/\d+(\?img_host=\d)?$/,
			e: ".img-content"
		},
		init: async () => {
			_unsafeWindow.Function.prototype.constructor = () => {};
			fn.css(".ad-area{opacity:0!important;}#cp_img>.two-ad-area:nth-child(1)>.ad-area,#cp_img>.two-ad-area:nth-child(2){display:none!important}");
			fn.remove(".ad-area,body>div[id]:not([id^='pv-'],[class^='pv-'],[id^='pagetual'],[class^='pagetual'],#comicRead,#fab,[id^='FullPictureLoad'],[class^='FullPictureLoad'],[class^=fancybox])", 5000);
			await fn.waitVar("jQuery");
			const $ = _unsafeWindow.jQuery;
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					$(".view-fix-top-bar").attr("style", "top: -60px;");
					$(".view-fix-bottom-bar").attr("style", "bottom: -60px;");
					$(".detail-comment-fix-bottom").hide("fast");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					$(".view-fix-top-bar").attr("style", "top: 0px;");
					$(".view-fix-bottom-bar").attr("style", "bottom: 0px;");
					$(".detail-comment-fix-bottom").show("fast");
					lastScrollTop = st;
				}
			});
			await fn.waitEle(".content-img.lazy_img[src^=blob]");
			if (autoScrollAllElement === 1) _this.scrollEle();
		},
		imgs: async () => {
			let is = fn.gae(".content-img").length;
			let bs = fn.gae(".content-img[src^=blob]").length;
			if (is != bs || options.autoDownload == 1 || options.shadowGallery == 1 || options.mobileGallery == 1) {
				await _this.scrollEle();
			}
			return fn.imgBlobUrlArr(".content-img[src^=blob]");
		},
		scrollEle: () => fn.aotoScrollEles({
			scale: ".img-content",
			ele: ".img-content .content-img",
			time: 60000,
			cb: (img) => /^blob/.test(img.src),
			top: 1
		}),
		autoDownload: [0],
		next: ".view-fix-bottom-bar-item-menu-next",
		prev: ".view-fix-bottom-bar-item-menu-prev",
		customTitle: () => fn.title("在线阅读", 1),
		css: "body{padding-bottom:0px!important}div:has(>.view-fix-top-bar){z-index:1000!important}",
		category: "comic"
	}, {
		name: "漫蛙選目錄展開全部章節",
		url: {
			h: "manwa",
			p: /^\/book\/\d+$/
		},
		init: async () => {
			_unsafeWindow.Function.prototype.constructor = () => {};
			await fn.waitEle("#detail-list-select li");
			await fn.waitVar(["titleSelect", "charpterMore"]);
			EClick("//a[text()='目录']");
			EClick("a.detail-list-more");
		},
		category: "none"
	}, {
		name: "漫蛙自動載入更多",
		url: {
			h: "manwa",
			p: /^\/update$/
		},
		init: "Function.prototype.constructor=()=>{}",
		observerClick: "#loadMore",
		category: "autoPager"
	}, {
		name: "開車漫画",
		host: ["18p.fun"],
		reg: /^https?:\/\/(www\.)?(18p|gohaveababy|imynest|healthway|beforeout)\.[a-z]{2,5}\/(ForInject\/|Article\/|content\/)/,
		imgs: async () => {
			await fn.waitEle("//script[contains(text(),'_curChap')]");
			if (fn.lh != "18p.fun") {
				location.replace("https://18p.fun/ForInject/Chapter/?id=" + _unsafeWindow.$_curChap.id);
				await delay(3000);
			}
			await fn.getNP("img[data-src].lazy:not(.demo-lazy)", "//a[@data-url and contains(text(),'下一頁')] | //a[@data-url and contains(text(),'下一章')]", null, "div[class^=picnext]");
			return fn.gae("img[data-src].lazy:not(.demo-lazy)");
		},
		insertImg: ["div[class^=pictures]", 3],
		endColor: "white",
		category: "comic"
	}, {
		name: "開車漫画",
		host: ["18p.fun"],
		enable: 0,
		icon: 0,
		key: 0,
		reg: /^https?:\/\/18p\.fun\//,
		include: ".loadmore>button",
		init: () => fn.addMutationObserver(() => {
			for (let img of fn.gae("img.lazy[src$=svg]")) img.src = img.dataset.src;
		}),
		observerClick: ".loadmore>button",
		openInNewTab: "#itemlist li>a:not([target=_blank])",
		css: ".loadmore{display:block!important}",
		hide: ".page",
		category: "comic"
	}, {
		name: "漫画皮",
		host: ["www.manhuapi.cc", "m.manhuapi.cc"],
		url: {
			h: "manhuapi",
			p: "/chapter/"
		},
		update: "/manhua/onclick/10/",
		init: "document.onkeydown=null && $('body').unbind()",
		imgs: (dom = document) => fn.gae("option[jhc-data]", dom).map(e => e.getAttribute("jhc-data").replace("-mht.middle.webp", "")).map(e => e.replace(new URL(e).protocol, location.protocol)),
		button: [4],
		insertImg: [".mh_list,#content", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][contains(@href,'chapter')]",
		prev: "//a[text()='上一章'][contains(@href,'chapter')]",
		chapters: () => {
			let a = fn.ge("//a[text()='作品目录'] | //a[text()='章节目录']");
			if (fn.lh.startsWith("m.")) {
				let chapters = [];
				return fn.fetchDoc(a).then(dom => {
					const get = (_dom) => fn.gae(".readlist a", _dom).map(a => ({
						text: a.innerText.trim(),
						url: a.href
					}));
					let pages = fn.ge(".hd-sel", dom);
					if (pages) {
						let doms = [dom];
						let links = fn.gae("option[value]", pages).map(e => e.value);
						let resArr = links.map(fn.fetchDoc);
						return Promise.all(resArr).then(res => {
							doms = [...doms, ...res];
							return doms.map(get).flat();
						});
					}
					return get(dom);
				});
			}
			return fn.fetchDoc(a).then(dom => fn.gae(".cy_plist~.cy_plist a", dom).map(a => ({
				text: a.innerText.trim(),
				url: a.href
			})));
		},
		customTitle: (dom = document) => fn.attr("meta[name='keywords']", "content", dom).replace(",", " - "),
		preloadNext: true,
		hide: "#prePage,#nextPage,select[onchange],.jump-list,.apjg,a[href*=taobao],body>*[style*='z-index'][style*='2147483646']",
		category: "comic"
	}, {
		name: "千漫谷",
		host: "www.wuforcongress.com",
		url: {
			t: "千漫谷",
			p: "/zhangjie/",
			st: "txt_url"
		},
		update: "/fenlei/2.html",
		box: ["#content_neirong", 1],
		imgs: () => fn.sm5().then(() => fn.xhr(_unsafeWindow.txt_url).then(t => [...fn.doc(t.trim().slice(6, -2)).images])),
		button: [4],
		insertImg: [
			["box", 0, "#content_neirong"], 2
		],
		autoDownload: [0],
		next: "//a[text()='下一章'][contains(@href,'.html')]",
		prev: "//a[text()='上一章'][contains(@href,'.html')]",
		chapters: {
			url: "//a[text()='目录']",
			target: ".myui-content__list a"
		},
		mcss: ".neirong{margin: unset!important;padding: unset!important}",
		category: "comic"
	}, {
		name: "哈哈漫画",
		url: {
			h: "www.hahacomic.com",
			p: /^\/manhua\/\d+\/\d+\.html/
		},
		imgs: "img[data-original]",
		button: [4],
		insertImg: [".chapter-images", 2],
		autoDownload: [0],
		next: "//a[label[text()='下一章'] and not(starts-with(@href,'java'))]",
		prev: "//a[label[text()='上一章'] and not(starts-with(@href,'java'))]",
		chapters: {
			url: "//a[div[text()='返回漫画']]",
			target: ".fm-chapter-list-wrap a",
			sort: "r"
		},
		customTitle: (dom = document) => dom.title,
		preloadNext: true,
		category: "comic"
	}, {
		name: "哈哈漫画 - 分類自動翻頁",
		url: {
			h: "www.hahacomic.com",
			p: "/list/"
		},
		autoPager: {
			ele: ".mdui-col-lg-2",
			observer: ".mdui-col-lg-2",
			next: (dom) => fn.ge("span.current+a", dom) ? siteUrl.replace(/\?page=\d+/, "") + "?page=" + fn.ge("span.current+a", dom).getAttribute("href").match(/\d+/)[0] : null,
			re: ".pages",
			pageNum: () => nextLink.match(/\d+$/)[0]
		},
		openInNewTab: ".mdui-col-lg-2>a",
		category: "autoPager"
	}, {
		name: "风车漫画",
		url: {
			h: "www.jiburico.com",
			p: "/read/"
		},
		update: "/up/5/",
		clearEvent: true,
		imgs: () => fn.gae("#full-none img", doc),
		button: [4],
		insertImg: ["#full-none", 2],
		autoDownload: [0],
		next: () => fn.gu({
			s: "a[href^='/read/']",
			t: "下一话"
		}, doc),
		prev: () => fn.gu({
			s: "a[href^='/read/']",
			t: "上一话"
		}, doc),
		chapters: () => fn.gae(".playlist a", doc).map(a => ({
			text: a.text,
			url: a.href
		})),
		customTitle: () => {
			let code = fn.gst("ReadData", doc);
			let object = fn.textToObject(code, "ReadData");
			return object.comicName + " - " + object.readName;
		},
		category: "comic"
	}, {
		name: "风车漫画",
		url: {
			h: "www.jiburico.com"
		},
		clearEvent: true,
		init: () => {
			for (let a of fn.gae("a[data-original]")) a.style.backgroundImage = `url(${a.dataset.original})`;
		},
		category: "none"
	}, {
		name: "土豪漫画",
		url: {
			h: "www.thmanhua.com",
			p: "/chapter/"
		},
		imgs: ".more-box img",
		button: [4],
		insertImg: [".more-box", 2],
		autoDownload: [0],
		next: "//a[text()='下一章'][starts-with(@href,'/')]",
		prev: "//a[text()='上一章'][starts-with(@href,'/')]",
		chapters: {
			url: "//a[text()='详情']",
			target: "#chapterList a"
		},
		customTitle: [".btn+div+div", ".btn+div"],
		preloadNext: true,
		category: "comic"
	}, {
		name: "轻之国度",
		url: {
			h: "www.lightnovel.us",
			p: /^\/\w+\/detail\/\d+/
		},
		imgs: ".article-content img",
		button: [4],
		insertImg: [".article-content", 3],
		customTitle: ".article-title",
		category: "comic"
	}, {
		name: "微信公众号",
		url: {
			h: "mp.weixin.qq.com",
			p: /^\/[^&]+&mid=\d+/
		},
		imgs: "img.js_insertlocalimg,img.wxw-img",
		category: "comic"
	}, {
		name: "微信公众号",
		url: {
			h: "mp.weixin.qq.com",
			s: "sn="
		},
		imgs: "img.js_insertlocalimg,img.wxw-img",
		category: "comic"
	}, {
		name: "虎扑社区",
		url: {
			h: "bbs.hupu.com",
			p: /^\/\d+\.html/
		},
		init: () => (siteJson = JSON.parse(fn.attr("#bbs-admin-main-post-container", "data-admininfo"))),
		imgs: () => {
			let data = JSON.parse(siteJson.format);
			if (data.imgList) {
				return data.imgList.map(e => e.remoteUrl);
			} else if (data.jsonV3) {
				return data.jsonV3.content.filter(item => item.type == "image").map(e => e.attrs.src);
			}
			return [];
		},
		customTitle: () => siteJson.postTitle,
		category: "comic"
	}, {
		name: "微漫画 目錄頁",
		host: ["medibang.com"],
		url: {
			h: "medibang.com",
			p: "/book/",
			d: "pc"
		},
		box: ["#contentsDetailShow"],
		imgs: () => {
			fn.sm5();
			let links;
			let chapterIds;
			if (fn.ge("a.btn_more")) {
				links = fn.gau("a.btn_more").reverse();
				chapterIds = links.map(url => url.split("/").at(-1));
			} else {
				links = fn.gau(".btn_book_read>a");
				chapterIds = links.map(url => url.split("/").at(-2));
			}
			let resArr = [];
			let fetchNum = 0;
			for (let id of chapterIds) {
				let res = fn.j(`/api/book/fixedList2/${id}/?quality=pc`).then(json => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${links.length}`, 0);
					try {
						let arr = [json.coverUrl];
						for (let e of json.chapterList[0].pageList) arr.push(e.publicBgImage);
						return arr;
					} catch (error) {
						console.error(error);
						return [];
					}
				});
				resArr.push(res);
			}
			return Promise.all(resArr).then(data => data.flat());
		},
		button: [4],
		insertImg: ["box", 3],
		customTitle: ".box_data>h1.tit",
		category: "comic"
	}, {
		name: "微漫画 閱讀頁",
		host: ["medibang.com"],
		url: {
			h: "medibang.com",
			p: "/viewer/",
			d: "pc"
		},
		imgs: () => {
			fn.sm5();
			let id = fn.lp.split("/").at(-2);
			return fn.j(`/api/book/fixedList2/${id}/?quality=pc`).then(json => {
				try {
					let arr = [json.coverUrl];
					for (let e of json.chapterList[0].pageList) arr.push(e.publicBgImage);
					return arr;
				} catch (error) {
					console.error(error);
					return [];
				}
			});
		},
		capture: () => _this.imgs(),
		hide: ".mdModal.mdWd1",
		category: "comic"
	}, {
		name: "Rawkuma",
		url: {
			h: "rawkuma.net",
			p: "/chapter-"
		},
		imgs: "[data-image-data] img",
		button: [4],
		insertImg: ["[data-image-data]", 2],
		autoDownload: [0],
		next: "//a[div[p[text()='Next']]][contains(@href,'chapter')]",
		prev: "//a[div[p[text()='Prev']]][contains(@href,'chapter')]",
		chapters: {
			api: () => fn.attr("div[hx-get]", "hx-get"),
			target: "[id^=chapter] a",
			sort: "r"
		},
		customTitle: () => fn.title(" – Rawkuma"),
		category: "comic"
	}, {
		name: "MangaRw",
		host: ["mangarw.com"],
		url: {
			e: "meta[content='漫画 raw']",
			p: "/read",
			s: "id=",
			st: "__INITIAL_STATE__"
		},
		init: () => {
			siteJson = _unsafeWindow.__INITIAL_STATE__;
			return fn.fetchDoc(`/api/v1/chapters?id=${siteJson.mangaId}`).then(dom => (siteJson.chapters = fn.gae("option", dom).reverse()));
		},
		imgs: "#viewer .page-img",
		button: [4],
		insertImg: ["#viewer", 2],
		autoDownload: [0],
		np: (i) => {
			let ci = siteJson.chapters.findIndex(o => o.value == siteJson.chapterId);
			let o = siteJson.chapters[ci + i];
			return isEle(o) ? "/read?id=" + o.value : null;
		},
		next: () => _this.np(1),
		prev: () => _this.np(-1),
		chapters: () => siteJson.chapters.map(o => ({
			text: o.text,
			url: "/read?id=" + o.value
		})),
		checkCurrentChapter: (url) => {
			let cid = fn.getUSP("id");
			let uid = fn.getUSP("id", location.origin + url);
			return cid == uid;
		},
		customTitle: () => {
			let {
				mangaTitle,
				chapterTitle
			} = siteJson;
			return mangaTitle + " - " + chapterTitle;
		},
		category: "comic"
	}, {
		name: "漫画 raw",
		host: ["mangaraw.best"],
		url: {
			e: "img[alt='Manga Raw - 漫画 raw']",
			p: "/raw/"
		},
		imgs: "main>div>nav+div>img",
		button: [4, 4],
		insertImg: ["main>div>nav+div", 2],
		autoDownload: [0],
		next: "//a[button[span[text()='次の章']]][starts-with(@href,'/raw/')]",
		prev: "//a[button[span[text()='前の章']]][starts-with(@href,'/raw/')]",
		chapters: {
			target: "div.absolute:has(>ul>a>li):has(.cursor-pointer) ul a",
			sort: "r"
		},
		customTitle: "main>div>div:nth-of-type(2)",
		category: "comic"
	}, {
		name: "漫画raw/Dokiraw",
		host: ["mangaraw.ad", "dokiraw.onl"],
		url: {
			e: "meta[content='Manga Raw'][name=Author],meta[content=Dokiraw][name=Author]",
			p: "/chapter"
		},
		init: async () => {
			await fn.wait(() => !!fn.gst("comicId"));
			let code = fn.gst("comicId");
			let mid = fn.numVar(code, "comicId");
			return fn.j(`/Comic/Services/ComicService.asmx/ProcessChapterList?comicId=${mid}`).then(json => (siteJson = json));
		},
		box: [".items-center:has(.swiper-vertical)", 2, 1280],
		imgs: ".page-chapter img",
		button: [4, 4],
		insertImg: [
			["box", 0, ".items-center:has(.swiper-vertical)"], 2
		],
		autoDownload: [0],
		np: (i) => {
			let ci = siteJson.chapters.findIndex(({
				url
			}) => url == fn.url);
			let o = siteJson.chapters[ci + i];
			return isObject(o) ? o.url : null;
		},
		next: () => _this.np(-1),
		prev: () => _this.np(1),
		chapters: () => siteJson.chapters.map(({
			name,
			url
		}) => ({
			text: name,
			url
		})).reverse(),
		customTitle: () => fn.title(" RAW"),
		category: "comic"
	}, {
		name: "HachiRAW",
		url: {
			h: ["hachiraw.net"],
			p: "/chapter"
		},
		box: ["#TopPage", 2, 1200],
		imgs: () => fn.getImgSrcArr("#TopPage img").filter(e => e != "https://hachiraw.net/01.png"),
		button: [4],
		insertImg: ["box", 2],
		insertImgAF: () => fn.hideEle("#TopPage"),
		autoDownload: [0],
		current: () => fn.ge("div:has(>.btn-success)"),
		next: () => {
			let next = _this.current()?.previousElementSibling?.firstElementChild;
			return next ? next.href : null;
		},
		prev: () => {
			let prev = _this.current()?.nextElementSibling?.firstElementChild;
			return prev ? prev.href : null;
		},
		chapters: {
			target: "#ChapterModal a",
			sort: "r"
		},
		category: "comic"
	}, {
		name: "comic imgs",
		host: ["www.manhua4.com"],
		url: {
			st: "var imgs",
			e: [".info-title,.con_top", "#content"],
			p: "/manhua/"
		},
		imgs: () => {
			let f = fn.html(_unsafeWindow.imgs.join(""));
			return fn.gae("img", f);
		},
		button: [4],
		insertImg: ["#content", 2],
		autoDownload: [0],
		next: "//a[text()='下一章']",
		prev: "//a[text()='上一章']",
		customTitle: () => {
			let texts = fn.gt(".info-title,.con_top").split(">").map(t => t.trim());
			return texts.at(-2) + " - " + texts.at(-1);
		},
		category: "comic"
	}, {
		name: "九天AD",
		url: {
			e: ["#body-header-top", ".logo-pc", ".logo-moible"]
		},
		hide: "#installContainer",
		category: "ad"
	}, {
		name: "漫畫類 自動展開目錄",
		reg: [
			/(mangabz|xmanhua|yymanhua|dm5|1kkk|manhuaren|manben|mkzhan)\.com\/[\w-]+\//,
			/(m\.dmzj\.com|m\.gmh1234\.com)\/(info|comic)\/\d+\.html$/,
			/(manhua456|xwmanhua|mh160)\.(com|cc)\/(comic|manhua|manga|maga|kanmanhua|szcbook)\/[\w-]+\/?$/,
			/www\.mhua5\.com\/[\w-]+\.html/,
			/m\.guoman\.net\/comic\/\w+/,
			/rumanhua\d?\.\w+\/\w+\/$/i,
			/dumanwu\d?\.\w+\/\w+\/$/i,
			/haoguoman\.net\/\d+$/,
			/^https?:\/\/www\.colamanga\.com\/manga-\w+\/$/
		],
		init: async () => {
			if (isM) {
				if (["xmanhua", "yymanhua"].some(h => fn.lh.includes(h)) && fn.ge("//a[text()='章節']")) {
					EClick("//a[text()='章節']");
				}
			}
			if (fn.lh.includes("haoguoman")) {
				setTimeout(() => {
					EClick(".j-chapter-more");
				}, 1500);
			}
		},
		autoClick: [`
        span.more,
        a.detail-list-form-more,
        a.detail-list-more,
        .deatil-list-more>a,
        .detail-more,
        .moreChapter,
        .show-more,
        a#zhankai,
        .gengduo_dt1>button,
        .morechapter>button,
        .gengduo_dt1>a,
        .chapterList+.more,
        li.add,a.extend,
        a.action-collapse:not(.on),
        .chapter__more .down,
        .listmore,
        .more.chapLiList-cont>a,
        .m-load-more-sm>a,
        .more>a,
        .allmulu,
        .show-more>a,
        .morechp,
        .nnmore>a,
        .chaplist-more>button,
        .website-display-all
        `, 1500],
		hide: ".comic-info-box+a,.cartoon-introduction.cmg,.cartoon-introduction+a,.msloga,.comic_intro>a,.Introduct+a,[class^='ad']",
		category: "none"
	}, {
		name: "94i.in 自動簽到",
		host: ["94i.in"],
		reg: /^https?:\/\/94i\.in\//,
		autoClick: "#pper_a:not([style='display: none;'])",
		category: "none"
	}, {
		name: "Supjav 立即顯示影片縮圖",
		host: ["supjav.com"],
		delay: 300,
		reg: /^https?:\/\/supjav\.com\/(zh\/|ja\/)?\d+\.html/,
		init: async () => {
			let t = fn.ge("title");
			t.innerText = t.innerText.replace(/-\sSupjav.com.+/, "").trim();
			let ele = "#vserver.play-button";
			if (await fn.waitEle(ele)) EClick(ele);
		},
		category: "none"
	}, {
		name: "ouo.io 自動跳轉",
		host: ["ouo.io"],
		reg: /^https?:\/\/ouo\./,
		init: async () => {
			let ele = "#btn-main:not(.disabled)";
			if (await fn.waitEle(ele)) EClick(ele);
		},
		category: "none"
	}, {
		name: "cuty.io 自動跳轉",
		host: ["cuty.io"],
		reg: /^https?:\/\/cutt?y\.(io|app)\/\w+/i,
		init: async () => {
			let ele = "//button[@id='submit-button' and text()= 'Continue' or text()= 'I am not a robot' or text()= 'Go ->']";
			if (await fn.waitEle(ele)) EClick(ele);
		},
		category: "none"
	}, {
		name: "m.4khd.com 自動跳轉",
		host: ["m.4khd.com"],
		enable: 0,
		url: {
			h: "m.4khd.com",
			p: /^\/\w+$|^\/link\/|^\/vip\//i
		},
		init: () => {
			if (fn.ge("#content a[href*='reload']")) {
				return location.reload();
			}
			if (fn.lp.includes("/vip/")) {
				fn.css(FullPictureLoadStyle, "FullPictureLoadMainStyle");
				fn.showMsg("系統錯誤,1秒後關閉。");
				return setTimeout(() => window.close(), 1000);
			}
			const selector = "//a[text()='GET LINK']|//a[span[text()='GET LINK']]";
			if (fn.ge(selector)) {
				let url = fn.gu(selector);
				EClick(selector);
				ge("#cz").innerHTML = "&#9650";
				ge("#zc_tiaozhuan").style.display = "block";
				fn.clearAllTimer(3);
			}
		},
		hide: "#divExoLayerWrapper,.exo-ipp,.exo_wrapper,div:has(>.centered-contai),.center-container,.centered-contai",
		category: "none"
	}, {
		name: "4kup.net 自動跳轉",
		host: ["4kup.net"],
		reg: /^https?:\/\/4kup\.net\/getlink\/$/,
		init: async () => {
			let selectorArr = ["#output:not([style*=none]) button", "#gotolink:not([disabled])"];
			for (let selector of selectorArr) {
				await fn.waitEle(selector);
				EClick(selector);
				await delay(200);
			}
		},
		category: "none"
	}, {
		name: "terabox.fun 自動跳轉",
		host: ["terabox.fun"],
		reg: /^https?:\/\/terabox\.fun\/slmiddlepage\//,
		init: async () => {
			let ele = ".btn.active";
			setInterval(async () => {
				if (await fn.waitEle(ele)) EClick(ele);
			}, 1000);
		},
		category: "none"
	}, {
		name: "MediaFire 自動下載",
		host: ["www.mediafire.com"],
		reg: /^https?:\/\/www\.mediafire\.com\//,
		autoClick: ".download_link:not(.started) #downloadButton",
		category: "none"
	}, {
		name: "anonfiles 自動下載",
		host: ["anonfiles.com"],
		reg: /^https?:\/\/anonfiles\.com\//,
		autoClick: ["#download-url"],
		category: "none"
	}, {
		name: "letsupload 自動下載",
		host: ["letsupload.cc"],
		reg: /^https?:\/\/letsupload\.cc\//,
		autoClick: ["#download-url"],
		category: "none"
	}, {
		name: "stfly.me 半自動跳轉",
		host: ["stfly.me"],
		reg: () => fn.ge("img[src^='https://stfly.me/']") ? true : false,
		init: async () => {
			if (await fn.waitEle(".btn-captcha:not(.disable)")) setInterval(() => EClick(".btn-captcha:not(.disable)"), 3000);
		},
		category: "none"
	}, {
		name: "link1s 自動跳轉",
		host: ["link1s.com"],
		reg: () => fn.ge("a.site-logo[href='https://link1s.com/'],a.logo-image[href='https://link1s.com/']") ? true : false,
		init: async () => {
			if (await fn.waitEle("//button[@onclick='link1sgo()'] | //button[@id='link' and contains(@style,'none')] | //a[text()='Get Link']")) EClick("//button[@onclick='link1sgo()'] | //a[@id='link1s'] | //a[text()='Get Link']");
		},
		category: "none"
	}, {
		name: "Binto.click 自動跳轉",
		host: ["binto.click"],
		reg: () => /^https?:\/\/binto\.click\/\w+$/i.test(siteUrl) && fn.ge("#go-link"),
		init: async () => {
			if (await fn.waitEle("//a[text()='Get Link']")) location.href = fn.gu("//a[text()='Get Link']");
		},
		category: "none"
	}, {
		name: "網址清單新分頁開啟",
		host: ["github.com"],
		reg: [
			/github\.com\/skofkyo\/AutoPager\/tree\/main\/CustomPictureDownload$/,
			/github\.com\/skofkyo\/AutoPager\/blob\/main\/CustomPictureDownload\/README\.md$/
		],
		init: async () => await fn.waitEle(".markdown-body a"),
		openInNewTab: ".markdown-body a[href]:not([target=_blank]):not([id])",
		css: ".markdown-body a{text-decoration:none!important}",
		category: "none"
	}];
	//自定義站點規則結束

	function debug(str, obj = "", title = "debug") {
		console.log(`%c[Full Picture Load] ${title}:`, "color: #000;background-color: #C9FFC9;", str, obj);
	}

	function getType(object) {
		return Object.prototype.toString.call(object).replace("[object ", "")?.replace("]", "");
	}

	function addElement(node, tag, attrs) {
		const elem = document.createElement(tag);
		Object.assign(elem, {
			...attrs
		});
		node.appendChild(elem);
		return elem;
	}

	const hasTouchEvent = ("ontouchstart" in _unsafeWindow);
	const isM = ("ontouchstart" in _unsafeWindow);
	const isMobileDeviceUA = ["Mobi", "Android", "iPhone", "iPad", "iPod", "BlackBerry", "IEMobile", "Opera Mini"].some(d => _unsafeWindow.navigator.userAgent.includes(d));
	const isPC = !isMobileDeviceUA || !("ontouchstart" in _unsafeWindow);
	const isCh = language.includes("zh") || language.includes("TW");
	const isMobileEdge = ["Mobile", "EdgA"].every(t => _unsafeWindow.navigator.userAgent.includes(t));
	const isMobileYandex = ["Mobile", "YaBrowser"].every(t => _unsafeWindow.navigator.userAgent.includes(t));
	const isFirefox = _unsafeWindow.navigator.userAgent.includes("Firefox");
	const isXBrowser = ("mbrowser" in _unsafeWindow) && !!_unsafeWindow?.mbrowser?.GM_xmlhttpRequest;
	const isVia = ("via" in _unsafeWindow) && ("via_gm" in _unsafeWindow);
	const isString = str => getType(str) === "String";
	const isNumber = num => getType(num) === "Number";
	const isBoolean = b => getType(b) === "Boolean";
	const isRegExp = reg => getType(reg) === "RegExp";
	const isObject = obj => getType(obj) === "Object";
	const isArray = arr => getType(arr) === "Array";
	const isSet = set => getType(set) === "Set";
	const isFn = fn => getType(fn).endsWith("Function");
	const isPromise = p => getType(p) === "Promise";
	const isEle = e => getType(e).endsWith("Element") || getType(e) === "DocumentFragment";
	const isVH = (v) => innerWidth > innerHeight ? (v == "H") : (v == "V");
	const isURL = (url) => {
		if ("canParse" in URL) {
			return URL.canParse(url);
		}
		try {
			new URL(url);
			return true;
		} catch {
			return false;
		}
	};
	const cancelDefault = (event) => {
		event.preventDefault();
		event.stopPropagation();
	};
	const _GM_xmlhttpRequest = (() => isFn(GM_xmlhttpRequest) ? GM_xmlhttpRequest : GM.xmlHttpRequest)();
	const _GM_openInTab = (() => isFn(GM_openInTab) ? GM_openInTab : GM.openInTab)();
	const _GM_getValue = (() => isFn(GM_getValue) ? GM_getValue : GM.getValue)();
	const _GM_setValue = (() => isFn(GM_setValue) ? GM_setValue : GM.setValue)();
	const _GM_listValues = (() => isFn(GM_listValues) ? GM_listValues : GM.listValues)();
	const _GM_deleteValue = (() => isFn(GM_deleteValue) ? GM_deleteValue : GM.deleteValue)();
	const _GM_registerMenuCommand = (() => isFn(GM_registerMenuCommand) ? GM_registerMenuCommand : GM.registerMenuCommand)();
	const _GM_unregisterMenuCommand = (() => isFn(GM_unregisterMenuCommand) ? GM_unregisterMenuCommand : GM.unregisterMenuCommand)();
	const _GM_getResourceText = (() => isFn(GM_getResourceText) ? GM_getResourceText : GM.getResourceText)();
	const _GM_addElement = (() => {
		try {
			return GM_addElement;
		} catch {
			return addElement;
		}
	})();

	const UI_zIndex = Number(_GM_getValue("UI_zIndex", 2147483647));
	const pageViewMode = _GM_getValue("pageViewMode", 0);

	const JSZip_code = _GM_getResourceText("JSZip_code");
	const ajaxHookerJS = _GM_getResourceText("ajaxHookerJS");
	const CryptoJS_code = _GM_getResourceText("CryptoJS_code");
	const JqueryJS = _GM_getResourceText("JqueryJS");
	const FancyboxV6JS = _GM_getResourceText("FancyboxV6JS");
	const FancyboxV6Css = _GM_getResourceText("FancyboxV6Css");
	const FancyboxV5JS = _GM_getResourceText("FancyboxV5JS");
	const FancyboxV5Css = _GM_getResourceText("FancyboxV5Css");
	const FancyboxV3JS = _GM_getResourceText("FancyboxV3JS");
	const FancyboxV3Css = _GM_getResourceText("FancyboxV3Css");
	const ViewerJs = _GM_getResourceText("ViewerJs");
	const ViewerJsCss = _GM_getResourceText("ViewerJsCss");

	const addJSZipLibrary = () => {
		if (_unsafeWindow?.JSZip?.version !== "3.10.1") {
			_GM_addElement(document.body, "script", {
				textContent: JSZip_code
			});
		}
		return _unsafeWindow.JSZip;
	};

	const addAjaxHookerLibrary = () => {
		if (!("ajaxHooker" in _unsafeWindow)) {
			_GM_addElement(document.body, "script", {
				textContent: ajaxHookerJS
			});
		}
		return _unsafeWindow.ajaxHooker;
	};

	const addCryptoJSLibrary = () => {
		if (!("CryptoJS" in _unsafeWindow)) {
			_GM_addElement(document.body, "script", {
				textContent: CryptoJS_code
			});
		}
		return _unsafeWindow.CryptoJS;
	};

	const addLibrarysV3 = async () => {
		try {
			const jsArr = [JqueryJS, FancyboxV3JS];
			for (let [i, code] of jsArr.entries()) {
				if (i == 0 && ("jQuery" in _unsafeWindow)) continue;
				_GM_addElement(document.body, "script", {
					textContent: code
				});
			}
			if ("fancybox" in siteData && siteData?.fancybox?.css !== false) {
				fn.css(FancyboxV3Css, "FancyboxV3Css");
			}
		} catch (error) {
			console.error("\naddLibrarysV3() 注入函式庫失敗", error);
		}
	};

	const addLibrarysV6 = () => {
		try {
			const jsArr = [JqueryJS, FancyboxV6JS];
			for (let [i, code] of jsArr.entries()) {
				if (i == 0 && ("jQuery" in _unsafeWindow)) continue;
				if (i == 1 && ("Fancybox" in _unsafeWindow)) return;
				_GM_addElement(document.body, "script", {
					textContent: code
				});
			}
			fn.css(FancyboxV6Css, "FancyboxV6Css");
		} catch (error) {
			console.error("\naddLibrarysV6() 注入函式庫失敗", error);
		}
	};

	const FancyboxWheelValue = _GM_getValue("FancyboxWheel", 1);
	let FancyboxWheel;
	if (FancyboxWheelValue == 0) {
		FancyboxWheel = "zoom";
	} else {
		FancyboxWheel = "slide";
	}
	const FancyboxIdle = _GM_getValue("FancyboxIdle", 0) == 0 ? false : (Number(_GM_getValue("FancyboxIdle", 0)) * 1000);
	const FancyboxSlideshowTimeout = Number(_GM_getValue("FancyboxSlideshowTimeout", 3));
	const FancyboxSlideshowTimeoutNum = FancyboxSlideshowTimeout == 0 ? 500 : (FancyboxSlideshowTimeout * 1000);
	const FancyboxSlideshowTransition = _GM_getValue("FancyboxSlideshowTransition", "fade");
	const FancyboxShowThumbs = _GM_getValue("FancyboxShowThumbs", 0) == 1 ? true : false;
	const FancyboxThumbnails = _GM_getValue("FancyboxThumbnails", "modern");
	const FancyboxAutoClose = _GM_getValue("FancyboxAutoClose", 0);
	const FancyboxAutoNext = _GM_getValue("FancyboxAutoNext", 0);

	let isOpenFancybox = false;
	let slideIndex = null;

	const FancyboxOptions = {
		Hash: false,
		idle: FancyboxIdle,
		fadeEffect: false,
		zoomEffect: false,
		showClass: false,
		hideClass: false,
		wheel: FancyboxWheel,
		mainStyle: {
			"--fancybox-backdrop-bg": "rgba(0, 0, 0, .96)",
			"--f-toolbar-padding": "0px"
		},
		Carousel: {
			transition: FancyboxSlideshowTransition,
			Autoplay: {
				autoStart: false,
				timeout: FancyboxSlideshowTimeoutNum,
			},
			Thumbs: {
				type: FancyboxThumbnails,
				showOnStart: FancyboxShowThumbs,
			},
			Toolbar: {
				display: {
					left: ["counter"],
					right: ["flipX", "flipY", "iterateZoom", "autoplay", "thumbs", "close"]
				}
			},
			breakpoints: {
				"(min-width: 768px)": {
					Toolbar: {
						display: {
							left: ["counter"],
							middle: ["zoomIn", "zoomOut", "iterateZoom", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY", "reset"],
							right: ["autoplay", "fullscreen", "thumbs", "close"]
						}
					}
				}
			}
		},
		on: {
			ready: (ref) => {
				isOpenFancybox = true;
				slideIndex = ref.getSlide().index;
				fn.scrollEvent(slideIndex);
			},
			"Carousel.change": (ref) => {
				const index = ref.getSlide().index;
				if (index == 0 && ref.getCarousel().getPages().at(-1).index == slideIndex) {
					if (FancyboxAutoClose == 1) {
						ref.close();
					}
					if (FancyboxAutoNext == 1) {
						if (!!nextLink) {
							fn.showMsg(DL.str_34.n);
							setTimeout(() => (location.href = nextLink), 100);
						}
					}
				}
				slideIndex = index;
				fn.scrollEvent(slideIndex);
			},
			close: (ref) => {
				document.body.classList.remove("imgbox-show", "hide-scrollbar");
				slideIndex = ref.getSlide().index;
				fn.scrollEvent(slideIndex);
				setTimeout(() => {
					isOpenFancybox = false;
				}, 100);
			}
		}
	};

	const fancyboxBlackList = () => siteData.fancybox?.blacklist === 1;

	const icon = {
		main: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAACFlBMVEVEREAAAABEREBEREBUXnFTXXBTXG5VXXJUXHFUW28grV0grV0hrl4hrV0hq10iql0oomAhrV2BiZiAiJd/h5V+h5Uiq16OlaKNlKGMk5+Mkp+KkZ89p28nq2Hp9+/n9u3t8PHs7/Dg9Ojp7O3d8+bo7O3o6+zn6+3m6uzl6evX8OLV8OHi5ujh5efO7dze4uTe4ePb3+LY3eDX29/W2t7T19u35Mu25Mr01lqw4sbz1Vmv4sXA1NWs4cPw0lnv0lmp4MCk3r3ozVuh3buu0M6vz83kylugysefycadx8OexsOdxsOF0qZ6zp5pyJK1p2S0pmOsoGRWv4SLlKEmuZpBsnc5t3AmuJmQi2ont5kmtpcptJiOiWg0tWwytGorr5Yqr5YsrpUws2kqrJRNmpMusmcsqpIuqJMssWkqsWQqsGUnsGUzoI8lsGGAf2wkr2Ekr2BzfI0irl8hrl5ye4x9fGogrWAhrV03mIwgrF9xeoshq10gql8dp2ccp2cdpmkcnIUanIYcm4QRoIUTnoURn4QdmYM/h4QcmIMSnYMXmoMWmoIbloIclYJDgYIYl4EaloAek4IfkYFqbm0jjoBqbW0ni4ApiX9Hd35kanBjaXBhaG9MbnpOanhOaXhPaHdDbXZHanZGanRLZnZJZ3RSYnVMZXRPY3ROY3VSYXRQYnRTYHRVX3NUX3RSYHNUXnNTXXJTXXFME6frAAAAHnRSTlMAAAUGZ2dqeHh7lrzNzc7O3O/09PT19fn5+fn5/f4hZOrvAAAB1UlEQVR42oWTzYoTQRSFv6q6RqOoqBicTTCKK1cOURBGBV9AXCgu9Vl8FF/ApcshI4qKgrtBByZK0HSGmMxkMrF/qq6LTjptErGX5zu3uu65dY3TYCh9ag2UNPsfjnmpZW4MgBbaIy/6PCnxvL7gEQhJ7AruAqifcZ96EHDX67ngKgCJn/k3B6AC1O9Cj9ri/2mBsZIf9iLi0rMFDhhjbO6NsL9er+CQG3pYMT+XuGVmuH9SzPF7S/UONDfUHl44/6A24wfdpMgsSO6tP52ffxjF6cUT056MBdxf/cVRzP6PiQG8KhZMJedhewik0QT43RsBQUEwLufZx53Td85p7wCwEu+Fs6qAGBsA1aO3XUZbG/EAsAJJlM/MGgOoDltdYNTam3JIOlVmOaj2N/sAjHf9lGdBqwACmmi0FU/TOWxfEY483o/9tcuvJBXU+90PaZHf5NtVFzTL+N7bqD4GS9DRmzl3btJWk2WFIKradqX8LfudU3VKBuKd0vwc+HCjNDJhkJXfB6jq+wZJBSAT5MmKN1/la7sJ+jmsiyQrdkZo9N819FNnXcSZFTt1rGnXhl/G6a26IP/YOXczi5prQmFY3snbkzNSXGyBV+28p+nNF+vn2h97PvHD5SOHkgAAAABJRU5ErkJggg==",
		eye: "data:image/webp;base64,UklGRsYDAABXRUJQVlA4WAoAAAAQAAAAHwAAHwAAQUxQSOAAAAABgBxJkiIpB6q6l587iuzxabKgwzEKwyzI4H8ZBcGBLg0iYgKYkGkfP/4Go1H493yukJOQrq/m65zzK52VbvWW64KLrpVLvawNfpdzeOHaaOBlaH9tOCmnWB9r478WCOitBTvE0AuJVYNxtRa9ZmsqM+PjtfDBo9Tdr9RXJBUMpPpysVTwL/X1LHV3LtXiqczMwpXMBaDnEjMFoCvRBgDr3dwbUrVvKi4DBABeYMZvAsR7UC8mvkoAcRqszrzIvA2AOAtUv57mmVwoAMTMlEbMzAd33/5g4H/ftSwAIGYmAFZQOCDAAgAAEBAAnQEqIAAgAD4pEIZCIaEMAgAMAUJbACdMoR1B4B+Lv43c+fq53mw0f9VtBm4A/gH+G/U32K9Qd9ADyvfYV/bn0c6PJj4f4CaU2oLHX/pPTTzMfQn/T/tnwB/xj+b/6L+v9TN7Ef7DsCGa+ST6lWtII1sP5556JMwBiQJ/v6G3hkIztqj0FNAA/vZ/+/+APed/uyjSeg9KUi2ZJZ80f4rCO/pikd6rMSCxHotqPS5q30sTLG32jT2xL9EP7/Xb/bMDGn9F++qv+ycP9T2DMPkrD0s9qwMd/2j/XP7/Dcp90+EUo/kENdISaKoAQ2+YjgTMW/+yoiirvPEEC//dYC/9r0UY3/+3+9pz/4Zdbayk0o15hBW75xf0fGctvz//O9q5NnQ7iqZitP0iHE5aqz1J0Pc/mFu0FU1LccFZIs3xzolGgtlMMFc9+/RX6lt5WKP+bzc+/5uPB8tUv0LEVXizp2tTzmerN7LhLBt0HVdPFKSItp97AEATujh3YSWiHHzc283n9fbywZxk6NReo2r/rj1oK/oT+4aRH7tYjCyPO2wNr7pqf5BMjAeu6aW3aLSDwAK0rtgvAAivRIDkPyvvGW17Qcz3GBvk6rE95m1KWLi7WU+ufL9MMlCx1A8JYz9lerDLrsz9skvA43mZ0lrkQc9fk2Dc5zyr+LT5DPfJqflpiCbZz7dHDkicQZ/2v13TDxv37Mfl+AuHXhzSWT/bBv5KUsR1kQfqUwy74AYmKSP0qgK3ddqA5kiG1T8M1Arj4wcj44OP/wmIGJ6eeT1p+h9VrjkpeDCsgLAsBSIEovVqLIykoUZzsuPRKSVLIT+rIpbJOoa/jLr+J7KVmJ0sT5KDWPRNgbuveXc79pTjxVfGKjK9n+D9xMq24eUJRbnUDt/+c1oGsHfLUBzIh1k5W0owA4YVXvw4kC4AAAA=",
		arrow_u: "data:image/webp;base64,UklGRgADAABXRUJQVlA4WAoAAAAQAAAAHwAAHwAAQUxQSLkAAAABcFRbW+P86XHAIAIXaYiaHQZSwUtWPVHQWA4Kpq17+xxEBAO3jRQly3z4CGpxJs3FxrG9GDmjHnIdZS1GmncxV2nWYarmrXjvrIdvrwXhsl460Sy7rKeuXpy/s96+5xUqA1RExFOElBPpDFLTLMKIZjIDlQbFXFAuFsXGKDEOXsGH4AvhzwV/rqQxTuh7FTP0vfTR9/o+Bb+LgIHfVSDA7/LOsO869qfQfyE8tbR2/1eiz3m7mFBTAgBWUDggIAIAANAPAJ0BKiAAIAA+KRCGQiGhDAYCAAwBQlsAJ0yhHUHjH4m8yrri2Gcbckf2T7dO0B4kf+H6gHmA/gH95/UDhAP0g6wD0AP1u9L39nfgl/bv9Y/gA/Vi5QVyf87zgDnl83Lst7gn6a/7ngGv1VW9p+Rh0pxS4KW/dJDUMojJnr/eXdEyp+UXAAD++l+HpOrnOlx8/3Z79rD/mI7hsW4/QzMD4K4o41SOI6blpRqcf1qzeftffrK+tmr8dvSn/2uOQNHhgAx/xLX/NT5bvwlMsuugVpIRsfc//0W32hw5yLS7ehfC9eaOnHVCEFrD87xU+jwfUc3eVqB/qqcgev1LUCGhnQ8YZSOKdke0ezKbjIDXDo9WXtx9hh3EeRDdV7fv+7p0HyIv/+18StHi/gRaKiY2x1/BoTHQpQ5ymbck9eq6ZNo6HDde13uuG91GM53rKampWEGx84+9+wGWkPwvz9aQ6vhD14RFT3xPkz6gNGSd8SddraNbqt7grkynplAu24w36/q2UH6WJ3B28Fmu2B8rpirsg1B9PAaovgu1lD16Lk07Ro48qLlrYzZ7NN6/zL311srnNR+xVZX6yaZ/f+Vi1s6UN//8RNhJQg+ekdltTyX61Vdf7F1t6H/ELMEuHXSJ2EPRPgAB9mSK4WnYYAyflSeeeUUagqp8/agKBcIsKZWSU3+PfhbOj839Qmr+B2xWBXlY1Rcwhho1tXgAAAA=",
		top: "data:image/png;base64,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",
		loading: {
			m: "data:image/webp;base64,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",
			g: "data:image/gif;base64,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",
			a: "data:image/webp;base64,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"
		},
	};

	let loading_bak = icon.loading.m;
	let bunny_girl_loading_bak = icon.loading.g;
	let autoPagerLoading_gif = icon.loading.a;

	const svg = {
		control: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M398.933333 202.666667v170.666666h-170.666666v-170.666666h170.666666m21.333334-85.333334h-213.333334c-36.266667 0-64 27.733333-64 64v213.333334c0 36.266667 27.733333 64 64 64h213.333334c36.266667 0 64-27.733333 64-64v-213.333334c0-34.133333-29.866667-64-64-64zM398.933333 629.333333v170.666667h-170.666666v-170.666667h170.666666m21.333334-85.333333h-213.333334c-36.266667 0-64 27.733333-64 64v213.333333c0 36.266667 27.733333 64 64 64h213.333334c36.266667 0 64-27.733333 64-64v-213.333333c0-34.133333-29.866667-64-64-64zM825.6 202.666667v170.666666h-170.666667v-170.666666h170.666667m21.333333-85.333334h-213.333333c-36.266667 0-64 27.733333-64 64v213.333334c0 36.266667 27.733333 64 64 64h213.333333c36.266667 0 64-27.733333 64-64v-213.333334c0-34.133333-29.866667-64-64-64zM740.266667 885.333333c-23.466667 0-42.666667-19.2-42.666667-42.666666v-256c0-23.466667 19.2-42.666667 42.666667-42.666667s42.666667 19.2 42.666666 42.666667v256c0 23.466667-19.2 42.666667-42.666666 42.666666z"></path><path d="M868.266667 757.333333h-256c-23.466667 0-42.666667-19.2-42.666667-42.666666s19.2-42.666667 42.666667-42.666667h256c23.466667 0 42.666667 19.2 42.666666 42.666667s-19.2 42.666667-42.666666 42.666666z"></path></svg>',
		home: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M946.56 504.96L560.064 118.848l-25.92-25.856a31.488 31.488 0 0 0-44.416 0L77.504 504.96a63.936 63.936 0 0 0-18.816 45.952c0.384 35.2 29.696 63.36 64.896 63.36h42.496v325.632h691.84V614.272h43.392a63.68 63.68 0 0 0 45.312-18.752c12.096-12.16 18.688-28.16 18.688-45.312a63.616 63.616 0 0 0-18.816-45.184z m-378.56 363.072h-112v-204.032h112v204.032z m217.92-325.76v325.76H632V640a40 40 0 0 0-40-40h-160a40 40 0 0 0-40 40v228.032H238.08v-325.76h-96l370.048-369.664 23.04 23.04 346.88 346.624H785.92z"></path></svg>',
		heart: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M529.066667 910.933333c-10.666667 0-21.333333-4.266667-29.866667-12.8L172.8 571.733333c-93.866667-93.866667-93.866667-247.466667 0-343.466666 93.866667-93.866667 247.466667-93.866667 343.466667 0l12.8 12.8 12.8-12.8c93.866667-93.866667 247.466667-93.866667 343.466666 0 44.8 44.8 70.4 106.666667 70.4 170.666666s-25.6 125.866667-70.4 170.666667L558.933333 898.133333c-8.533333 8.533333-19.2 12.8-29.866666 12.8z m-183.466667-667.733333c-42.666667 0-81.066667 17.066667-110.933333 46.933333-61.866667 61.866667-61.866667 160 0 221.866667l294.4 294.4L825.6 512c29.866667-29.866667 46.933333-68.266667 46.933333-110.933333s-17.066667-81.066667-46.933333-110.933334c-29.866667-29.866667-68.266667-46.933333-110.933333-46.933333s-81.066667 17.066667-110.933334 46.933333l-42.666666 42.666667c-17.066667 17.066667-42.666667 17.066667-59.733334 0l-42.666666-42.666667c-32-29.866667-72.533333-46.933333-113.066667-46.933333z"></path></svg>',
		download: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M168 660.032a16 16 0 0 1 16 14.72v133.248h659.008v-132.032a16 16 0 0 1 16-16h64a16 16 0 0 1 16 16v164.032a64 64 0 0 1-62.72 64H152a64 64 0 0 1-64-62.72v-165.312a16 16 0 0 1 16-16h64z m379.648-564.8a16 16 0 0 1 14.72 15.168v364.352l128.64-127.68a16 16 0 0 1 19.2-2.56l3.328 2.56 45.248 45.312 1.408 1.536a16 16 0 0 1-1.408 21.12L538.24 634.048l-0.192-0.192-9.344 9.472a16 16 0 0 1-18.944 2.752l-3.392-2.56-126.72-120.768a16 16 0 0 1-0.192-0.192L268.224 416.512a16 16 0 0 1-0.64-22.528l43.648-46.848a16 16 0 0 1 22.656-0.832l132.48 124.8V111.168l0.128-1.216a16 16 0 0 1 15.104-14.72z"></path></svg>',
		list: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M853.333333 218.666667a37.333333 37.333333 0 0 1 3.072 74.538666L853.333333 293.333333H362.666667a37.333333 37.333333 0 0 1-3.072-74.538666L362.666667 218.666667h490.666666zM853.333333 474.666667a37.333333 37.333333 0 0 1 3.072 74.538666L853.333333 549.333333H362.666667a37.333333 37.333333 0 0 1-3.072-74.538666L362.666667 474.666667h490.666666zM853.333333 730.666667a37.333333 37.333333 0 0 1 3.072 74.538666L853.333333 805.333333H362.666667a37.333333 37.333333 0 0 1-3.072-74.538666L362.666667 730.666667h490.666666z"></path><path d="M202.666667 256m-53.333334 0a53.333333 53.333333 0 1 0 106.666667 0 53.333333 53.333333 0 1 0-106.666667 0Z"></path><path d="M202.666667 512m-53.333334 0a53.333333 53.333333 0 1 0 106.666667 0 53.333333 53.333333 0 1 0-106.666667 0Z"></path><path d="M202.666667 768m-53.333334 0a53.333333 53.333333 0 1 0 106.666667 0 53.333333 53.333333 0 1 0-106.666667 0Z"></path></svg>',
		gear: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M992.6 404.1 897.9 404.1C889.2 372.8 876.9 343.1 861.3 315.4L928.2 248.5C940.4 236.3 940.4 216.3 928.2 204L820 95.9C813.9 89.8 805.8 86.7 797.8 86.7 789.8 86.7 781.7 89.8 775.6 95.9L708.7 162.8C681 147.2 651.3 134.9 620 126.2L620 31.4C620 14.1 605.8 0 588.6 0L435.6 0C418.3 0 404.2 14.2 404.2 31.4L404.2 126.1C372.9 134.8 343.2 147.1 315.5 162.7L248.6 95.8C242.5 89.7 234.4 86.6 226.4 86.6 218.4 86.6 210.3 89.7 204.2 95.8L95.9 204C83.7 216.2 83.7 236.2 95.9 248.5L162.8 315.4C147.2 343.1 134.9 372.8 126.2 404.1L31.4 404.1C14.2 404.1 0 418.3 0 435.6L0 588.5C0 605.8 14.2 619.9 31.4 619.9L126.1 619.9C134.8 651.2 147.1 680.9 162.7 708.6L95.8 775.5C83.6 787.7 83.6 807.7 95.8 820L204 928.1C210.1 934.2 218.2 937.3 226.2 937.3 234.2 937.3 242.3 934.2 248.4 928.1L315.3 861.2C343 876.8 372.7 889.1 404 897.8L404 992.5C404 1009.8 418.2 1023.9 435.4 1023.9L588.3 1023.9C605.6 1023.9 619.7 1009.7 619.7 992.5L619.7 897.8C651 889.1 680.7 876.8 708.4 861.2L775.3 928.1C781.4 934.2 789.5 937.3 797.5 937.3 805.5 937.3 813.6 934.2 819.7 928.1L928.1 820C940.3 807.8 940.3 787.8 928.1 775.5L861.2 708.6C876.8 680.9 889.1 651.2 897.8 619.9L992.5 619.9C1009.8 619.9 1023.9 605.7 1023.9 588.5L1023.9 435.6C1024 418.3 1009.9 404.1 992.6 404.1L992.6 404.1ZM960 555.9 897.8 555.9 849.2 555.9 836.1 602.7C828.8 629 818.4 654.1 805.4 677.2L781.5 719.5 815.9 753.9 859.8 797.8 797.7 859.9 753.8 816 719.4 781.6 677.1 805.5C654 818.5 628.9 828.9 602.6 836.2L555.8 849.3 555.8 897.9 555.8 960 468 960 468 897.8 468 849.2 421.2 836.1C394.9 828.8 369.8 818.4 346.7 805.4L304.4 781.5 270 815.9 226.1 859.8 164 797.7 207.9 753.8 242.3 719.4 218.4 677.1C205.4 654 195 628.9 187.7 602.6L174.6 555.8 126 555.8 64 555.8 64 468 126.2 468 174.8 468 187.9 421.2C195.2 394.9 205.6 369.8 218.6 346.7L242.5 304.4 208.1 270 164.2 226.1 226.3 164 270.2 207.9 304.6 242.3 346.9 218.4C370 205.4 395.1 195 421.4 187.7L468.2 174.6 468.2 126 468.2 64 556 64 556 126.2 556 174.8 602.8 187.9C629.1 195.2 654.2 205.6 677.3 218.6L719.6 242.5 754 208.1 797.9 164.2 860 226.3 816.1 270.2 781.7 304.6 805.6 346.9C818.6 370 829 395.1 836.3 421.4L849.4 468.2 898 468.2 960 468.2 960 555.9 960 555.9Z"></path><path d="M512 320C406 320 320 406 320 512 320 618 406 704 512 704 618 704 704 618 704 512 704 406 618 320 512 320L512 320ZM512 640C477.8 640 445.7 626.7 421.5 602.5 397.3 578.3 384 546.2 384 512 384 477.8 397.3 445.7 421.5 421.5 445.7 397.3 477.8 384 512 384 546.2 384 578.3 397.3 602.5 421.5 626.7 445.7 640 477.8 640 512 640 546.2 626.7 578.3 602.5 602.5 578.3 626.7 546.2 640 512 640Z"></path></svg>',
		arrow: '<svg class="icon" fill="currentColor" viewBox="0 0 512 512"><path d="M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z"></path></svg>',
		plus: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M1024 432v160c0 8.8-7.2 16-16 16H624c-8.8 0-16 7.2-16 16v384c0 8.8-7.2 16-16 16H432c-8.8 0-16-7.2-16-16V624c0-8.8-7.2-16-16-16H16c-8.8 0-16-7.2-16-16V432c0-8.8 7.2-16 16-16h384c8.8 0 16-7.2 16-16V16c0-8.8 7.2-16 16-16h160c8.8 0 16 7.2 16 16v384c0 8.8 7.2 16 16 16h384c8.8 0 16 7.2 16 16z"></path></svg>',
		minus: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M1024 432v160c0 8.8-7.2 16-16 16H16c-8.8 0-16-7.2-16-16V432c0-8.8 7.2-16 16-16h992c8.8 0 16 7.2 16 16z"></path></svg>',
		reset: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M860.138659 410.730667l157.610667 0L1017.749326 130.389333l-86.378667 82.133333C838.655992 83.797333 687.594659 0 516.991992 0 234.901326 0 6.250659 228.949333 6.250659 511.381333c0 282.453333 228.650667 511.402667 510.741333 511.402667 246.613333 0 452.416-175.04 500.224-407.808L859.370659 614.976c-44.373333 147.306667-180.821333 254.634667-342.378667 254.634667-197.568 0-357.76-160.384-357.76-358.229333 0-197.824 160.170667-358.208 357.76-358.208 127.061333 0 238.250667 66.56 301.674667 166.528l-95.701333 91.008L860.138659 410.709333z"></path></svg>',
		x: '<svg class="icon" fill="currentColor" viewBox="0 0 1024 1024"><path d="M842.947 778.117l-266.1-266.104 266.1-266.13c8.675-8.674 13.447-20.208 13.439-32.478-0.009-12.232-4.773-23.715-13.415-32.332-8.655-8.678-20.15-13.45-32.385-13.457-12.286 0-23.808 4.771-32.474 13.434L512.019 447.144 245.882 181.05c-8.663-8.663-20.175-13.434-32.416-13.434-12.24 0-23.752 4.77-32.414 13.432-8.66 8.637-13.43 20.125-13.438 32.357-0.008 12.27 4.764 23.804 13.438 32.477l266.135 266.13L181.05 778.118c-8.664 8.663-13.436 20.173-13.436 32.415 0 12.24 4.773 23.753 13.438 32.418 8.662 8.663 20.173 13.432 32.413 13.432 12.24 0 23.754-4.77 32.416-13.432L512.015 576.85l266.102 266.1c8.663 8.664 20.186 13.433 32.443 13.433 12.265-0.008 23.749-4.771 32.369-13.412 17.887-17.89 17.893-46.98 0.018-64.854z"></path></svg>',
		imageError: 'data:image/svg+xml;base64,PHN2ZyBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMjggODMyVjUxMmg2NHYxNDYuNzUybDE5Mi0xOTJMNzQ5LjI0OCA4MzJIODMyVjE5Mkg1MTJWMTI4aDMyMGE2NCA2NCAwIDAgMSA2NCA2NHY2NDBhNjQgNjQgMCAwIDEtNjQgNjRIMTkyYTY0IDY0IDAgMCAxLTY0LTY0eiBtMjU2LTI3NC43NTJsLTE5MiAxOTJWODMyaDQ2Ni43NTJMMzg0IDU1Ny4yNDh6IiBmaWxsPSIjMDAwMDAwIiBmaWxsLW9wYWNpdHk9Ii44NSI+PC9wYXRoPjxwYXRoIGQ9Ik03NjggMzg0YTEyOCAxMjggMCAxIDEtMjU2IDAgMTI4IDEyOCAwIDAgMSAyNTYgMHogbS02NCAwYTY0IDY0IDAgMSAwLTEyOCAwIDY0IDY0IDAgMCAwIDEyOCAwek00MDIuMDQ4IDM1NS44NGwtNDUuMjQ4IDQ1LjE4NC05MC40OTYtOTAuNDk2LTkwLjQ5NiA5MC40OTYtNDUuMzEyLTQ1LjI0OCA5MC41Ni05MC40OTYtOTAuNTYtOTAuNDk2IDQ1LjMxMi00NS4yNDhMMjY2LjI0IDIyMC4wMzJsOTAuNDk2LTkwLjQ5NiA0NS4yNDggNDUuMjQ4LTkwLjQ5NiA5MC40OTYgOTAuNDk2IDkwLjQ5NnoiIGZpbGw9IiMwMDAwMDAiIGZpbGwtb3BhY2l0eT0iLjg1Ij48L3BhdGg+PC9zdmc+'
	};

	//顯示語言
	switch (language) {
	case "TW":
	case "zh-TW":
	case "zh-HK":
	case "zh-MO":
	case "zh-Hant-TW":
	case "zh-Hant-HK":
	case "zh-Hant-MO":
		DL = {
			xchina_picnum_error: "圖片數量不符,請反饋。",
			str_00: "語言",
			str_01: "獲取圖片元素中...",
			str_02: "獲取圖片中 ",
			str_03: "獲取圖片逾時",
			str_04: "等待關鍵元素中...",
			str_05: "獲取資料中...",
			str_06: "獲取資料中 ",
			str_07: "確認登錄狀態中...",
			str_08: "獲取預覽圖中...",
			str_09: "獲取最後一張圖...",
			str_10: "是否複製連結至剪貼簿?",
			str_11: "已複製連結至剪貼簿",
			str_12: "只有複製連結功能",
			str_13: "請輸入圖片抓取最大次數",
			str_14: "獲取下一頁中...",
			str_15: "獲取下一頁結束",
			str_16: "獲取元素中...",
			str_17: "獲取元素中 ",
			str_18: "已聚集所有圖片",
			str_19: "用來定位插入的元素不存在",
			str_20: "沒有能插入的圖片",
			str_21: "延遲",
			str_22: "毫秒",
			str_23: "第",
			str_24: "張下載",
			str_25: "完成",
			str_26: "錯誤",
			str_27: "下載失敗了",
			str_28: "張",
			str_29: "\n是否只保存目前下載成功的圖片?\n只要圖片不是100%掛掉,可以調低下載線程數或重新載入網頁後重新下載試試看,網站如有Cloudflare防火牆,需要自行取得Cookie,使用Set Cloudflare Clearance Cookies填入或更新Cookie。",
			str_30: "圖片extension錯誤",
			str_31: "壓縮進度: ",
			str_32: "自動下載倒數",
			str_33: "秒",
			str_34: {
				n: "nextJS前往下一頁",
				p: "prevJS前往上一頁"
			},
			str_35: "已點擊下一頁",
			str_36: "自動下載完畢",
			str_37: "沒有下一頁元素",
			str_38: "返回上一頁",
			str_39: "已點擊上一頁",
			str_40: "沒有上一頁元素",
			str_41: "已取消",
			str_42: "字數小於3已取消",
			str_43: "下載失敗數據為空...",
			str_44: "沒有任何圖片元素...",
			str_45: "網址已複製",
			str_46: "即將進行滾動...",
			str_47: "左鍵:進行下載打包壓縮\n中鍵:匯出網址URLs.txt文件\n右鍵:複製圖片網址和標題或手動模式聚集所有圖片",
			str_48: "下載&壓縮中請稍後再操作!",
			str_49: "獲取圖片中請稍後再操作!",
			str_50: "自訂網站收藏的網址在新分頁開啟",
			str_51: "請輸入自訂壓縮檔資料夾名稱",
			str_52: "聚圖數量",
			str_53: "圖片繪製中...",
			str_54: "403,未登錄網站?",
			str_55: "下載載入中...",
			str_56: "確認圖片狀態中...",
			str_57: "自動翻頁載入中...",
			str_58: "已到達最後一頁",
			str_59: "沒有任何主體元素",
			str_60: "圖片縮放",
			str_61: "取消縮放",
			str_62: "前往第一張圖",
			str_63: "左鍵:前往最後一張圖\n右鍵:匯出網址URLs.txt文件",
			str_64: "即將開始自動下載!!!",
			str_65: "已停止自動下載!!!",
			str_66: "💬 Greasy Fork 反饋",
			str_67: "⚙️ 設定",
			str_68: "當前(※全局)網站選項",
			str_69: "顯示左下圖示按鈕",
			str_70: "最大線程數:",
			str_71: "下載後壓縮打包",
			str_72: "壓縮檔副檔名:",
			str_73: "自動下載",
			str_74: "ESC鍵:可中斷自動下載\n快捷鍵 [ ctrl + . ]:開始自動下載或取消自動下載",
			str_75: "自動下載倒數秒數:",
			str_76: "啟用當前漫畫站點規則",
			str_77: "自動進入畫廊需點擊主圖示按鈕",
			str_78: "Fancybox&Viewer燈箱功能",
			str_79: "頁面容器圖片縮放比例:",
			str_80: "頁面容器圖片並排數量:",
			str_81: "comic類固定為2,comic類並排後為右至左的漫讀模式,hcomic類也設定為2將套用。",
			str_82: isM ? "取消" : "取消 (Esc)",
			str_83: "重置設定",
			str_84: "保存設定",
			str_85: isM ? "腳本選項" : "腳本選項(*)",
			str_86: isM ? "切換模式" : "切換模式(5)",
			str_87: isM ? "比例縮放" : "比例縮放(-+)",
			str_88: isM ? "取消縮放" : "取消縮放(.)",
			str_89: "暫停自動翻頁",
			str_90: "啟用自動翻頁",
			str_91: "初始化設定",
			str_92: "原始模式",
			str_93: "並排模式",
			str_94: "返回開頭了",
			str_95: "前往下一集",
			str_96: "已是最後一集",
			str_97: "共",
			str_98: "頁獲取出錯,建議反饋",
			str_99: "重試第",
			str_100: "次",
			str_101: "網址.txt已匯出",
			str_102: "格式轉換中...",
			str_103: "頁面容器預設使用並排模式",
			str_104: isM ? "匯出圖址" : "匯出圖址(7)",
			str_105: isM ? "複製圖址" : "複製圖址(1)",
			str_106: isM ? "分頁畫廊" : "分頁畫廊(8)",
			str_107: isM ? "一鍵下載" : "一鍵下載(3)",
			str_108: "※ 訊息提示顯示的位置:",
			str_109: {
				c: "置中",
				ul: "左上",
				ur: "右上",
				ll: "左下",
				lr: "右下",
			},
			str_110: "WEBP轉換為JPG",
			str_111: "匯出",
			str_112: "提示",
			str_113: "滾動煞車:",
			str_114: "E/Ex-Hentai 載入原始圖片連結",
			str_115: "自動滾動至首張圖片",
			str_116: "自動滾動所有惰性載入的圖片元素",
			str_117: "顯示浮動選單",
			str_118: "圖集標題已更新",
			str_119: "Fancybox空閒逾時隱藏UI(秒)",
			str_120: "分頁畫廊使用Viewer插件",
			str_121: "關閉頁面容器圖片導覽快捷鍵 ↑↓",
			str_122: "此漫畫站使用無限滾動閱讀模式",
			str_123: "顯示右下捕獲之眼圖示",
			str_124: "下載影片",
			str_125: "🔄 重置網站設定",
			str_126: "🔄 重置全局設定",
			str_127: "右鍵:匯出圖址(7)",
			str_128: isM ? "開啟收藏" : "開啟收藏(9)",
			str_129: "關閉收藏",
			str_130: "編輯收藏",
			str_131: "保存",
			str_132: "關閉",
			str_133: "選單",
			str_134: "浮動選單",
			str_135: "無限滾動初始化中...",
			str_136: "右鍵:增加圖片縮放級別(+)",
			str_137: "頁面圖片添加燈箱模式",
			str_138: "此網站禁用",
			str_139: "自動聚圖至頁面容器",
			str_140: "自動進入影子畫廊",
			str_141: isM ? "影子畫廊" : "影子畫廊(G)",
			str_142: isM ? "離開畫廊" : "離開畫廊 (Esc)",
			str_143: "下一話",
			str_144: "下一篇",
			str_145: "Fancybox&Viewer幻燈片播放間隔:",
			str_146: "Fancybox滾輪操作:",
			str_147: "畫廊 ( 0、1、3 ) 滾輪操作:",
			str_148: "Fancybox幻燈片過場效果:",
			str_149: "已中斷下載!!!",
			str_150: "JK滾動",
			str_151: "JK平滑滾動",
			str_152: "一個視口",
			str_153: "標題:",
			str_154: "全部選取",
			str_155: "取消全選",
			str_156: "重新載入",
			str_157: "開始下載",
			str_158: isM ? "篩選下載" : "篩選下載(F)",
			str_159: isM ? "自訂函式" : "自訂函式(6)",
			str_160: isM ? "插入圖片" : "插入圖片(1)",
			str_161: "載入線程:",
			str_162: isM ? "預載:" : "圖片預載數:",
			str_163: "🖼️ 開啟簡易模式",
			str_164: "🖼️ 關閉簡易模式",
			str_165: "圖片總數:",
			str_166: "篩選數量:",
			str_167: "篩選寬度:",
			str_168: "篩選高度:",
			str_169: "佈景主題:",
			str_170: "反向選取",
			str_171: "檔案大小",
			str_172: "拖動排序",
			str_173: "可拖動圖片來改變圖片順序。",
			str_174: "匯出為JSON格式",
			str_175: "已匯出JSON格式",
			str_176: "匯出為MD格式",
			str_177: "已匯出Markdown格式",
			str_178: "複製為MD格式",
			str_179: "複製為Markdown格式",
			str_180: "自動匯出URLs.txt",
			str_181: "拼接下載",
			str_182: "※ 畫廊圖片循環切換",
			str_183: "排除格式",
			str_184: "排除錯誤",
			str_185: "自動排錯",
			str_186: "更多選單",
			str_187: "壓縮檔裡創建資料夾",
			str_188: "手機畫廊",
			str_189: "單圖模式",
			str_190: "條漫模式",
			str_191: "預設開啟簡易模式",
			str_192: "自動進入手機畫廊",
			str_193: "匯出JSON",
			str_194: "複製MD",
			str_195: "匯出MD",
			str_196: "前往下一話",
			str_197: "前往下一篇",
			str_198: "畫廊 ( 5 ) 滾輪操作:",
			str_199: "移動裝置雙擊前往下一頁",
			str_200: "AVIF轉換為JPG",
			str_201: "JPG格式轉換品質",
			str_202: "Hitomi.la 圖片格式:",
			str_203: isM ? "點我提示✨" : "懸停提示✨",
			str_204: "⚙️ 腳本UI最外層堆疊順序",
			str_205: "請輸入z-index值(7 ~ 2147483647)",
			str_206: "列表大小:",
			str_207: "預設",
			str_208: "圖片代理",
			str_209: "不使用",
			str_210: "Fancybox尾返首時自動關閉",
			str_211: "Fancybox尾返首時自動前往下一頁",
			str_212: "匯入",
			str_213: "",
			str_214: "下載方法",
			str_215: "Fetch API、XMLHttpRequest,需搭配擴充套件來使用\nChrome關鍵字:--disable-web-security 或 CORS Unblock 或 CORS Control\nFireFox關鍵字:CORS Unblock 或 CORS Everywhere\n禁用同源策略,注意此操作極不安全,不懂別做,用完即關。\n無法通過Cloudflare防火牆驗證時須先刪除,過了再加上。",
			str_216: isM ? "漫畫目錄" : "漫畫目錄 ( C )",
			str_217: "網站首頁",
			str_218: "章節跳轉中...",
			str_219: "上一話",
			str_220: "上一篇",
			str_221: "前往上一話",
			str_222: "前往上一篇",
			str_223: "前往網站首頁",
			str_224: "返回目錄",
			str_225: "前往目錄頁",
			str_226: isM ? "最新更新" : "最新更新( U )",
			str_227: "前往更新頁",
			str_228: "暫停翻頁",
			str_229: "啟用翻頁",
			str_230: "🔄 重置圖示座標",
			str_231: "錯誤重試次數:",
			str_232: "錯誤重試間隔(秒):",
			str_233: "文檔",
			str_234: "長圖拼接畫布限制",
			str_235: "所選圖片寬度不一致",
			str_236: "圖片拼接中",
			str_237: "圖片寬度必須一致。",
			str_238: "為單線程要求時則間隔(秒):",
			str_239: "反轉排序",
			str_240: "Fancybox初始顯示縮圖",
			str_241: "Fancybox6縮圖外觀",
			galleryMenu: {
				horizontal: isM ? "水平模式" : "水平模式 (5,B,R)",
				webtoon: isM ? "條漫模式" : "條漫模式 (4,+,-)",
				rtl: isM ? "右至左模式" : "右至左模式 (3,B,R)",
				small: isM ? "小圖像模式" : "小圖像模式 (2,B,R)",
				single: isM ? "單圖像模式" : "單圖像模式 (1)",
				default: isM ? "預設模式" : "預設模式 (0,B,R)",
			},
			FancyboxWheel: {
				z: "圖片縮放",
				s: "圖片切換"
			},
			FancyboxTransition: {
				fade: "淡出",
				crossfade: "淡入淡出",
				slide: "滑動"
			},
			ShadowGalleryWheel: {
				d: "畫廊滾動",
				t: "圖片切換",
				s: "圖列切換"
			},
			horizontalWheel: {
				d: "水平滾動",
				d2: "水平滾動自訂JK",
				t: "圖片切換"
			},
			colorThemes: {
				light: "淺色",
				dark: "深色"
			},
			tab: {
				p: "頁面",
				g: "畫廊",
				l: "燈箱",
				d: "下載",
				o: "其他"
			}
		};
		break;
	case "zh":
	case "zh-CN":
	case "zh-SG":
	case "zh-MY":
	case "zh-Hans-CN":
	case "zh-Hans-SG":
	case "zh-Hans-MY":
		DL = {
			xchina_picnum_error: "图片数量不符,请反馈。",
			str_00: "语言",
			str_01: "获取图片元素中...",
			str_02: "获取图片中 ",
			str_03: "获取图片逾时",
			str_04: "等待关键元素中...",
			str_05: "获取数据中...",
			str_06: "获取数据中 ",
			str_07: "确认登录状态中...",
			str_08: "获取预览图中...",
			str_09: "获取最后一张图...",
			str_10: "是否拷贝链接至剪贴板?",
			str_11: "已拷贝链接至剪贴板",
			str_12: "只有拷贝链接功能",
			str_13: "请输入图片抓取最大次数",
			str_14: "获取下一页中...",
			str_15: "获取下一页结束",
			str_16: "获取元素中...",
			str_17: "获取元素中 ",
			str_18: "已聚集所有图片",
			str_19: "用来定位插入的元素不存在",
			str_20: "没有能插入的图片",
			str_21: "延迟",
			str_22: "毫秒",
			str_23: "第",
			str_24: "张下载",
			str_25: "完成",
			str_26: "错误",
			str_27: "下载失败了",
			str_28: "张",
			str_29: "\n是否只保存目前下载成功的图片?\n只要图片不是100%挂掉,可以调低下载线程数或重新加载网页后重新下载试试看,网站如有Cloudflare防火墙,需要自行取得Cookie,使用Set Cloudflare Clearance Cookies填入或更新Cookie。",
			str_30: "图片extension错误",
			str_31: "压缩进度: ",
			str_32: "自动下载倒数",
			str_33: "秒",
			str_34: {
				n: "nextJS前往下一页",
				p: "prevJS前往上一页"
			},
			str_35: "已点击下一页",
			str_36: "自动下载完毕",
			str_37: "没有下一页元素",
			str_38: "返回上一页",
			str_39: "已点击上一页",
			str_40: "没有上一页元素",
			str_41: "已取消",
			str_42: "字数小于3已取消",
			str_43: "下载失败数据为空...",
			str_44: "没有任何图片元素...",
			str_45: "网址已拷贝",
			str_46: "即将进行滚动...",
			str_47: "左键:进行下载打包压缩\n中键:导出网址URLs.txt文档\n右键:拷贝图片网址和标题或手动模式聚集所有图片",
			str_48: "下载&压缩中请稍后再操作!",
			str_49: "获取图片中请稍后再操作!",
			str_50: "自定义网站收藏的网址在新标籤页打开",
			str_51: "请输入自定义压缩档文件夹名称",
			str_52: "聚图数量",
			str_53: "图片绘制中...",
			str_54: "403,未登录网站?",
			str_55: "下载加载中...",
			str_56: "确认图片状态中...",
			str_57: "自动翻页加载中...",
			str_58: "已到达最后一页",
			str_59: "没有任何主体元素",
			str_60: "图片缩放",
			str_61: "取消缩放",
			str_62: "前往第一张图",
			str_63: "左键:前往最后一张图\n右键:导出网址URLs.txt文档",
			str_64: "即将开始自动下载!!!",
			str_65: "已停止自动下载!!!",
			str_66: "💬 Greasy Fork 反馈",
			str_67: "⚙️ 设置",
			str_68: "当前(※全局)网站设置",
			str_69: "显示左下图标按钮",
			str_70: "最大线程数:",
			str_71: "下载后压缩打包",
			str_72: "压缩档文件扩展名:",
			str_73: "自动下载",
			str_74: "ESC键:可中断自动下载\n快捷键 [ ctrl + . ]:开始自动下载或取消自动下载",
			str_75: "自动下载倒数秒数:",
			str_76: "启用当前漫画站点规则",
			str_77: "自动进入画廊需点击主图示按钮",
			str_78: "Fancybox&Viewer灯箱功能",
			str_79: "页面容器图片缩放比例:",
			str_80: "页面容器图片并排数量:",
			str_81: "comic类固定为2,comic类并排后为右至左的漫读模式,hcomic类也设置为2将套用。",
			str_82: isM ? "取消" : "取消 (Esc)",
			str_83: "重置设置",
			str_84: "保存设置",
			str_85: isM ? "脚本设置" : "脚本设置(*)",
			str_86: isM ? "切换模式" : "切换模式(5)",
			str_87: isM ? "比例缩放" : "比例缩放(-+)",
			str_88: isM ? "取消缩放" : "取消缩放(.)",
			str_89: "暂停自动翻页",
			str_90: "启用自动翻页",
			str_91: "初始化设置",
			str_92: "原始模式",
			str_93: "并排模式",
			str_94: "返回开头了",
			str_95: "前往下一集",
			str_96: "已是最后一集",
			str_97: "共",
			str_98: "页获取出错,建议反馈",
			str_99: "重试第",
			str_100: "次",
			str_101: "网址.txt已导出",
			str_102: "格式转换中...",
			str_103: "页面容器默认使用并排模式",
			str_104: isM ? "导出图址" : "导出图址(7)",
			str_105: isM ? "复制图址" : "复制图址(1)",
			str_106: isM ? "标签画廊" : "标签画廊(8)",
			str_107: isM ? "一键下载" : "一键下载(3)",
			str_108: "※ 讯息提示显示的位置:",
			str_109: {
				c: "置中",
				ul: "左上",
				ur: "右上",
				ll: "左下",
				lr: "右下",
			},
			str_110: "WEBP转换为JPG",
			str_111: "导出",
			str_112: "提示",
			str_113: "滚动煞车:",
			str_114: "E/Ex-Hentai 加载原始图片链接",
			str_115: "自动滚动至首张图片",
			str_116: "自动滚动所有懒加载的图片元素",
			str_117: "显示浮动菜单",
			str_118: "图集标题已更新",
			str_119: "Fancybox空闲逾时隐藏UI(秒)",
			str_120: "标签画廊使用Viewer插件",
			str_121: "关闭页面容器图片导览快捷键 ↑↓",
			str_122: "此漫画站使用无限滚动阅读模式",
			str_123: "显示右下捕获之眼图标",
			str_124: "下载视频",
			str_125: "🔄 重置网站设置",
			str_126: "🔄 重置全局设置",
			str_127: "右键:导出图址(7)",
			str_128: isM ? "打开收藏" : "打开收藏(9)",
			str_129: "关闭收藏",
			str_130: "编辑收藏",
			str_131: "保存",
			str_132: "关闭",
			str_133: "菜单",
			str_134: "浮动菜单",
			str_135: "无限滚动初始化中...",
			str_136: "右键:增加图片缩放级别(+)",
			str_137: "页面图片添加灯箱模式",
			str_138: "此网站禁用",
			str_139: "自动聚图至页面容器",
			str_140: "自動進入影子畫廊",
			str_141: isM ? "影子画廊" : "影子画廊(G)",
			str_142: isM ? "离开画廊" : "离开画廊 (Esc)",
			str_143: "下一话",
			str_144: "下一篇",
			str_145: "Fancybox&Viewer幻灯片播放间隔:",
			str_146: "Fancybox滚轮操作:",
			str_147: "画廊 ( 0、1、3 ) 滚轮操作:",
			str_148: "Fancybox幻灯片过场效果:",
			str_149: "已中断下载!!!",
			str_150: "JK滚动",
			str_151: "JK平滑滚动",
			str_152: "一个视口",
			str_153: "标题:",
			str_154: "全部选取",
			str_155: "取消全选",
			str_156: "重新加载",
			str_157: "开始下载",
			str_158: isM ? "筛选下载" : "筛选下载(F)",
			str_159: isM ? "定义函式" : "定义函式(6)",
			str_160: isM ? "插入图片" : "插入图片(1)",
			str_161: "加载线程:",
			str_162: isM ? "预载:" : "图片预载数:",
			str_163: "🖼️ 开启简易模式",
			str_164: "🖼️ 关闭简易模式",
			str_165: "图片总数:",
			str_166: "筛选数量:",
			str_167: "筛选宽度:",
			str_168: "筛选高度:",
			str_169: "布景主题:",
			str_170: "反向选取",
			str_171: "文件大小",
			str_172: "拖动排序",
			str_173: "可拖动图片来改变图片顺序。",
			str_174: "导出为JSON格式",
			str_175: "已导出JSON格式",
			str_176: "导出为MD格式",
			str_177: "已导出Markdown格式",
			str_178: "拷贝为MD格式",
			str_179: "拷贝为Markdown格式",
			str_180: "自动导出URLs.txt",
			str_181: "拼接下载",
			str_182: "※ 画廊图片循环切换",
			str_183: "排除格式",
			str_184: "排除错误",
			str_185: "自动排错",
			str_186: "更多选单",
			str_187: "压缩档里创建资料夹",
			str_188: "手机画廊",
			str_189: "单图模式",
			str_190: "条漫模式",
			str_191: "默认打开简易模式",
			str_192: "自动进入手机画廊",
			str_193: "导出JSON",
			str_194: "拷贝MD",
			str_195: "导出MD",
			str_196: "前往下一话",
			str_197: "前往下一篇",
			str_198: "画廊 ( 5 ) 滚轮操作:",
			str_199: "移动设备双击前往下一页",
			str_200: "AVIF转换为JPG",
			str_201: "JPG格式转换品质",
			str_202: "Hitomi.la 图片格式:",
			str_203: isM ? "点我提示✨" : "悬停提示✨",
			str_204: "⚙️ 脚本UI最外层堆叠顺序",
			str_205: "请输入z-index值(7 ~ 2147483647)",
			str_206: "列表大小:",
			str_207: "默认",
			str_208: "图片代理",
			str_209: "不使用",
			str_210: "Fancybox尾返首时自动关闭",
			str_211: "Fancybox尾返首时自动前往下一页",
			str_212: "导入",
			str_213: "",
			str_214: "下载方法",
			str_215: "Fetch API、XMLHttpRequest,需搭配扩展来使用\nChrome关键字:--disable-web-security 或 CORS Unblock 或 CORS Control\n详见稀土掘金:https://juejin.cn/post/7280435431328710716\nFireFox 关键字:CORS Unblock 或 CORS Everywhere\n禁用同源策略,注意此操作极不安全,不懂别做,用完即关。\n无法通过Cloudflare防火墙验证时须先删除,过了再加上。",
			str_216: isM ? "漫画目录" : "漫画目录 ( C )",
			str_217: "网站首页",
			str_218: "章节跳转中...",
			str_219: "上一话",
			str_220: "上一篇",
			str_221: "前往上一话",
			str_222: "前往上一篇",
			str_223: "前往网站首页",
			str_224: "返回目录",
			str_225: "前往目录页",
			str_226: isM ? "最新更新" : "最新更新( U )",
			str_227: "前往更新页",
			str_228: "暂停翻页",
			str_229: "启用翻页",
			str_230: "🔄 重置图标座标",
			str_231: "错误重试次数:",
			str_232: "错误重试间隔(秒):",
			str_233: "文档",
			str_234: "长图拼接画布限制",
			str_235: "所选图片宽度不一致",
			str_236: "图片拼接中",
			str_237: "图片宽度必须一致。",
			str_238: "为单线程请求时则间隔(秒):",
			str_239: "反转排序",
			str_240: "Fancybox初始显示缩图",
			str_241: "Fancybox6缩图外观",
			galleryMenu: {
				horizontal: isM ? "水平模式" : "水平模式 (5,B,R)",
				webtoon: isM ? "条漫模式" : "条漫模式 (4,+,-)",
				rtl: isM ? "右至左模式" : "右至左模式 (3,B,R)",
				small: isM ? "小图像模式" : "小图像模式 (2,B,R)",
				single: isM ? "单图像模式" : "单图像模式 (1)",
				default: isM ? "默认模式" : "默认模式 (0,B,R)",
			},
			FancyboxWheel: {
				z: "图片缩放",
				s: "图片切换"
			},
			FancyboxTransition: {
				fade: "淡出",
				crossfade: "淡入淡出",
				slide: "滑动"
			},
			ShadowGalleryWheel: {
				d: "画廊滚动",
				t: "图片切换",
				s: "图列切换"
			},
			horizontalWheel: {
				d: "水平滚动",
				d2: "水平滚动自訂JK",
				t: "图片切换"
			},
			colorThemes: {
				light: "浅色",
				dark: "深色"
			},
			tab: {
				p: "页面",
				g: "画廊",
				l: "灯箱",
				d: "下载",
				o: "其他"
			}
		};
		break;
	default:
		DL = {
			xchina_picnum_error: "图片数量不符,请反馈。",
			str_00: "Language",
			str_01: "Get Images...",
			str_02: "Get Images ",
			str_03: "Get timed out",
			str_04: "Wait Element...",
			str_05: "Get Data...",
			str_06: "Get Data ",
			str_07: "Confirm Login Status",
			str_08: "Get Preview Thumbnail",
			str_09: "Get Element...",
			str_10: "Whether To Copy Link To Clipboard?",
			str_11: "Copied",
			str_12: "Only Link Can Be Copied",
			str_13: "Please Enter The Number Of Images",
			str_14: "Get Next Page...",
			str_15: "Get Next Page End",
			str_16: "Get Element...",
			str_17: "Get Element ",
			str_18: "All Images Gathered",
			str_19: "Element Does Not Exist",
			str_20: "No Images",
			str_21: "Delay",
			str_22: "ms",
			str_23: "No. ",
			str_24: " Download ",
			str_25: "Completed",
			str_26: "Error",
			str_27: "Download Failed",
			str_28: "P",
			str_29: "\nDo you want to save only the Images that have been successfully downloaded so far?\nAs long as the image is not 100% dead, you can reduce the number of download threads or reload the web page and try downloading again.\nIf website has a Cloudflare firewall, you need to obtain cookies yourself and use Set Cloudflare Clearance Cookies to fill in the cookies.",
			str_30: "Image Extension Error",
			str_31: "Compression Progress: ",
			str_32: "Countdown ",
			str_33: " sec",
			str_34: {
				n: "JS Go To Next Page",
				p: "JS Go To Prev Page",
			},
			str_35: "Next Page Clicked",
			str_36: "AutoDownload Completed",
			str_37: "No Next Page Element",
			str_38: "Return To Previous Page",
			str_39: "Previous Page Clicked",
			str_40: "No Previous Page Element",
			str_41: "Cancelled",
			str_42: "Cancelled",
			str_43: "Download Failed Data Is Empty",
			str_44: "No Picture Element",
			str_45: "URLs Copied ",
			str_46: "About To Scroll...",
			str_47: "Left Click:Download And Compress\nMiddle Click:Export URLs.txt\nRight Click:Copy Image URL And Title Or Aggregate Images",
			str_48: "Downloading & Compressing, Please Try Again Later!",
			str_49: "Get Pictureing Please Try Again Later!",
			str_50: "Favored Website URL Open in New Tab",
			str_51: "Please Enter A Custom zip File Folder Name",
			str_52: "Number Of Images",
			str_53: "Picture Drawing...",
			str_54: "403,Not Logged In To Website?",
			str_55: "Download Loading...",
			str_56: "Check Picture Statusing...",
			str_57: "AutoPager Loading...",
			str_58: "Reached The Last Page",
			str_59: "No Main Element",
			str_60: "Image Zoom",
			str_61: "Cancel Zoom",
			str_62: "Go To First Image",
			str_63: "Left Click:Go To Last Image\nLeft Click:Export URLs.txt",
			str_64: "Start Auto Download!!!",
			str_65: "Stop Auto Download!!!",
			str_66: "💬 Greasy Fork Feedback",
			str_67: "⚙️ Settings",
			str_68: "Current(※Global) Website Options",
			str_69: "Show Lower Left Icon Button",
			str_70: "Maximum Threads:",
			str_71: "Compressed Packaging",
			str_72: "Compressed File Extension:",
			str_73: "Auto Download",
			str_74: "ESC:Interrupt Auto Download\nShortcut key [ ctrl + . ]:Start Auto Download Or Cancel Auto Download",
			str_75: "AutoDownload Countdown Sec:",
			str_76: "Comic Site Rules Switch",
			str_77: "Auto enter Gallery In Icon Button",
			str_78: "Fancybox&Viewer Plugin",
			str_79: "Image Zoom Ratio:",
			str_80: "Number Of Images Side By Side:",
			str_81: "Comic Category Fixed To 2",
			str_82: isM ? "Cancel" : "Cancel (Esc)",
			str_83: "Reset",
			str_84: "Save",
			str_85: isM ? "Settings" : "Settings(*)",
			str_86: isM ? "Toggle" : "ToggleMode(5)",
			str_87: isM ? "Zoom" : "ToggleZoom(-+)",
			str_88: isM ? "Cancel" : "CancelZoom(.)",
			str_89: "Pause Automatic Page Turning",
			str_90: "Enable Automatic Page Turning",
			str_91: "Initialization Settings",
			str_92: "Original Mode",
			str_93: "Side-By-Side Mode",
			str_94: "Back To The Beginning",
			str_95: "Go To Next Episode",
			str_96: "It’s The Last Episode",
			str_97: "Have",
			str_98: "Page Fetch Error Please Feedback",
			str_99: "Retry No.",
			str_100: "Bout",
			str_101: "MediaURLs.txt Exported",
			str_102: "Format Converting",
			str_103: "Enable Side-By-Side Mode",
			str_104: isM ? "Export" : "ExportURLs(7)",
			str_105: isM ? "Copy" : "CopyURLs(1)",
			str_106: isM ? "TabView" : "NewTabView(8)",
			str_107: isM ? "Download" : "FastDownload(3)",
			str_108: "※ Where the message appears:",
			str_109: {
				c: "Center",
				ul: "Upper left",
				ur: "Upper right",
				ll: "Lower left",
				lr: "Lower right",
			},
			str_110: "Convert WEBP to JPG",
			str_111: "Export",
			str_112: "Prompt Message",
			str_113: "Scroll:",
			str_114: "E/Ex-Hentai Load Original Image",
			str_115: "Auto Scroll To First Image",
			str_116: "Auto Scroll All Image Elements",
			str_117: "Show Fixed Menu",
			str_118: "Album title has been updated",
			str_119: "Fancybox Activate Idle Mode (sec)",
			str_120: "New Tab View Uses Viewer Plugin",
			str_121: "Turn Off Image Navigation Shortcut Keys ↑↓",
			str_122: "This Website Uses Infinite Scroll Read Mode",
			str_123: "Show Capture Eye Icon",
			str_124: "Download Videos",
			str_125: "🔄 Reset Site Settings",
			str_126: "🔄 Reset Global Settings",
			str_127: "Right Click:Export URLs(7)",
			str_128: isM ? "OpenFavor" : "OpenFavor(9)",
			str_129: "Close Favor",
			str_130: "Edit Favor",
			str_131: "Save",
			str_132: "Close",
			str_133: "Menu",
			str_134: "Float Menu",
			str_135: "Infinite Scroll Initializing",
			str_136: "Right Click:Increase Image Zzoom Level(+)",
			str_137: "Add Fancybox To Image",
			str_138: "This Website Is Disabled",
			str_139: "Page Content Auto Insert Images",
			str_140: "Auto enter Shadow Gallery",
			str_141: isM ? "ShadowGallery" : "ShadowGallery(G)",
			str_142: isM ? "Close" : "Close (Esc)",
			str_143: "Next Chapter",
			str_144: "Next Post",
			str_145: "Fancybox&Viewer Play Delay:",
			str_146: "Fancybox Wheel:",
			str_147: "Gallery (0、1、3) Wheel:",
			str_148: "Fancybox Slideshow Transition:",
			str_149: "Download Interrupted!!!",
			str_150: "JK Scroll ",
			str_151: "JK Smooth Scroll",
			str_152: "Viewport",
			str_153: "Title:",
			str_154: "Select All",
			str_155: "Unselect All",
			str_156: "Reload",
			str_157: "Download",
			str_158: isM ? "FilterDownload" : "FilterDownload(F)",
			str_159: isM ? "Function" : "Function(6)",
			str_160: isM ? "Insert Images" : "Insert Images(1)",
			str_161: "Threads:",
			str_162: "Preload:",
			str_163: "🖼️ Enable Simple Mode",
			str_164: "🖼️ Turn Off Simple Mode",
			str_165: "Images:",
			str_166: "Filters:",
			str_167: "Width:",
			str_168: "Height:",
			str_169: "Theme:",
			str_170: "Reverse Selection",
			str_171: "Show File Size",
			str_172: "Drag Sort",
			str_173: "Drag the image to change the order of images",
			str_174: "Export JSON",
			str_175: "Exported JSON",
			str_176: "Export Markdown",
			str_177: "Exported Markdown",
			str_178: "Copy Markdown",
			str_179: "Copied to Markdown format",
			str_180: "Auto Export URLs.txt",
			str_181: "Combine Download",
			str_182: "※ Gallery Image Loop Toggle",
			str_183: "Exclude Format",
			str_184: "Culling",
			str_185: "Auto Culling",
			str_186: "More Menu",
			str_187: "Create a folder in compressed file",
			str_188: "Phone Gallery",
			str_189: "Single",
			str_190: "Webtoon",
			str_191: "Simple mode enabled by default",
			str_192: "Auto enter Phone Gallery",
			str_193: "Export JSON",
			str_194: "Copy Markdown",
			str_195: "Export Markdown",
			str_196: "Go To Next",
			str_197: "Go To Next",
			str_198: "Gallery (5) Wheel:",
			str_199: "Double Click Go To Next Page",
			str_200: "Convert AVIF to JPG",
			str_201: "Convert Quality",
			str_202: "Hitomi.la Image Format:",
			str_203: "TIP✨",
			str_204: "⚙️ UI z-index",
			str_205: "Please enter a z-index value(7 ~ 2147483647)",
			str_206: "List Size:",
			str_207: "Default",
			str_208: "Image CDN",
			str_209: "Not used",
			str_210: "Fancybox Last To First Auto Close",
			str_211: "Fancybox Last To First Auto Go To Next",
			str_212: "Import",
			str_213: "",
			str_214: "Download Method",
			str_215: "Fetch API, XMLHttpRequest, Need to be used with extensions\nChrome Keywords:--disable-web-security or CORS Unblock or CORS Control\nFireFox Keywords:CORS Unblock or CORS Everywhere\nWarning:Unsafe",
			str_216: isM ? "Chapters" : "Chapters ( C )",
			str_217: "Home Page",
			str_218: "Jumping to chapter...",
			str_219: "Prev Chapter",
			str_220: "Prev Post",
			str_221: "Go To Prev",
			str_222: "Go To Prev",
			str_223: "Go To Home Page",
			str_224: "Chapters",
			str_225: "Go to Catalog Page",
			str_226: isM ? "Last Updates" : "Last Updates( U )",
			str_227: "Go to Last Updates Page",
			str_228: "Pause AutoPager",
			str_229: "Enable AutoPager",
			str_230: "🔄 Reset ICON Coordinates",
			str_231: "Error Retry Count:",
			str_232: "Error Retry Interval (sec):",
			str_233: "Documentation",
			str_234: "Combine Images Canvas Limit",
			str_235: "Inconsistent Image Width",
			str_236: "Images Combineing",
			str_237: "Images Widths Must Be Consistent.",
			str_238: "Single-threaded request lnterval (sec):",
			str_239: "Reverse Sort",
			str_240: "Fancybox Thumbs Show On Start",
			str_241: "Fancybox6 Thumbs Appearance",
			galleryMenu: {
				horizontal: isM ? "Horizontal" : "Horizontal (5,B,R)",
				webtoon: isM ? "Webtoon" : "Webtoon (4,+,-)",
				rtl: isM ? "Right To Left" : "Right To Left (3,B,R)",
				small: isM ? "Small Image" : "Small Image (2,B,R)",
				single: isM ? "Single Image" : "Single Image (1)",
				default: isM ? "Default" : "Default (0,B,R)",
			},
			FancyboxWheel: {
				z: "zoom",
				s: "slide"
			},
			FancyboxTransition: {
				fade: "Fade",
				crossfade: "Crossfade",
				slide: "Slide"
			},
			ShadowGalleryWheel: {
				d: "Gallery Scroll",
				t: "Toggle Image",
				s: "Toggle Row"
			},
			horizontalWheel: {
				d: "Horizontal Scroll",
				d2: "Horizontal Scroll Custom JK",
				t: "Toggle Image"
			},
			colorThemes: {
				light: "Light",
				dark: "Dark"
			},
			tab: {
				p: "Page",
				g: "Gallery",
				l: "Lightbox",
				d: "Download",
				o: "Other"
			}
		};
		break;
	}

	const FullPictureLoadBlacklist = localStorage.getItem("FullPictureLoadBlacklist") ?? 0;
	_GM_registerMenuCommand(DL.str_66, () => _GM_openInTab("https://greasyfork.org/scripts/463305/feedback"));
	_GM_registerMenuCommand(FullPictureLoadBlacklist == 0 ? "❌ " + DL.str_138 : "✔️  " + DL.str_138, () => {
		FullPictureLoadBlacklist == 0 ? localStorage.setItem("FullPictureLoadBlacklist", 1) : localStorage.setItem("FullPictureLoadBlacklist", 0);
		location.reload();
	});
	if (FullPictureLoadBlacklist == 1) return;

	const FullPictureLoadMsgPos = _GM_getValue("FullPictureLoadMsgPos", 0);
	let msgTimeId;

	const fn = {
		url: (() => siteUrl)(),
		lo: (() => _unsafeWindow.location.origin)(),
		lp: (() => _unsafeWindow.location.pathname)(),
		lh: (() => _unsafeWindow.location.hostname)(),
		ls: (() => _unsafeWindow.location.search)(),
		curl: (p = null) => {
			const url = currentURL;
			if (isString(p)) {
				return url.includes(p);
			} else if (isRegExp(p)) {
				return url.search(p) > -1;
			}
			return url;
		},
		clh: (p = null) => {
			const hostname = new URL(currentURL).hostname;
			if (isString(p)) {
				return hostname.includes(p);
			} else if (isRegExp(p)) {
				return hostname.search(p) > -1;
			}
			return hostname;
		},
		clp: (p = null) => {
			const pathname = new URL(currentURL).pathname;
			if (isString(p)) {
				return pathname.includes(p);
			} else if (isRegExp(p)) {
				return pathname.search(p) > -1;
			}
			return pathname;
		},
		cls: (p = null) => {
			const search = new URL(currentURL).search;
			if (isString(p)) {
				return search.includes(p);
			} else if (isRegExp(p)) {
				return search.search(p) > -1;
			}
			return search;
		},
		durl: (p = null) => {
			const url = _unsafeWindow.document.URL;
			if (isString(p)) {
				return url.includes(p);
			} else if (isRegExp(p)) {
				return url.search(p) > -1;
			}
			return url;
		},
		dlh: (p = null) => {
			const hostname = _unsafeWindow.document.location.hostname;
			if (isString(p)) {
				return hostname.includes(p);
			} else if (isRegExp(p)) {
				return hostname.search(p) > -1;
			}
			return hostname;
		},
		dlp: (p = null) => {
			const pathname = _unsafeWindow.document.location.pathname;
			if (isString(p)) {
				return pathname.includes(p);
			} else if (isRegExp(p)) {
				return pathname.search(p) > -1;
			}
			return pathname;
		},
		dls: (p = null) => {
			const search = _unsafeWindow.document.location.search;
			if (isString(p)) {
				return search.includes(p);
			} else if (isRegExp(p)) {
				return search.search(p) > -1;
			}
			return search;
		},
		getUSP: (p, s = "s") => {
			if (s === "u") {
				return new URL(fn.cls()).searchParams.get(p);
			}
			if (s === "s") {
				return new URLSearchParams(fn.cls()).get(p);
			}
			if (s?.startsWith("http")) {
				return new URL(s).searchParams.get(p);
			}
			if (s?.startsWith("?")) {
				new URLSearchParams(s).get(p);
			}
			return "";
		},
		cp: (obj) => new URLSearchParams(obj).toString(),
		cookie: (key) => {
			try {
				let cookie_object = {
					...Object.fromEntries(document.cookie.replace(/\s/g, "").split(";").map(e => e.split("=")))
				};
				if (key in cookie_object) {
					return Reflect.get(cookie_object, key);
				}
			} catch {}
			return "";
		},
		src: (p, dom = document) => {
			let ele;
			if (isEle(p)) {
				ele = p;
			} else if (isString(p)) {
				ele = fn.ge(p, dom, dom);
				if (!isEle(ele)) return "";
			} else {
				return "";
			}
			return ("src" in ele) ? ele.src : "";
		},
		dir: url => {
			if (!url?.includes("/")) return "";
			if (isURL(url) && url?.startsWith("http")) {
				let obj = new URL(url);
				url = obj.origin + obj.pathname;
			}
			let index = url.lastIndexOf("/") + 1;
			url = url.slice(0, index);
			return url;
		},
		wurl: (value, url = fn.clp(), index = -1) => {
			let array = url.split("/");
			array = array.with(index, value);
			url = array.join("/");
			return url;
		},
		cdn: (src, cdn) => {
			if (
				src.includes("?") && !src.includes("wp.com/") && !src.includes("wsrv.nl/") && !src.includes("image.baidu.com") ||
				src.startsWith("data") ||
				src.startsWith("blob")
			) {
				return src;
			}
			if (src.includes("wp.com/")) {
				src = src.replace(/i\d\.wp\.com\/|\?.+$/g, "");
			}
			if (src.includes("wsrv.nl/") || src.includes("image.baidu.com")) {
				src = fn.getUSP("url", src);
			}
			if (cdn == "w") {
				src = "https://wsrv.nl/?url=" + src;
			} else if (cdn == "b") {
				src = "https://image.baidu.com/search/down?thumburl=https://baidu.com&url=" + src;
			} else {
				let _old = new URL(src).host;
				let _new = `i${cdn}.wp.com/` + _old;
				src = src.replace(_old, _new).replace("http:", "https:") + "?ssl=1";
			}
			return src;
		},
		ex: e => {
			const object = {
				j: "jpg",
				jpg: "jpg",
				p: "png",
				png: "png",
				g: "gif",
				gif: "gif",
				w: "webp",
				webp: "webp",
				a: "avif",
				avif: "avif",
				t: "tif",
				tif: "tif",
				b: "bmp",
				bmp: "bmp"
			};
			return object[e];
		},
		isImage: file => {
			file = String(file);
			if (file.includes("/")) {
				file = file.split("/").at(-1);
			}
			return /\.(png|jpe?g|webp|avif|gif|svg|ico|bmp|tiff?|jfif|heif|heic|raw|cr2|nef|arw|dng)/i.test(file);
		},
		isVideo: file => {
			file = String(file);
			if (file.includes("/")) {
				file = file.split("/").at(-1);
			}
			return /\.(mp4|avi|mkv|mov|wmv|flv|webm|mpeg|mpg|3gp|m4v|ts|vob|ogv|rm|rmvb|m2ts|mxf|asf|swf)/i.test(file);
		},
		isZip: file => {
			file = String(file);
			if (file.includes("/")) {
				file = file.split("/").at(-1);
			}
			return /\.(rar|zip|7z|cbz)/i.test(file);
		},
		checkUrl: (obj = {}) => {
			if (fn.clp() === "/" && fn.cls() === "" && !("SPA" in tempData) && !("autoPager" in tempData) && !["none", "ad"].some(c => tempData.category == c)) return false;
			const {
				u: url,
				h: hosts,
				p: pathname,
				s: search,
				st: script_text,
				e: elements,
				ee: exclude_elements,
				t: title,
				d: device,
				i: comicInfiniteScroll,
				cookie: cookie_key
			} = obj;
			if ("ee" in obj) {
				if (isArray(exclude_elements)) {
					if (exclude_elements.some(selector => !!fn.ge(selector))) return false;
				} else if (isString(exclude_elements)) {
					if (!!fn.ge(exclude_elements)) return false;
				}
			}
			const {
				box,
				imgs: imgSelector,
				srcset: srcsetSelector,
				customTitle: titleSelector
			} = tempData;
			let checkU = true;
			let checkH = true;
			let checkP = true;
			let checkS = true;
			let checkE = true;
			let checkI = true;
			let checkT = true;
			let checkD = true;
			let checkC = true;
			if ("i" in obj) {
				checkI = comicInfiniteScroll === 0 ? comicInfiniteScrollMode != 1 : comicInfiniteScrollMode == 1;
				if (!checkI) return false;
			}
			if ("d" in obj) {
				if (device === "pc") {
					checkD = isPC;
				} else if (device === "m") {
					checkD = isM || isMobileDeviceUA;
				}
				if (!checkD) return false;
			}
			if ("h" in obj) {
				if (isArray(hosts)) {
					checkH = hosts.some(h => {
						if (isRegExp(h)) {
							return h.test(fn.lh);
						} else if (isString(h)) {
							return h === fn.lh;
						}
						return false;
					});
				} else if (isRegExp(hosts)) {
					checkH = hosts.test(fn.lh);
				} else if (isString(hosts)) {
					checkH = fn.lh.includes(hosts);
				}
				if (!checkH) return false;
			}
			if ("u" in obj) {
				if (isArray(url)) {
					checkU = url.some(u => {
						if (isRegExp(u)) {
							return u.test(fn.url);
						} else if (isString(u)) {
							return fn.url.includes(u);
						}
						return false;
					});
				} else if (isRegExp(url)) {
					checkU = url.test(fn.url);
				} else if (isString(url)) {
					checkU = fn.url.includes(url);
				}
				if (!checkU) return false;
			}
			if ("t" in obj) {
				if (isArray(title)) {
					checkT = title.some(t => {
						if (isString(t)) {
							return document.title.includes(t);
						} else if (isRegExp(t)) {
							return t.test(document.title);
						}
						return false;
					});
				} else if (isString(title)) {
					checkT = document.title.includes(title);
				} else if (isRegExp(title)) {
					checkT = title.test(document.title);
				}
				if (!checkT) return false;
			}
			if ("st" in obj) {
				if (isArray(script_text)) {
					checkT = script_text.every(text => !![...document.scripts].find(script => {
						if (isString(text)) {
							return script.textContent.includes(text);
						} else if (isRegExp(text)) {
							return script.textContent.search(text) > -1;
						}
					}));
				} else if (isString(script_text) || isRegExp(script_text)) {
					checkT = !![...document.scripts].find(script => {
						if (isString(script_text)) {
							return script.textContent.includes(script_text);
						} else if (isRegExp(script_text)) {
							return script.textContent.search(script_text) > -1;
						}
					});
				}
				if (!checkT) return false;
			}
			if ("e" in obj) {
				if (isArray(elements)) {
					checkE = elements.every(selector => !!fn.ge(selector));
				} else if (isString(elements)) {
					checkE = !!fn.ge(elements);
				}
				if (!checkE) return false;
			}
			if ("p" in obj) {
				if (isArray(pathname)) {
					checkH = pathname.some(p => {
						if (isRegExp(p)) {
							return p.test(fn.lp);
						} else if (isString(p)) {
							return fn.lp.includes(p);
						}
						return false;
					});
				} else if (isRegExp(pathname)) {
					checkP = pathname.test(fn.lp);
				} else if (isString(pathname)) {
					checkP = fn.lp.includes(pathname);
				}
				if (!checkP) return false;
			}
			if ("s" in obj) {
				if (isRegExp(search)) {
					checkS = search.test(fn.ls);
				} else if (isString(search)) {
					checkS = fn.ls.includes(search);
				}
				if (!checkS) return false;
			}
			if ("cookie" in obj) {
				checkC = document.cookie.includes(cookie_key);
			}
			if ("box" in tempData && isArray(box) && !("SPA" in tempData)) {
				const [selector] = box;
				checkE = !!fn.ge(selector);
				if (!checkE) {
					debug("\n頁面沒有創建容器的定位元素", selector);
				}
			}
			if ("imgs" in tempData && isString(imgSelector) && !("SPA" in tempData)) {
				checkI = !!fn.ge(imgSelector);
				if (!checkI) {
					debug("\n頁面沒有指定的圖片元素", imgSelector);
				}
			}
			if ("srcset" in tempData && isString(srcsetSelector) && !("SPA" in tempData)) {
				checkI = !!fn.ge(srcsetSelector);
				if (!checkI) {
					debug("\n頁面沒有指定的圖片元素", srcsetSelector);
				}
			}
			if ("customTitle" in tempData && (isString(titleSelector) || isArray(titleSelector)) && !("SPA" in tempData)) {
				if (isString(titleSelector)) {
					checkT = !!fn.ge(titleSelector);
				} else if (isArray(titleSelector)) {
					if (titleSelector.length == 2) {
						checkT = titleSelector.every(selector => !!fn.ge(selector));
					} else if (titleSelector.length == 3) {
						let [s] = titleSelector;
						checkT = !!fn.ge(s);
					}
				}
				if (!checkT) {
					if (isString(titleSelector)) {
						debug("\n頁面沒有指定的標題元素", titleSelector);
					} else if (isArray(titleSelector)) {
						debug("\n頁面沒有指定的所有標題元素", titleSelector);
					}
				}
			}
			return checkU && checkH && checkP && checkS && checkE && checkI && checkT && checkC;
		},
		checkAutoPagerEle: (data = {}) => {
			let check = true;
			const {
				ele: pageElementSelector,
				observer: observerSelector,
				next: nextSelector,
				re: replaceSelector
			} = data;
			const selectors = [
				pageElementSelector,
				observerSelector,
				nextSelector,
				replaceSelector
			].filter(item => isString(item));
			if (selectors.length > 0) {
				check = selectors.every(selector => !!fn.ge(selector));
				if (check) {
					debug("\n圖片全載AutoPager\n頁面包含自動翻頁必須的所有元素");
				} else {
					console.error("\n圖片全載AutoPager\n頁面沒有包含自動翻頁必須的所有元素");
				}
			}
			return check;
		},
		getModeUrl: (url, mode, i) => {
			//【.html ==> .html?page=2】第一頁 ==> 第二頁
			//【 ==> ?page=2】第一頁 ==> 第二頁
			if (mode === 1) return url.replace(/\?page=\d+$/, "") + "?page=" + i;
			//【.html ==> /2.html】 第一頁 ==> 第二頁
			if (mode === 2) return url.slice(0, -5) + "/" + i + ".html";
			//【.html ==> _1.html】  第一頁 ==> 第二頁
			//return siteUrl.replace(/(_\d+)?\.html$/, "") + "_" + (i - 1) + ".html";
			if (mode === 3) return url.replace(/\.html$/, "") + "_" + (i - 1) + ".html";
			//【/ ==> /2/】  第一頁 ==> 第二頁
			if (mode === 4) return url.slice(0, -1) + "/" + i + "/";
			//【 ==> /2】  第一頁 ==> 第二頁
			if (mode === "4") return url + "/" + i;
			//【.html ==> -2.html】  第一頁 ==> 第二頁
			if (mode === 5) return url.replace(/\.html$/, "") + "-" + i + ".html";
			//【-1.html ==> -2.html】  第一頁 ==> 第二頁
			if (mode === "5") return url.replace(/(-\d+)?\.html$/, "") + "-" + i + ".html";
			//【?p=1 ==> ?p=2】  第一頁 ==> 第二頁
			if (mode === 6) return url.replace(/\?p=\d+$/, "") + "?p=" + i;
			//【/1 ==> /2】  第一頁 ==> 第二頁
			//【.html ==> .html/2】  第一頁 ==> 第二頁
			if (mode === 7) return url.replace(/(\.html).*$/, "$1").replace(/\/\d+$/, "") + "/" + i;
			//【 ==> &page=1】  第一頁 ==> 第二頁
			if (mode === 8) return url.replace(/&page=\d+$/, "") + "&page=" + (i - 1);
			//【 ==> &page=2】  第一頁 ==> 第二頁
			if (mode === "8") return url.replace(/&page=\d+$/, "") + "&page=" + i;
			//【.html ==> _2.html】  第一頁 ==> 第二頁
			if (mode === 9) return url.replace(/(_\d+)?\.html$/, "") + "_" + i + ".html";
			//【.html ==> .html/2】  第一頁 ==> 第二頁
			if (mode === 10) return url.replace(/\.html(\/\d+)?$/, "") + ".html/" + i;
			//【/ ==> /2.html】  第一頁 ==> 第二頁
			//【/1.html ==> /2.html】  第一頁 ==> 第二頁
			if (mode === 11) return url.replace(/\/(\d+\.html)?$/, "") + "/" + i + ".html";
			//【/ ==> /2.htm】  第一頁 ==> 第二頁
			//【/1.htm ==> /2.htm】  第一頁 ==> 第二頁
			if (mode === 12) return url.replace(/\/(\d+\.htm)?$/, "") + "/" + i + ".htm";
			//【-1-* ==> -2-*】  第一頁 ==> 第二頁
			if (mode === 13) return url.replace(/-\d+-[^-]+$/, "") + "-" + i;
			//【/1/ ==> /2/】  第一頁 ==> 第二頁
			if (mode === 14) return url.replace(/\/\d+\/$/, "") + "/" + i + "/";
			//【/index.html ==> /index_2.html】  第一頁 ==> 第二頁
			if (mode === 15) return url.replace(/\/(index(_\d+)?\.html)?$/, "") + "/index_" + i + ".html";
			//【 ==> /2#list】  第一頁 ==> 第二頁
			if (mode === 16) return url.replace(/\/(index(_\d+)?\.html)?$/, "") + "/" + i + "#list";
			//【.htm ==> _2.htm】  第一頁 ==> 第二頁
			if (mode === 17) return url.replace(/#$/, "").replace(/(_\d+)?\.htm$/, "") + "_" + i + ".htm";
			//【/ ==> /page/2/】  第一頁 ==> 第二頁
			if (mode === 18) return url.replace(/\/(page\/\d+\/)?$/, "") + "/page/" + i + "/";
			//【-1 ==> -2】  第一頁 ==> 第二頁
			if (mode === 19) return url.replace(/-\d+$/, "") + "-" + i;
			//【 ==> -p-2】  第一頁 ==> 第二頁
			if (mode === 20) return url.replace(/-p-\d+$/, "") + "-p-" + i;
		},
		//重新發送要求
		retryUrl: async (url, res, func, retryCount = 10) => {
			debug(`\n${func}連線錯誤碼:${res.status}\n`, url);
			let retryNum = 1;
			let obj = {
				fn: func,
				url: url,
				status: res.status
			};
			debug(`\n${func}連線錯誤碼:${res.status}重試第${retryNum}次\n`, url);
			let retry = await new Promise(async resolve => {
				for (let check = 1; check <= retryCount; check++) {
					let checkRes = await fetch(url);
					if (checkRes.status == 304 || checkRes.status == 200) {
						let buffer = await checkRes.arrayBuffer();
						resolve({
							ok: true,
							buffer: buffer
						});
						break;
					} else {
						debug(`\n${func}連線錯誤碼:${checkRes.status}重試第${retryNum += 1}次\n`, url);
						await delay(3000);
					}
					if (check >= retryCount) {
						resolve({
							ok: false
						});
					}
				}
			});
			if (retry.ok) {
				return retry.buffer;
			} else {
				fetchErrorArray.push(obj);
				return null;
			}
		},
		fetchErrorMsg: () => {
			if (fetchErrorArray.length > 0) {
				debug(`\nfetchErrorArray\n`, fetchErrorArray);
				setTimeout(() => fn.showMsg(`${DL.str_97}${fetchErrorArray.length}${DL.str_98}`, 10000), 1500);
			}
		},
		//並行要求取得圖片網址,返回圖片網址。
		getImg: async (img, maxPage = 1, mode = 1, rText = null, time = 50, url = siteUrl, msg = 1, request = 0) => {
			if (fn.ge(".FullPictureLoadImage") && request == 0) return fn.gae(".FullPictureLoadImage:not(.small)");
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getImg()")) getImgFnProcessRecord += " > fn.getImg()";
			if (msg == 1) fn.sm1();
			let imgsArray = [];
			let fetchNum = 0;
			const html = _url => fetch(_url).then(async res => {
				debug(`\nfn.getImg() URL`, _url);
				if (res.status >= 400) {
					let resData = await fn.retryUrl(_url, res, "fn.getImg()");
					if (resData !== null) return resData;
				}
				return res.arrayBuffer();
			}).then(buffer => {
				const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
				const htmlText = decoder.decode(buffer);
				if (msg == 1) fn.showMsg(`${DL.str_02}${fetchNum+=1}/${Number(maxPage)}`, 0);
				return htmlText;
			}).catch(error => {
				console.error(`\nfn.getImg() > fetch()出錯:\n${decodeURIComponent(_url)}`, error);
			});
			const resArr = [];
			resArr.push(html(url));
			if (Number(maxPage, 10) > 1) {
				for (let i = 2, n = Number(maxPage); i <= n; i++) {
					resArr.push(html(fn.getModeUrl(url, mode, i)));
					await delay(time);
				}
			}
			await Promise.all(resArr).then(htmls => {
				isFetching = false;
				if (msg == 1) fn.hm();
				for (let i = 0, n = htmls.length; i < n; i++) {
					let dom = fn.doc(htmls[i]);
					let imgs = fn.gae(img, dom, dom);
					//debug(`\nfn.getImg() DOM${i}`, dom);
					for (let p = 0, pn = imgs.length; p < pn; p++) {
						let check = fn.checkImgSrc(imgs[p], rText);
						check.ok ? imgsArray.push(decodeURIComponent(check.src)) : debug(`\nfn.getImg() imgs[${p}]錯誤`, imgs[p]);
					}
				}
			});
			fn.fetchErrorMsg();
			return imgsArray;
		},
		//單線程要求取得圖片網址,完成一個要求會把圖片元素先插入到當前文檔,類翻頁模式,返回圖片網址。
		getImgO: async (img, maxPage = 1, mode = 1, rText = null, time = 200, replaceElement = null, url = siteUrl, msg = 1, request = 0) => {
			if (fn.ge(".FullPictureLoadImage") && request == 0) return fn.gae(".FullPictureLoadImage:not(.small)");
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getImgO()")) getImgFnProcessRecord += " > fn.getImgO()";
			if (msg == 1) fn.sm1();
			let imgsArray = [];
			let fetchNum = 0;
			const html = async (_url, id = 1) => {
				await delay(time);
				return fetch(_url).then(async res => {
					debug(`\nfn.getImgO() URL`, _url);
					if (res.status >= 400) {
						let resData = await fn.retryUrl(_url, res, "fn.getImgO()");
						if (resData !== null) return resData;
					}
					return res.arrayBuffer();
				}).then(buffer => {
					const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
					const htmlText = decoder.decode(buffer);
					let dom = fn.doc(htmlText);
					for (let ele of fn.gae(img, dom, dom)) {
						let check = fn.checkImgSrc(ele);
						if (ele.tagName == "IMG" && check.ok) ele.src = check.src;
						if (id == 1) {
							let targetEle = fn.gae(img).at(-1);
							insertAfter(targetEle, ele.cloneNode(true));
						}
					}
					if (isString(replaceElement)) {
						let ce = fn.gae(replaceElement);
						let re = fn.gae(replaceElement, dom, dom);
						if (ce.length === re.length) {
							for (let [i, e] of ce.entries()) e.outerHTML = re[i].outerHTML;
						}
					}
					if (msg == 1) fn.showMsg(`${DL.str_02}${fetchNum+=1}/${Number(maxPage)}`, 0);
					return htmlText;
				}).catch(error => {
					console.error(`\nfn.getImgO() > fetch()出錯:\n${decodeURIComponent(_url)}`, error);
				});
			};
			const resArr = [];
			resArr.push(await html(url, 0));
			if (Number(maxPage) > 1) {
				for (let i = 2, n = Number(maxPage); i <= n; i++) {
					resArr.push(await html(fn.getModeUrl(url, mode, i)));
				}
			}
			await Promise.all(resArr).then(htmls => {
				isFetching = false;
				fn.hm();
				for (let i = 0, n = htmls.length; i < n; i++) {
					let dom = fn.doc(htmls[i]);
					let imgs = fn.gae(img, dom, dom);
					//debug(`\nfn.getImgO() DOM${i}`, dom);
					for (let p = 0, pn = imgs.length; p < pn; p++) {
						let check = fn.checkImgSrc(imgs[p], rText);
						check.ok ? imgsArray.push(decodeURIComponent(check.src)) : debug(`\nfn.getImgO() imgs[${p}]錯誤`, imgs[p]);
					}
				}
			});
			fn.fetchErrorMsg();
			return imgsArray;
		},
		//使用Iframe框架載入網頁,完成一個載入會把圖片元素先插入到當前文檔,類翻頁模式,返回圖片網址。
		getImgIframe: async (img, maxPage = 1, mode = 1, rEle = null, time = 500, showMsg = 1) => {
			if (fn.ge(".FullPictureLoadImage")) return fn.gae(".FullPictureLoadImage:not(.small)");
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getImgIframe()")) getImgFnProcessRecord += " > fn.getImgIframe()";
			if (showMsg == 1) fn.sm1();
			let imgsArray = await fn.waitEle([img]) || [];
			let fetchNum = 1;
			const html = async (url, index = 0) => {
				let targetEle = fn.gae(img).at(-1);
				let load = fn.ce("p", {
					className: "FullPictureLoadLoading",
					innerText: "Loading..."
				});
				insertAfter(targetEle, load);
				await delay(time);
				let dom = null;
				for (let i = 1; i < 20; i++) {
					dom = await fn.iframeSrcDoc(url, img);
					if (dom !== null) {
						break;
					}
				}
				if (dom) {
					debug("iframeDoc" + index, dom);
					for (let ele of fn.gae(img, dom, dom)) {
						imgsArray.push(ele);
						insertAfter(targetEle, ele.cloneNode(true));
					}
					if (rEle) {
						let ce = fn.gae(rEle);
						let re = fn.gae(rEle, dom, dom);
						if (ce.length === re.length) {
							for (let [i, e] of ce.entries()) e.outerHTML = re[i].outerHTML;
						}
					}
					load.remove();
					if (showMsg == 1) fn.showMsg(`${DL.str_02}${fetchNum+=1}/${Number(maxPage)}`, 0);
				} else {
					fetchNum += 1;
					load.remove();
					let obj = {
						fn: "fn.getImgIframe()",
						url: url
					};
					fetchErrorArray.push(obj);
					fn.showMsg(DL.str_03, 3000);
					return;
				}
			}
			if (Number(maxPage) > 1) {
				for (let i = 2, n = Number(maxPage); i <= n; i++) {
					await html(fn.getModeUrl(siteUrl, mode, i), i);
				}
			}
			debug("\nfn.getImgiframe() 聚集的所有IMG", imgsArray);
			isFetching = false;
			fn.hm();
			fn.fetchErrorMsg();
			return imgsArray;
		},
		//從指定的所有連結取得圖片網址,有並行要求、單線程、翻頁模式,返回圖片網址。
		getImgA: async (elementSelector, link, mode = 0, rText = null, showMsg = 1, request = 0) => {
			if (fn.ge(".FullPictureLoadImage") && request == 0) return fn.gae(".FullPictureLoadImage:not(.small)");
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getImgA()")) getImgFnProcessRecord += " > fn.getImgA()";
			if (showMsg == 1) fn.sm1();
			let links, linkEles, linksNum;
			if (isFn(link)) {
				links = await link();
				linksNum = links.length;
			} else if (isArray(link)) {
				links = link;
				linksNum = links.length;
			} else if (isString(link)) {
				linkEles = fn.gae(link);
				links = [...new Set(linkEles.map(a => a.href))];
				linksNum = links.length + 1;
			} else {
				console.error("\nfn.getImgA() link參數錯誤", link);
				return;
			}
			debug("\nfn.getImgA() links", links);
			let imgsArray = [];
			let fetchNum = 0;
			const html = url => fetch(url).then(async res => {
				debug(`\nfn.getImgA() URL`, url);
				if (res.status >= 400) {
					let resData = await fn.retryUrl(url, res, "fn.getImgA()");
					if (resData !== null) return resData;
				}
				return res.arrayBuffer();
			}).then(buffer => {
				if (showMsg == 1) fn.showMsg(`${DL.str_02}${fetchNum+=1}/${linksNum}`, 0);
				const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
				const htmlText = decoder.decode(buffer);
				return htmlText;
			}).catch(error => {
				console.error(`\nfn.getImgA fetch()出錯:\n${decodeURIComponent(url)}`, error);
			});
			const resArr = [];
			if (isString(link)) resArr.push(html(siteUrl));
			for (let i = 0, n = links.length; i < n; i++) {
				if (mode == 0) {
					resArr.push(html(links[i]));
				} else if (mode >= 100) {
					await delay(mode);
					resArr.push(html(links[i]));
				} else if (mode == 1) {
					let res = await html(links[i]);
					resArr.push(res);
					if (isString(link)) {
						let dom = fn.doc(res);
						debug(`\nfn.getImgA()單線程模式 DOM\n${links[i].href}`, dom);
						let imgs = fn.gae(elementSelector, dom, dom);
						let imgHtml = "";
						for (let p = 0, pn = imgs.length; p < pn; p++) {
							let imgSrc;
							let check = fn.checkImgSrc(imgs[p], rText);
							if (check.ok) {
								imgSrc = check.src;
								//let blob = await GM_XHR_Download(imgSrc);
								//let objectURL = await URL.createObjectURL(blob.blob);
								//imgSrc = objectURL;
								debug("\nfn.getImgA() 單線程模式imgSrc", imgSrc);
							} else {
								console.error("\nfn.getImgA() 單線程模式出錯", imgs[p]);
								continue;
							}
							imgHtml += `<img src="${imgSrc}" style="width: auto; height: auto; max-width: 100%; max-height: unset; display:block; float: unset; opacity: 1; border: none; border-radius: unset; padding: 0; margin: 0 auto; transition: unset; transform: unset;">`;
						}
						linkEles[i].outerHTML = imgHtml;
					}
				} else if (mode == 2) {
					let res = await html(links[i]);
					await delay(200);
					resArr.push(res);
					if (i !== 0) {
						let dom = fn.doc(res);
						let tE = fn.gae(elementSelector).at(-1);
						let eles = fn.gae(elementSelector, dom, dom);
						for (let e of eles) insertAfter(tE, e);
					}
				}
			}
			await Promise.all(resArr).then(htmls => {
				isFetching = false;
				fn.hm();
				for (let i = 0, n = htmls.length; i < n; i++) {
					let dom = fn.doc(htmls[i]);
					//if (mode != 1) debug(`\nfn.getImgA() DOM${i}`, dom);
					let imgs = fn.gae(elementSelector, dom, dom);
					for (let p = 0, pn = imgs.length; p < pn; p++) {
						let check = fn.checkImgSrc(imgs[p], rText);
						check.ok ? imgsArray.push(check.src) : console.error("\nfn.getImgA() PromiseAll出錯", imgs[p]);
					}
				}
			});
			fn.fetchErrorMsg();
			return imgsArray;
		},
		//跨域從指定的所有連結取得圖片網址,並行要求有要求間隔參數,返回圖片網址。
		getImgCorsA: (imgSelector, aSelector, time = 100) => {
			isFetching = true;
			fn.sm1();
			let xhrNum = 0;
			let links;
			isString(aSelector) ? links = fn.gau(aSelector) : links = aSelector;
			let resArr = links.map(async (url, i, arr) => {
				await delay(time * i);
				return fn.xhrDoc(url).then(dom => {
					fn.showMsg(`${DL.str_02}${xhrNum+=1}/${arr.length}`, 0);
					return fn.gae(imgSelector, dom, dom);
				});
			});
			return Promise.all(resArr).then(arr => {
				isFetching = false;
				fn.hm();
				return fn.getImgSrcArr(arr.flat());
			});
		},
		//補全網址
		complementSrc: (src, rText = null) => {
			if (src.startsWith("//")) {
				src = location.protocol + src;
			}
			if (src.startsWith("data:image/svg+xml,<svg") || src.startsWith("data:image/svg+xml;utf8,<svg")) {
				src = fn.dataURLtoBlobURL(src);
			}
			if (/^\/[^\/]+/.test(src)) {
				src = location.origin + src;
			}
			if (!/^(https?:|blob:|data:)/.test(src) && /^\w+/i.test(src)) {
				src = location.origin + "/" + src;
			}
			if (isArray(rText) && rText.length == 2) {
				src = src.replace(rText[0], rText[1]);
			}
			src = src.replace(/\n/g, "").trim();
			return src;
		},
		//確認元素和圖片網址,嘗試取得網址和補全網址。
		checkImgSrc: (ele, rText = null) => {
			let src;
			let check = fn.checkDataset(ele);
			if (isEle(ele)) {
				if (["IMG", "DIV", "A", "SPAN", "LI", "FIGURE", "ARTICLE", "P", "VIDEO"].some(n => n === ele.tagName) && check.ok) {
					src = fn.complementSrc(check.src, rText);
				} else if (["IMG", "AMP-IMG"].some(n => n === ele.tagName)) {
					if (ele.tagName == "IMG") {
						src = ele.src;
					}
					if (ele.tagName == "AMP-IMG") {
						src = ele.getAttribute("src");
					}
					src = fn.complementSrc(src, rText);
				} else if (["A", "LINK"].some(n => n === ele.tagName)) {
					src = ele.href;
					if (isArray(rText) && rText.length == 2) {
						src = src.replace(rText[0], rText[1]);
					}
				} else if (ele.tagName == "svg" && ["viewBox", "version", "xmlns"].every(a => ele.hasAttribute(a))) {
					//src = "data:image/svg+xml;base64," + btoa(ele.outerHTML);
					src = URL.createObjectURL(new Blob([ele.outerHTML], {
						type: "image/svg+xml"
					}));
				} else if (ele.tagName == "CANVAS") {
					try {
						src = ele.toDataURL();
						src = fn.dataURLtoBlobURL(src);
					} catch {}
				}
			}
			if (isString(ele)) {
				if (/^(https?:|blob:|data:|\/|\w+)/i.test(ele)) {
					src = ele;
					src = fn.complementSrc(src, rText);
				}
			}
			if (isURL(src)) {
				if (src === location.href) {
					return {
						ok: false
					}
				}
				return {
					ok: true,
					src
				}
			} else {
				return {
					ok: false
				}
			}
		},
		//確認元素有沒有把圖片原始網址放在src以外的屬性
		checkDataset: ele => {
			if (!isEle(ele)) {
				return {
					ok: false
				}
			}
			if (["IMG", "DIV", "A", "SPAN", "LI", "FIGURE", "P", "ARTICLE", "VIDEO"].some(n => n === ele.tagName)) {
				const datasetArr = [
					"data-hd",
					"data-high-res-src",
					"data-src",
					"data-src_big",
					"data-orig",
					"data-orig-file",
					"data-origin",
					"data-original",
					"data-original-url",
					"data-url",
					"data-lazy",
					"data-lazy-load-src",
					"data-lazy-src",
					"data-lazyload",
					"data-lazyload-src",
					"data-full-path",
					"data-full-url",
					"data-image",
					"data-imageurl",
					"data-img-url",
					"data-actualsrc",
					"data-bgset",
					"data-bgsrc",
					"data-bigsrc",
					"data-cfsrc",
					"data-cover",
					"data-defer-src",
					"data-echo",
					"data-ecp",
					"data-ks-lazyload",
					"data-ks-lazyload-custom",
					"data-large-file",
					"data-lbwps-srcsmall",
					"data-loadsrc",
					"data-mfp-src",
					"data-page-image-url",
					"data-pin-media",
					"data-placeholder",
					"data-preview",
					"data-wpfc-original-src",
					"data-speedycache-original-src",
					"data-thumb",
					"org_img_url",
					"org_src",
					"origin-src",
					"original",
					"bigimg",
					"imgsrc",
					"lazysrc",
					"lg-data-src",
					"load-src",
					"ess-data",
					"zoomfile",
					"file",
					"zsrc",
					"mydatasrc",
					"ng-src",
					"poster",
					"real_src",
					"z-image-loader-url"
				];
				let hasA = datasetArr.find(a => ele.hasAttribute(a));
				if (hasA) {
					return {
						ok: true,
						src: fn.attr(ele, hasA)
					}
				}
				if (["CANVAS", "svg", "IMG"].every(t => ele.tagName != t)) {
					let src = fn.getBackgroundImage(ele);
					if (isString(src)) {
						return {
							ok: true,
							src
						}
					}
				}
			}
			return {
				ok: false
			}
		},
		//取得元素的背景圖片網址
		getBackgroundImage: (ele) => {
			if (!isEle(ele)) {
				return null;
			}
			let backgroundImage = getComputedStyle(ele).getPropertyValue("background-image");
			if (backgroundImage != "none" && backgroundImage?.startsWith("url")) {
				return backgroundImage.slice(5, -2).trim();
			}
			return null;
		},
		//指定元素選擇器或元素陣列,返回提取出的圖片網址陣列。
		getImgSrcArr: (selector, dom = document) => {
			let imgs;
			isString(selector) ? imgs = fn.gae(selector, dom, dom) : imgs = selector;
			let srcs = imgs.map(ele => {
				let check = fn.checkImgSrc(ele);
				return check.ok ? check.src : null;
			}).filter(Boolean);
			return [...new Set(srcs)];
		},
		//指定圖片元素選擇器或圖片元素陣列,返回提取出的圖片網址陣列。
		getImgSrcset: (selector, dom = document) => {
			let imgs;
			isString(selector) ? imgs = fn.gae(selector, dom, dom) : imgs = selector;
			let srcs = imgs.map(ele => {
				let srcset = ele.getAttribute("srcset") || ele.getAttribute("data-srcset") || ele.getAttribute("data-lazy-srcset") || ele.getAttribute("data-bgset") || ele.getAttribute("data-jg-srcset");
				if (srcset && String(srcset).includes(",")) {
					let splitArr = srcset.split(",").map(src => src.trim()).filter(Boolean);
					splitArr = splitArr.sort((a, b) => {
						let a_num;
						try {
							a_num = a.match(/\s([\d\.]+)(w|x)$/)[1];
						} catch {
							a_num = 1;
						}
						let b_num;
						try {
							b_num = a.match(/\s([\d\.]+)(w|x)$/)[1];
						} catch {
							b_num = 1;
						}
						return a_num - b_num;
					});
					let [src] = splitArr.at(-1).trim().split(" ");
					if (/^https:\/\/i\d\.wp\.com/.test(src)) {
						src = src.replace(/\?.+$/, "?ssl=1");
					}
					if (!src.includes(".yituyu.")) {
						src = src.replace(/-\d+x\d+\./, ".");
					}
					//if (decodeURIComponent(src).includes("/none")) console.log(ele);
					try {
						return decodeURIComponent(src);
					} catch {
						return src;
					}
				} else if (srcset && isString(srcset)) {
					if (fn.isImage(srcset)) {
						return srcset;
					} else {
						return null;
					}
				} else {
					if (ele?.parentElement?.id === "pagetual-preload") return null;
					if (isSimpleMode && ele?.tagName === "A") {
						let check = fn.checkDataset(ele);
						if (check.ok) {
							//if (decodeURIComponent(check.src).includes("/none")) console.log(ele);
							if (!fn.isImage(check.src)) {
								console.log("\n可能不是含圖片網址的A元素\n", ele);
								return null;
							}
							try {
								return decodeURIComponent(check.src);
							} catch {
								return check.src;
							}
						} else {
							return null;
						}
					}
					let check = fn.checkImgSrc(ele);
					if (check.ok) {
						let src = check.src;
						if (/^https:\/\/i\d\.wp\.com/.test(src)) {
							src = src.replace(/\?.+$/, "?ssl=1").replace(/-\d+x\d+\./, ".");
						} else {
							if (!src.includes(".yituyu.")) {
								src = src.replace(/-\d+x\d+\./, ".");
							}
							if (src.includes(".jpg.jpg")) {
								src = src.replace(".jpg.jpg", ".jpg");
							}
							if (src.includes(".png.png")) {
								src = src.replace(".png.png", ".png");
							}
						}
						//if (decodeURIComponent(src).includes("/none")) console.log(ele);
						try {
							return decodeURIComponent(src);
						} catch {
							return src;
						}
					} else {
						return null;
					}
				}
			}).filter(Boolean);
			return srcs;
		},
		capture: async (detail = {}) => {
			const {
				s,
				ecb,
				scb,
				vs,
				vcb
			} = detail;
			if (!("s") in detail) return;
			addNewTabViewButton();
			const get = async () => {
				let eles = fn.gae(s);
				if (eles.length) {
					for (let e of eles) e.classList.add("get");
					if ("ecb" in detail) {
						for (let i = 0, n = eles.length; i < n; i++) {
							await ecb(eles[i]);
						}
					} else {
						let src;
						for (src of fn.getImgSrcset(eles)) {
							if ("scb" in detail) {
								await scb(src);
							} else {
								setArray.add(src);
							}
						}
						src = null;
					}
				}
				if ("vs" in detail) {
					let videos = fn.gae(vs);
					if (videos.length) {
						for (let i = 0, n = videos.length; i < n; i++) {
							videos[i].classList.add("get");
							setVideoArray.add(videos[i].getAttribute("value") || videos[i].src);
							if ("vcb" in detail) {
								await vcb(videos[i]);
							}
						}
						videoSrcArray = [...setVideoArray];
					}
				}
				if (captureTotal != setArray.size) {
					captureTotal = setArray.size;
					return captureSrcB();
				}
			};
			fn.addMutationObserver(async () => {
				if (captureExclude()) return;
				await get();
			});
		},
		//確認加了CDN的圖片網址是否有效,無效則刪除CDN返回原始來源的圖片網址
		checkImageCDN: srcArr => {
			fn.showMsg("fn.xhrHEA(check)...", 0);
			let xhrNum = 0;
			return srcArr.map(async (src, i, arr) => {
				await delay(25 * i);
				let res = await fn.xhrHEAD(src);
				fn.showMsg(`fn.xhrHEAD(${xhrNum+=1}/${arr.length})`, 0);
				let status = res.status;
				if (src.includes("wsrv.nl")) {
					return status > 399 ? fn.getUSP("url", src) : src; //wsrv.nl_CDN
				} else {
					return status > 399 ? src.replace(/i\d\.wp\.com\/|\?.+$/g, "") : src; //WordPressCDN
				}
			});
		},
		//移除CDN返回原始來源的圖片網址
		removeImageCDN: srcArr => srcArr.map(src => {
			if (src.includes("wsrv.nl")) {
				return fn.getUSP("url", src); //wsrv.nl_CDN
			} else {
				return src.replace(/i\d\.wp\.com\/|\?.+$/g, ""); //WordPressCDN
			}
		}),
		//從用AList架設的雲端硬碟,提取圖片和影片網址
		getAList: () => {
			let paths = [...document.querySelectorAll("a.list-item")].map(a => decodeURIComponent(a.getAttribute("href"))).map(href => fn.isImage(href) || fn.isVideo(href) || /\.(zip|rar)$/i.test(href) ? href : null).filter(Boolean);
			fn.sm5();
			let fetchNum = 0;
			let password;
			if ("browser-password" in localStorage) {
				password = localStorage.getItem("browser-password");
			} else {
				password = "";
			}
			let resArr = paths.map((path, i, arr) => {
				const body = {
					path,
					password
				};
				return fn.j("/api/fs/get", {
					"headers": {
						"accept": "application/json, text/plain, */*",
						"content-type": "application/json;charset=UTF-8"
					},
					"body": JSON.stringify(body),
					"method": "POST"
				}).then(json => {
					fn.showMsg(`${DL.str_06}${fetchNum+=1}/${arr.length}`, 0);
					return json.code == 200 ? {
						name: json.data.name,
						//url: decodeURIComponent(json.data.raw_url)
						url: json.data.raw_url
					} : null;
				});
			});
			return Promise.all(resArr).then(arr => {
				console.log("AListDataArray", arr);
				return arr.map(obj => {
					if (!obj) return null;
					if (fn.isVideo(obj.name)) {
						videoSrcArray.push(obj.url);
						return null;
					} else if (fn.isZip(obj.name)) {
						fileUrlArray.push(obj.url);
						return null;
					} else {
						return obj.url;
					}
				}).filter(Boolean);
			});
		},
		//從頭一路翻到尾的自動翻頁函式
		getNP: async (pageEle, nextLinkEle, lastEle = null, replaceElement = null, time = 0, dataset = null, msg = 1, retry = 10) => {
			//翻頁模式聚集所有圖片或是預覽縮圖然後fn.getImgA()
			//用在規則init,fn.getNP(picsEle, nextLinkEle, lastEle, replaceElement, time);
			if (fn.ge(".FullPictureLoadImage")) return;
			if (isString(nextLinkEle) && !fn.ge(nextLinkEle)) return;
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getNP()")) getImgFnProcessRecord += " > fn.getNP()";
			let pageEles = fn.gae(pageEle);
			let nextlink = null;
			let page = 1;
			if (msg == 1) fn.showMsg(DL.str_14, 0);
			const getNextLink = async (url = "", dom = document) => {
				if (isFn(nextLinkEle)) {
					nextlink = await nextLinkEle(dom);
				} else if (isString(nextLinkEle)) {
					let ele = fn.ge(nextLinkEle, dom, dom);
					if (!!ele) {
						if (!!ele?.dataset?.url) {
							if (!/^http/.test(ele.dataset.url)) return null;
							nextlink = ele.dataset.url;
						} else if (ele.tagName === "A") {
							nextlink = ele.href;
							let nh = ele.hostname;
							let lh = fn.lh;
							if (nh != lh) nextlink = nextlink.replace(nh, lh);
						} else {
							try {
								ele.getAttribute("href") ? nextlink = ele.getAttribute("href") : nextlink = ele.getAttribute("_href");
							} catch {
								nextlink = null;
							}
						}
					} else {
						nextlink = null;
					}
				} else {
					nextlink = null;
				}
				if (isString(url) && isString(nextlink) && (url === nextlink)) {
					if (msg == 1) fn.showMsg(DL.str_15);
					nextlink = null;
				}
				return nextlink;
			};
			const getNextPageEles = async url => {
				if (msg == 1) fn.showMsg(`${DL.str_14} (Page${page += 1})`, 0);
				await fetch(url).then(async res => {
					if (res.status >= 400) {
						let resData = await fn.retryUrl(url, res, "fn.getNP()");
						if (resData !== null) return resData;
					}
					return res.arrayBuffer();
				}).then(buffer => {
					const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
					const htmlText = decoder.decode(buffer);
					return htmlText;
				}).then(async htmlText => {
					let dom = fn.doc(htmlText);
					let lastPage = null;
					if (isString(lastEle)) {
						lastPage = fn.ge(lastEle, dom, dom);
					} else if (isFn(lastEle)) {
						try {
							lastPage = await lastEle(dom);
						} catch (error) {
							debug("fn.getNP() lastEle() 函式錯誤", error);
							lastPage = null;
						}
					}
					if (lastPage) {
						isFetching = false;
						if (msg == 1) fn.showMsg(DL.str_15);
						return;
					}
					if (!fn.ge(pageEle, dom, dom)) {
						for (let i = 1; i <= retry; i++) {
							dom = await fn.iframeSrcDoc(url, pageEle);
							if (dom != null) {
								break;
							}
						}
					}
					if (!dom) dom = fn.doc(htmlText);
					if (isString(dataset)) {
						for (let e of fn.gae(dataset, dom, dom)) {
							let check = fn.checkImgSrc(e);
							if (check.ok) {
								if (e.tagName == "IMG") {
									e.src = check.src;
								} else if (["A", "DIV", "SPAN", "LI", "FIGURE"].some(n => n === e.tagName)) {
									e.style.backgroundImage = `url(${check.src})`;
								}
							}
						}
					}
					//debug(`\nfn.getNP() > getNextPageEles() DOM\n${decodeURIComponent(url)}`, dom);
					let eles = fn.gae(pageEle, dom, dom).map(e => e.cloneNode(true));
					pageEles = [...pageEles, ...eles];
					fragment.append(...eles);
					let targetEle = fn.gae(pageEle).at(-1);
					insertAfter(targetEle, fragment);
					if (replaceElement) {
						let currentPageEles = fn.gae(replaceElement);
						let nextPageEles = fn.gae(replaceElement, dom, dom);
						if (currentPageEles.length === nextPageEles.length) {
							for (let [i, e] of currentPageEles.entries()) e.outerHTML = nextPageEles[i].outerHTML;
						}
					}
					nextlink = await getNextLink(url, dom);
					if (nextlink) {
						await delay(time);
						await getNextPageEles(nextlink);
					} else {
						isFetching = false;
						if (msg == 1) fn.showMsg(DL.str_15);
						return;
					}
				});
			};
			nextlink = await getNextLink();
			if (nextlink) {
				await delay(time);
				await getNextPageEles(nextlink);
			} else {
				isFetching = false;
				if (msg == 1) fn.showMsg(DL.str_15);
			}
			return pageEles;
		},
		//傳入免費圖片空間的連結陣列,提取圖片網址
		getImageHost: async (links = captureLinksArray) => {
			let imgsSrcArr = [];
			if (links.length > 0) {
				if (/\.\w+$/.test(links[0]) && !/\.html$/.test(links[0]) && !/\/fappic\.com\//.test(links[0]) && !/pixhost\.to\/show\//.test(links[0]) && !/^https?:\/\/imagetwist\.com\//.test(links[0])) return links;
				fn.sm1();
				let xhrNum = 0;
				let resArr = links.map(async (url, i, arr) => {
					await delay(100 * i);
					if (/imagebam/.test(url)) {
						return fn.imageBamXHR(url).then(dom => {
							fn.showMsg(`${DL.str_02}${xhrNum+=1}/${arr.length}`, 0);
							let img = fn.ge("img.main-image", dom);
							return img ? img.src : null;
						});
					} else if (/postimg/.test(url)) {
						return fn.xhr(url, {
							responseType: "document"
						}).then(dom => {
							fn.showMsg(`${DL.str_02}${xhrNum+=1}/${arr.length}`, 0);
							let a = fn.ge("a#download", dom);
							return a ? a.href : null;
						});
					} else {
						return fn.xhr(url, {
							responseType: "document"
						}).then(dom => {
							fn.showMsg(`${DL.str_02}${xhrNum+=1}/${arr.length}`, 0);
							let img = fn.ge("#imgpreview,#image,.pic.img.img-responsive,#imageid,#img.image-content,.card-body img,.image.img-fluid,img.pic[alt][title]", dom);
							return img ? img.src : null;
						});
					}
				})
				await Promise.all(resArr).then(arr => (imgsSrcArr = arr.filter(Boolean)));
			}
			return imgsSrcArr;
		},
		// 讓用Iframe框架載入網頁,能像fetch的寫法
		iframe: (url, details = {}) => new Promise((resolve, reject) => {
			const {
				srcdoc,
				loadTime,
				timeout,
				wait,
				waitEle,
				waitVar,
				cb,
				hide
			} = details;
			const iframe = fn.ace("bodya", "iframe", {
				id: "FullPictureLoadIframe",
				name: "FullPictureLoad-iframe",
				sandbox: "allow-same-origin allow-scripts allow-popups allow-forms"
			}, {
				display: ("hide" in details) ? "none" : ""
			});
			const tid = setTimeout(() => resolve({
				dom: null,
				frame: null
			}), ("timeout" in details && isNumber(timeout)) ? timeout : 30000);
			const call = async () => {
				clearTimeout(tid);
				await delay(("loadTime" in details && isNumber(loadTime)) ? loadTime : 1000);
				const frame = iframe.contentWindow;
				const dom = iframe.contentDocument || iframe.contentWindow.document;
				dom.body.scrollTop = 9999999;
				dom.documentElement.scrollTop = 9999999;
				if ("wait" in details && isFn(wait)) {
					await fn.wait(() => wait(dom, frame));
				}
				if ("waitEle" in details && (isString(waitEle) || isArray(waitEle))) {
					await fn.waitEle(waitEle, 600, dom);
				}
				if ("waitVar" in details) {
					await new Promise(end => {
						const loop = setInterval(() => {
							let check;
							if (isString(waitVar)) {
								check = (waitVar in frame);
							} else if (isArray(waitVar)) {
								check = waitVar.every(k => (k in frame));
							}
							if (check) {
								clearInterval(loop);
								end();
							}
						}, 100);
					});
				}
				const {
					frameCode
				} = siteData;
				if (isString(frameCode)) {
					fn.script(frameCode, dom.body);
				}
				if ("cb" in details && isFn(cb)) {
					await cb(dom, frame);
				}
				resolve({
					dom,
					frame
				});
				setTimeout(() => iframe.remove(), 1000);
			};
			iframe.onload = () => call();
			iframe.error = reject;
			if ("srcdoc" in details) {
				iframe.srcdoc = srcdoc;
			} else {
				iframe.src = url;
			}
		}),
		//使用Iframe框架載入網頁,直到框架的window出現指定的環境變數,返回框架的window
		iframeVar: (url, key, loadTime = 1000) => fn.iframe(url, {
			waitVar: key,
			loadTime,
			hide: true
		}).then(({
			frame
		}) => frame),
		//Iframe框架載入網頁返回框架的document
		iframeDoc: (url, selector, timeout = 5000) => fn.iframe(url, {
			waitEle: selector,
			loadTime: Number(siteData?.autoPager?.loadTime) || 200,
			timeout
		}).then(({
			dom,
			frame
		}) => {
			frameWindow = frame;
			return dom;
		}),
		//先用Fetch API取得網頁原始碼,再傳入Iframe框架載入網頁返回框架的document
		iframeSrcDoc: (url, selector, timeout = 5000) => fetch(url).then(async res => {
			debug(`\nfn.iframeSrcDoc() URL`, url);
			if (res.status >= 400) {
				let resData = await fn.retryUrl(url, res, "fn.iframeSrcDoc()");
				if (resData !== null) return resData;
			}
			return res.arrayBuffer();
		}).then(buffer => {
			const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
			const htmlText = decoder.decode(buffer);
			return htmlText;
		}).then(resText => fn.iframe(url, {
			srcdoc: resText,
			waitEle: selector,
			loadTime: siteData?.autoPager?.loadTime || 200,
			timeout
		}).then(({
			dom,
			frame
		}) => {
			frameWindow = frame;
			return dom;
		})),
		//無限滾動模式添加頁面控制按鈕
		createAutoPagerButtons: () => {
			const ab = fn.ace("bodya", "div", {
				id: "FullPictureLoadAutoPagerButtonsRoot"
			});
			const shadow = ab.attachShadow({
				mode: "closed"
			});
			fn.ace(shadow, "style", {
				type: "text/css",
				innerHTML: `
.button {
    font-size: 16px;
    font-family: "Microsoft YaHei", Arial, sans-serif;
    padding: 2px 10px 4px;
    color: #fff;
    border-style: solid;
    border-color: #444;
    background-color: #444;
    border-radius: 0.5rem;
    min-width: 88px;
    position: fixed;
    z-index: ${UI_zIndex - 3} !important;
    top: auto;
    left: 24px;
    right: auto;
    user-select: none;
}
.hide {
    display: none;
}
#setting-btn-div {
    width: auto;
    height: auto;
    position: fixed;
    right: ${isM ? "10px" : "30px"};
    bottom: 150px;
    z-index: ${UI_zIndex - 3};
}
.setting-btn {
    width: 48px;
    height: 48px;
    text-align: center;
    user-select:none;
    color: #333;
    margin: 5px 0;
    overflow: hidden;
    border: #333 2px solid;
    background: rgba(255, 255, 255, 0.8);
    border-radius: 12px;
    cursor: pointer;
}
.setting-btn .icon {
    margin-top: 10px;
    width: 28px;
    height: 28px;
}
#modal-content-list {
    background-color: #eee;
    position: fixed;
    z-index: ${UI_zIndex - 3};
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    padding: 10px;
    border: 1px solid #888;
    min-width: 350px;
    max-width: 600px;
    max-height: 74%;
    overflow-y: auto;
}
.closeModal {
    position: absolute;
    color: #000;
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
}
.chapter-list-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
    padding-top: 20px;
}
.chapter-btn {
    background-color: #fff;
    color: #000;
    border: 1px solid #a2a2a2;
    padding: 10px;
    cursor: pointer;
    border-radius: 5px;
    font-size: 13px;
    width: calc(33.3333% - 8px);
    box-sizing: border-box;
    text-align: center;
    overflow:hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.chapter-btn:not(.current-chapter):hover {
    background-color: #ffa64d;
    color: #fff;
}
.current-chapter {
    background-color: #1790e6;
    color: #fff;
}
#chapters-footer {
    margin: 10px 0;
    display: flex;
    justify-content: flex-end;
}
#footer_close_button {
    display: block;
    width: 100%;
    color: #000;
    background-color: #ccc;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 10px;
    box-sizing: content-box;
    font-size: 16px;
    font-weight: 600;
}`
			});

			const {
				home,
				list,
				update,
				scroll,
				background,
				color
			} = siteData.autoPager;

			let list_link;
			if (isFn(list)) {
				list_link = list();
			} else {
				list_link = fn.gu(list);
			}

			let toggle_button;
			let list_button;

			const array = [{
				id: "settings",
				text: fn.rt(DL.str_85, "(*)", ""),
				cb: (event) => {
					cancelDefault(event);
					createPictureLoadOptionsShadowElement();
				}
			}, {
				id: "toggle",
				text: DL.str_228,
				cb: (event) => {
					cancelDefault(event);
					fn.toggleAutoPager();
					if (autoPagerSwitch) {
						toggle_button.innerText = DL.str_228;
					} else {
						toggle_button.innerText = DL.str_229;
					}
				}
			}, {
				id: "favor",
				text: fn.rt(DL.str_128, "(9)", ""),
				cb: (event) => {
					cancelDefault(event);
					createFavorShadowElement();
				}
			}, {
				id: "list",
				text: DL.str_224,
				cb: (event) => {
					cancelDefault(event);
					fn.showMsg(DL.str_225, 0);
					return (isGoToNext = true) && (location.href = list_link);
				}
			}, {
				id: "update",
				text: DL.str_226.replace("( U )", ""),
				cb: (event) => {
					cancelDefault(event);
					fn.showMsg(DL.str_227, 0);
					return (isGoToNext = true) && (location.href = update);
				}
			}, {
				id: "home",
				text: DL.str_217,
				cb: (event) => {
					cancelDefault(event);
					fn.showMsg(DL.str_223, 0);
					return (isGoToNext = true) && (location.href = home ? home : location.origin);
				}
			}];

			if (!list && !update) {
				array.splice(3, 2);
			} else if (!update) {
				array.splice(4, 1);
			} else if (!list || !list_link) {
				array.splice(3, 1);
			}

			const buttons = array.map((o, i) => {
				const button = fn.ce("button", {
					id: o.id,
					className: o.id == "settings" && siteData?.category?.includes("comic") ? "button" : "button hide",
					innerText: o.text,
					oncontextmenu: () => false,
					onclick: o.cb
				}, {
					color: color ? color : "",
					borderColor: background ? background : "",
					backgroundColor: background ? background : "",
					bottom: (80 + (i * 40)) + "px"
				});
				if (o.id == "toggle") {
					toggle_button = button;
				}
				if (o.id == "list") {
					list_button = button;
				}
				return button;
			});
			shadow.append(...buttons);

			if (isPC && siteData?.category?.includes("comic")) {
				const config = getConfig();
				let changeSizeTimeId;

				const resetWidth = () => {
					if (getType(changeSizeTimeId) == "Number") {
						clearTimeout(changeSizeTimeId);
					}
					isChangeSize = true;
					let imgs = gae(".FullPictureLoadImage");
					config.webtoonWidth = isM ? innerWidth : 800;
					saveConfig(config);
					fn.showMsg("Reset");
					for (let e of imgs) e.style.maxWidth = "";
					changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
				};

				const increaseWidth = () => {
					if (getType(changeSizeTimeId) == "Number") {
						clearTimeout(changeSizeTimeId);
					}
					isChangeSize = true;
					let imgs = gae(".FullPictureLoadImage");
					let parent = imgs.at(0).parentElement;
					if (config.webtoonWidth < parent.offsetWidth) {
						config.webtoonWidth = (Number(config.webtoonWidth) + 50);
						saveConfig(config);
						fn.showMsg(config.webtoonWidth);
						for (let e of imgs) e.style.maxWidth = config.webtoonWidth + "px";
					} else {
						config.webtoonWidth = isM ? innerWidth : 800;
						saveConfig(config);
						fn.showMsg(config.webtoonWidth);
						for (let e of imgs) e.style.maxWidth = "";
					}
					changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
				};

				const reduceWidth = () => {
					if (getType(changeSizeTimeId) == "Number") {
						clearTimeout(changeSizeTimeId);
					}
					isChangeSize = true;
					let imgs = gae(".FullPictureLoadImage");
					let parent = imgs.at(0).parentElement;
					if (config.webtoonWidth > 100) {
						config.webtoonWidth = (Number(config.webtoonWidth) - 50);
						saveConfig(config);
						fn.showMsg(config.webtoonWidth);
						for (let e of imgs) e.style.maxWidth = config.webtoonWidth + "px";
					} else {
						config.webtoonWidth = isM ? innerWidth : 800;
						saveConfig(config);
						fn.showMsg(config.webtoonWidth);
						for (let e of imgs) e.style.maxWidth = "";
					}
					changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
				};

				const btn_div = fn.ace(shadow, "div", {
					id: "setting-btn-div",
					className: "hide"
				});
				[{
					id: "resetBtn",
					svg: svg.reset,
					cb: resetWidth
				}, {
					id: "addBtn",
					svg: svg.plus,
					cb: increaseWidth
				}, {
					id: "reduceBtn",
					svg: svg.minus,
					cb: reduceWidth
				}].forEach(o => fn.ace(btn_div, "div", {
					id: o.id,
					className: "setting-btn",
					innerHTML: o.svg,
					oncontextmenu: () => false,
					onclick: o.cb
				}));
				buttons.push(btn_div);
			}

			let scrollNode = document;
			if (scroll) {
				scrollNode = fn.ge(scroll);
			}
			let lastScrollTop = 0;
			scrollNode.addEventListener("scroll", event => {
				if (isRemove) return (lastScrollTop = 0);
				const st = event?.srcElement?.scrollingElement?.scrollTop || event.srcElement.scrollTop;
				if (st > lastScrollTop) {
					for (let e of buttons) e.classList.add("hide");
					list_main?.classList.add("hide");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					if (autoPagerSwitch) {
						toggle_button.innerText = DL.str_228;
					} else {
						toggle_button.innerText = DL.str_229;
					}
					for (let e of buttons)(e.id == "settings" && !siteData?.category?.includes("comic")) ? void 0 : e.classList.remove("hide");
					lastScrollTop = st;
				}
			});

			let list_main;

			if (("chapters" in siteData.autoPager) && list) {
				// 創建目錄
				const get_chapters = siteData.autoPager.chapters;
				const createChapterList = async () => {
					let chapterListData = [];
					if (isObject(get_chapters)) {
						chapterListData = await fn.getChapters(get_chapters);
					} else if (isFn(get_chapters)) {
						chapterListData = await get_chapters();
					}
					if (!isArray(chapterListData) || !chapterListData?.length) return;
					if (isNumber(chapterListData?.length)) {
						if (chapterListData.length < 2) return;
					}
					const tempURLs = new Set();
					chapterListData = chapterListData.filter(({
						url
					}) => {
						if (tempURLs.has(url) || url == "#") {
							return false;
						} else {
							tempURLs.add(url);
						}
						return true;
					});
					list_main = fn.ace(shadow, "div", {
						id: "modal-content-list",
						className: "hide"
					});
					fn.ace(list_main, "span", {
						className: "closeModal",
						innerText: `× ${DL.str_132}`,
						onclick: () => {
							list_main.classList.add("hide");
						}
					});
					const list_container = fn.ace(list_main, "div", {
						id: "chapterListContainer",
						className: "chapter-list-container"
					});
					const footer = fn.ace(list_main, "div", {
						id: "chapters-footer"
					});
					fn.ace(footer, "button", {
						id: "footer_close_button",
						innerText: DL.str_132,
						onclick: () => {
							list_main.classList.add("hide");
						}
					});
					let lists;
					list_button.innerText = fn.rt(DL.str_216, " ( C )", "");
					list_button.onclick = () => {
						list_main.classList.remove("hide");
						lists = [];
						list_container.innerHTML = "";
						const pathname = decodeURIComponent(fn.clp());
						const search = fn.cls();
						let isCurrent = false;
						let currentButton;
						lists = chapterListData.map(({
							text,
							url
						}) => {
							const button = fn.ce("button", {
								className: "chapter-btn",
								innerText: text,
								dataset: {
									url
								}
							});
							if ("checkCurrentChapter" in siteData) {
								isCurrent = siteData.checkCurrentChapter(url, text);
							}
							if (
								isCurrent ||
								search && url.endsWith(search) ||
								!search && decodeURIComponent(url).endsWith(pathname) ||
								search.includes("page=") && url.includes(pathname)
							) {
								button.classList.add("current-chapter");
								currentButton = button;
							} else {
								button.addEventListener("click", (event) => {
									cancelDefault(event);
									fn.showMsg(DL.str_218, 0);
									return (isGoToNext = true) && setTimeout(() => (location.href = button.dataset.url), 200);
								});
							}
							return button;
						});
						fragment.append(...lists);
						list_container.append(fragment);
						list_main.scrollTop = currentButton.offsetTop - (list_main.clientHeight / 2) + currentButton.clientHeight;
					}
				};
				createChapterList();
			}
		},
		//無限滾動切換狀態
		toggleAutoPager: () => {
			if (isChangeSize) return;
			let hide = siteData.autoPager?.hide;
			if (autoPagerSwitch === true) {
				autoPagerSwitch = false;
				fn.showMsg(DL.str_89);
				for (let e of fn.gae(".autoPagerTitle")) e.classList.add("off");
				if (isString(hide)) {
					fn.remove("#autoPagerHide");
				}
			} else {
				autoPagerSwitch = true;
				fn.showMsg(DL.str_90);
				for (let e of fn.gae(".autoPagerTitle")) e.classList.remove("off");
				if (isString(hide)) {
					hide += "{display:none!important;}";
					fn.css(hide, "autoPagerHide");
				}
			}
		},
		//無限滾動自動翻頁函式
		infiniteScroll: async () => {
			fn.addLoading();
			let hide = siteData.autoPager?.hide;
			let url;
			try {
				url = await fn.getNextLink(doc);
				if (!url) {
					autoPagerSwitch = false;
					fn.showMsg(DL.str_58, 3000);
					fn.removeLoading();
					if (isString(hide)) {
						fn.remove("#autoPagerHide");
					}
					return;
				}
			} catch (error) {
				console.error("\n取得下一頁連結出錯\n", error);
				fn.removeLoading();
				if (isString(hide)) {
					fn.remove("#autoPagerHide");
				}
				return;
			}
			let mode = siteData.autoPager?.mode;
			let eleSelector = siteData.autoPager.ele;
			let apiJson = {};
			if (isString(mode) && mode == "json") {
				let options = {
					cache: "no-cache"
				};
				if (isFn(siteData.autoPager?.fetchOptions)) {
					options = siteData.autoPager.fetchOptions();
				}
				apiJson = await fn.j(url, options).then(json => {
					if (isFn(siteData.autoPager?.fetchCB)) {
						siteData.autoPager.fetchCB(json);
					}
					return json;
				});
				siteJson = apiJson;
			} else if (isNumber(mode) && mode == 1) {
				doc = await fn.iframeDoc(url, (siteData.autoPager?.waitEle || eleSelector), 30000);
			} else {
				if (httpFetchError === false) {
					doc = await fn.fetchDoc(url, 0);
				}
				if (httpFetchError === true || !doc) {
					doc = await fn.xhrDoc(url);
				}
			}
			//debug(`\nfn.infiniteScroll()\n${url}\n`, doc);
			debug(`\nfn.infiniteScroll()\n${url}`);
			let stop = siteData.autoPager?.stop;
			if (isFn(stop) || isString(eleSelector)) {
				let stopCheck;
				if (isFn(stop)) {
					try {
						stopCheck = await stop(doc);
					} catch (error) {
						console.error("\nsiteData.autoPager.stop() 函式錯誤\n", error);
						stopCheck = false;
					}
				} else if (isString(eleSelector)) {
					stopCheck = !fn.ge(eleSelector, doc, doc); //有元素false沒有元素true
				}
				if (stopCheck) {
					autoPagerSwitch = false;
					fn.removeLoading();
					fn.showMsg(DL.str_58, 3000);
					if (isString(hide)) {
						let eles = fn.gae(hide);
						for (let e of eles) e.style.display = "";
					}
					return;
				}
			}
			let isSkip = false;
			if ("skipHistory" in siteData.autoPager) {
				isSkip = await siteData.autoPager.skipHistory(url);
			}
			let history = siteData.autoPager?.history;
			if (history != 0 && mode != "json" && !isSkip) {
				try {
					await fn.addHistory(doc?.title ?? document.title, url);
				} catch (error) {
					console.error(error);
				}
			}
			if (history != 0 && mode == "json" && !isSkip) {
				try {
					let title;
					if (isFn(siteData.autoPager?.title)) {
						title = await siteData.autoPager?.title(apiJson);
					}
					await fn.addHistory(title ?? document.title, currentURL);
				} catch (error) {
					console.error(error);
				}
			}
			if (mode != "json" && !isSkip) {
				currentURL = url
			}
			let wait = siteData.autoPager?.wait;
			if (isFn(wait)) {
				await wait(doc);
			}
			let script = siteData.autoPager?.script;
			if (isString(script)) {
				let scripts = fn.gae(script, doc);
				for (let i = 0, n = scripts.length; i < n; i++) {
					if (scripts[i].src == "") {
						let code = scripts[i].innerHTML;
						fn.script(code);
					}
				}
			}
			let lazySrc = siteData.autoPager?.lazySrc;
			if (isString(lazySrc)) {
				let eles = fn.gae(lazySrc, doc, doc);
				for (let i = 0, n = eles.length; i < n; i++) {
					let check = fn.checkDataset(eles[i]);
					if (check.ok) {
						if (eles[i].tagName === "IMG") {
							eles[i].src = check.src;
						} else if (["DIV", "A", "SPAN", "LI", "FIGURE"].some(t => t === eles[i].tagName)) {
							eles[i].style.backgroundImage = `url("${check.src}")`;
						}
					}
				}
			}
			let bF = siteData.autoPager?.bF;
			if (isFn(bF)) await bF(doc);
			let re = siteData.autoPager?.re;
			if (isString(re)) {
				let currentPageEles = fn.gae(re);
				let nextPageEles = fn.gae(re, doc, doc);
				if (currentPageEles.length === nextPageEles.length) {
					for (let [i, e] of currentPageEles.entries()) e.outerHTML = nextPageEles[i].outerHTML;
				}
			}
			let newEles, tE;
			let pos = siteData.autoPager?.pos;
			if (isFn(eleSelector) && pos || isString(eleSelector)) {
				if (isString(mode) && mode == "json") {
					newEles = await eleSelector(apiJson);
				} else if (isFn(eleSelector)) {
					newEles = await eleSelector(doc);
				} else if (isString(eleSelector)) {
					let nextEle = fn.ge(eleSelector, doc, doc);
					if (!nextEle) {
						fn.removeLoading();
						fn.showMsg(DL.str_59, 3000);
						return;
					}
					tE = fn.gae(eleSelector).at(-1);
					newEles = fn.gae(eleSelector, doc, doc);
				}
				if (siteData.autoPager?.showTitle !== 0) {
					let add = true;
					let titleText = null;
					let num = siteData.autoPager?.pageNum;
					let title = siteData.autoPager?.title;
					if (isString(num)) {
						titleText = `Page ${fn.gt(num, 1, doc)}`;
					} else if (isFn(num)) {
						titleText = `Page ${await num(doc)}`;
					} else if (isFn(title)) {
						try {
							titleText = await title(mode == "json" ? apiJson : doc, frameWindow);
							if (isObject(titleText)) {
								titleText.ok ? titleText = titleText.text : add = false;
							}
						} catch (error) {
							console.error("\nsiteData.autoPager.title() 函式錯誤\n", error);
						}
					}
					if (add) {
						if (mode == "json") {
							url = document.URL;
						}
						fragment.append(fn.titleUrlEle(url, (titleText || doc?.title || document.title)));
					}
				}
				fragment.append(...newEles);
				if (isArray(pos) && pos.length == 2 && isString(pos[0]) && isNumber(pos[1])) {
					const [selector, p] = pos;
					tE = fn.ge(selector);
					if (p === 0) { //元素裡面
						tE.append(fragment);
					} else if (p === 1) { //元素之前
						insertBefore(tE, fragment);
					} else if (p === 2) { //元素之後
						insertAfter(tE, fragment);
					}
				} else {
					insertAfter(tE, fragment);
				}
			} else if (isFn(eleSelector)) {
				await eleSelector(doc);
			}
			fn.removeLoading();
			let aF = siteData.autoPager?.aF;
			if (isFn(aF)) await aF(doc);
			if (siteData.category === "comic autoPager") {
				await fn.lazyload();
				let pagerTitles = fn.gae(".autoPagerTitle");
				if (pagerTitles.length > 3) {
					isRemove = true;
					let parentE = pagerTitles[0].parentNode;
					pagerTitles[0].remove();
					let nodes = [...parentE.childNodes];
					for (let i = 0, n = nodes.length; i < n; i++) {
						if (nodes[i].className === "autoPagerTitle") {
							break;
						}
						nodes[i].remove();
					}
					setTimeout(() => (isRemove = false), 200);
				}
			}
			let observer = siteData.autoPager?.observer;
			if (isString(observer)) {
				await delay(siteData.autoPager?.sleep ?? 1000);
				let ele = fn.gae(observer).at(-1);
				fn.nextObserver.observe(ele);
			}
			if ("preloadNextPage" in siteData.autoPager) {
				setTimeout(() => fn.preloadNextPage(mode == "json" ? apiJson : doc), 3000);
			}
		},
		//無限滾動預讀下一頁
		preloadNextPage: async (o = document) => {
			let preloadNextPage = siteData.autoPager?.preloadNextPage;
			if (isNumber(preloadNextPage) && preloadNextPage === 1 && siteData.category === "comic autoPager") {
				let nextSelector = siteData.autoPager.next;
				let nextUrl = null;
				if (isString(nextSelector)) {
					let nextE = fn.ge(nextSelector, o, o);
					if (!!nextE) {
						nextUrl = nextE.href;
					}
				} else if (isFn(nextSelector)) {
					nextUrl = await nextSelector(o, 0);
				}
				if (!!nextUrl) {
					let _fetch;
					if (siteData.autoPager?.mode == 1 && "waitEle" in siteData.autoPager) {
						_fetch = fn.iframeDoc(nextUrl, siteData.autoPager.waitEle);
					} else if ("cors" in siteData) {
						_fetch = fn.xhrDoc(nextUrl);
					} else {
						_fetch = fn.fetchDoc(nextUrl);
					}
					_fetch.then(async nextDoc => {
						let srcs = await siteData.getSrcs(nextDoc);
						let text;
						let title = siteData.autoPager?.title;
						if (isFn(title)) {
							text = await title(nextDoc);
							if (isObject(text)) {
								text = nextDoc.title;
							}
						} else {
							text = nextDoc.title;
						}
						fn.picPreload(srcs, text, "next");
					});
				}
			} else if (isFn(preloadNextPage)) {
				preloadNextPage(o);
			}
		},
		//無限滾動函式用來觀察元素觸發自動翻頁
		nextObserver: new IntersectionObserver((entries, observer) => {
			for (let entry of entries) {
				if (entry.isIntersecting && autoPagerSwitch) {
					observer.unobserve(entry.target);
					fn.infiniteScroll();
				}
			}
		}),
		//無限滾動取得下一頁連結函式
		getNextLink: async (dom) => {
			let nextSelector = siteData.autoPager.next;
			if (isFn(nextSelector)) {
				let nextCode = await nextSelector(dom);
				if (nextLink === nextCode && siteData?.autoPager?.mode !== "json") return null;
				nextLink = nextCode;
			} else if (isString(nextSelector)) {
				let nextEle = fn.ge(nextSelector, dom, dom);
				try {
					if (!nextEle || (nextEle && (nextLink === nextEle.href))) return null;
				} catch (error) {
					console.error("\nfn.getNextLink() ERROR\n", error);
					return null;
				}
				nextLink = nextEle.href;
				const nh = nextEle.hostname;
				const lh = fn.lh;
				if (nh !== lh) nextLink = nextLink.replace(nh, lh);
			} else {
				return null;
			}
			if (!nextLink) return null;
			return nextLink;
		},
		//無限滾動創建標題函式
		titleUrlEle: (url, title) => {
			let div = fn.ce("div", {
				className: autoPagerSwitch ? "autoPagerTitle" : "autoPagerTitle off"
			});
			if (siteData?.autoPager?.mode === "json") {
				div.innerText = title;
			} else {
				fn.ace(div, "a", {
					href: url,
					innerText: title
				});
			}
			div.addEventListener("click", event => {
				if (event.target.tagName === "DIV") {
					fn.toggleAutoPager();
				}
			});
			return div;
		},
		//無限滾動創建載入中圖示函式
		addLoading: () => {
			if (siteData.autoPager?.loading === "msg") {
				fn.showMsg(DL.str_57, 0);
			} else {
				try {
					let img = new Image();
					img.className = "autoPagerLoading";
					img.src = autoPagerLoading_gif;
					let tE;
					let pos = siteData.autoPager?.pos;
					if (isArray(pos) && pos.length == 2 && isString(pos[0]) && isNumber(pos[1])) {
						const [selector, p] = pos;
						tE = fn.ge(selector);
						if (p === 0) { //元素裡面
							tE.append(img);
						} else if (p === 1) { //元素之前
							insertBefore(tE, img);
						} else if (p === 2) { //元素之後
							insertAfter(tE, img);
						}
					} else {
						tE = fn.gae(siteData.autoPager.ele).at(-1);
						insertAfter(tE, img);
					}
				} catch {
					fn.showMsg(DL.str_57, 0);
				}
			}
		},
		//無限滾動移除載入中圖示函式
		removeLoading: () => {
			if (siteData.autoPager?.loading === "msg") {
				fn.hm();
			} else {
				try {
					fn.ge(".autoPagerLoading").remove();
				} catch {
					fn.hm();
				}
			}
		},
		//無限滾動添加瀏覽器歷史紀錄函式
		addHistory: (title, url) => {
			history.pushState(null, title, url);
			document.title = title;
		},
		//修改A元素以新分頁的方式開啟連結
		openInNewTab: selector => {
			for (let a of fn.gae(selector)) a.setAttribute("target", "_blank");
		},
		//傳入連結陣列使用iframe框架載入,取得元素插入到當前頁面指定的位置或返回元素
		getEleF: async (links, elements, targetEle = null) => {
			if (fn.ge(".FullPictureLoadImage")) return;
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getEleF()")) getImgFnProcessRecord += " > fn.getEleF()";
			fn.showMsg(DL.str_16, 0);
			if (isString(links)) {
				links = fn.gau(links);
			}
			let resArr = [];
			let fetchNum = 0;
			for (let url of links) {
				let res = await fn.iframeDoc(url, elements).then(dom => {
					fn.clearAllTimer();
					fn.showMsg(`${DL.str_17}${fetchNum+=1}/${links.length}`, 0);
					let eles = fn.gae(elements, dom, dom);
					if (targetEle === null) {
						return eles;
					}
					let ele;
					fragment.append(...eles);
					if (isArray(targetEle)) {
						const [selector, p] = targetEle;
						ele = fn.ge(selector);
						if (p == 0) ele.append(fragment);
						else if (p == 1) insertBefore(ele, fragment);
						else if (p == 2) insertAfter(ele, fragment);
					}
					return eles;
				});
				resArr.push(res);
			}
			isFetching = false;
			fn.hm();
			return Promise.all(resArr).then(arr => arr.flat());
		},
		//傳入連結陣列並行要求取得元素插入到當前頁面指定的位置或返回元素
		getEle: async (links, elements, targetEle = null, removeEles = null, time = 100, retry = 40) => {
			if (fn.ge(".FullPictureLoadImage")) return;
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getEle()")) getImgFnProcessRecord += " > fn.getEle()";
			let resArr = [];
			let xhrNum = 0;
			fn.showMsg(DL.str_16, 0);
			if (isString(links)) {
				links = fn.gau(links);
			}
			for (let i = 0, n = links.length; i < n; i++) {
				let res;
				if (time === 0) {
					res = await fn.fetchDoc(links[i], {}, retry).then(dom => {
						debug(`\nfn.getEle() URL`, decodeURIComponent(links[i]));
						fn.showMsg(`${DL.str_17}${xhrNum+=1}/${links.length}`, 0);
						//debug(`fn.getEle()\n${decodeURIComponent(links[i])}\n`, dom);
						return fn.gae(elements, dom, dom);
					});
				} else {
					res = fn.fetchDoc(links[i], {}, retry).then(dom => {
						debug(`\nfn.getEle() URL`, decodeURIComponent(links[i]));
						fn.showMsg(`${DL.str_17}${xhrNum+=1}/${links.length}`, 0);
						//debug(`fn.getEle()\n${decodeURIComponent(links[i])}\n`, dom);
						return fn.gae(elements, dom, dom);
					});
				}
				resArr.push(res);
				if (time !== 0 && isNumber(time)) await delay(time);
			}
			return Promise.all(resArr).then(arr => arr.flat()).then(eles => {
				isFetching = false;
				fn.hm();
				if (targetEle === null) {
					if (removeEles) fn.remove(removeEles);
					return eles;
				}
				let ele;
				fragment.append(...eles);
				if (isArray(targetEle)) {
					const [selector, p] = targetEle;
					ele = fn.ge(selector);
					if (p == 0) ele.append(fragment);
					else if (p == 1) insertBefore(ele, fragment);
					else if (p == 2) insertAfter(ele, fragment);
				} else if (isString(targetEle)) {
					ele = fn.ge(targetEle);
					ele.innerHTML = "";
					ele.append(fragment);
				}
				if (removeEles) fn.remove(removeEles);
				fn.fetchErrorMsg();
			});
		},
		//跨域,傳入連結陣列並行要求取得元素插入到指定的位置
		getCorsEle: async (links, elements, targetEle = null, removeEles = null, time = 100) => {
			if (fn.ge(".FullPictureLoadImage")) return;
			isFetching = true;
			if (!getImgFnProcessRecord.includes("getCorsEle()")) getImgFnProcessRecord += " > fn.getCorsEle()";
			let resArr = [];
			let xhrNum = 0;
			fn.showMsg(DL.str_16, 0);
			if (isString(links)) {
				links = fn.gau(links);
			}
			for (let i = 0, n = links.length; i < n; i++) {
				let res;
				if (time === 0) {
					res = await fn.xhrDoc(links[i]).then(dom => {
						debug(`\nfn.getEle() URL`, decodeURIComponent(links[i]));
						fn.showMsg(`${DL.str_17}${xhrNum+=1}/${links.length}`, 0);
						//debug(`fn.getEle()\n${decodeURIComponent(links[i])}\n`, dom);
						return fn.gae(elements, dom, dom);
					});
				} else {
					res = fn.xhrDoc(links[i]).then(dom => {
						debug(`\nfn.getEle() URL`, decodeURIComponent(links[i]));
						fn.showMsg(`${DL.str_17}${xhrNum+=1}/${links.length}`, 0);
						//debug(`fn.getEle()\n${decodeURIComponent(links[i])}\n`, dom);
						return fn.gae(elements, dom, dom);
					});
				}
				resArr.push(res);
				if (time !== 0 && isNumber(time)) await delay(time);
			}
			return Promise.all(resArr).then(arr => arr.flat()).then(eles => {
				isFetching = false;
				fn.hm();
				if (targetEle === null) {
					if (removeEles) fn.remove(removeEles);
					return eles;
				}
				let ele;
				fragment.append(...eles);
				if (isArray(targetEle)) {
					const [selector, p] = targetEle;
					ele = fn.ge(selector);
					if (p == 0) ele.append(fragment);
					else if (p == 1) insertBefore(ele, fragment);
					else if (p == 2) insertAfter(ele, fragment);
				} else if (isString(targetEle)) {
					ele = fn.ge(targetEle);
					ele.innerHTML = "";
					ele.append(fragment);
				}
				if (removeEles) fn.remove(removeEles);
				fn.fetchErrorMsg();
			});
		},
		//單線程背景讀取圖片IMG元素陣列的圖片網址
		singleThreadLoadImgs: async imgArr => {
			for (let i = 0, n = imgArr.length; i < n; i++) {
				if (!isValidPage) return;
				if (!imgArr[i].dataset?.src) continue;
				let loadSrc = imgArr[i].dataset.src;
				let parent = imgArr[i].parentNode;
				let temp = new Image();
				if ("referrerpolicy" in (siteData ?? {})) {
					temp.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				await new Promise(resolve => {
					temp.onload = () => {
						imgArr[i].src = loadSrc;
						resolve();
					};
					temp.onerror = () => {
						if (loadSrc.includes("https://wsrv.nl/")) {
							loadSrc = loadSrc.replace("https://wsrv.nl/?url=", ""); //wsrv.nl_CDN
							imgArr[i].dataset.src = loadSrc;
							if (!!parent && parent?.nodeName === "A" && !!parent?.getAttribute("data-fancybox")) {
								parent.href = loadSrc;
								parent.dataset.thumb = loadSrc;
							}
						} else if (loadSrc.includes(".wp.com/") && !document.title.endsWith("4KHD")) {
							loadSrc = loadSrc.replace(/i\d\.wp\.com\/|\?.+$/g, ""); //WordPressCDN
							imgArr[i].dataset.src = loadSrc;
							if (!!parent && parent?.nodeName === "A" && !!parent?.getAttribute("data-fancybox")) {
								parent.href = loadSrc;
								parent.dataset.thumb = loadSrc;
							}
						}
						resolve();
					};
					temp.src = loadSrc;
				});
			}
		},
		//單線程背景讀取圖片網址陣列的圖片網址
		singleThreadLoadSrcs: async srcArr => {
			for (let src of srcArr) {
				if (!isValidPage) return;
				const temp = new Image();
				if ("referrerpolicy" in (siteData ?? {})) {
					temp.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				await new Promise(resolve => {
					temp.onload = resolve;
					temp.onerror = resolve;
					temp.src = src;
				});
			}
		},
		//圖片預讀函式
		picPreload: async (srcArr, title = (apiCustomTitle || customTitle || document.title), page = "current") => {
			const errorNumArr = new Array(srcArr.length).fill(0);
			const loadImg = async (src, index) => {
				await new Promise(resolve => {
					const temp = new Image();
					if ("referrerpolicy" in siteData) {
						temp.setAttribute("referrerpolicy", siteData.referrerpolicy);
					}
					temp.onload = () => {
						resolve("OK");
					};
					temp.onerror = error => {
						if (!isValidPage) return;
						const errorNum = errorNumArr[index] + 1;
						errorNumArr[index] = errorNum;
						if (src.includes("https://wsrv.nl/")) {
							src = src.replace("https://wsrv.nl/?url=", ""); //wsrv.nl_CDN
						} else if (src.includes(".wp.com/") && !document.title.endsWith("4KHD")) {
							src = src.replace(/i\d\.wp\.com\/|\?.+$/g, ""); //WordPressCDN
						}
						if (/e-hentai\.org|exhentai\.org/.test(fn.lh)) {
							resolve("OK");
							return;
						}
						if (errorNum >= 10) {
							debug(`\n圖片全載Lazyloading預讀重新載入出錯的圖片已達到10次上限:\n${src}`);
							resolve("OK");
							return;
						}
						resolve("OK");
						setTimeout(() => {
							if (/www\.yinghuamh\.net/.test(fn.lh)) {
								const {
									Gm,
									media
								} = _unsafeWindow;
								debug(`\n圖片全載Lazyloading預讀出錯 樱花漫画 重新載入另一個圖片伺服器的圖片網址:\n${src}\nto\n${src.replace(Gm.getMediaHost(media), media)}`);
								loadImg(src.replace(Gm.getMediaHost(media), media), index);
							} else {
								debug(`\n圖片全載Lazyloading預讀重新載入出錯的圖片:\n${src}\n錯誤次數:${errorNum}`);
								loadImg(src, index);
							}
						}, 2000);
					};
					temp.src = src;
				});
			};
			page == "next" ? debug(`\n${title}\n圖片全載開始預讀下一頁`, srcArr) : debug(`\n${title}\n圖片全載Lazyloading開始預讀`);
			for (let i = 0, n = srcArr.length; i < n; i++) {
				if (!isValidPage) return;
				if (/youtube|\.mp4|\.m3u8$|\.webm$/.test(srcArr[i])) continue;
				let load = await loadImg(srcArr[i], i);
			}
			page == "next" ? debug(`\n${title}\n圖片全載下一頁預讀結束`) : debug(`\n${title}\n圖片全載Lazyloading預讀結束`);
		},
		//观察者 MutationObserver事件,根據圖片燈箱插件檢視圖片時的索引,滾動到頁面相對應的圖片位置
		MutationObserver_aff: () => {
			const openEvent = () => {
				if (fn.ge("span[data-fancybox-current-index]") !== null) {
					slideIndex = Number(fn.gt("span[data-fancybox-current-index]")) - 1;
				} else if (fn.ge("span[data-fancybox-index]") !== null) {
					slideIndex = Number(fn.gt("span[data-fancybox-index]")) - 1;
				} else if (fn.ge("badge.b-black.counter") !== null) {
					slideIndex = Number(fn.gt("badge.b-black.counter").match(/\d+/)[0]) - 1;
				}
				if (isNumber(slideIndex)) {
					console.log("open - # " + slideIndex + " slide is open!");
				}
			};
			const ContentContainer = document.body;
			const configObserver = {
				childList: true,
				subtree: true,
				attributeFilter: ["class"]
			};
			//当观察到突变时执行的回调函数
			const Callbacks = mutationsList => {
				for (let item of mutationsList) {
					if (item.type === "attributes") {
						if (
							item.target.className === "fancybox-slide fancybox-slide--image fancybox-slide--current fancybox-slide--complete" ||
							item.target.className === "fancybox__slide has-image can-zoom_in is-selected" ||
							item.target.className === "swiper-slide swiper-slide-active" && ![
								"www.elitebabes.com",
								"pmatehunter.com",
								"www.jperotica.com",
								"www.metarthunter.com",
								"www.femjoyhunter.com",
								"nakedporn.pics",
								"www.6tu.com"
							].some(h => fn.lh.includes(h))
						) {
							console.log(" # ", item);
							openEvent();
							fn.scrollEvent(slideIndex);
						}
					} else if (item.type === "childList") {
						if (item.removedNodes.length > 1 && /fancybox|swiper/.test(item.removedNodes[1].className)) {
							console.log(" # ", item);
							console.log("close - # " + slideIndex + " slide is closed!");
							fn.scrollEvent(slideIndex);
						}
					}
				}
			};
			//创建一个链接到回调函数的观察者实例
			const Observer = new MutationObserver(Callbacks);
			ContentContainer && Observer.observe(ContentContainer, configObserver);
		},
		//創建用來添加圖片元素的主容器
		createImgBox: (selector, pos = 0, width = null) => {
			if (fn.ge("#FullPictureLoadMainImgBox") || !isString(selector) && !isArray(selector) && !isEle(selector)) return;
			let div = fn.ce("div", {
				id: "FullPictureLoadMainImgBox"
			}, {
				display: "block",
				textAlign: "center",
				margin: "0 auto",
				maxWidth: (isNumber(width)) ? width + "px" : ""
			});
			let targetEle;
			if (isString(selector) || isArray(selector)) {
				targetEle = fn.ge(selector);
			} else if (isEle(selector)) {
				targetEle = selector;
			}
			if (pos == 0) targetEle.append(div);
			if (pos == 1) insertBefore(targetEle, div);
			if (pos == 2) insertAfter(targetEle, div);
			return div;
		},
		//插入圖片函式
		insertImg: async (imgsArray, insertTargetEle, mode = 2) => {
			if (fn.ge(".FullPictureLoadImage") || isFetching || isDownloading) return;
			if ("insertImgBF" in siteData && isFn(siteData.insertImgBF)) {
				await siteData.insertImgBF();
			}
			let srcArr = [];
			for (let i = 0, n = imgsArray.length; i < n; i++) {
				let check = fn.checkImgSrc(imgsArray[i]);
				check.ok ? srcArr.push(check.src) : console.error("\nfn.insertImg(imgsArray) 格式錯誤!", imgsArray[i]);
			}
			srcArr = [...new Set(srcArr)];
			let noVideoNum = srcArr.filter(src => !/youtube|\.mp4$|\.webm$/.test(src)).length;
			let buttonFn = siteData.button;
			let buttonBar;
			if (isArray(buttonFn)) {
				let [, insertBr] = buttonFn;
				buttonBar = fn.ace(fragment, "div", {
					id: "FullPictureLoadOptionsButtonParentDiv"
				}, {
					marginTop: isNumber(insertBr) ? insertBr * 20 + "px" : ""
				});
				const buttonObj = [{
					id: "FullPictureLoadOpenFavoritesBtn",
					className: "FullPictureLoadPageButtonTop",
					text: DL.str_128,
					cfn: event => {
						cancelDefault(event);
						createFavorShadowElement();
					}
				}, {
					id: "FullPictureLoadShadowGalleryBtn",
					className: "FullPictureLoadPageButtonTop",
					text: isM ? DL.str_141.replace("Shadow", "") : DL.str_141,
					cfn: event => {
						cancelDefault(event);
						createShadowGallery();
					}
				}, {
					id: "FullPictureLoadFastDownloadBtn",
					className: "FullPictureLoadPageButtonTop",
					text: isM ? DL.str_107 : DL.str_107 + ` | [ ${noVideoNum}P ]`,
					cfn: event => {
						cancelDefault(event);
						fastDownloadSwitch = true;
						DownloadFn();
					}
				}, {
					id: "FullPictureLoadNewTabViewBtn",
					className: "FullPictureLoadPageButtonTop",
					text: DL.str_106,
					cfn: event => {
						cancelDefault(event);
						newTabView();
					}
				}, {
					id: "FullPictureLoadOptionsBtn",
					className: "FullPictureLoadPageButtonBottom",
					text: DL.str_85,
					cfn: event => {
						cancelDefault(event);
						createPictureLoadOptionsShadowElement();
					}
				}, {
					id: "FullPictureLoadToggleImgModeBtn",
					className: "FullPictureLoadPageButtonBottom",
					text: DL.str_86,
					cfn: event => {
						cancelDefault(event);
						toggleImgMode();
					}
				}, {
					id: "FullPictureLoadToggleZoomeBtn",
					className: "FullPictureLoadPageButtonBottom",
					text: DL.str_87,
					title: DL.str_136,
					cfn: event => {
						cancelDefault(event);
						fn.clearAllTimer(2);
						reduceZoom();
					},
					mfn: event => {
						if (event.button == 2) {
							cancelDefault(event);
							increaseZoom();
						}
					}
				}, {
					id: "FullPictureLoadCancelZoomBtn",
					className: "FullPictureLoadPageButtonBottom",
					text: DL.str_88,
					cfn: event => {
						cancelDefault(event);
						fn.clearAllTimer(2);
						cancelZoom();
					}
				}];

				if (isM) {
					buttonObj[1] = {
						id: "FullPictureLoadShadowGalleryBtn",
						className: "FullPictureLoadPageButtonTop",
						text: DL.str_188.replace("Phone ", ""),
						cfn: event => {
							cancelDefault(event);
							createFilterUI(1);
						}
					}
				}

				const createButton = obj => fn.ace(buttonBar, "button", {
					id: obj.id,
					className: obj.className,
					innerText: obj.text,
					title: ("title" in obj) ? obj.title : "",
					oncontextmenu: () => false,
					onclick: obj.cfn,
					onmousedown: ("mfn" in obj) ? obj.mfn : null
				});
				[...buttonObj].forEach(createButton);
			}
			let blackList = fancyboxBlackList();
			if (options.fancybox == 1 && thumbnailSrcArray.length > 0) {
				if (!/(www\.)?24cos\.org|www\.lovecos\.net|luohuaxiu\.com|kemono\.su|coomer\.su/.test(fn.lh) || !/^data/.test(thumbnailSrcArray[0])) {
					thumbnailSrcArray = [...new Set(thumbnailSrcArray)];
				}
			}
			debug("\nfn.insertImg()插入圖片最後確認 thumbnailSrcArray", thumbnailSrcArray);
			debug("\nfn.insertImg()插入圖片最後確認 srcArr", srcArr);
			for (let i = 0, n = srcArr.length; i < n; i++) {
				let img = new Image();
				img.alt = `no.${i + 1}`;
				img.dataset.index = i;
				img.className = "FullPictureLoadImage";
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.dataset.errorNum = 0;
				//if (/vipr\.im/.test(srcArr[i])) img.referrerPolicy = "no-referrer";
				if (options.zoom <= 10 && options.zoom > 0 && (blackList || options.fancybox !== 1)) {
					img.style.width = `${options.zoom * 10}%`;
					img.style.height = "auto";
				}
				if (mode == 2 || mode == 3) {
					img.src = loading_bak;
					img.dataset.src = srcArr[i];
				} else {
					img.loading = "lazy";
					img.decoding = "async";
					img.onload = () => {
						img.classList.remove("error");
					};
					img.onerror = error => {
						const num = Number(error.target.dataset.errorNum);
						if (num < 10) {
							error.target.dataset.errorNum = num + 1;
						} else {
							return;
						}
						error.target.classList.add("error");
						setTimeout(() => {
							debug(`\nfn.insertImg()重新載入出錯的圖片:\n${error.target.src}`);
							error.target.src = error.target.src;
						}, 1000);
					};
					img.src = srcArr[i];
				}
				if (options.fancybox == 1 && !blackList) {
					let isZoom = (options.zoom <= 10 && options.zoom > 0);
					let a = fn.ace(fragment, "a", {
						id: "imgLocationOriginal_" + i,
						href: "#",
						dataset: {
							fancybox: "FullPictureLoadImageOriginal",
							src: srcArr[i],
							thumb: (thumbnailSrcArray.length > 0 && thumbnailSrcArray.length == noVideoNum) ? thumbnailSrcArray[i] : srcArr[i]
						}
					}, {
						width: isZoom ? `${options.zoom * 10}%` : "",
						height: isZoom ? "auto" : ""
					});
					a.append(img);
				} else {
					fragment.append(img);
				}
			}
			if (videoSrcArray.length > 0) {
				debug("\nfn.insertImg()插入圖片最後確認 videoSrcArray", videoSrcArray);
				if (isPC && siteData.downloadVideo === true && FullPictureLoadCustomDownloadVideo == 1) {
					let dbtn = fn.ge("#FullPictureLoadFastDownloadBtn", fragment);
					if (dbtn) {
						dbtn.innerText = dbtn.innerText.replace("P", `P + ${videoSrcArray.length}V`);
					}
				}
				for (let i = 0, n = videoSrcArray.length; i < n; i++) {
					let video = fn.ace(fragment, "video", {
						className: "FullPictureLoadVideo",
						controls: true,
						loop: false,
						autoplay: false,
						preload: "none",
						style: "height: 500px;width: 100%;max-width:100%"
					});
					fn.ace(video, "source", {
						src: videoSrcArray[i],
						type: "video/mp4"
					});
				}
			}
			let end = fn.ace(fragment, "p", {
				id: "FullPictureLoadEnd",
				innerText: `${DL.str_52}:${noVideoNum}P`
			});
			if ("endColor" in siteData) {
				if (isFn(siteData.endColor)) {
					end.style.color = siteData.endColor();
				} else if (isString(siteData.endColor)) {
					end.style.color = siteData.endColor;
				}
			}
			if (srcArr.length > 0 || (srcArr.length >= 0 && videoSrcArray.length > 0)) {
				const [, insertMode] = siteData.insertImg;
				if ((insertMode == 2 || insertMode == 3) && siteData.preload != 0) {
					fn.picPreload(srcArr);
				}
				let targetEle;
				try {
					if (isArray(insertTargetEle)) {
						let [selector, pos, removeSelector] = insertTargetEle;
						if (("box" in siteData) || selector == "box") {
							selector = "#FullPictureLoadMainImgBox";
						}
						targetEle = fn.ge(selector);
						if (pos == 0) {
							targetEle.append(fragment);
							//targetEle.style.textAlign = "center";
							targetEle.style.display = "block";
						} else if (pos == 1) {
							insertBefore(targetEle, fragment);
							//targetEle.parentNode.style.textAlign = "center";
							targetEle.parentNode.style.display = "block";
							targetEle = targetEle.parentNode;
						} else if (pos == 2) {
							insertAfter(targetEle, fragment);
							//targetEle.parentNode.style.textAlign = "center";
							targetEle.parentNode.style.display = "block";
							targetEle = targetEle.parentNode;
						}
						if (isString(removeSelector)) await fn.remove(removeSelector);
						if (siteData.msg != 0 && siteData.category != "comic") fn.showMsg(DL.str_18);
					} else if (isString(insertTargetEle)) {
						let selector = insertTargetEle;
						if (("box" in siteData) || selector == "box") {
							selector = "#FullPictureLoadMainImgBox";
						}
						targetEle = fn.ge(selector);
						targetEle.innerHTML = "";
						targetEle.append(fragment);
						//targetEle.style.textAlign = "center";
						targetEle.style.display = "block";
						if (siteData.msg != 0 && siteData.category != "comic") fn.showMsg(DL.str_18);
					}
					let insertImgAF = siteData.insertImgAF;
					if (isFn(insertImgAF)) insertImgAF(targetEle, buttonBar);
					if (isPC && ShowFullPictureLoadFixedMenu == 1) {
						fn.waitEle("#insertImgMenu").then(e => isEle(e) ? fn.hideEle(e) : void 0);
					}
				} catch (error) {
					for (let e of [...fragment.children]) e.remove();
					fn.showMsg(DL.str_19, 3000);
					console.error("\nfn.insertImg() ele參數錯誤,或用來定位插入的元素不存在。", error);
					return;
				}
				let imgs = fn.gae("img.FullPictureLoadImage:not(.small)");
				if (mode == 2 || mode == 3) {
					setTimeout(() => {
						for (let img of imgs) fn.imagesObserver.observe(img);
					}, 1000);
				}
				if (siteData.preload != 0) {
					let oddNumberImgs = imgs.filter((img, index) => index % 2 == 0);
					let evenNumberImgs = imgs.filter((img, index) => index % 2 != 0);
					fn.singleThreadLoadImgs(oddNumberImgs);
					fn.singleThreadLoadImgs(evenNumberImgs);
				}
				if (TurnOffImageNavigationShortcutKeys != 1) {
					let imgsNum = 0;
					document.addEventListener("keydown", event => {
						if (isOpenOptionsUI || isOpenGallery || fn.ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
						if (event.code === "ArrowUp" || event.key === "ArrowUp") {
							if (imgsNum > 0 && viewMode == 0) {
								imgsNum -= 1;
								imgs[imgsNum].scrollIntoView();
							}
						} else if (event.code === "ArrowDown" || event.key === "ArrowDown") {
							event.preventDefault();
							if (imgsNum < imgs.length && viewMode == 0) {
								imgsNum += 1;
								try {
									imgs[imgsNum].scrollIntoView();
								} catch {
									imgsNum = 0;
									imgs[0].scrollIntoView();
									fn.showMsg(DL.str_94);
								}
							}
						} else {
							imgsNum = 0 - 1;
						}
					});
				}
				if (siteData.category === "comic") {
					let lastImg = imgs.at(-1);
					fn.comicNextObserver.observe(lastImg);
				}
				if (isPC && ShowFullPictureLoadFixedMenu === 1) {
					fn.waitEle("#FullPictureLoadFixedMenu").then(menu => {
						for (let e of fn.gae(".zoom,.toggleImgMode", menu)) e.style.display = "";
					});
				}
				if (options.icon == 1 || siteData.icon == 1) {
					fn.waitEle(["#FullPictureLoadGoToFirstImage", "#FullPictureLoadGoToLastImage"]).then(eles => {
						for (let e of eles) e.style.display = "unset";
					});
				}
				if (options.fancybox == 1 && !("fancybox" in siteData) && ("Fancybox" in _unsafeWindow)) {
					_unsafeWindow.Fancybox.bind("[data-fancybox='FullPictureLoadImageOriginal']", isObject(_unsafeWindow?.Fancybox?.defaults) ? {} : FancyboxOptions);
				}
				if (
					!["tupianwu.com", "hentairead.com", "manhwaread.com", "whoreshub.com", "porntrex.com"].some(h => fn.lh.includes(h)) &&
					!fn.ge(".umRelevant.umBox") &&
					!fn.ge(".videoPlayerWrap") &&
					!fn.ge("#xqbj-main") &&
					!fn.ge(".PcHeader_rightBox") &&
					!fn.ge(".gallery-page #toggle-column")
				) {
					fn.MutationObserver_aff();
				}
				if (pageViewMode == 1 || siteData.viewMode == 1) toggleImgMode();
				if (goToFirstImage == 1) goToNo1Img();
			} else {
				fn.showMsg(DL.str_20);
			}
		},
		immediateInsertImg: async (manual = "no") => {
			if (captureExclude() || ge(".FullPictureLoadImage")) return;
			if ("SPA" in siteData && isFn(siteData.SPA)) {
				const validPage = await siteData.SPA();
				if (!validPage) return;
			}
			if (options.autoInsert == 1 && manual === "no" || options.autoInsert == 0 && manual === "yes" || manual === "yes") {
				let [insertSelector, insertMode, delayTime] = siteData.insertImg;
				await fn.delay(delayTime || 0);
				let selector = siteData.srcset || siteData.imgs;
				let imgsSrcArray = await getImgs(selector);
				await fn.insertImg(imgsSrcArray, insertSelector, insertMode);
			}
		},
		//創建元素
		ce: (tag, attr = null, css = null) => {
			let e = document.createElement(tag);
			if (isObject(attr)) {
				if ("dataset" in attr) {
					Object.assign(e.dataset, {
						...attr.dataset
					});
					delete attr.dataset;
				}
				Object.assign(e, {
					...attr
				});
			}
			if (isObject(css)) {
				Object.assign(e.style, {
					...css
				});
			}
			return e;
		},
		//往元素裡創建元素
		ace: (node, tag, attr = null, css = null) => {
			let e = fn.ce(tag, attr, css);
			if (node == "bodya") {
				document.body.after(e);
			} else if (node == "buttons") {
				node = document.getElementById("FullPictureLoadButtons");
				if (!node) {
					node = fn.ce("div", {
						id: "FullPictureLoadButtons"
					});
					document.body.after(node);
				}
				node.append(e);
			} else {
				node.append(e);
			}
			return e;
		},
		//創建style元素
		css: (css, id = null) => {
			if (isString(id)) {
				if (document.getElementById(id)) return;
			}
			return fn.ace(document.head, "style", {
				type: "text/css",
				id: isString(id) ? id : "",
				className: "FullPictureLoadStyle",
				innerHTML: css
			});
		},
		//創建script插入到document.body
		script: (code, node = document.body) => {
			let script = fn.ace(node, "script", {
				textContent: code
			});
			if (siteData.category === "comic autoPager") {
				script.remove();
			}
		},
		isXPath: xpath => /^\(*(descendant::|\.\/|\/|id\()/.test(xpath),
		//返回選擇器的首個元素
		ge: (selector, contextNode = null, dom = document) => {
			let isXPath = false;
			if (isArray(selector)) {
				let [s] = selector;
				isXPath = fn.isXPath(s);
			} else {
				isXPath = fn.isXPath(selector);
			}
			if (isObject(selector)) {
				let {
					s,
					t
				} = selector;
				let node = fn.gae(s, contextNode, dom).find(e => {
					let texts = [e?.text, e?.innerHTML, e?.parentElement?.innerText].map(e => String(e));
					let pt = texts.at(2);
					if (["下", "上"].every(k => pt.includes(k)) || ["前", "次"].every(k => pt.includes(k)) || ["next", "prev"].every(k => pt.toLowerCase().includes(k))) {
						texts = texts.slice(0, -1);
					}
					if (isArray(t)) {
						return t.some(k => texts.some(s => s.includes(k)));
					} else {
						return texts.some(s => s.includes(t));
					}
				});
				return isEle(node) ? node : null;
			} else if (isXPath) {
				if (isArray(selector)) {
					selector = selector.join("|");
				}
				return dom.evaluate(selector, (contextNode ?? document), null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
			} else {
				if (isArray(selector)) {
					selector = selector.join(",");
				}
				return (contextNode ?? document).querySelector(selector);
			}
		},
		//返回A選擇器的首個A元素的href
		gu: (selector, contextNode = null, dom = document) => {
			let href = fn.ge(selector, contextNode, dom)?.href;
			return href ? href : null;
		},
		gp: (selector, contextNode = null, dom = document) => {
			let pathname = fn.ge(selector, contextNode, dom)?.pathname;
			return pathname ? pathname : null;
		},
		//返回選擇器的所有元素的陣列
		gae: (selector, contextNode = null, dom = document) => {
			let isXPath = false;
			if (isArray(selector)) {
				let [s] = selector;
				isXPath = fn.isXPath(s);
			} else {
				isXPath = fn.isXPath(selector);
			}
			if (isXPath) {
				if (isArray(selector)) {
					selector = selector.join(" | ");
				}
				let nodes = [];
				let results = dom.evaluate(selector, (contextNode ?? document), null, XPathResult.ANY_TYPE, null);
				let node = null;
				while (node = results.iterateNext()) {
					nodes.push(node);
				}
				return nodes;
			} else {
				if (isArray(selector)) {
					selector = selector.join(",");
				}
				return [...(contextNode ?? document).querySelectorAll(selector)];
			}
		},
		//返回A選擇器的所有A元素的href的陣列並且去除重複
		gau: (selector, contextNode = null, dom = document) => [...new Set(fn.gae(selector, contextNode, dom)?.map(a => a?.href))],
		//取元素陣列的最大數字字串
		um: (selector, node = document) => {
			let arr;
			if (isArray(selector)) {
				arr = selector;
			} else {
				arr = fn.gae(selector, node);
			}
			return arr.map(a => Number(a.innerText.replaceAll(".", ""))).filter(Boolean).sort((a, b) => a - b).at(-1);
		},
		//取得網頁喧染後的元素字串
		gt: (selector, mode = 1, dom = document) => {
			try {
				let e;
				if (isEle(selector)) {
					e = selector;
				} else {
					e = fn.ge(selector, dom, dom);
				}
				if (mode == 1) return e?.innerText;
				if (mode == 2) return e?.previousElementSibling?.innerText;
				if (mode == 3) return e?.previousElementSibling?.previousElementSibling?.innerText;
			} catch (error) {
				console.error(`\nfn.gt() ERROR\nselector:${selector}\n`, error);
				return null;
			}
		},
		//返回元素的字串陣列
		gat: (selector, contextNode = null, dom = document) => fn.gae(selector, contextNode, dom).map(e => fn.dt({
			t: fn.gt(e)
		})),
		getText: (selector, dom = document) => {
			let text = "";
			if (isString(selector)) {
				let ele = fn.ge(selector, dom, dom);
				text = ele?.innerText;
				if (!!ele && !!text && text?.length > 0) {
					return fn.dt({
						t: text
					});
				}
			} else if (isArray(selector)) {
				for (let s of selector) {
					let ele = fn.ge(s, dom, dom);
					text = ele?.innerText;
					if (!!ele && !!text && text?.length > 0) {
						return fn.dt({
							t: text
						});
					}
				}
			}
			return text;
		},
		rt: (e, a, b) => {
			if (!isString(e)) return e;
			if (isArray(a)) {
				for (let p of a) e = e.replace(...p);
				return e;
			}
			return e.replace(a, b);
		},
		//根據關鍵字串或正則搜索符合條件的script,返回script字串
		gst: (searchValue, dom = document) => {
			try {
				let text = [...dom.scripts]?.find(script => {
					if (isString(searchValue)) {
						return script.textContent.includes(searchValue);
					} else if (isRegExp(searchValue)) {
						return script.textContent.search(searchValue) > -1;
					} else if (isArray(searchValue)) {
						return searchValue.every(k => {
							if (isString(k)) {
								return script.textContent.includes(k);
							} else if (isRegExp(k)) {
								return script.textContent.search(k) > -1;
							}
						});
					}
				})?.textContent;
				return text ? text : "";
			} catch {
				return null;
			}
		},
		__next_f: (dom = document) => [...dom.scripts]
			.filter(script => ["self.__next_f.push", '"'].every(str => script.textContent.includes(str)))
			.map(script => {
				let code = script.textContent;
				let s_index = code.indexOf('"') + 1;
				let e_index = code.lastIndexOf('"');
				return code.slice(s_index, e_index);
			})
			.join("")
			.replaceAll("\n", "")
			.replaceAll("\\", ""),
		rStr: (str) => fn.rt(str, [
			[/\n/g, " "],
			[/\t/g, " "],
			[/ /g, " "],
			[/\:/g, ":"],
			[/\*/g, "*"],
			[/\?/g, "?"],
			[/\"/g, "“"],
			[/\</g, "《"],
			[/\>/g, "》"],
			[/\|/g, "|"],
			[/\//g, "/"],
			[/\\/g, "\"],
			[/\s{2,10000}/g, " "],
		]).trim().replaceAll("&ldquo;", "“").replaceAll("&rdquo;", "”"),
		//刪除指定字串返回字串
		dt: (obj = {}, dom = document) => {
			let str = dom.title;
			if ("s" in obj) {
				let selector = obj.s;
				str = fn.gt(selector, 1, dom);
			} else if ("t" in obj) {
				str = obj.t;
			}
			let dt = obj.d ?? "";
			if (isString(dt) && dt !== "" || isRegExp(dt)) {
				str = str?.replace(dt, "");
			} else if (isArray(dt)) {
				for (let r of dt) str = str?.replace(r, "");
			}
			if ("r" in obj) {
				str = fn.rt(str, obj.r);
			}
			const _delete = () => {
				str = str?.replace(/[\s-]+\([Page\s\d\/]+\)|[\/\s]?[\(\[[(【“]\d+[\w\s\\\/\.\+-/]+[\)\]])】”]|\s?\d+p[\+\s]+\d+v|\s?\d+p\+?\d+v|\s?\d+P|\(\d\)/gi, "")
					.replace(/\d+枚(まとめ)?/, "").replace(/^[🌶\s]+/, "");
			};
			let j_g_num = ["【", "】"].every(e => str?.includes(e));
			if (j_g_num) {
				let m = str.match(/【(.+)】/);
				if (m) {
					let [, text] = m;
					if (!Number(text)) {
						_delete();
					}
				}
			} else {
				_delete();
			}
			let params = [
				[/《/g, ""],
				[/》/g, ""],
				[" - 4KHD", ""],
				[/ - Mitaku$/, ""]
			];
			str = fn.rt(String(str?.trim()), params);
			str = fn.rStr(str);
			return str;
		},
		//傳入字串和起始關鍵字串(不包含在需要的字串內)和結束的關鍵字串,提取出需要的字串。
		stringSlicer: (string, startText, endText) => {
			const a = string.indexOf(startText);
			if (a < 0) return null;
			const startIndex = a + startText.length;
			const endIndex = string.indexOf(endText, startIndex);
			return string.slice(startIndex, endIndex + endText.length);
		},
		//傳入代碼字串和變數關鍵字串提取變數的字串
		textVar: (str, key, end = ";") => {
			let a = str.indexOf(key);
			if (a < 0) return null;
			let b = str.indexOf("=", a);
			let c = str.indexOf(end, b);
			if (end == '"' || end == "'" || end == "`") {
				c = str.indexOf(end, c + 1);
			}
			str = str.slice(b + 1, c).replaceAll("'", "").replaceAll('"', "").replaceAll("`", "").trim();
			return String(str);
		},
		//傳入代碼字串和變數關鍵字串提取變數的Number數字
		numVar: (str, key, end = ";") => {
			let a = str.indexOf(key);
			if (a < 0) return null;
			let b = str.indexOf("=", a);
			let c = str.indexOf(end, b);
			str = str.slice(b + 1, c);
			return Number(str);
		},
		//傳入字串和關鍵字串提取Object字串轉為Object物件
		textToObject: (str, key, mode = 1, last = 0) => {
			let a = str.indexOf(key);
			let b = str.indexOf("{", a);
			let c;
			if (last) {
				c = str.lastIndexOf("}") + 1;
			} else {
				c = str.indexOf("}", b) + 1;
			}
			str = str.slice(b, c);
			if (mode == 2) {
				str = str.slice(1, -1).replaceAll("\n", "").replaceAll("'", "").replaceAll('"', "");
				let arr = str.split(",");
				let arr_arr = arr.map(e => {
					try {
						let [k, v] = e.split(":");
						return [k.trim(), v.trim()];
					} catch {
						return null;
					}
				});
				arr_arr = arr_arr.filter(Boolean);
				return Object.fromEntries(arr_arr);
			} else {
				return fn.run(str);
			}
		},
		//傳入字串和關鍵字串提取Array字串轉為Array陣列物件
		textToArray: (str, key, last = 0) => {
			let a = str.indexOf(key);
			let b = str.indexOf("[", a);
			let c;
			if (last) {
				c = str.lastIndexOf("]") + 1;
			} else {
				c = str.indexOf("]", b) + 1;
			}
			str = str.slice(b, c);
			return fn.run(str);
		},
		//簡單解析執行一些壓縮混淆過的代碼
		parseCode: str => {
			let s = str.indexOf("(");
			let e = str.lastIndexOf(")") + 1;
			str = str.slice(s, e);
			return fn.run(str);
		},
		//取得元素的屬性值
		attr: (s, attr, dom = document) => {
			if (isEle(s)) {
				return s.getAttribute(attr)?.trim();
			}
			return fn.ge(s, dom, dom)?.getAttribute(attr)?.trim();
		},
		//傳入代碼執行代碼
		run: code => new Function(`"use strict";return (${code})`)(),
		gm_run: code => {
			_GM_addElement(document.body, "script", {
				textContent: code
			})?.remove();
		},
		//將字串解析為document物件
		doc: str => new DOMParser().parseFromString(str, "text/html"),
		//將字串解析為XML物件
		xml: str => new DOMParser().parseFromString(str, "text/xml"),
		//將字串解析為DOM Node文檔片段
		html: str => fn.ce("template", {
			innerHTML: str
		}).content,
		//根據參數返回修改後的網頁標題
		title: (str, mode = 0, dom = document) => {
			let split = dom.title.replace(/漫画|\s-\s(漫本)|\[\d+p(\d+v)?\]/gi, "").split(str);
			try {
				if (mode == 0) return dom.title.replace(str, "").trim();
				if (mode == 1) return split[0].replace(/,$/g, "").replace(/,/g, " ").trim();
				if (mode == 2) return (split[0] + str + split[1]).replace(/,$/g, "").replace(/,/g, " ").trim();
				if (mode == 3) return (split[1] + str + split[0]).replace(/,$/g, "").replace(/,/g, " ").trim();
			} catch (error) {
				console.error("\nfn.title() ERROR", error);
				return dom.title;
			}
		},
		//創建一個指定長度的陣列
		arr: (num, cb = null) => isFn(cb) ? Array.from({
			length: Number(num)
		}, cb) : Array.from({
			length: Number(num)
		}),
		// 隨機抽取陣列中的其中一個
		arrayOne: (array) => array.at(Math.floor(Math.random() * array.length)),
		//顯示簡短的訊息
		showMsg: async (text, time = 1000) => {
			if (getType(msgTimeId) == "Number") {
				clearTimeout(msgTimeId);
			}
			let msgE = fn.ge("#FullPictureLoadMsg");
			if (!msgE) {
				msgE = fn.ace("bodya", "div", {
					id: "FullPictureLoadMsg"
				});
				if (FullPictureLoadMsgPos == 1) {
					msgE.style.cssText = "top:10px;left:10px;";
				} else if (FullPictureLoadMsgPos == 2) {
					msgE.style.cssText = "top:10px;right:10px;";
				} else if (FullPictureLoadMsgPos == 3) {
					msgE.style.cssText = "bottom:10px;left:72px;";
				} else if (FullPictureLoadMsgPos == 4) {
					msgE.style.cssText = "bottom:10px;right:10px;";
				} else {
					msgE.style.cssText = "top:30%;left:50%;margin-left:-180px;";
				}
			}
			msgE.innerText = text;
			if (!!time && isNumber(time)) {
				msgTimeId = setTimeout(() => fn.hm(), time);
			}
		},
		sm1: () => fn.showMsg(DL.str_01, 0),
		sm4: () => fn.showMsg(DL.str_04, 0),
		sm5: () => fn.showMsg(DL.str_05, 0),
		//隱藏訊息
		hideMsg: () => {
			const msgE = fn.ge("#FullPictureLoadMsg");
			msgE?.remove();
		},
		hm: () => fn.hideMsg(),
		//圖片元素觀察者,圖片進入可視範圍時把data-src屬性寫入src
		imagesObserver: new IntersectionObserver((entries, observer) => {
			for (let entry of entries) {
				if (entry.isIntersecting) {
					observer.unobserve(entry.target);
					let realSrc = entry.target.dataset.src;
					let nE = entry.target.nextElementSibling;
					let fancyboxE = entry.target.parentNode;
					let fancyboxA = null;
					let fancyboxNE = null;
					if (fancyboxE && fancyboxE?.tagName == "A" && fancyboxE.hasAttribute("data-fancybox")) {
						fancyboxA = fancyboxE;
						fancyboxNE = fancyboxE.nextElementSibling;
					}
					if (realSrc) {
						entry.target.classList.remove("lazyload");
						entry.target.onload = () => {
							if (!/^(data|blob)/.test(entry.target.src)) {
								entry.target.classList.remove("error");
							}
						};
						entry.target.onerror = async (error) => {
							if (realSrc.includes("wsrv.nl/")) {
								let newSrc = realSrc.replace("https://wsrv.nl/?url=", ""); //wsrv.nl_CDN
								entry.target.dataset.src = newSrc;
								if (!!fancyboxA) {
									fancyboxA.href = newSrc;
									fancyboxA.dataset.thumb = newSrc;
								}
							} else if (realSrc.includes(".wp.com/") && !document.title.endsWith("4KHD")) {
								let newSrc = realSrc.replace(/i\d\.wp\.com\/|\?.+$/g, ""); //WordPressCDN
								entry.target.dataset.src = newSrc;
								if (!!fancyboxA) {
									fancyboxA.href = newSrc;
									fancyboxA.dataset.thumb = newSrc;
								}
							}
							const errorNum = Number(entry.target.dataset?.errorNum) || 0;
							if (errorNum < 20) {
								entry.target.dataset.errorNum = errorNum + 1;
							} else {
								return;
							}
							if (/www\.yinghuamh\.net/.test(fn.lh)) {
								const {
									Gm,
									media
								} = _unsafeWindow;
								error.target.dataset.src = error.target.dataset.src.replace(Gm.getMediaHost(media), media);
							}
							if (/e-hentai\.org|exhentai\.org/.test(fn.lh) && errorNum < 1) {
								let url = error.target.dataset.loadfail ?? fn.gae(".gdtm a,.gdtl a")[error.target.dataset.index].href;
								let newSrc = await fn.fetchDoc(url).then(async dom => {
									let loadfail = fn.ge("#loadfail", dom);
									let newUrl = url.replace(/\?nl=.+$/, "") + "?nl=" + loadfail.getAttribute("onclick").split("'")[1];
									error.target.dataset.loadfail = newUrl;
									return await fn.fetchDoc(newUrl).then(newDoc => {
										let src = fn.ge("#img", newDoc).src;
										if (fancyboxE && fancyboxE.tagName == "A") fancyboxE.href = src;
										return src;
									});
								});
								error.target.dataset.src = newSrc;
							}
							if (/civitai\.com/.test(fn.lh)) {
								if (error.target.dataset.url) {
									error.target.dataset.src = error.target.dataset.url;
								} else {
									error.target.dataset.src = error.target.dataset.src.replace("original=true/", "");
								}
							}
							error.target.src = loading_bak;
							error.target.classList.add("error");
							setTimeout(() => {
								if (/www\.yinghuamh\.net/.test(fn.lh)) {
									debug(`\nimagesObserver 樱花漫画圖片出錯 重新載入另一個圖片伺服器的圖片網址:\n${realSrc}\nto\n${error.target.dataset.src}`);
								} else if (/e-hentai\.org|exhentai\.org/.test(fn.lh)) {
									debug(`\nimagesObserver E紳士圖片出錯 重新載入新的圖片網址:\n${realSrc}\nto\n${error.target.dataset.src}`);
								} else {
									debug(`\nimagesObserver重新載入出錯圖片:\n${realSrc}\n錯誤次數:${errorNum}`);
								}
								error.target.src = error.target.dataset.src;
							}, 3000);
						};
						entry.target.src = realSrc;
					}
					if (!!nE && nE.tagName == "IMG" && !!nE?.dataset?.src) nE.src = nE.dataset.src;
					if (fancyboxNE && fancyboxNE.tagName == "A") {
						let ele = fancyboxNE.firstElementChild;
						if (!!ele && ele.tagName == "IMG" && !!ele?.dataset?.src) ele.src = ele.dataset.src;
					}
				}
			}
		}),
		imagesViewObserver: new IntersectionObserver((entries, observer) => {
			for (let entry of entries) {
				if (entry.isIntersecting) {
					entry.target.classList.add("isView");
				} else {
					entry.target.classList.remove("isView");
				}
			}
		}),
		//看漫畫當最後一張圖進入可視範圍時,按住空白鍵前往下一話
		comicNextObserver: new IntersectionObserver((entries, observer) => {
			for (let entry of entries) {
				if (entry.isIntersecting) {
					observer.unobserve(entry.target);
					if (!!nextLink) {
						const comicSpaceClickNext = () => {
							let click = 0;
							const callback = event => {
								if (event.code === "Space" || event.key === " ") {
									click += 1;
									if (click >= 5) {
										document.removeEventListener("keydown", callback);
										fn.showMsg(DL.str_34.n);
										location.href = nextLink;
									}
								}
							};
							document.addEventListener("keydown", callback);
						};
						comicSpaceClickNext();
					}
				}
			}
		}),
		//延遲
		delay: (time, msg = 1) => {
			if (time > 200 && msg == 1) fn.showMsg(`${DL.str_21}${time}${DL.str_22}...`, time);
			return new Promise(resolve => setTimeout(resolve, time));
		},
		//等待函式寫法
		wait: (callback, num = 300) => {
			if (!isFn(callback)) return;
			let isUI = ["imgElements.at(-1)"].some(s => String(callback).includes(s));
			if (!isUI) {
				debug("fn.wait()函式判斷等待中...", String(callback));
			}
			let loopNum = 0;
			return new Promise(resolve => {
				const loopFn = async () => {
					let check = await callback(document, _unsafeWindow);
					if (!!check) {
						if (!isUI) {
							debug(`fn.wait()函式判斷等待結束。耗時:${loopNum * 100}ms。`, String(callback));
						}
						resolve(true);
						return;
					}
					if (loopNum >= num) {
						debug("fn.wait()函式判斷達循環上限。", String(callback));
						resolve(false);
						return;
					}
					if (!check) {
						loopNum += 1;
						await delay(100);
						return loopFn();
					}
				};
				loopFn();
			});
		},
		//等待元素
		waitEle: (selector, max = 200, dom = document, ee = null) => {
			let loopNum = 0;
			let str = String(selector);
			let isUI = ["insertImgMenu", "FullPictureLoad"].some(s => str.includes(s));
			if (selector !== "body" && !isUI) {
				debug(`fn.waitEle()等待"${String(selector)}"元素中...`);
			}
			return new Promise(resolve => {
				let loop = setInterval(() => {
					loopNum += 1;
					let check;
					let ele;
					if (isString(ee)) {
						if (fn.ge(ee, dom, dom)) {
							clearInterval(loop);
							resolve(null);
						}
					}
					if (isString(selector)) {
						ele = fn.ge(selector, dom, dom);
						check = isEle(ele);
					} else if (isArray(selector)) {
						check = selector.every(s => isEle(fn.ge(s, dom, dom)));
						ele = selector.map(s => fn.gae(s, dom, dom));
						ele = [...new Set(ele.flat())];
					}
					if (check) {
						if (selector !== "body" && !isUI) {
							debug(`fn.waitEle()等待"${String(selector)}"元素結束。耗時:${loopNum * 100}ms。`);
						}
						clearInterval(loop);
						resolve(ele);
					}
					if (loopNum >= max) {
						clearInterval(loop);
						debug(`fn.waitEle()達循環上限,沒有出現"${String(selector)}"元素。`);
						resolve(null);
					}
				}, 100);
			});
		},
		//等待window環境變數
		waitVar: (key, max = 200) => {
			let loopNum = 0;
			debug(`fn.waitVar()等待"${String(key)}"環境變數中...`);
			return new Promise(resolve => {
				let loop = setInterval(() => {
					loopNum += 1;
					let check;
					if (isString(key)) {
						check = (key in _unsafeWindow);
					} else if (isArray(key)) {
						check = key.every(k => (k in _unsafeWindow));
					}
					if (check) {
						debug(`fn.waitVar()等待"${String(key)}"環境變數結束。耗時:${loopNum * 100}ms。`);
						clearInterval(loop);
						resolve(true);
					}
					if (loopNum >= max) {
						clearInterval(loop);
						debug(`fn.waitVar()等待環境變數達循環上限,沒有出現"${String(key)}"屬性。`);
						resolve(false);
					}
				}, 100);
			});
		},
		//攔截創建IMG元素時的src
		HTMLImageElementSrcHook: callback => {
			const originalSrcDescriptor = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, "src");
			Object.defineProperty(HTMLImageElement.prototype, "src", {
				set: function (value) {
					if (isFn(callback)) {
						callback(value);
					}
					originalSrcDescriptor.set.call(this, value);
				}
			});
		},
		//確認圖片狀態返回圖片寬高
		checkImgStatus: (src, msg = 1) => {
			if (isString(msg)) {
				fn.showMsg(msg, 0);
			} else if (msg === 1) {
				fn.showMsg(DL.str_56, 0);
			}
			return new Promise(resolve => {
				const temp = new Image();
				if ("referrerpolicy" in siteData) {
					temp.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				temp.onload = () => {
					if (isString(msg)) fn.hm();
					resolve({
						ok: true,
						src: src,
						width: temp.width,
						height: temp.height
					});
				};
				temp.onerror = () => {
					if (isString(msg)) fn.hm();
					resolve({
						ok: false,
						src: src
					});
				};
				temp.src = src;
			});
		},
		//產生隨機字串
		generateRandomString: (num, mode = 0) => {
			let characters;
			if (mode === 0) {
				characters = "0123456789";
			} else {
				characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
			}
			let string = "";
			let charactersLength = characters.length;
			for (let i = 0; i < num; i++) {
				string += characters.charAt(Math.floor(Math.random() * charactersLength));
			}
			return string;
		},
		//取得代碼並創建script注入到當前頁面
		getCode: (url, obj = {}) => {
			fn.sm5();
			const {
				mode,
				cors,
				key
			} = obj;
			if (mode == "dom" && (isString(key) || isRegExp(key))) {
				let xhr;
				if (cors == true) {
					xhr = fn.xhrDoc(url);
				} else {
					xhr = fn.fetchDoc(url);
				}
				return xhr.then(dom => {
					fn.hm();
					let code = fn.gst(key, dom);
					_GM_addElement(document.body, "script", {
						textContent: code
					});
					return code;
				});
			} else {
				let xhr;
				if (cors == true) {
					xhr = fn.xhr(url);
				} else {
					xhr = fn.t(url);
				}
				return xhr.then(text => {
					fn.hm();
					_GM_addElement(document.body, "script", {
						textContent: text
					});
					return text;
				});
			}
		},
		//用Promise封裝GM_xmlhttpRequest
		xhr: (url, details = {}) => new Promise((resolve, reject) => {
			_GM_xmlhttpRequest({
				method: "GET",
				url: url,
				responseType: "text",
				headers: {
					"Referer": _unsafeWindow.location.href,
					"User-Agent": _unsafeWindow.navigator.userAgent
				},
				onload: data => {
					if (data.status > 400) debug(`\nfn.xhr()連線錯誤碼:${data.status}\n`, url);
					resolve(data.response);
				},
				onerror: error => {
					console.error("fn.xhr()ERROR", error);
					reject(error)
				},
				...details
			});
		}),
		//用Promise封裝GM_xmlhttpRequest
		xhrHEAD: (url, details = {}) => new Promise(resolve => {
			_GM_xmlhttpRequest({
				method: "HEAD",
				url: url,
				headers: {
					"Referer": _unsafeWindow.location.href,
					"User-Agent": _unsafeWindow.navigator.userAgent
				},
				timeout: 20000,
				onload: data => {
					resolve(data);
				},
				onerror: error => {
					console.log(`fn.xhrHEAD() ERROR\n${url}`, error);
					resolve({
						status: 403
					});
				},
				ontimeout: error => {
					console.log(`fn.xhrHEAD() Timeout\n${url}`, error);
					resolve({
						status: 524
					});
				},
				...details
			});
		}),
		checkCors: (url) => new Promise(resolve => {
			fetch(url, {
				method: "HEAD",
			}).then(res => {
				resolve(res.ok);
			}).catch((error) => {
				resolve(false);
			});
		}),
		//用Promise封裝GM_xmlhttpRequest
		imageBamXHR: url => new Promise((resolve, reject) => {
			_GM_xmlhttpRequest({
				method: "GET",
				url: url,
				responseType: "document",
				headers: {
					"referrer": url,
					"referrerPolicy": "strict-origin-when-cross-origin"
				},
				onload: data => {
					resolve(data.response);
				},
				onerror: error => {
					reject(error);
				}
			});
		}),
		//用Promise封裝GM_xmlhttpRequest,返回經過文字編碼的document物件
		xhrDoc: (url = fn.curl(), details = {}) => {
			if ("xhrOptions" in siteData) {
				details = siteData.xhrOptions
			}
			return new Promise(resolve => {
				_GM_xmlhttpRequest({
					method: "GET",
					url: url,
					responseType: "arraybuffer",
					headers: {
						"Referer": _unsafeWindow.location.href,
						"User-Agent": _unsafeWindow.navigator.userAgent
					},
					onload: data => {
						let decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
						let htmlText = decoder.decode(data.response);
						let dom = fn.doc(htmlText);
						if (data.status >= 400) {
							console.error(`\nfn.xhrDoc()連線錯誤碼:${data.status}\n`, url, data, dom);
							let obj = {
								fn: "fn.xhrDoc()",
								url: url,
								status: data.status
							};
							fetchErrorArray.push(obj);
						}
						resolve(dom);
					},
					onerror: error => {
						console.error(`\nfn.xhrDoc()出錯:\n${decodeURIComponent(url)}`, error);
						resolve(null);
					},
					...details
				});
			});
		},
		//用Fetc API,返回經過文字編碼的document物件
		fetchDoc: (url = fn.curl(), details = {}, retry = 40) => {
			if ("xhrOptions" in siteData) {
				details = siteData.xhrOptions
			}
			return new Promise(async resolve => {
				fetch(url, {
					...details
				}).then(async res => {
					if (res.status >= 400 && retry > 0) {
						let resData = await fn.retryUrl(url, res, "fn.fetchDoc()", retry);
						if (resData !== null) return resData;
					}
					return res.arrayBuffer();
				}).then(buffer => {
					const decoder = new TextDecoder(document.characterSet || document.charset || document.inputEncoding);
					const htmlText = decoder.decode(buffer);
					resolve(fn.doc(htmlText));
				}).catch(error => {
					console.error(`\nfn.fetchDoc()出錯:\n${decodeURIComponent(url)}`, error);
					httpFetchError = true;
					resolve(null);
				});
			});
		},
		rd: (log) => fn.sm5().then(() => fn.fetchDoc().then(dom => {
			doc = dom;
			fn.hm();
			if (log) debug("Document\n", dom);
			return dom;
		})),
		fetch: async (url, detail = {}) => {
			let res;
			while (true) {
				res = await fetch(url, {
					...detail
				});
				if (res.ok) {
					break;
				} else {
					fn.showMsg(`fetch error code:${res.status}`, 3000);
					await fn.delay(3000, 0);
				}
			}
			return res;
		},
		t: (url, detail = {}) => fn.fetch(url, detail).then(res => res.text()),
		j: (url, detail = {}) => fn.fetch(url, detail).then(res => res.json()),
		b: (url, detail = {}) => fn.fetch(url, detail).then(res => res.blob()),
		getChapters: async (detail = {}) => {
			let {
				url,
				urlIndex,
				api,
				mode,
				node,
				wait,
				target,
				textNode,
				urlNode,
				sort,
				cb
			} = detail;
			let chapters = [];
			let eles = [];
			let dom = document;
			if ("url" in detail || "api" in detail) {
				if ("api" in detail) {
					if (isString(api)) {
						url = api
					} else if (isFn(api)) {
						url = await api();
					}
				} else {
					if ("urlIndex" in detail) {
						url = fn.gae(url)?.at(urlIndex)?.href;
					} else {
						if (isFn(url)) {
							url = await url();
						} else {
							url = fn.gu(url);
						}
					}
				}
				if (!url) return [];
				if (mode == "g") {
					dom = await fn.xhrDoc(url);
				} else if (mode == "f") {
					dom = await fn.iframeDoc(url, target);
				} else {
					dom = await fn.fetchDoc(url);
				}
			}
			if ("node" in detail) {
				dom = fn.ge(node);
			}
			if ("wait" in detail) {
				if (isString(wait)) {
					await fn.waitEle(wait);
					eles = fn.gae(target, dom, dom);
				} else if (isArray(wait)) {
					eles = await fn.waitEle(wait);
				} else if (isFn(wait)) {
					await wait();
					eles = fn.gae(target, dom, dom);
				}
			} else {
				eles = fn.gae(target, dom, dom);
			}
			chapters = eles.map(e => {
				let text, url;
				text = e.innerText;
				if ("textNode" in detail) {
					let node = fn.ge(textNode, e, dom);
					if (node) {
						text = node.innerText;
					}
				}
				text = fn.dt({
					t: text
				});
				text = text.charAt(0).toUpperCase() + text.slice(1);
				if (e.tagName == "OPTION") {
					url = e.value;
				} else if ("urlNode" in detail) {
					url = fn.ge(urlNode, e, dom).href;
				} else if (e.tagName == "A") {
					url = e.href;
				}
				if ("cb" in detail) {
					return cb(text, url || e, e);
				}
				return {
					text,
					url
				}
			});
			if (sort == "r") {
				chapters = chapters.reverse();
			}
			return chapters;
		},
		hentai_t: (url) => {
			fn.sm5();
			let _token = fn.attr('meta[name="csrf-token"]', "content");
			let server = fn.ge("#load_server")?.value;
			let u_id = fn.ge("#gallery_id")?.value;
			let g_id = fn.ge("#load_id")?.value;
			let g_ch = fn.ge("#gallery_ch")?.value;
			let img_dir = fn.ge("#load_dir")?.value;
			let total_pages = fn.ge("#load_pages")?.value;
			let t_pages = fn.ge("#t_pages")?.value;
			let id = fn.ge("#load_id")?.value || fn.ge("#gallery_id")?.value;
			let dir = fn.ge("#load_dir")?.value;
			return fn.t(url, {
				"headers": {
					"x-csrf-token": _token,
					"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
					"x-requested-with": "XMLHttpRequest"
				},
				"body": `_token=${_token}&server=${server}&id=${id}&dir=${dir}&u_id=${u_id}&g_id=${g_id}&g_ch=${g_ch}&img_dir=${img_dir}&visible=0&visible_pages=0&total_pages=${total_pages}&t_pages=${t_pages}&type=2`,
				"method": "POST"
			}).then(str => {
				let dom;
				try {
					let json = JSON.parse(str);
					dom = fn.doc(json.html);
				} catch {
					dom = fn.doc(str);
				}
				thumbnailSrcArray = fn.getImgSrcArr([...dom.images]);
				return thumbnailSrcArray;
			});
		},
		manhuaguiJson: (dom = document) => {
			let code = fn.gst('x6c"]', dom);
			let data = fn.parseCode(code);
			let s = data.indexOf("{");
			let e = data.lastIndexOf("}") + 1;
			data = data.slice(s, e);
			return JSON.parse(data);
		},
		DM5_getSrcs: (dom, msg = 1) => {
			if (msg == 1) fn.sm5();
			let code = fn.gst("DM5_IMAGE_COUNT", dom);
			let imagesNum = fn.numVar(code, "DM5_IMAGE_COUNT");
			let chapterURL = fn.textVar(code, "DM5_CURL");
			let cid = fn.numVar(code, "DM5_CID");
			let mid = fn.numVar(code, "DM5_MID");
			let dt = fn.textVar(code, "DM5_VIEWSIGN_DT");
			let sing = fn.textVar(code, "DM5_VIEWSIGN");
			let keyE = fn.ge("#dm5_key", dom);
			let key = keyE.value;
			let fetchNum = 0;
			let resArr = fn.arr(imagesNum, (v, i) => {
				let params = fn.cp({
					cid: cid,
					page: i + 1,
					key: key,
					language: 1,
					gtk: 6,
					_cid: cid,
					_mid: mid,
					_dt: dt,
					_sign: sing
				});
				let api = `${chapterURL}chapterfun.ashx?${params}`;
				return fn.t(api).then(text => {
					if (msg == 1) fn.showMsg(`${DL.str_06}(${fetchNum+=1}/${imagesNum})`, 0);
					return fn.run(text)[0];
				});
			});
			return Promise.all(resArr).then(data => {
				if (msg == 1) fn.hm();
				return data;
			});
		},
		MXY_getSrcs: (dom, msg = 1) => {
			if (msg == 1) fn.sm5();
			let code = fn.gst("_IMAGE_COUNT", dom);
			let imagesNum = fn.numVar(code, "_IMAGE_COUNT");
			let chapterURL = fn.textVar(code, "_CURL");
			let cid = fn.numVar(code, "_CID");
			let mid = fn.numVar(code, "_MID");
			let dt = fn.textVar(code, "_VIEWSIGN_DT");
			dt = encodeURIComponent(dt);
			let sing = fn.textVar(code, "_VIEWSIGN");
			let fetchNum = 0;
			let resArr = fn.arr(imagesNum, (v, i) => {
				let params = fn.cp({
					cid: cid,
					page: i + 1,
					key: "",
					_cid: cid,
					_mid: mid,
					_dt: dt,
					_sign: sing
				});
				let api = `${chapterURL}chapterimage.ashx?${params}`;
				return fn.t(api).then(text => {
					if (msg == 1) fn.showMsg(`${DL.str_06}(${fetchNum+=1}/${imagesNum})`, 0);
					return fn.run(text)[0];
				});
			});
			return Promise.all(resArr).then(data => {
				if (msg == 1) fn.hm();
				return data;
			});
		},
		mqzjw_decrypted_data: (data) => {
			const {
				CryptoJS,
			} = _unsafeWindow;
			const key = CryptoJS.enc.Utf8.parse("TRHvYbpGlNFoOdLaXrKRYgvdGwGfjnJj");
			const iv = CryptoJS.enc.Utf8.parse("kBKXQIpFYTDOHGLQlRUklPLtNPcBKSve");
			const decrypted = CryptoJS.AES.decrypt(data, key, {
				iv,
				mode: CryptoJS.mode.CBC
			});
			const pic_list = decrypted.toString(CryptoJS.enc.Utf8);
			data = JSON.parse(pic_list);
			return data;
		},
		getMqzjwSrc: async (url = fn.lp, msg = 1) => {
			const {
				Mcpath,
				jQuery: $
			} = _unsafeWindow;
			const cid = url.split("/").at(-1);
			let page = 1;
			const datas = [];
			let loop = true;
			let temp = "";
			if (msg === 1) fn.sm5();
			while (loop) {
				await $.getJSON("//" + Mcpath.url + Mcpath.web + "index.php/api/data/pic?callback=?", {
					cid,
					page
				}, (res) => {
					if (res.code == 1) {
						if (temp != res.data) {
							temp = res.data;
						} else if (temp == res.data) {
							loop = false;
							return;
						}
						let data = fn.mqzjw_decrypted_data(res.data);
						if (data.length > 0) {
							if (msg === 1) fn.showMsg(`${DL.str_06}${page}/???`, 0);
							datas.push(data);
							page++;
						} else {
							loop = false;
						}
					} else {
						loop = false;
					}
				});
			}
			return datas.flat().map(e => e.img).filter(src => !src.includes("tongzhi"));
		},
		CPMH_PC_C: () => fn.fetchDoc(fn.ge(".list>a")).then(dom => axios.get(`/comicdetail/${fn.lp.split("/").at(2)}/chapters`, {
			headers: {
				"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
				"dnts": fn.ge("#dnt", dom)?.getAttribute("value") || 3
			}
		}).then(json => {
			let code = fn.gst("contentKey");
			let [, key] = code.split("'");
			let data = fn.copymanga_decrypt_B(json.data.results, key);
			let chapters = data.groups.default.chapters;
			return chapters.map(({
				name,
				id
			}) => ({
				text: name,
				url: fn.wurl(id)
			}));
		})),
		CPMH_M_C: () => axios.get(`https://api.2025copy.com/api/v3/comic/${fn.curl().split("/").at(5)}/group/default/chapters?limit=500&offset=0`, {
			headers: {
				"Accept": "application/json",
				"platform": "1",
				"version": "2025.11.21",
				"webp": 1,
				"region": 1
			}
		}).then(json => {
			let chapters = json.data.results.list;
			return chapters.map(({
				name,
				comic_path_word,
				uuid,
			}) => ({
				text: name,
				url: `/h5/comicContent/${comic_path_word}/${uuid}`
			}));
		}),
		RLMH_PC_C: () => axios.get(`/comicdetail/${fn.lp.split("/").at(2)}/chapters`).then(json => {
			let key = fn.attr(".disPass", "contentkey");
			let data = fn.copymanga_decrypt_B(json.data.results, key);
			let chapters = data.groups.default.chapters;
			let dir = fn.dir(fn.url);
			return chapters.map(({
				name,
				id
			}) => ({
				text: name,
				url: dir + id
			}));
		}),
		RLMH_M_C: () => axios.get(`https://mapi.hotmangasd.com/api/v3/comic/${fn.curl().split("/").at(5)}/group/default/chapters?limit=500&offset=0`, _this.getHeaders()).then(json => {
			let chapters = json.data.results.list;
			return chapters.map(({
				name,
				comic_path_word,
				uuid,
			}) => ({
				text: name,
				url: `/v2h5/comicContent/${comic_path_word}/${uuid}`
			}));
		}),
		MHG_PC_C: () => {
			let a = fn.ge("#viewList");
			return fn.fetchDoc(a).then(dom => {
				let node = fn.ge(".chapter", dom);
				let hideData = fn.ge("#__VIEWSTATE", dom);
				if (hideData) {
					node = fn.html(_unsafeWindow.LZString.decompressFromBase64(hideData.value));
				}
				return fn.gae("[id^='chapter-list']", node).reverse().map(list => {
					let uls = fn.gae("ul", list);
					return uls.map(ul => {
						let lis = fn.gae("li", ul).reverse();
						return lis.map(li => ({
							text: li.firstElementChild.title,
							url: li.firstElementChild.href
						}));
					});
				}).flat(Infinity);
			});
		},
		MHG_M_C: () => {
			let a = fn.ge("#mangaTitle a");
			return fn.fetchDoc(a).then(dom => {
				let node = fn.ge("#chapterList", dom);
				let hideData = fn.ge("#__VIEWSTATE", dom);
				if (hideData) {
					node = fn.html(_unsafeWindow.LZString.decompressFromBase64(hideData.value));
				}
				return fn.gae("a", node).map(a => ({
					text: a.text,
					url: a.href
				})).reverse();
			});
		},
		BZMH_C: () => {
			let url = new URL(fn.gu("a.goto")).pathname;
			return fn.fetchDoc(url).then(dom => {
				let get = (_eles) => _eles.map(a => ({
					text: a.text,
					url: `${fn.dir(fn.clp())}0_${fn.getUSP("chapter_slot", a.href)}.html`
				}));
				let eles;
				let node = fn.ge("#chapter-items", dom);
				if (node) {
					eles = fn.gae("#chapter-items a,#chapters_other_list a", dom);
				} else {
					eles = fn.gae(".section-title+.pure-g a", dom).reverse();
				}
				return get(eles);
			});
		},
		RUDUMH_C: () => {
			let a = fn.ge(".headwrap a[title]~a[title],.chaphead-name a");
			let chapters = [];
			return fn.fetchDoc(a).then(dom => {
				chapters = fn.gae(".chapterlistload a,.chaplist-box a", dom).map(a => ({
					text: a.innerText.trim(),
					url: a.href
				}));
				if (fn.ge(".chaplist-more", dom)) {
					let [, id] = a.pathname.split("/");
					return fn.j("/morechapter", {
						"headers": {
							"content-type": "application/x-www-form-urlencoded; charset=UTF-8"
						},
						"body": `id=${id}`,
						"method": "POST"
					}).then(json => {
						let more = json.data.map(({
							chapterid,
							chaptername
						}) => ({
							text: chaptername,
							url: `${a.href}${chapterid}.html`
						}));
						chapters = [...chapters, ...more];
						return chapters.reverse();
					});
				}
				return chapters.reverse();
			});
		},
		GODA_A_BZ_C: () => {
			let chapterDataE = fn.ge("#chapterContent");
			let mid = chapterDataE.dataset.ms;
			let api = `https://api-get-v3.mgsearcher.com/api/manga/get?mid=${mid}&mode=all`;
			return fn.j(api).then(json => {
				return json.data.chapters.map(d => {
					let {
						attributes: {
							slug,
							title
						}
					} = d;
					return {
						text: title,
						url: fn.wurl(slug)
					}
				});
			});
		},
		D_A_DI_C: () => {
			let a = fn.ge("//a[text()='目录']");
			let chapters = [];
			return fn.fetchDoc(a).then(dom => {
				let more_e = fn.ge(".load-more .button", dom);
				if (more_e) {
					let [id] = a.pathname.split("/").at(-1).match(/\d+/);
					return fn.j(`/comic/${id}`, {
						"headers": {
							"content-type": "application/json"
						},
						"body": "{}",
						"method": "POST"
					}).then(json => {
						let dir = fn.dir(fn.url);
						chapters = json.data.chapters.map(({
							chapterName,
							contentId,
							id
						}) => ({
							text: chapterName,
							url: `${dir}${contentId}-${id}.html`
						}));
						return chapters.reverse();
					});
				}
				chapters = fn.gae(".chapter-list a", dom).map(a => ({
					text: a.innerText.trim(),
					url: a.href
				}));
				return chapters.reverse();
			});
		},
		TTMH_C: () => {
			let [, , id] = fn.lp.split("/");
			let api;
			if (fn.lh.startsWith("m.")) {
				api = `/ajax.php?chapter_list=1&aid=${id}`;
			} else {
				api = `/modules/article/ajax.php?act=chapterlist&aid=${id}`;
			}
			return fn.j(api).then(obj => {
				let _array;
				if (isObject(obj)) {
					_array = obj.result;
				} else {
					_array = obj;
				}
				let dir = fn.dir(fn.url);
				return _array.map(({
					chapterid,
					chaptername
				}) => ({
					text: chaptername,
					url: `${dir}${chapterid}.html`
				}));
			});
		},
		MYC_C: () => fn.fetchDoc(fn.ge("[data-flux-breadcrumbs-item] a:not([aria-label])")).then(dom => fn.gae("div[x-data*='chapters']", dom).map(e => fn.textToArray(fn.attr(e, "x-data"), "chapters")).flat().reverse().map(({
			id,
			title
		}) => ({
			text: title,
			url: fn.wurl(id)
		}))),
		//移除元素
		remove: async (p, time = 0) => {
			if (isString(p)) {
				await delay(time);
				let selector = p;
				for (let e of fn.gae(selector)) {
					if (!e?.id?.startsWith("FullPictureLoadIframe")) {
						e.remove();
					}
				}
			} else if (isArray(p)) {
				let selectors = p;
				await delay(time);
				for (let selector of selectors) {
					for (let e of fn.gae(selector)) {
						if (!e?.id?.startsWith("FullPictureLoadIframe")) {
							e.remove();
						}
					}
				}
			}
		},
		hideEle: p => {
			let eles;
			if (isEle(p)) {
				eles = [p];
			} else if (isString(p)) {
				let selector = p;
				eles = fn.gae(selector);
			} else if (isArray(p)) {
				let selectors = p;
				eles = selectors.map(selector => fn.gae(selector));
				eles = [...new Set(eles.flat())];
			}
			for (let e of eles) e.setAttribute("style", "display: none !important;");
		},
		//創建A元素
		addUrlHtml: (url, selector, pos = 0, text = "點選進入下一話", css = 0) => {
			let _pos;
			switch (pos) {
			case 0:
				_pos = "beforebegin"; //在元素之前。
				break;
			case 1:
				_pos = "afterend"; //在元素之後。
				break;
			case 2:
				_pos = "beforeend"; //在元素裡面,最後一個子元素之後。
				break;
			case 3:
				_pos = "afterbegin"; //在元素裡面,第一個子元素之前。
				break;
			}
			let html = `<div class="addUrl" style="padding: 20px 0; text-align: center;"><a href="${url}"style="font-size: 26px;line-height: 50px;height: 50px;text-align: center;">${text}</a></div>`;
			if (isEle(selector)) {
				selector.insertAdjacentHTML(_pos, html);
			} else if (isString(selector)) {
				fn.ge(selector).insertAdjacentHTML(_pos, html);
			} else {
				return console.error("fn.addUrlHtml() 參數selector錯誤", selector);
			}
			switch (css) {
			case 1:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(255 255 255);background-color:rgb(137 5 188);border:solid #bbb;border-radius:0.25rem;font-weight:700;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 2:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(50 50 50);background-color:rgb(200 200 200);border-radius:0.25rem;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 3:
				fn.css(".addUrl>a{text-decoration:none;color:#6c757d;background-color:#fff;border:solid #6c757d;border-radius:0.25rem;padding:.5rem 2rem;transition:background-color .2s,color .2s;&:hover{color:#fff;background-color:#6c757d}}", "addUrlHtml");
				break;
			case 4:
				fn.css(".addUrl>a{text-decoration:none;color:#003366;background-color:#fff;border:solid #6c757d;border-radius:0.25rem;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 5:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(255 255 255);background-color:rgb(77 147 255);border:solid #bbb;border-radius:0.25rem;font-weight:700;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 6:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(255 255 255);background-color:#b5d540;border:solid #b5d540;border-radius:0.25rem;font-weight:700;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 7:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(255 255 255);background-color:#65415f;border:solid #65415f;border-radius:0.25rem;font-weight:700;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 8:
				fn.css(".addUrl>a{text-decoration:none;color:#ddd;background-color:#555;border-radius:0.25rem;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 9:
				fn.css(".addUrl>a{text-decoration:none;color:#2f98f1;background-color:#2f2f3b;border:solid #c67605;border-radius:0.25rem;padding:.5rem 2rem}", "addUrlHtml");
				break;
			case 10:
				fn.css(".addUrl>a{text-decoration:none;color:rgb(255 255 255);background: var(--success) url('../img/slice.jpg') repeat-x;background-size: contain;border:none;border-radius:0.25rem;padding:.5rem 2rem}", "addUrlHtml");
				break;
			}
		},
		dataURLtoBlobURL: dataurl => {
			try {
				if (dataurl.startsWith("data:image/svg+xml")) {
					try {
						dataurl = decodeURIComponent(dataurl);
					} catch {}
					let svg = dataurl.split(",")[1].replaceAll("&quot;", '"').replaceAll('\\"', '"');
					//console.log(svg);
					return URL.createObjectURL(new Blob([svg], {
						type: "image/svg+xml"
					}));
				}
				let arr = dataurl.split(","),
					mime = arr[0].match(/:(.*?);/)[1],
					bstr = atob(arr[1]),
					n = bstr.length,
					u8arr = new Uint8Array(n);
				while (n--) {
					u8arr[n] = bstr.charCodeAt(n);
				}
				return URL.createObjectURL(new Blob([u8arr], {
					type: mime
				}));
			} catch (error) {
				console.error(dataurl);
				console.error(error);
				return dataurl;
			}
		},
		blobURLtoDataURL: bloburl => fn.b(bloburl).then(blob => fn.blobToDataURL(blob)),
		imgSrcToDataURL: (src, type = "image/jpeg", cros = 0) => new Promise((resolve, reject) => {
			const img = new Image();
			if (cros == 1) {
				img.setAttribute("crossOrigin", "");
			}
			img.onload = () => {
				let canvas = document.createElement("canvas");
				canvas.height = img.naturalWidth;
				canvas.width = img.naturalHeight;
				canvas.getContext("2d").drawImage(img, 0, 0);
				URL.revokeObjectURL(img.src);
				let dataURL = canvas.toDataURL(type);
				resolve(dataURL);
			};
			img.onerror = error => {
				reject(error);
			}
			img.src = src;
		}),
		imgSrcToBlobURL: (src, type = "image/jpeg", cros = 0) => new Promise((resolve, reject) => {
			const img = new Image();
			if (cros == 1) {
				img.setAttribute("crossOrigin", "");
			}
			img.onload = () => {
				const canvas = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
				canvas.getContext("2d").drawImage(img, 0, 0);
				URL.revokeObjectURL(img.src);
				canvas.convertToBlob({
					type: type,
					quality: 0.95
				}).then(blob => {
					let blobURL = URL.createObjectURL(blob);
					resolve(blobURL);
				});
			};
			img.onerror = error => {
				reject(error);
			}
			img.src = src;
		}),
		imgToBlobURL: (img, type = "image/jpeg", quality = 0.95) => {
			const canvas = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
			canvas.getContext("2d").drawImage(img, 0, 0);
			return canvas.convertToBlob({
				type,
				quality
			}).then(blob => URL.createObjectURL(blob));
		},
		imgBlobUrlArr: async (selector, type = "image/jpeg", quality = 0.95) => {
			fn.showMsg(DL.str_53, 0);
			await delay(200);
			let num = 0;
			let imgs = await fn.gae(selector).map(async (img, index, arr) => {
				let blobUrl = await fn.imgToBlobURL(img, type, quality);
				fn.showMsg(`DrawImage ${num += 1}/${arr.length}`, 0);
				return blobUrl;
			});
			fn.hm();
			return imgs;
		},
		blobToDataURL: blob => new Promise(resolve => {
			const reader = new FileReader();
			reader.onload = () => {
				resolve(reader.result);
			};
			reader.readAsDataURL(blob);
		}),
		convertImage: async (blob, type = "image/jpeg", quality = 0.95) => {
			const img = new Image();
			await new Promise((resolve, reject) => {
				img.onload = resolve;
				img.onerror = reject;
				img.src = URL.createObjectURL(blob);
			});
			const canvas = new OffscreenCanvas(img.naturalWidth, img.naturalHeight);
			canvas.getContext("2d").drawImage(img, 0, 0);
			URL.revokeObjectURL(img.src);
			return canvas.convertToBlob({
				type,
				quality
			});
		},
		//自動滾動元素
		scrollEles: async (ele, time = 100, top = 1) => {
			if (isAutoScrolling) return;
			isAutoScrolling = true;
			let eles = fn.gae(ele);
			for (let e of eles) {
				if (isEsc) {
					isAutoScrolling = false;
					_unsafeWindow.scrollTo({
						top: 0
					});
					return;
				}
				e.scrollIntoView({
					behavior: "smooth",
					block: "end"
				});
				await delay(time);
			}
			if (top === 1) {
				_unsafeWindow.scrollTo({
					top: 0
				});
			}
			isAutoScrolling = false;
		},
		//自動滾動元素
		aotoScrollEles: async (obj = {}) => {
			if (isAutoScrolling) return;
			isAutoScrolling = true;
			let {
				ele: selector,
				cb: callback,
				time,
				top,
				end: end_selector,
				end_time,
				block,
				scale
			} = obj;
			let isEnd = false;
			let css = null;
			if (scale) {
				css = fn.css(`${scale}{transform:scale(0.1);}`);
			}
			if (isString(end_selector)) {
				let time_id;
				let endE = fn.ge(end_selector);
				if (isEle(endE)) {
					let observer = new IntersectionObserver(entries => {
						for (let entry of entries) {
							if (entry.isIntersecting) {
								time_id = setTimeout(() => {
									isEnd = true;
									observer.unobserve(endE);
									observer = null;
								}, end_time || 2000);
							} else {
								isEnd = false;
								if (isNumber(time_id)) {
									clearTimeout(time_id);
								}
							}
						}
					}, {
						threshold: 1,
					});
					observer.observe(endE);
				}
			}
			let sn = 0;
			let timeout = false;
			let imgs = fn.gae(selector);
			let imgNum = imgs.length;
			const autoScrollIntoView = async (arr, num) => {
				for (let i = 0, n = arr.length; i < n; i++) {
					if (isEsc) {
						fn.hm();
						isAutoScrolling = false;
						_unsafeWindow.scrollTo({
							top: 0
						});
						return;
					}
					fn.showMsg(`AutoScroll ${sn += 1}/${num}`, 0);
					await new Promise(resolve => {
						let timeId = setTimeout(() => {
							timeout = true;
							clearInterval(loop);
							resolve();
						}, time || 5000);
						let loop = setInterval(async () => {
							if (isEsc) {
								clearTimeout(timeId);
								clearInterval(loop);
								fn.hm();
								isAutoScrolling = false;
								_unsafeWindow.scrollTo({
									top: 0
								});
								resolve();
								return;
							}
							arr[i].scrollIntoView({
								block: (block ?? "start")
							});
							if (isFn(end_selector)) {
								isEnd = end_selector(sn);
							}
							if (isEnd || await callback(arr[i])) {
								clearTimeout(timeId);
								clearInterval(loop);
								resolve();
							}
						}, 50);
					});
					if (timeout) break;
				}
				fn.hm();
				if (timeout) fn.showMsg("Timeout");
				let newImgs = fn.gae(selector);
				let newImgNum = newImgs.length;
				if (imgNum < newImgNum) {
					newImgs = newImgs.slice(imgNum);
					imgNum = newImgNum;
					await autoScrollIntoView(newImgs, newImgNum);
				}
			};
			await autoScrollIntoView(imgs, imgNum);
			if (top === 1) {
				_unsafeWindow.scrollTo({
					top: 0
				});
			}
			if (isString(top)) {
				fn.ge(top)?.scrollTo({
					top: 0
				});
			}
			css?.remove();
			isAutoScrolling = false;
		},
		openInTab: (url, target = "_blank") => {
			let a = fn.ace(document.body, "a", {
				href: url,
				target,
				style: "display: none;"
			});
			a.click();
			a.remove();
		},
		addMutationObserver: (callback, node = document.documentElement, config = MutationObserverConfig) => {
			callback();
			new MutationObserver(callback).observe(node, config);
		},
		scrollEvent: slideIndex => {
			if (!isNumber(slideIndex)) return;
			let modeName = "Samll";
			switch (viewMode) {
			case 0:
				modeName = "Original";
				break;
			case 1:
				modeName = "Samll";
				break;
			default:
				console.error("模式错误");
				break;
			}
			debug(`\nfn.scrollEvent() > imgLocation${modeName}_` + slideIndex);
			let elementById = document.getElementById(`imgLocation${modeName}_` + slideIndex);
			let [sa, sb, sc] = [
				".FullPictureLoadImage",
				"#FullPictureLoadImgBox:not([style*=none]) .FullPictureLoadImage.small",
				".FullPictureLoadImage:not(.small)"
			];
			if (!!elementById) {
				elementById.scrollIntoView();
			} else if (fn.ge(".swiper-slide.swiper-slide-active") && fn.ge(sa)) {
				smoothScrollIntoView(fn.gae(sa)[slideIndex]);
			} else if (fn.ge(sb)) {
				smoothScrollIntoView(fn.gae(sb)[slideIndex]);
			} else if (fn.ge(sc)) {
				smoothScrollIntoView(fn.gae(sc)[slideIndex]);
			} else {
				console.error(" # ", "未定位id!");
			}
		},
		//清除定時器
		clearAllTimer: (mode = 0) => {
			if (mode == 0 || mode == 1) {
				if ((() => {}).constructor === Function) {
					_unsafeWindow.Function.prototype.constructor = () => {};
				}
			}
			if (mode == 0 || mode == 2) {
				let endTid = _unsafeWindow.setTimeout(() => {});
				for (let i = 0; i <= endTid; i++) {
					_unsafeWindow.clearTimeout(i);
				}
			}
			if (mode == 0 || mode == 3) {
				let endIid = _unsafeWindow.setInterval(() => {});
				for (let i = 0; i <= endIid; i++) {
					_unsafeWindow.clearInterval(i);
				}
			}
		},
		//清除定時器
		clearSetTimeout: () => {
			let endTid = setTimeout(() => {});
			for (let i = 0; i <= endTid; i++) {
				clearTimeout(i);
			}
		},
		//清除元素事件
		clearElementEvent: () => fn.fetchDoc(document.URL).then(dom => {
			let newDocumentElement = document.importNode(dom.documentElement, true);
			let oldDocumentElement = document.documentElement;
			document.replaceChild(newDocumentElement, oldDocumentElement);
			doc = dom;
			debug("網站元素事件已清除");
		}),
		rjk: () => fn.run("jQuery(document).off('keydown') && jQuery(document).off('keypress') && jQuery(document).off('keyup')"),
		//創建IMG元素陣列
		createImgArray: (srcs) => {
			const config = getConfig();
			return srcs.map((src, i) => fn.ce("img", {
				className: "FullPictureLoadImage lazyload",
				src: loading_bak,
				dataset: {
					src
				}
			}, {
				maxWidth: config.webtoonWidth != 800 ? config.webtoonWidth + "px" : ""
			}));
		},
		//清除元素和添加自動翻頁的元素
		caae: async (target, eles, re = null) => {
			let tE;
			if (isString(target)) {
				tE = fn.ge(target);
			} else if (isEle(target)) {
				tE = target;
			}
			tE.innerHTML = "";
			fragment.append(...eles);
			tE.append(fragment);
			if (isString(re)) {
				await fn.remove(re);
			}
			await fn.lazyload();
		},
		//傳入選擇器參數為頁面圖片添加Fancybox6功能
		setFancybox: (selector) => {
			if (!isOpenFilter) fn.showMsg(DL.str_137);
			const loadSrcs = (srcArr) => {
				const oddNumberSrcs = srcArr.filter((img, index) => index % 2 == 0);
				const evenNumberSrcs = srcArr.filter((img, index) => index % 2 != 0);
				fn.singleThreadLoadSrcs(oddNumberSrcs);
				fn.singleThreadLoadSrcs(evenNumberSrcs);
			};
			for (let e of fn.gae(selector)) {
				let check = fn.checkImgSrc(e);
				if (e.nodeName === "IMG") {
					let pE = e.parentNode;
					if (pE.nodeName === "A") {
						let src = check.ok ? check.src : e.src;
						pE.dataset.fancybox = "gallery";
						pE.href = src;
						pE.dataset.thumb = src;
						pE.removeAttribute("title");
					} else {
						let src = check.ok ? check.src : e.src;
						let a = fn.ce("a", {
							href: src,
							dataset: {
								fancybox: "gallery",
								thumb: src
							}
						});
						insertBefore(e, a);
						a.append(e);
					}
				} else if (e.nodeName === "A") {
					let img = e.querySelector("img");
					let check = fn.checkImgSrc(img);
					let src = check.ok ? check.src : img.src;
					e.dataset.fancybox = "gallery";
					e.dataset.thumb = src;
				}
			}
			let srcs = fn.getImgSrcArr(selector);
			loadSrcs(srcs);
			if (siteData.fancybox?.v === 3) {
				return;
			}
			let gallery = fn.gae("[data-fancybox]");
			_unsafeWindow.Fancybox.bind("[data-fancybox]", {
				...FancyboxOptions,
				...{
					on: {
						ready: (ref) => {
							isOpenFancybox = true;
							smoothScrollIntoView(gallery[ref.getSlide().index]);
						},
						"Carousel.change": (ref) => {
							smoothScrollIntoView(gallery[ref.getSlide().index]);
						},
						close: () => {
							setTimeout(() => {
								isOpenFancybox = false;
							}, 100);
						}
					}
				}
			});
		},
		lazyload: async () => {
			let check = !!fn.ge("img.FullPictureLoadImage.lazyload");
			if (check) {
				let lazyload = siteData?.autoPager?.lazyload;
				let imgs = fn.gae("img.FullPictureLoadImage.lazyload");
				if (lazyload != 0) {
					let oddNumberImgs = imgs.filter((img, index) => index % 2 == 0);
					let evenNumberImgs = imgs.filter((img, index) => index % 2 != 0);
					fn.singleThreadLoadImgs(oddNumberImgs);
					fn.singleThreadLoadImgs(evenNumberImgs);
					await delay(1000);
					for (let img of imgs) fn.imagesObserver.observe(img);
				} else {
					await delay(1000);
					for (let [i, img] of imgs.entries()) {
						setTimeout(() => {
							img.src = img.dataset.src;
							img.classList.remove("lazyload");
							fn.imagesObserver.observe(img);
						}, i * 200);
					}
				}
			}
		},
		copymangaUI: () => {
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				if (isRemove) return (lastScrollTop = 0);
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					fn.ge("h4.header").setAttribute("style", "top: -30px;");
					fn.ge("div.footer").setAttribute("style", "bottom: -41px;");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					fn.ge("h4.header").removeAttribute("style");
					fn.ge("div.footer").removeAttribute("style");
					lastScrollTop = st;
				}
			});
			fn.run("$(document).off()");
			document.body.onmouseup = null;
		},
		MyComicUI: () => {
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				if (isRemove) return (lastScrollTop = 0);
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					fn.ge("header[data-flux-header]").style.display = "none";
					fn.ge("div:has(>div>div>div>button[x-ref])").style.display = "none";
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					fn.ge("header[data-flux-header]").style.display = "";
					fn.ge("div:has(>div>div>div>button[x-ref])").style.display = "";
					lastScrollTop = st;
				}
			});
		},
		MangabzUI: () => {
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				if (isRemove) return (lastScrollTop = 0);
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					fn.ge(".top-bar").setAttribute("style", "top: -74px;");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					fn.ge(".top-bar").removeAttribute("style");
					lastScrollTop = st;
				}
			});
		},
		XmanhuaUI: () => {
			const clickToggleToolbar = () => {
				if (isOpenGallery) return;
				let ht = fn.ge(".header.toolbar");
				let h = fn.ge(".header");
				if (ht) {
					h.classList.remove("toolbar");
					h.removeAttribute("style");
				} else {
					h.classList.add("toolbar");
					h.setAttribute("style", "top: -64px;")
				}
				let bt = fn.ge(".reader-bottom.toolbar");
				let b = fn.ge(".reader-bottom");
				if (bt) {
					b.classList.remove("toolbar");
					b.removeAttribute("style");
				} else {
					b.classList.add("toolbar");
					b.setAttribute("style", "bottom: -50px;");
				}
			};
			document.addEventListener("click", clickToggleToolbar);
			let lastScrollTop = 0;
			document.addEventListener("scroll", event => {
				if (isRemove) return (lastScrollTop = 0);
				let st = event.srcElement.scrollingElement.scrollTop;
				if (st > lastScrollTop) {
					fn.ge(".header").classList.add("toolbar");
					fn.ge(".header").setAttribute("style", "top: -64px;");
					fn.ge(".reader-bottom").classList.add("toolbar");
					fn.ge(".reader-bottom").setAttribute("style", "bottom: -50px;");
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					fn.ge(".header").classList.remove("toolbar");
					fn.ge(".header").removeAttribute("style");
					fn.ge(".reader-bottom").classList.remove("toolbar");
					fn.ge(".reader-bottom").removeAttribute("style");
					lastScrollTop = st;
				}
			});
		},
		tukuMangaUI: () => {
			let lastScrollTop = 0;
			fn.ge(".read-doc-center,.app").addEventListener("scroll", (event) => {
				if (isRemove) return (lastScrollTop = 0);
				let st = event.srcElement.scrollTop;
				if (st > lastScrollTop) {
					for (let e of fn.gae(".read-header,.read-footer,.btn-wrap")) e.style.display = "none";
					if (isPC) {
						fn.ge(".read-doc-center").style.height = "100vh";
					}
					lastScrollTop = st;
				} else if (st < lastScrollTop - 20) {
					for (let e of fn.gae(".read-header,.read-footer,.btn-wrap")) e.style.display = "";
					if (isPC) {
						fn.ge(".read-doc-center").style.height = "";
					}
					lastScrollTop = st;
				}
			});
		},
		cartoonmadUI: () => {
			fn.run("document.onkeydown=null");
			fn.remove("//td[div[@id='sidebar-follow']] | //td[ins[@class='adsbygoogle']] | //tr[td[script]] | //select");
			let ele = fn.ge("//tr[td[@bgcolor='#EAEAEA']]");
			if (ele) ele.parentNode.append(ele.cloneNode(true));
			let eleM = fn.ge("//tr[td[table[@bgcolor='#CCCCCC']]]");
			if (eleM) {
				let x = eleM.parentNode.lastElementChild.previousElementSibling;
				insertBefore(x, eleM.cloneNode(true));
			}
		},
		copymanga_decrypt_A: async (raw, key) => {
			// 解密方法來自https://greasyfork.org/scripts/397848
			const encoder = new TextEncoder();
			const decoder = new TextDecoder();
			const dioKey = encoder.encode(key);
			const header = raw.substring(0, 16);
			const body = raw.substring(16);
			const iv = encoder.encode(header);
			const bodyBytes = new Uint8Array(body.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
			const cryptoKey = await _unsafeWindow.crypto.subtle.importKey("raw", dioKey, {
				name: "AES-CBC"
			}, false, ["decrypt"]);
			const decryptedBytes = await _unsafeWindow.crypto.subtle.decrypt({
				name: "AES-CBC",
				iv
			}, cryptoKey, bodyBytes);
			return JSON.parse(await decoder.decode(decryptedBytes));
		},
		copymanga_decrypt_B: (raw, key) => {
			const CryptoJS = addCryptoJSLibrary();
			// 解密方法來自https://greasyfork.org/scripts/421371
			const header = raw.substring(0, 16);
			const body = raw.substring(16);
			const iv = CryptoJS.enc.Utf8.parse(header);
			const string = CryptoJS.AES.decrypt(
				CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(body)),
				CryptoJS.enc.Utf8.parse(key), {
					iv,
					mode: CryptoJS.mode.CBC,
					padding: CryptoJS.pad.Pkcs7
				}
			).toString(CryptoJS.enc.Utf8);
			return JSON.parse(string);
		}
	};

	function simpleLoadImg(img) {
		return new Promise((resolve) => {
			if (!img) {
				resolve("error" + String(img));
				return;
			}
			const index = img.dataset.index;
			let loadSrc = img.dataset.src;
			const temp = new Image();
			if ("referrerpolicy" in siteData) {
				temp.setAttribute("referrerpolicy", siteData.referrerpolicy);
			}
			temp.onload = () => {
				img.dataset.width = temp.naturalWidth;
				img.dataset.height = temp.naturalHeight;
				img.classList.add("loaded");
				img.src = loadSrc;
				resolve(index + " | load | " + loadSrc);
			};
			temp.onerror = async () => {
				if (loadSrc.includes("https://wsrv.nl/")) {
					loadSrc = loadSrc.replace("https://wsrv.nl/?url=", ""); //wsrv.nl_CDN
				} else if (loadSrc.includes(".wp.com/") && !document.title.endsWith("4KHD")) {
					loadSrc = loadSrc.replace(/i\d\.wp\.com\/|\?.+$/g, ""); //WordPressCDN
				}
				let check = await fn.delay(3000, 0).then(() => fn.checkImgStatus(loadSrc, 0));
				if (check.ok) {
					img.dataset.width = check.width;
					img.dataset.height = check.height;
					img.classList.add("loaded");
					img.dataset.src = loadSrc;
					img.src = loadSrc;
					resolve(index + " | load | " + loadSrc);
				} else {
					img.classList.add("loaded");
					img.classList.add("error");
					img.dataset.src = loadSrc;
					img.src = loadSrc;
					resolve(index + " | error | " + loadSrc);
				}
			};
			temp.src = loadSrc;
		});
	}

	class FunctionQueue {
		constructor(workerLength, _function, parameters) {
			this.workerLength = Number(workerLength) || 2;
			this._function = _function;
			this.parameters = parameters;
			this.executing = new Set();
			this.interval = Number(options.singleThreadInterval);
			return this.run();
		}
		async run() {
			const results = [];
			for (let i = 0, n = this.parameters.length; i < n; i++) {
				if (!isOpenGallery && !isOpenFilter) return;
				const p = this._function(this.parameters[i]).then(value => value || String(i)).finally(() => this.executing.delete(p));
				this.executing.add(p);
				results.push(p);
				if (this.executing.size >= this.workerLength) {
					await Promise.race(this.executing);
				}
				if (this.workerLength == 1 && this.interval > 0) {
					await delay(this.interval * 1000);
				}
			}
			return Promise.all(results);
		}
	}

	//CSS取得元素返回元素
	function ge(selector, node = null) {
		return (node || document).querySelector(selector);
	}

	//延遲
	function delay(time = 1000) {
		return new Promise(resolve => setTimeout(resolve, time));
	}

	//等待直至回調函式返回有效物件
	function wait(callback) {
		return new Promise(ending => {
			const loopFn = async () => {
				const check = await callback();
				if (!!check) {
					ending();
					return;
				} else {
					await delay(100);
					return loopFn();
				}
			};
			loopFn();
		});
	}

	//CSS取得所有元素返回元素陣列
	const gae = (selector, node = null) => [...(node || document).querySelectorAll(selector)];
	//Xpath取得元素返回元素
	const gx = (xpath) => document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
	//Xpath取得所有元素返回元素陣列
	const gax = (xpath) => {
		let nodes = [];
		let results = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
		let node;
		while (node = results.iterateNext()) {
			nodes.push(node);
		}
		return nodes;
	};

	//元素插入在節點之前
	const insertBefore = (targetNode, newNode) => {
		if ([targetNode, newNode].every(e => isEle(e))) {
			targetNode.parentNode.insertBefore(newNode, targetNode);
		} else {
			console.error("insertBefore參數錯誤\n", targetNode, getType(targetNode), newNode, getType(newNode));
		}
	};

	//元素插入在節點之後
	const insertAfter = (targetNode, newNode) => {
		if ([targetNode, newNode].every(e => isEle(e))) {
			targetNode.parentNode.insertBefore(newNode, targetNode.nextSibling);
		} else {
			console.error("insertAfter參數錯誤\n", targetNode, getType(targetNode), newNode, getType(newNode));
		}
	};

	//創建Style
	const createStyle = css => {
		const style = fn.ce("style", {
			type: "text/css",
			innerHTML: css
		});
		return style;
	};

	//平滑滾動至元素位置
	function smoothScrollIntoView(element) {
		element.scrollIntoView(smoothOptions);
	}

	//立即滾動至元素位置
	function instantScrollIntoView(element) {
		element.scrollIntoView(instantOptions);
	}

	//數字字串補0
	const getNum = (i, pad = 4) => String(i + 1).padStart(pad, "0");

	const getDataMsg = (text, picNum, imgsNum) => {
		if (isStopDownload) return;
		if (picNum != "none") fn.showMsg(`${DL.str_23}${downloadNum += 1}/${imgsNum}${DL.str_24}${text}`, 0);
	};

	//取得參照頁
	const getReferer = (srcUrl) => {
		let referer;
		if (isString(siteData.referer) && siteData.referer == "url") {
			referer = document.URL;
		} else if (/vipr\.im|imagetwist\.com|imgspice\.com/.test(srcUrl) || siteData.referer == "src") {
			referer = srcUrl;
		} else if (/\.sinaimg\./.test(srcUrl)) {
			referer = "https://weibo.com/";
		} else if (/imgtaxi\.com/.test(srcUrl)) {
			referer = "https://imgtaxi.com/";
		} else if (/saint2\.su/.test(srcUrl)) {
			referer = "https://saint2.su/";
		} else if (/imhentai\.xxx/.test(srcUrl)) {
			referer = "https://imhentai.xxx/";
		} else if (/mitaku\.net/.test(srcUrl)) {
			referer = "https://mitaku.net/";
		} else if (isString(siteData.referer) || siteData.referer == "") {
			referer = siteData.referer;
		} else {
			referer = fn.lo + "/";
		}
		return referer;
	};

	let v2ph_cookie = _GM_getValue("v2ph_cookie", "");
	let myreadingmanga_cookie = _GM_getValue("myreadingmanga_cookie", "");

	//取得cookie
	const getCookie = () => {
		if (fn.lh.includes(".v2ph.")) {
			return v2ph_cookie;
		} else if (fn.lh.includes("myreadingmanga")) {
			return myreadingmanga_cookie;
		} else if ("_cf_cookie" in localStorage) {
			return localStorage.getItem("_cf_cookie");
		}
		return "";
	};

	const XHR_Download = async (src, picNum = "none", imgsNum = "none") => {
		let errorNum = 0;
		let request;
		while (true) {
			request = await new Promise(resolve => {
				const xhr = new XMLHttpRequest();
				xhr.open("GET", src);
				xhr.responseType = "blob";
				xhr.onload = () => {
					if (isStopDownload) {
						resolve({
							stop: "stop"
						});
						return;
					}
					if (
						/\/octet-stream/.test(String(xhr.response?.type)) && Number(xhr.response?.size) > 1024 ||
						isM && xhr.response?.type == "" && Number(xhr.response?.size) > 1024 ||
						/^image|^video|text\/base64\.jpg/.test(String(xhr.response?.type))) {
						resolve({
							load: "下載成功",
							blob: xhr.response,
							picNum,
							src,
							finalUrl: xhr.responseURL,
							get: "XMLHttpRequest"
						});
					} else {
						let htmlText = "none";
						if (/text\/html/.test(String(xhr.response?.type))) {
							htmlText = xhr.response.text();
						}
						resolve({
							htmlText: htmlText,
							blob: xhr.response,
							error: "下載錯誤",
							picNum,
							src,
							finalUrl: xhr.responseURL,
							data: xhr,
							get: "XMLHttpRequest"
						});
					}
				};
				xhr.onerror = (error) => {
					resolve({
						error: "下載錯誤",
						picNum,
						src,
						errorLog: error,
						data: xhr,
						get: "XMLHttpRequest"
					});
					console.error("XHR_Download() Error: ", error);
				};
				xhr.send();
			});
			if (!("load" in request)) {
				errorNum++;
				if (!isStopDownload && errorNum <= Number(options.retry)) {
					await fn.delay(Number(options.interval) * 1000, 0);
				}
			}
			if (isStopDownload || ("load" in request) || errorNum > Number(options.retry)) {
				break;
			}
		}
		getDataMsg(("load" in request) ? DL.str_25 : DL.str_26, picNum, imgsNum);
		return request;
	};

	//Fetch API下載圖片
	const Fetch_API_Download = async (src, picNum = "none", imgsNum = "none") => {
		let errorNum = 0;
		let request;
		while (true) {
			request = await new Promise(resolve => {
				fetch(src, {
					headers: {
						"Accept": "*/*",
						//"accept": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
						//"cache-control": "no-cache",
						//"Upgrade-Insecure-Requests": "1"
					},
					referrer: getReferer(src),
					referrerPolicy: "strict-origin-when-cross-origin",
					cache: "force-cache",
					credentials: "same-origin"
				}).then(async res => ({
					data: res,
					blob: await res.blob()
				})).then(obj => {
					if (isStopDownload) {
						resolve({
							stop: "stop"
						});
						return;
					}
					if (/\/octet-stream/.test(String(obj?.blob?.type)) && Number(obj?.blob?.size) > 1024 || isM && obj?.blob?.type == "" && Number(obj?.blob?.size) > 1024 || /^image|^video|text\/base64\.jpg/.test(String(obj?.blob?.type))) {
						resolve({
							load: "下載成功",
							blob: obj.blob,
							picNum,
							src,
							finalUrl: obj.data?.url,
							get: "Fetch API"
						});
					} else {
						let htmlText = "none";
						if (/text\/html/.test(String(obj?.blob?.type))) {
							htmlText = obj.blob.text();
						}
						resolve({
							htmlText: htmlText,
							blob: obj.blob,
							error: "下載錯誤",
							picNum,
							src,
							finalUrl: obj.data?.url,
							data: obj.data,
							get: "Fetch API"
						});
					}
				}).catch(error => {
					resolve({
						error: "下載錯誤",
						picNum,
						src,
						errorLog: error,
						get: "Fetch API"
					});
					console.error("Fetch_API_Download() Error: ", error);
				});
			});
			if (!("load" in request)) {
				errorNum++;
				if (!isStopDownload && errorNum <= Number(options.retry)) {
					await fn.delay(Number(options.interval) * 1000, 0);
				}
			}
			if (isStopDownload || ("load" in request) || errorNum > Number(options.retry)) {
				break;
			}
		}
		getDataMsg(("load" in request) ? DL.str_25 : DL.str_26, picNum, imgsNum);
		return request;
	};

	//GM_xmlhttpRequest下載圖片
	const GM_XHR_Download = async (src, picNum = "none", imgsNum = "none") => {
		let errorNum = 0;
		let request;
		while (true) {
			request = await new Promise(resolve => {
				_GM_xmlhttpRequest({
					method: "GET",
					url: src,
					responseType: "blob",
					headers: {
						"Origin": fn.lo,
						"Referer": getReferer(src),
						"User-Agent": navigator.userAgent,
						"Accept": "*/*",
						//"Upgrade-Insecure-Requests": "1"
					},
					cookie: getCookie(),
					onload: async data => {
						if (isStopDownload) {
							resolve({
								stop: "stop"
							});
							return;
						}
						let blob = data.response;
						//debug("GM blob", blob);
						//XBrowser Blob的type是""
						if (/\/octet-stream/.test(blob.type) && blob.size > 1024 || isM && blob.type == "" && blob.size > 1024 || /^image|^video|text\/base64\.jpg/.test(blob.type)) {
							resolve({
								load: "下載成功",
								blob: blob,
								picNum,
								src,
								finalUrl: data.finalUrl,
								get: "GM_xmlhttpRequest"
							});
						} else {
							let htmlText = "none";
							if (/text\/html/.test(blob.type)) {
								htmlText = blob.text();
							}
							resolve({
								htmlText: htmlText,
								blob: blob,
								error: "下載錯誤",
								picNum,
								src,
								finalUrl: data.finalUrl,
								data: data,
								get: "GM_xmlhttpRequest"
							});
						}
					},
					onerror: error => {
						resolve({
							error: "下載錯誤",
							picNum,
							src,
							errorLog: error,
							get: "GM_xmlhttpRequest"
						});
						console.error("GM_XHR_Download() Error: ", error);
					}
				});
			});
			if (!("load" in request)) {
				errorNum++;
				if (!isStopDownload && errorNum <= Number(options.retry)) {
					await fn.delay(Number(options.interval) * 1000, 0);
				}
			}
			if (isStopDownload || ("load" in request) || errorNum > Number(options.retry)) {
				break;
			}
		}
		getDataMsg(("load" in request) ? DL.str_25 : DL.str_26, picNum, imgsNum);
		/*
		debug("下載完成", {
		    src,
		    request
		});
		*/
		return request;
	};

	//下載儲存
	const saveData = (blob, fileName) => {
		let href = URL.createObjectURL(blob);
		let a = fn.ce("a", {
			href,
			download: fileName
		});
		EClick(a);
		//document.body.append(a);
		//a.click();
		//a.remove();
		setTimeout(() => URL.revokeObjectURL(href), 4000);
	};

	const captureExclude = () => (isChangeNum || isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || isFetching || isDownloading);

	const checkGeting = () => {
		if (isDownloading) {
			alert(DL.str_48);
			return true;
		}
		if (isFetching) {
			alert(DL.str_49);
			return true;
		}
		return false;
	};

	//取得圖片主函式
	const getImgs = async selector => {
		isFetching = true;
		let imgs = null;
		if (!("SPA" in siteData) && siteData.repeat != 1 && siteData.infiniteCapture != 1 && globalImgArray.length > 0) {
			isFetching = false;
			imgs = globalImgArray;
			return imgs;
		} else if (lastValidPageURL === currentURL && siteData.repeat != 1 && siteData.infiniteCapture != 1 && globalImgArray.length > 0) {
			isFetching = false;
			imgs = globalImgArray;
			return imgs;
		} else if (ge(".FullPictureLoadImage,.FullPictureLoadVideo") && siteData.repeat != 1) {
			imgs = gae(".FullPictureLoadImage:not(.small)");
		} else if (isFn(selector)) {
			imgs = await selector();
			if (isSet(imgs)) {
				imgs = [...imgs];
			}
			if (getImgFnProcessRecord == "" && !getImgFnProcessRecord.includes("專用Fn")) {
				getImgFnProcessRecord += " > " + siteData.name + "專用Fn";
			}
		} else if (isSet(selector)) {
			imgs = [...selector];
		} else if (!selector || selector === "") {
			fn.showMsg(DL.str_41);
			return;
		} else if (selector.length < 3) {
			fn.showMsg(DL.str_42);
			return;
		} else if ("srcset" in siteData && isString(siteData.srcset)) {
			imgs = fn.getImgSrcset(selector);
			if (!getImgFnProcessRecord.includes("fn.getImgSrcset(selector)")) {
				getImgFnProcessRecord += " > fn.getImgSrcset(selector)";
			}
		} else if (/^\//.test(selector)) {
			imgs = gax(selector);
			if (!getImgFnProcessRecord.includes("gax(selector)")) {
				getImgFnProcessRecord += " > gax(selector)";
			}
		} else {
			imgs = gae(selector);
			if (!getImgFnProcessRecord.includes("gae(selector)")) {
				getImgFnProcessRecord += " > gae(selector)";
			}
		}
		if (!isArray(imgs)) {
			isFetching = false;
			alert("getImgs() Error! ImageList Not Array");
			return [];
		}
		if (isPromise(imgs[0])) {
			imgs = await Promise.all(imgs); //取出new Promise的值
		}
		fn.hm();
		if (!isValidPage) return [];
		imgs = imgs.flat().filter(Boolean); //去除空、無用
		let imgsSrcArr = imgs.map(img => {
			let check = fn.checkImgSrc(img);
			if (check.ok) {
				return check.src;
			} else {
				console.error("\ngetImgs() imgs 格式錯誤!", img);
				return null;
			}
		}).filter(Boolean);
		if (globalImgArray.length === 0 && imgs.length !== 0) {
			debug(`\ngetImgs()${getImgFnProcessRecord} 所有圖片網址:`, imgsSrcArr);
			debug(`\ngetImgs()${getImgFnProcessRecord} 去重複後的圖片網址:`, [...new Set(imgsSrcArr)]);
		}
		imgsSrcArr = [...new Set(imgsSrcArr)];
		let cdn = options.cdn;
		if (cdn > -1 || cdn == "w" || cdn == "b") {
			imgsSrcArr = imgsSrcArr.map(e => fn.cdn(e, cdn));
			debug("加了CDN後的圖片網址:", imgsSrcArr);
		}
		globalImgArray = imgsSrcArr;
		let thums = siteData.thums;
		if (isString(thums)) {
			thumbnailSrcArray = fn.getImgSrcArr(thums);
		}
		let videos = siteData.videos;
		if (isString(videos)) {
			videoSrcArray = fn.gae(videos).map(e => e.src);
		} else if (isFn(videos)) {
			videoSrcArray = await videos();
		}
		isFetching = false;
		return imgsSrcArr;
	};

	//自動下載函式
	const startAutoDownload = async () => {
		let autoDownload = siteData.autoDownload;
		if (!autoDownload) return;
		let [start, time] = autoDownload;
		let next = siteData.next;
		let ele;
		isFn(next) ? ele = await next() : ele = fn.ge(next);
		if (!!ele && start == 1 || !!ele && options.autoDownload == 1) {
			isCountdowning = true;
			let max = time || options.autoDownloadCountdown;
			let countdownNum = Number(max);
			fn.showMsg(`${DL.str_32}${max}${DL.str_33}`, 0);
			for (let i = 1, n = Number(max); i <= n; i++) {
				await delay(1000);
				if (isStopDownload) return;
				fn.showMsg(`${DL.str_32}${countdownNum-=1}${DL.str_33}`, 0);
			}
			await delay(500);
			if (isStopDownload) return;
			if (isFn(next) && isString(ele)) {
				fn.showMsg(DL.str_34.n);
				location.href = ele;
			} else if (isEle(ele)) {
				fn.showMsg(DL.str_35);
				EClick(ele);
			}
		} else if (!ele && start == 1 || !ele && options.autoDownload == 1) {
			fn.showMsg(DL.str_36, 0);
			options.autoDownload = 0;
			let jsonStr = JSON.stringify(options);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
		}
	};

	const checkURL = (obj) => {
		if (isArray(obj)) {
			return obj.filter(url => isURL(url));
		} else if (isString(obj)) {
			if (isURL(obj)) {
				return obj;
			}
		}
		return null;
	};

	const checkDownloadCondition = () => {
		if (fn.lh.includes(".v2ph.")) {
			const cookie = v2ph_cookie;
			if (!!cookie) {
				return true;
			} else {
				alert("微圖坊下載需先填入Cloudflare clearance cookie。");
				v2ph_cookie = prompt("Set Cookie", v2ph_cookie || "");
				if (!!v2ph_cookie) {
					_GM_setValue("v2ph_cookie", v2ph_cookie);
				}
				return false;
			}
		}
		if (fn.lh.includes("myreadingmanga")) {
			const cookie = myreadingmanga_cookie;
			if (!!cookie) {
				return true;
			} else {
				alert("MyReadingManga download requires filling in Cloudflare clearance cookie。");
				myreadingmanga_cookie = prompt("Set Cookie", myreadingmanga_cookie || "");
				if (!!myreadingmanga_cookie) {
					_GM_setValue("myreadingmanga_cookie", myreadingmanga_cookie);
				}
				return false;
			}
		}
		return true;
	};

	//長圖拼接下載函式
	const combineDownloadImages = async (all_data, fileName) => {

		const all_blobs = all_data.map(e => e.blob);

		const srcs = all_blobs.map(blob => URL.createObjectURL(blob));

		const loadImage = src => new Promise((resolve, reject) => {
			const img = new Image();
			img.onload = () => resolve(img);
			img.onerror = reject;
			img.src = src;
		});

		let all_images = await Promise.all(srcs.map(loadImage));

		let cw = all_images.every((e, i, a) => a.at(0).width == e.width);
		if (!cw) {
			all_images = null;
			promiseBlobArray = [];
			downloadNum = 0;
			isDownloading = false;
			combineDownloadSwitch = false;
			for (let src of srcs) {
				URL.revokeObjectURL(src);
			}
			return fn.showMsg(DL.str_235, 5000);
		}

		const limit = options.combineLimit == 66 ? 65535 : Number(options.combineLimit) * 1000;
		let ch = 0;
		let wait_combine_array = [];
		let combine_array = [];
		wait_combine_array.push(combine_array);

		let next;
		for (let i = 0, n = all_images.length; i < n; i++) {
			ch += all_images[i].height;
			combine_array.push(all_images[i]);
			next = all_images[i + 1];
			if (next) {
				if ((ch + next.height) >= limit) {
					ch = 0;
					combine_array = [];
					wait_combine_array.push(combine_array);
				}
			}
		}

		const total = wait_combine_array.length;
		let complete = 0;
		const combineImages = (images, index) => new Promise(resolve => {
			const totalHeight = images.reduce((sum, img) => sum + img.height, 0);
			const canvas = new OffscreenCanvas(images[0].width, totalHeight);
			const ctx = canvas.getContext("2d");
			let currentY = 0;
			for (let img of images) {
				ctx.drawImage(img, 0, currentY);
				currentY += img.height;
			}
			canvas.convertToBlob({
				type: "image/jpeg",
				quality: jpgConvertQuality == 100 ? 1 : Number("0." + jpgConvertQuality)
			}).then(blob => {
				fn.showMsg(`${DL.str_236} ${complete += 1}/${total}`, 0);
				let combine_fileName;
				if (total > 1) {
					combine_fileName = `${fileName}_combine${String(index + 1).padStart(String(total).length, "0")}.jpg`;
				} else {
					combine_fileName = `${fileName}_combine.jpg`;
				}
				if (options.zip == 1) {
					resolve(blob);
				} else {
					saveData(blob, combine_fileName);
					resolve();
				}
			});
		});

		await fn.showMsg(`${DL.str_236}... 0/${total}`, 0).then(() => fn.delay(200, 0));

		if (options.zip == 1) {
			let combineTasks = wait_combine_array.map(a => combineImages(a));
			await Promise.all(combineTasks).then(blobs => {
				const _JSZip = addJSZipLibrary() || JSZip;
				const zip = new _JSZip();
				let zipFolder;
				if (zipFolderConfig == 1) {
					zipFolder = zip.folder(`${fileName} [${total}P]`);
				}
				for (let i = 0, n = blobs.length; i < n; i++) {
					let combine_fileName = `combine${String(i + 1).padStart(String(total).length, "0")}.jpg`;
					(zipFolderConfig == 1 ? zipFolder : zip).file(combine_fileName, blobs[i], {
						binary: true
					});
				}
				return zip.generateAsync({
					type: "blob"
				}, (metadata) => {
					fn.showMsg(DL.str_31 + metadata.percent.toFixed(2) + " %", 0);
				}).then(data => {
					debug("\nZIP壓縮檔數據:", data);
					saveData(data, `${fileName} [${total}P].${compressed_extension}`);
				});
			});
		} else {
			for (let i = 0; i < total; i++) {
				await combineImages(wait_combine_array[i], i);
			}
		}

		await fn.delay(200, 0);
		fn.hm();
		all_images = null;
		wait_combine_array = null;
		combine_array = null;
		promiseBlobArray = [];
		downloadNum = 0;
		isDownloading = false;
		combineDownloadSwitch = false;
		for (let src of srcs) {
			URL.revokeObjectURL(src);
		}
	};

	const compressed_extension = _GM_getValue("compressed_extension", "zip");
	const zipFolderConfig = _GM_getValue("zipFolderConfig", 1);
	const convertWebpToJpg = _GM_getValue("convertWebpToJpg", 0);
	const convertAvifToJpg = _GM_getValue("convertAvifToJpg", 0);
	const jpgConvertQuality = _GM_getValue("jpgConvertQuality", 95);

	//圖片影片下載函式
	const DownloadFn = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;

		const checkDC = checkDownloadCondition();
		if (!checkDC) return;

		isStopDownload = false;
		downloadNum = 0;
		promiseBlobArray = [];
		const executing = new Set();
		const treadLimit = Number(options.threading);
		const interval = Number(options.singleThreadInterval);
		const method = _GM_getValue("DownloadAPI", "default");
		let selector, titleText;
		let autoDownload = siteData.autoDownload;
		let start;
		if (isArray(autoDownload)) {
			[start] = autoDownload;
		}
		let titleReplace = fn.dt({
			s: "title"
		});
		if (fastDownloadSwitch && array === null) {
			selector = siteData.srcset || siteData.imgs;
			titleText = (customTitle || titleReplace);
		} else if (array === null) {
			if (!autoDownload || !!autoDownload && start != 1 && options.autoDownload != 1) {
				selector = siteData.srcset || siteData.imgs;
				titleText = await prompt(DL.str_51, (customTitle || titleReplace));
				if (titleText === null) {
					fn.showMsg(DL.str_41);
					return;
				}
			} else if (!!autoDownload) {
				if (start == 1 || options.autoDownload == 1) {
					selector = siteData.srcset || siteData.imgs;
					titleText = (customTitle || titleReplace);
				} else {
					debug("未開啟自動下載");
					return;
				}
			}
		}
		isDownloading = true;
		if (isString(text)) titleText = text;
		let imgsSrcArr = isArray(array) ? array : await getImgs(selector);
		videoSrcArray = checkURL(videoSrcArray);
		if (imgsSrcArr.length > 0 && titleText != null && titleText != "" || videoSrcArray.length > 0) {
			fn.showMsg(DL.str_55, 0);
			let loopMsg;
			const imgsNum = imgsSrcArr.length;
			let title = apiCustomTitle ?? titleText;
			const JSZip = addJSZipLibrary();
			const zip = new JSZip();
			let zipFolder;
			let videosNum;
			if (isPC && videoSrcArray.length > 0 && ("downloadVideo" in siteData) && siteData.downloadVideo == true && FullPictureLoadCustomDownloadVideo == 1) {
				videosNum = videoSrcArray.length;
				if (zipFolderConfig == 1) {
					zipFolder = zip.folder(`${title} [${imgsNum}P + ${videosNum}V]`);
				}
			} else {
				if (zipFolderConfig == 1) {
					zipFolder = zip.folder(`${title} [${imgsNum}P]`);
				}
			}
			if (imgsSrcArr.length > 0) {
				const pad = String(imgsSrcArr.length).length;
				for (let [i, src] of imgsSrcArr.entries()) {
					let picNum = getNum(i, pad);
					let promiseBlob;
					if (isStopDownload) {
						executing.clear();
						promiseBlobArray = [];
						return;
					}
					let sameOrigin = false;
					try {
						if (fn.clh() === new URL(src).hostname) {
							sameOrigin = true;
						}
					} catch (e) {}
					if (method == "xhr") {
						promiseBlob = XHR_Download(src, picNum, imgsNum).finally(() => executing.delete(promiseBlob));
					} else if (
						method == "fetch" ||
						sameOrigin && siteData.fetch != 0 ||
						src.startsWith("data:") ||
						src.startsWith("blob:") ||
						siteData.fetch == 1 ||
						src.includes(".wp.com/") ||
						src.includes("wsrv.nl/")
					) {
						promiseBlob = Fetch_API_Download(src, picNum, imgsNum).finally(() => executing.delete(promiseBlob));
					} else {
						promiseBlob = GM_XHR_Download(src, picNum, imgsNum).finally(() => executing.delete(promiseBlob));
					}
					executing.add(promiseBlob);
					promiseBlobArray.push(promiseBlob);
					if (executing.size >= treadLimit) {
						await Promise.race(executing);
					}
					if (treadLimit == 1 && interval > 0) {
						await delay(interval * 1000);
					}
				}
			}
			if (isPC && videoSrcArray.length > 0 && ("downloadVideo" in siteData) && siteData.downloadVideo == true && FullPictureLoadCustomDownloadVideo == 1) {
				const pad = String(videosNum).length;
				loopMsg = setInterval(() => {
					fn.showMsg("Video Downloading...", 0);
				}, 2000);
				for (let [i, src] of videoSrcArray.entries()) {
					let videoNum = getNum(i, pad);
					let promiseBlob;
					if (isStopDownload) {
						clearInterval(loopMsg);
						executing.clear();
						promiseBlobArray = [];
						return;
					}
					let sameOrigin = false;
					try {
						if (fn.clh() === new URL(src).hostname) {
							sameOrigin = true;
						}
					} catch (e) {}
					if (method == "xhr") {
						promiseBlob = XHR_Download(src, videoNum, imgsNum + videosNum).finally(() => executing.delete(promiseBlob));
					} else if (
						method == "fetch" ||
						sameOrigin && siteData.fetch != 0 ||
						src.startsWith("data:") ||
						src.startsWith("blob:") ||
						siteData.fetch == 1 ||
						src.includes(".wp.com/") ||
						src.includes("wsrv.nl/")
					) {
						promiseBlob = Fetch_API_Download(src, videoNum, imgsNum + videosNum).finally(() => executing.delete(promiseBlob));
					} else {
						promiseBlob = GM_XHR_Download(src, videoNum, imgsNum + videosNum).finally(() => executing.delete(promiseBlob));
					}
					executing.add(promiseBlob);
					promiseBlobArray.push(promiseBlob);
					if (executing.size >= treadLimit) {
						await Promise.race(executing);
					}
					if (treadLimit == 1 && interval > 0) {
						await delay(interval * 1000);
					}
				}
			}
			debug("\nPromiseBlobArray:", promiseBlobArray);
			Promise.all(promiseBlobArray).then(async data => {
				try {
					clearInterval(loopMsg);
				} catch {}
				if (isStopDownload) {
					data = null;
					executing.clear();
					promiseBlobArray = [];
					return;
				}
				debug("\nPromiseAllData:", data);
				let blobDataArray = data.filter(item => item.load); //成功下載
				let errorDataArray = data.filter(item => item.error); //下載錯誤
				debug("\nNewDataArray:", blobDataArray);
				debug("\nErrorDataArray:", errorDataArray);
				if (errorDataArray.length > 0) {
					fn.hm();
					options.autoDownload = 0;
					let jsonStr = JSON.stringify(options);
					localStorage.setItem("FullPictureLoadOptions", jsonStr);
					downloadNum = 0;
					isDownloading = false;
					let yes = await confirm(`${DL.str_27}${errorDataArray.length}${DL.str_28}${DL.str_29}`);
					if (!yes) {
						executing.clear();
						promiseBlobArray = [];
						blobDataArray = null;
						errorDataArray = null;
						return;
					}
				}
				if (combineDownloadSwitch && blobDataArray.length > 0) {
					return combineDownloadImages(blobDataArray, text);
				}
				if (blobDataArray.length > 0) {
					let total = blobDataArray.length;
					for (let [i, data] of blobDataArray.entries()) {
						let ex;
						let blobData = data.blob;
						let type = blobData.type;
						try {
							if (!fn.isVideo(data.src) && (/octet-stream/.test(type) || isM && type === "")) {
								let url = URL.createObjectURL(blobData);
								let check = await fn.checkImgStatus(url, 0);
								URL.revokeObjectURL(url);
								if (check.ok) {
									if (/\.webp/i.test(data.src) && convertWebpToJpg != 1) {
										blobData = await fn.convertImage(blobData, "image/webp");
										ex = "webp";
									} else {
										blobData = await fn.convertImage(blobData);
										ex = "jpg";
									}
									if (type === "") {
										fn.showMsg(`unknown type to ${ex} ${(i+ 1)}/${total}`, 0);
									} else {
										fn.showMsg(`octet-stream to ${ex} ${(i+ 1)}/${total}`, 0);
									}
								} else {
									console.error("\nDownloadFn() PromiseAll blob資料格式錯誤", data);
									fn.showMsg(DL.str_30, 0);
									return;
								}
							} else if (
								(/webp/i.test(type) || /\.webp/i.test(data.finalUrl)) && convertWebpToJpg == 1 ||
								(/avif/i.test(type) || /\.avif/i.test(data.finalUrl)) && convertAvifToJpg == 1
							) {
								let quality = jpgConvertQuality == 100 ? 1 : Number("0." + jpgConvertQuality);
								blobData = await fn.convertImage(blobData, "image/jpeg", quality);
								ex = "jpg";
								fn.showMsg(`${DL.str_102} to ${ex} ${(i+ 1)}/${total}`, 0);
							} else if (/^text\/base64\.jpg/.test(type)) {
								ex = "jpg";
							} else {
								[ex] = type.split("/")[1].match(/\w+/);
								if (data.src.endsWith("webm")) {
									ex = "webm";
								}
							}
						} catch {
							if (/^image/.test(type)) {
								ex = "jpg";
							} else if (type === "") {
								let url = URL.createObjectURL(blobData);
								let check = await fn.checkImgStatus(url, 0);
								URL.revokeObjectURL(url);
								if (check.ok) {
									if (/\.webp/i.test(data.src) && convertWebpToJpg != 1) {
										ex = "webp";
										fn.showMsg(`unknown type to ${ex} ${(i+ 1)}/${total}`, 0);
										blobData = await fn.convertImage(blobData, "image/webp");
									} else {
										ex = "jpg";
										fn.showMsg(`unknown type to ${ex} ${(i+ 1)}/${total}`, 0);
										blobData = await fn.convertImage(blobData);
									}
								} else {
									console.error("\nDownloadFn() PromiseAll blob資料格式錯誤", data);
									fn.showMsg(DL.str_30, 0);
									return;
								}
							} else {
								console.error("\nDownloadFn() PromiseAll blob資料格式錯誤", data);
								fn.showMsg(DL.str_30, 0);
								return;
							}
						}
						let fileName;
						["mp4", "webm", "mov"].includes(ex) ? fileName = `${data.picNum}V.${(ex)}` : fileName = `${data.picNum}P.${(siteData.ex || ex)}`;
						if (options.zip == 1) {
							//console.log(`第${n}/${total}張,檔案名:${fileName},大小:${parseInt(data.blob.size / 1024, 10)} Kb`);
							(zipFolderConfig == 1 ? zipFolder : zip).file(fileName, blobData, {
								binary: true
							});
						} else {
							saveData(blobData, title + "_" + fileName);
							await delay(200);
							if (i === total - 1) {
								fn.hm();
								executing.clear();
								promiseBlobArray = [];
								downloadNum = 0;
								isDownloading = false;
								startAutoDownload();
							}
						}
					}
					if (options.zip == 1) {
						zip.generateAsync({
							type: "blob"
						}, (metadata) => {
							fn.showMsg(DL.str_31 + metadata.percent.toFixed(2) + " %", 0);
						}).then(async data => {
							fn.hm();
							debug("\nZIP壓縮檔數據:", data);
							let fileName;
							if (videoSrcArray.length > 0 && siteData.downloadVideo == true && FullPictureLoadCustomDownloadVideo == 1) {
								fileName = `${title} [${imgsNum}P + ${videosNum}V].${compressed_extension}`;
							} else {
								fileName = `${title} [${imgsNum}P].${compressed_extension}`;
							}
							saveData(data, fileName);
							executing.clear();
							promiseBlobArray = [];
							downloadNum = 0;
							isDownloading = false;
							startAutoDownload();
						});
					}
				} else {
					executing.clear();
					promiseBlobArray = [];
					downloadNum = 0;
					isDownloading = false;
					fn.showMsg(DL.str_43);
					return;
				}
			});
		} else {
			isDownloading = false;
			fn.showMsg(DL.str_41);
			return;
		}
	};

	//匯出網址
	const exportImgSrcText = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = isArray(array) ? array : await getImgs(selector);
		if (srcArr.length == 0 && videoSrcArray.length == 0 && fileUrlArray.length == 0) return fn.showMsg(DL.str_44);
		srcArr = srcArr.map((src, i) => {
			if (src.startsWith("blob")) {
				src = fn.blobURLtoDataURL(src);
			}
			return src;
		});
		srcArr = await Promise.all(srcArr);
		let picNum = srcArr.length;
		let titleText = (text || apiCustomTitle || customTitle || document.title);
		let fileName = `${titleText}[${picNum}P]_MediaURLs.txt`;
		if (videoSrcArray.length > 0) {
			srcArr = srcArr.concat(videoSrcArray);
			fileName = `${titleText}[${picNum}P + ${videoSrcArray.length}V]_MediaURLs.txt`;
		}
		if (fileUrlArray.length > 0) {
			srcArr = srcArr.concat(fileUrlArray);
			fileName = `${titleText}[${picNum}P`;
			if (videoSrcArray.length > 0) {
				fileName += ` + ${videoSrcArray.length}V`;
			}
			fileName += ` + ${fileUrlArray.length} Files]_MediaURLs.txt`;
		}
		let str = srcArr.join("\n");
		let blob = new Blob([str], {
			type: "text/plain",
			endings: "native"
		});
		saveData(blob, fileName);
		fn.showMsg(`${DL.str_101}`);
	};

	//複製網址或手動模式的插入圖片
	const copyImgSrcText = async () => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = await getImgs(selector);
		//siteData.insertImg ? debug("手動插入圖片") : debug("複製網址");
		if (srcArr.length == 0) return fn.showMsg(DL.str_44);
		let imgsNum = srcArr.length;
		let videosNum;
		if ((!fn.ge(".FullPictureLoadImage") && !!siteData.insertImg) || siteData.repeat == 1 && !!siteData.insertImg) {
			const [insertTargetEle, insertMode] = siteData.insertImg;
			return fn.insertImg(srcArr, insertTargetEle, insertMode);
		}
		if (isM) return;
		srcArr = srcArr.map((src, i) => {
			if (src.startsWith("blob")) {
				src = fn.blobURLtoDataURL(src);
			}
			return src;
		});
		srcArr = await Promise.all(srcArr);
		if (videoSrcArray.length > 0) {
			videosNum = videoSrcArray.length;
			srcArr = srcArr.concat(videoSrcArray);
		}
		if (fileUrlArray.length > 0) srcArr = srcArr.concat(fileUrlArray);
		let title;
		if (isString(apiCustomTitle)) {
			title = apiCustomTitle;
		} else if (isString(customTitle)) {
			title = customTitle;
		} else {
			title = fn.dt({
				s: "title"
			});
		}
		if (fileUrlArray.length > 0) {
			title = `${title}[${imgsNum}P`;
			if (videoSrcArray.length > 0) {
				title += ` + ${videoSrcArray.length}V`;
			}
			title += ` + ${fileUrlArray.length}File]`;
		} else if (videoSrcArray.length > 0) {
			title = `${title} [${imgsNum}P + ${videosNum}V]`;
		} else {
			title = `${title} [${imgsNum}P]`;
		}
		let textArr = [title].concat(srcArr);
		let str = textArr.join("\n");
		//console.log(str);
		copyToClipboard(str);
		fn.showMsg(`${DL.str_45}(${textArr.length - 1})`);
	};

	//複製網址
	const copyImgSrcTextB = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = isArray(array) ? array : await getImgs(selector);
		if (srcArr.length == 0 && videoSrcArray.length == 0 && fileUrlArray.length == 0) return fn.showMsg(DL.str_44);
		srcArr = srcArr.map((src, i) => {
			if (src.startsWith("blob")) {
				src = fn.blobURLtoDataURL(src);
			}
			return src;
		});
		srcArr = await Promise.all(srcArr);
		let imgsNum = srcArr.length;
		let videosNum;
		if (videoSrcArray.length > 0) {
			videosNum = videoSrcArray.length;
			srcArr = srcArr.concat(videoSrcArray);
		}
		if (fileUrlArray.length > 0) srcArr = srcArr.concat(fileUrlArray);
		let title;
		if (isString(text)) {
			title = text;
		} else if (isString(apiCustomTitle)) {
			title = apiCustomTitle;
		} else if (isString(customTitle)) {
			title = customTitle;
		} else {
			title = fn.dt({
				s: "title"
			});
		}
		if (videoSrcArray.length > 0) {
			title = `${title} [${imgsNum}P + ${videosNum}V]`;
		} else {
			title = `${title} [${imgsNum}P]`;
		}
		let textArr = [title].concat(srcArr);
		let str = textArr.join("\n");
		//console.log(str);
		copyToClipboard(str);
		fn.showMsg(`${DL.str_45}(${textArr.length - 1})`);
	};

	//匯出為JSON格式
	const exportJsonFormat = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = isArray(array) ? array : await getImgs(selector);
		if (srcArr.length == 0 && videoSrcArray.length == 0 && fileUrlArray.length == 0) return fn.showMsg(DL.str_44);
		let images = srcArr.map((src, i) => {
			if (src.startsWith("blob")) {
				src = fn.blobURLtoDataURL(src);
			}
			return src;
		});
		images = await Promise.all(images);
		let object = {
			url: currentURL,
			title: (text || apiCustomTitle || customTitle || document.title),
			images
		}
		if (videoSrcArray.length > 0) {
			Reflect.set(object, "videos", videoSrcArray);
		};
		if (fileUrlArray.length > 0) {
			Reflect.set(object, "files", fileUrlArray);
		}
		let fileName = (text || apiCustomTitle || customTitle || document.title) + ".json";
		let blob = new Blob([JSON.stringify(object, null, 4)], {
			type: "application/json"
		});
		saveData(blob, fileName);
		fn.showMsg(DL.str_175);
	};

	//匯出為Markdown格式
	const exportMarkdownFormat = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = isArray(array) ? array : await getImgs(selector);
		if (srcArr.length == 0 && videoSrcArray.length == 0 && fileUrlArray.length == 0) return fn.showMsg(DL.str_44);
		let title = "## " + (text || apiCustomTitle || customTitle || document.title);
		let post = `Post Link:[${currentURL}](${currentURL})`;
		let imagesTitle = "## Images";
		let images = srcArr.map(async (src, i) => {
			if (src.startsWith("blob")) {
				src = await fn.blobURLtoDataURL(src);
			}
			return `![${(text || apiCustomTitle || customTitle || document.title)}${(i + 1)}P](${src})`;
		});
		images = await Promise.all(images);
		let textArr = [title, post, imagesTitle].concat(images);
		if (videoSrcArray.length > 0) {
			let videosTitle = "## Videos";
			textArr.push(videosTitle);
			let videos = videoSrcArray.map(src => "    " + src);
			textArr = textArr.concat(videos);
		};
		if (fileUrlArray.length > 0) {
			let filesTitle = "## Files";
			textArr.push(filesTitle);
			let files = fileUrlArray.map(url => "    " + url);
			textArr = textArr.concat(files);
		}
		let str = textArr.join("\n");
		let fileName = (text || apiCustomTitle || customTitle || document.title) + ".md";
		let blob = new Blob([str], {
			type: "text/markdown",
			endings: "native"
		});
		saveData(blob, fileName);
		fn.showMsg(DL.str_177);
	};

	//複製為Markdown格式
	const copyMarkdownFormat = async (array = null, text = null) => {
		if (checkGeting() || isOpenOptionsUI) return;
		let selector = siteData.srcset || siteData.imgs;
		let srcArr = isArray(array) ? array : await getImgs(selector);
		if (srcArr.length == 0 && videoSrcArray.length == 0 && fileUrlArray.length == 0) return fn.showMsg(DL.str_44);
		if (isString(text)) {
			text = fn.dt({
				t: text
			});
		}
		let title = "## " + (text || apiCustomTitle || customTitle || document.title);
		let post = `Post Link:[${currentURL}](${currentURL})`;
		let imagesTitle = "## Images";
		let images = srcArr.map(async (src, i) => {
			if (src.startsWith("blob")) {
				src = await fn.blobURLtoDataURL(src);
			}
			return `![${(text || apiCustomTitle || customTitle || document.title)}${(i + 1)}P](${src})`;
		});
		images = await Promise.all(images);
		let textArr = [title, post, imagesTitle].concat(images);
		if (videoSrcArray.length > 0) {
			let videosTitle = "## Videos";
			textArr.push(videosTitle);
			let videos = videoSrcArray.map(src => "    " + src);
			textArr = textArr.concat(videos);
		};
		let str = textArr.join("\n");
		//console.log(str);
		copyToClipboard(str);
		fn.showMsg(DL.str_179);
	};

	const copyToClipboard = text => {
		if (!!_unsafeWindow.navigator.clipboard && _unsafeWindow.isSecureContext) {
			return _unsafeWindow.navigator.clipboard.writeText(text);
		} else {
			let textArea = fn.ace(document.body, "textarea", {
				value: text
			}, {
				position: "absolute",
				opacity: 0,
				left: "-999999px",
				top: "-999999px"
			});
			textArea.focus();
			textArea.select();
			return new Promise((res, rej) => {
				document.execCommand("copy") ? res() : rej();
				textArea.remove();
			});
		}
	};

	//滾動至首張圖片(動畫效果)
	const goToNo1Img = (time = 1000) => {
		let ele;
		ge("#FullPictureLoadImgBox:not([style*=none])") ? ele = ge(".FullPictureLoadImage.small") : ele = ge(".FullPictureLoadImage");
		if (ele) {
			if (time != 0) fn.showMsg(DL.str_46);
			setTimeout(() => {
				ele.scrollIntoView({
					behavior: "smooth"
				});
			}, time);
		}
	};

	//滾動至首尾圖片
	const goToImg = img => {
		let ele = null;
		if (ge("#FullPictureLoadImgBox:not([style*=none])") && img == "first") {
			ele = ge(".FullPictureLoadImage.small");
		} else if (img == "first") {
			ele = ge(".FullPictureLoadImage:not(.small)");
		}
		if (ge("#FullPictureLoadImgBox:not([style*=none])") && img == "last") {
			ele = gae(".FullPictureLoadImage.small").at(-1);
		} else if (img == "last") {
			ele = gae(".FullPictureLoadImage:not(.small)").at(-1);
		}
		if (ele) ele.scrollIntoView();
	};

	//自動滾動元素
	const autoScrollEles = () => {
		if (isOpenOptionsUI) return;
		let scrollEle = siteData.scrollEle;
		if (isFn(scrollEle)) {
			scrollEle();
		} else if (isArray(scrollEle)) {
			const [selector, time] = scrollEle;
			fn.scrollEles(selector, time);
		}
	};

	//減少圖片縮放級別
	const reduceZoom = () => {
		if (isFetching || !siteData.insertImg || isOpenOptionsUI) return;
		if (options.zoom <= 10 && ge(".FullPictureLoadImage:not(.small)")) {
			options.zoom == 0 ? options.zoom = 10 : options.zoom = options.zoom -= 1;
			if (options.zoom == 0) cancelZoom();
			let jsonStr = JSON.stringify(options);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
			if (options.zoom > 0) {
				for (let img of gae(".FullPictureLoadImage:not(.small)")) {
					if (fancyboxBlackList() || options.fancybox !== 1) {
						img.style.width = `${options.zoom * 10}%`;
					} else {
						let pE = img.parentNode;
						if (pE.nodeName === "A") {
							pE.style.width = `${options.zoom * 10}%`;
						}
					}
				}
				fn.showMsg(`${DL.str_60} ${options.zoom * 10}%`);
			}
		}
	};

	//增加圖片縮放級別
	const increaseZoom = () => {
		if (isFetching || !siteData.insertImg || isOpenOptionsUI) return;
		if (options.zoom > 1 && options.zoom <= 10 && ge(".FullPictureLoadImage:not(.small)")) {
			options.zoom = options.zoom += 1;
			if (options.zoom > 10) cancelZoom();
			let jsonStr = JSON.stringify(options);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
			if (options.zoom > 0 && options.zoom <= 10) {
				for (let img of gae(".FullPictureLoadImage:not(.small)")) {
					if (fancyboxBlackList() || options.fancybox !== 1) {
						img.style.width = `${options.zoom * 10}%`;
					} else {
						let pE = img.parentNode;
						if (pE.nodeName === "A") {
							pE.style.width = `${options.zoom * 10}%`;
						}
					}
				}
				fn.showMsg(`${DL.str_60} ${options.zoom * 10}%`);
			}
		}
	};

	let viewMode = 0;

	//切換圖片檢視模式
	const toggleImgMode = async () => {
		if (isFetching || !siteData.insertImg || isOpenOptionsUI) return;
		let column;
		if (gae(".FullPictureLoadImage").length < 1) {
			fn.showMsg("沒有圖片或只有影片");
			return;
		}
		if (ge(".FullPictureLoadImage:not(.small):not([style*=none])")) {
			if (ge("#FullPictureLoadImgBox")) {
				ge("#FullPictureLoadImgBox").style.display = "block";
				for (let e of gae(".FullPictureLoadImage:not(.small),#FullPictureLoadEnd")) {
					if (e.tagName == "IMG") {
						e.setAttribute("style", "display:none!important;");
						if (options.zoom > 0) e.style.width = `${options.zoom * 10}%`;
					} else {
						e.setAttribute("style", "display:none!important;");
					}
				}
				viewMode = 1;
				fn.showMsg(DL.str_93);
				return;
			}
			let width;
			if (options.column == 2 || siteData.category == "comic") {
				width = "48.8%";
				column = 2;
			} else if (options.column == 3) {
				width = "32%";
				column = 3;
			} else if (options.column == 5) {
				width = "19.2%";
				column = 5;
			} else if (options.column == 6) {
				width = "16%";
				column = 6;
			} else {
				column = 4;
				isM ? width = "24%" : width = "24.4%";
			}
			let imgBox = fn.ace(fragment, "div", {
				id: "FullPictureLoadImgBox"
			}, {
				width: "100%",
				maxWidth: "1400px",
				backgroundColor: "#f6f6f6",
				textAlign: "center",
				display: "block",
				direction: (siteData.category == "comic" || (options.column == 2 && siteData.category == "hcomic")) ? "rtl" : ""
			});
			let srcArr = gae(".FullPictureLoadImage:not(.small)").map(e => e.dataset.src ?? e.src);
			let blackList = fancyboxBlackList();
			for (let [i, src] of srcArr.entries()) {
				let a = fn.ce("a");
				if (options.fancybox == 1 && !blackList) {
					a = fn.ce("a", {
						id: "imgLocationSamll_" + i,
						href: "#",
						dataset: {
							fancybox: "FullPictureLoadImageSmall",
							src,
							thumb: (thumbnailSrcArray.length > 0 && thumbnailSrcArray.length == srcArr.length) ? thumbnailSrcArray[i] : src
						}
					});
				}
				let img = new Image();
				img.alt = `no.${i + 1}`;
				img.dataset.index = i;
				img.className = "FullPictureLoadImage small";
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.dataset.errorNum = 0;
				if ([2, 3].some(n => siteData.insertImg[1] == n)) {
					img.src = loading_bak;
					img.dataset.src = src;
				} else {
					img.decoding = "async";
					img.loading = "lazy";
					img.onload = () => {
						img.classList.remove("error");
					};
					img.onerror = error => {
						const num = Number(error.target.dataset.errorNum);
						if (num < 20) {
							error.target.dataset.errorNum = num + 1;
						} else {
							return;
						}
						error.target.classList.add("error");
						setTimeout(() => {
							error.target.src = error.target.src;
						}, 3000);
					};
					img.src = src;
				}
				let item = fn.ace(imgBox, "div", null, {
					width,
					display: "inline-block",
					padding: "0.1%",
					border: "1px solid #a0a0a0",
					verticalAlign: (siteData.category == "comic" || (options.column == 2 && siteData.category == "hcomic")) ? "middle" : "top"
				});
				if (options.fancybox == 1 && !blackList) {
					a.append(img);
					item.append(a);
				} else {
					item.append(img);
				}
			}
			let tE = ge("#FullPictureLoadEnd");
			insertBefore(tE, fragment);
			if (ge(".FullPictureLoadVideo")) {
				for (let e of gae(".FullPictureLoadVideo")) insertBefore(tE, e);
			}
			if (options.fancybox == 1 && !("fancybox" in siteData) && ("Fancybox" in _unsafeWindow)) {
				_unsafeWindow.Fancybox.bind("[data-fancybox='FullPictureLoadImageSmall']", isObject(_unsafeWindow?.Fancybox?.defaults) ? {} : FancyboxOptions);
			}
			//tE.parentNode.style.textAlign = "center";
			tE.parentNode.style.display = "block";
			for (let e of gae(".FullPictureLoadImage:not(.small),#FullPictureLoadEnd")) {
				if (e.tagName == "IMG") {
					e.setAttribute("style", "display:none!important;");
					if (options.zoom > 0) e.style.width = `${options.zoom * 10}%`;
				} else {
					e.setAttribute("style", "display:none!important;");
				}
			}
			viewMode = 1;
			fn.showMsg(DL.str_93);
			let smallImgs = gae("img.FullPictureLoadImage.small");
			setTimeout(() => {
				for (let img of smallImgs) fn.imagesObserver.observe(img);
			}, 1000);
			let imgDivs = gae("#FullPictureLoadImgBox>div");
			if (siteData.category == "comic") {
				let lastImg = imgDivs.at(-1);
				fn.comicNextObserver.observe(lastImg);
			}
			let imgsNum = 0;
			if (imgDivs[0].nextSibling && siteData.category == "comic") {
				await fn.checkImgStatus(imgDivs[0].nextSibling.querySelector("img").dataset.src, "Wait Loading...");
				if (imgDivs[0].offsetHeight < imgDivs[0].nextSibling.offsetHeight) {
					imgDivs[0].style.height = (imgDivs[0].nextSibling.offsetHeight) + "px";
					let img = imgDivs[0].querySelector("img");
					await fn.checkImgStatus(img.dataset.src, "Wait Loading...");
					let num = (imgDivs[0].offsetHeight - img.height) / 2;
					img.style.marginTop = `${num}px`;
				}
				await delay(1200);
				instantScrollIntoView(imgDivs[0]);
			}
			if (TurnOffImageNavigationShortcutKeys != 1) {
				document.addEventListener("keydown", async event => {
					if (isOpenOptionsUI || isOpenGallery || ge(".fancybox-container,#FullPictureLoadFavorSites") || ["F11", "F12"].some(k => event.code === k || event.key === k)) return;
					if (event.code === "ArrowUp" || event.key === "ArrowUp") {
						event.preventDefault();
						if (imgsNum > 0 && viewMode == 1) {
							imgsNum -= column;
							instantScrollIntoView(imgDivs[imgsNum]);
						}
					} else if (event.code === "ArrowDown" || event.key === "ArrowDown") {
						event.preventDefault();
						if (imgsNum < imgDivs.length && imgsNum != imgDivs.length && viewMode == 1) {
							imgsNum += column;
							try {
								if (imgDivs[imgsNum].nextSibling && siteData.category === "comic") {
									debug(`\n第${imgsNum + 1}張(左)高:${imgDivs[imgsNum].offsetHeight}\n第${imgsNum + 2}張(右)高:${imgDivs[imgsNum].nextSibling.offsetHeight}`);
									await fn.checkImgStatus(imgDivs[imgsNum].nextSibling.querySelector("img").dataset.src, "Wait Loading...");
									if (imgDivs[imgsNum].offsetHeight < imgDivs[imgsNum].nextSibling.offsetHeight) {
										imgDivs[imgsNum].style.height = (imgDivs[imgsNum].nextSibling.offsetHeight) + "px";
										let img = imgDivs[imgsNum].querySelector("img");
										await fn.checkImgStatus(img.dataset.src, "Wait Loading...");
										let num = (imgDivs[imgsNum].offsetHeight - img.height) / 2;
										debug(`\n修改了之後\n第${imgsNum + 1}張(左)高:${imgDivs[imgsNum].offsetHeight}\n第${imgsNum + 2}張(右)高:${imgDivs[imgsNum].nextSibling.offsetHeight}`);
										img.style.marginTop = `${num}px`;
									}
								} else if (siteData.category === "comic") {
									imgDivs[imgsNum].src = imgDivs[imgsNum].dataset.src;
									await fn.checkImgStatus(imgDivs[imgsNum].dataset.src, "Wait Loading...");
								}
								instantScrollIntoView(imgDivs[imgsNum]);
								await delay(200);
								instantScrollIntoView(imgDivs[imgsNum]);
							} catch {
								if (siteData.category === "comic" && siteData.next && siteData.insertImg) {
									if (isString(siteData.next)) {
										let next = fn.ge(siteData.next);
										if (next) {
											fn.showMsg(DL.str_95, 3000);
											EClick(next);
										} else {
											imgsNum = 0 - column;
											fn.showMsg(DL.str_96, 3000);
										}
									} else if (isFn(siteData.next)) {
										let next = await siteData.next();
										if (next) {
											fn.showMsg(DL.str_95, 3000);
											location.href = next;
										} else {
											imgsNum = 0;
											fn.showMsg(DL.str_96, 3000);
										}
									}
								} else {
									imgsNum = 0;
									instantScrollIntoView(imgDivs[0]);
									fn.showMsg(DL.str_94);
								}
							}
						}
					} else if (event.code === "Delete" && (siteData.category === "comic" || (options.column == 2 && siteData.category === "hcomic"))) {
						if (imgDivs[0].style.display === "none") {
							imgDivs[0].style.display = "inline-block";
						} else {
							imgDivs[0].style.display = "none";
						}
					} else {
						imgsNum = 0 - column;
					}
				});
			}
		} else if (ge(".FullPictureLoadImage.small")) {
			ge("#FullPictureLoadImgBox").style.display = "none";
			for (let e of gae(".FullPictureLoadImage:not(.small),#FullPictureLoadEnd")) e.removeAttribute("style");
			if (options.zoom > 0) {
				for (let img of gae(".FullPictureLoadImage:not(.small)")) img.style.width = `${options.zoom * 10}%`;
			}
			viewMode = 0;
			fn.showMsg(DL.str_92);
		}
	};

	const newTabViewLightGallery = localStorage.getItem("newTabViewLightGallery") ?? 0;

	const getConfig = () => {
		const default_Config = {
			ViewMode: 0,
			MobileViewMode: "single",
			webtoonWidth: isM ? window.innerWidth : 800,
			shadowGalleryWheel: 2,
			horizontalWheel: 0,
			jumpNum: 100,
			behavior: "smooth",
			threading: 2,
			colorThemes: "dark",
			showSize: 0,
			noSize: 0,
			move: 0,
			aee: 0
		};
		let newWindowData = localStorage.getItem("newWindowData");
		if (newWindowData == null) {
			localStorage.setItem("newWindowData", JSON.stringify(default_Config));
			newWindowData = {};
		} else if (isString(newWindowData)) {
			newWindowData = JSON.parse(newWindowData);
		}
		const config = Object.assign(default_Config, newWindowData);
		return config;
	};

	const saveConfig = (config = getConfig()) => {
		localStorage.setItem("newWindowData", JSON.stringify(config));
	};

	const setDefault = () => {
		const keys = [
			"newTabViewLightGallery",
			"newWindowData",
			"FullPictureLoadComicInfiniteScrollMode",
			"FullPictureLoadOptions",
			"FullPictureLoadCustomDownloadVideo",
			"FullPictureLoadShowEye"
		];
		for (const key of keys) {
			if (!!localStorage.getItem(key)) {
				localStorage.removeItem(key);
			}
		}
		_GM_setValue("language", null);
		_GM_setValue("DownloadAPI", "default");
		_GM_setValue("UI_zIndex", 2147483647)
		_GM_setValue("FullPictureLoadMsgPos", 0);
		_GM_setValue("pageViewMode", 0);
		_GM_setValue("goToFirstImage", 1);
		_GM_setValue("GalleryInIcon", 0);
		_GM_setValue("ShowFullPictureLoadFixedMenu", 1);
		_GM_setValue("FavorOpenInNewTab", 0);
		_GM_setValue("FullPictureLoadLoopView", 1);
		_GM_setValue("convertWebpToJpg", 0);
		_GM_setValue("FancyboxSlideshowTimeout", 3);
		_GM_setValue("FancyboxWheel", 1);
		_GM_setValue("FancyboxIdle", 0);
		_GM_setValue("FancyboxSlideshowTransition", "fade");
		_GM_setValue("FancyboxShowThumbs", 0);
		_GM_setValue("FancyboxThumbnails", "modern");
		_GM_setValue("FancyboxAutoClose", 0);
		_GM_setValue("FancyboxAutoNext", 0);
		_GM_setValue("exclude_ex_config", {});
		_GM_setValue("compressed_extension", "zip");
		_GM_setValue("zipFolderConfig", 1);
		_GM_setValue("doubleTouchNext", 1);
		_GM_setValue("convertWebpToJpg", 0);
		_GM_setValue("convertAvifToJpg", 0);
		_GM_setValue("jpgConvertQuality", 95);
		_GM_setValue("icon_top", "auto");
		_GM_setValue("icon_bottom", "24px");
		_GM_setValue("icon_left", "24px");
		_GM_setValue("icon_right", "auto");
		_GM_setValue("eye_icon_top", "auto");
		_GM_setValue("eye_icon_bottom", "24px");
		_GM_setValue("eye_icon_left", "auto");
		_GM_setValue("eye_icon_right", "24px");
		_GM_setValue("eye_menu_top", "auto");
		_GM_setValue("eye_menu_bottom", "22px");
		_GM_setValue("eye_menu_left", "auto");
		_GM_setValue("eye_menu_right", "64px");
		_GM_setValue("image_size", -1);
		_GM_setValue("TurnOffImageNavigationShortcutKeys", 0);
	};

	//新分頁空白頁檢視圖片
	const newTabView = async (src_array = null) => {

		if (checkGeting() || isDragging || "eye" in siteData && siteData.eye === 0) return;

		const config = getConfig();

		let imgSrcs;
		if (isArray(src_array)) {
			imgSrcs = src_array;
		} else if ("SPA" in siteData) {
			let selector = siteData.capture || siteData.srcset || siteData.imgs;
			imgSrcs = await getImgs(selector);
		} else if (!("capture" in siteData)) {
			globalImgArray.length > 0 ? imgSrcs = globalImgArray : imgSrcs = await getImgs(siteData.srcset || siteData.imgs);
		} else {
			captureSrcArray.length > 0 ? imgSrcs = captureSrcArray : imgSrcs = await getImgs(siteData.srcset || siteData.imgs);
		}

		if (!!imgSrcs?.length && imgSrcs.length > 0) {

			let newWindow;
			let dom;
			try {
				if ("yujianobj" in _unsafeWindow || isXBrowser) {
					newWindow = _unsafeWindow.open(location.origin);
				} else {
					newWindow = _unsafeWindow.open("about:blank", "_blank");
				}
				dom = newWindow.document;
			} catch {
				alert("An error occurred\nUnable to use window.open()");
				return;
			}
			dom.write(`
<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=4, user-scalable=yes, shrink-to-fit=no">
        <title>${DL.str_106.replace(/\(.\)/, "")}:${apiCustomTitle ?? customTitle ?? document.title}</title>
    </head>
    <body style="text-align: center;">
        <div id="imgBox" tabindex="-1"></div>
    </body>
</html>
            `);
			newWindow.stop();

			Object.assign(newWindow, {
				fn,
				DL,
				svg,
				isM,
				isPC,
				isVH,
				delay,
				icon,
				config,
				options,
				loopView: _GM_getValue("FullPictureLoadLoopView", 1),
				siteData,
				newImgs: imgSrcs,
				category: siteData.category,
				lightGallery: newTabViewLightGallery,
				imgViewIndex: -1,
				webtoonWidth: config.webtoonWidth,
				menuLanguage: DL.galleryMenu,
				simpleLoadImg,
				smoothOptions,
				instantOptions,
				isOpenFancybox: false,
				lightboxSwitch: options.fancybox,
				thumbnailSrcArray: isArray(src_array) ? [] : thumbnailSrcArray,
				FancyboxAutoClose,
				smoothScrollIntoView,
				instantScrollIntoView,
				totalNumberOfElements: 0,
				currentReferenceElement: null
			});

			let newWindowStyleCss = `
body {
    background-color: #333;
    display: block;
    margin: 0px;
}
#FixedMenu {
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    font-weight: 500;
    font-size: 14px;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    width: ${isM ? "102px" : "152px"};
    height: auto;
    padding: 5px 5px 2px 5px;
    position: fixed;
    left: ${isM ? "0px" : "-158px"};
    bottom: 0px;
    border: #ccc 1px solid;
    border-radius: 3px;
    background-color: ${config.colorThemes == "dark" ? "#222" : "#fff"};
    z-index: 2;
    opacity: ${isM ? "1" : "0.5"};
    &:hover {
        left: 0px;
        opacity: 1;
    }
}
.FixedMenuitem {
    width: ${isM ? "90px" : "140px"};
    height: 24px;
    line-height: 24px;
    overflow: hidden;
    font-size: 14px;
    border: #ccc 1px solid;
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    padding: 0 5px 0 5px;
    margin: 0 2px 3px 0;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.FixedMenuitem.active {
    color: #fff;
    background: #1790E6;
}
#FixedMenu select {
    font-weight: normal;
    text-align: center;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    border: none;
    width: 100%;
    height: 100%;
    padding: 0 auto;
}
#setting-btn-div {
    width: auto;
    height: auto;
    position: fixed;
    right: ${isM ? "10px" : "30px"};
    bottom: 150px;
    z-index: ${UI_zIndex - 3};
}
.setting-btn {
    width: 48px;
    height: 48px;
    text-align: center;
    user-select:none;
    color: ${config.colorThemes == "dark" ? "#fff" : "#333"};
    margin: 5px 0;
    overflow: hidden;
    border: ${config.colorThemes == "dark" ? "rgb(200, 200, 200) 1px solid" : "#333 1px solid"};
    background: ${config.colorThemes == "dark" ? "rgba(37, 36, 44, 0.8)" : "rgba(255, 255, 255, 0.8)"};
    border-radius: 12px;
    cursor: pointer;
}
.setting-btn .icon {
    margin-top: 10px;
    width: 28px;
    height: 28px;
}
.hide {
    display: none !important;
}
img.default {
    vertical-align: middle;
    width: auto;
    height: auto;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
img.single {
    width: auto;
    height: auto;
    max-width: ${isFirefox ? "calc(100% - 6px)" : "calc(100% - 4px)"};
    max-height: 99vh;
    display: block;
    margin: 0 auto;
    border: solid #fff;
}
img.webtoon {
    width: 100%;
    height: auto;
    display: block;
    margin: 0 auto;
    border: unset !important;
}
img.small {
    display: inline-block;
    vertical-align: middle;
    width: auto;
    height: auto;
    max-width: 31.8%;
    max-height: 33vh;
    border: solid #fff;
}
img.horizontal {
    vertical-align: middle;
    width: auto;
    height: 100%;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
.horizontal_first {
    margin-left: 1em !important;
}
.horizontal_last {
    margin-right: 1em !important;
}
.no_r_l_border {
    border-right: none !important;
    border-left: none !important;
}
.fancybox__container:has(.fancybox__thumbs.is-scrollable) {
    flex-direction: row;
}
.fancybox__thumbs.is-scrollable {
    --f-thumbs-cols: 1 !important;
    --f-thumbs-gap: 4px;
    --f-thumbs-padding-x: 2px;
    --f-thumbs-padding-y: 2px;
    --f-thumbs-viewport-padding-x: 2px;
    --f-thumbs-viewport-padding-y: 2px;
    --f-thumb-width: 100px;
    --f-thumb-height: 75px;
    --f-thumb-border-radius: 0;
}
@media (min-width: 768px) {
    .fancybox__thumbs.is-scrollable {
        --f-thumbs-cols: 2 !important;
    }
}
.viewer-backdrop {
    background-color: rgba(0, 0, 0, .94) !important;
}
`;

			//添加主要CSS
			_GM_addElement(dom.head, "style", {
				textContent: newWindowStyleCss
			});

			//添加FancyboxCSS
			_GM_addElement(dom.head, "style", {
				textContent: FancyboxV6Css
			});

			//添加ViewerJsCSS
			_GM_addElement(dom.head, "style", {
				textContent: ViewerJsCss
			});

			//引入Fancybox
			_GM_addElement(dom.head, "script", {
				textContent: JqueryJS + FancyboxV6JS
			});

			//引入ViewerJs
			_GM_addElement(dom.head, "script", {
				textContent: ViewerJs
			});

			const newWindowScriptCode = `
const fragment = new DocumentFragment();

let loadQueue = null;

if (lightboxSwitch == 1 && lightGallery == 1) {
    var ViewerJsInstance = new Viewer(document.querySelector("#imgBox"), {
        navbar: false,
        title: false,
        initialCoverage: 0.99,
        interval: ${FancyboxSlideshowTimeoutNum},
        url: "data-src",
        viewed: event => {
            let slideIndex = event.detail.index;
            let imgs = [...document.images];
            imgViewIndex = slideIndex;
            let img = event.detail.originalImage;
            currentReferenceElement = img;
            if (config.ViewMode != 4) {
                for (let img of imgs) e.style.border = "";
                img.style.border = "solid #32a1ce";
            }
            smoothScrollIntoView(img);
        }
    });
}

function setFancybox() {
    switch (navigator.language) {
        case "TW":
        case "zh-TW":
        case "zh-HK":
        case "zh-Hant-TW":
        case "zh-Hant-HK":
            Fancybox.getDefaults().l10n = {
                IMAGE_ERROR: "找不到圖像",
                MOVE_UP: "上移",
                MOVE_DOWN: "下移",
                MOVE_LEFT: "左移",
                MOVE_RIGHT: "右移",
                ZOOM_IN: "放大",
                ZOOM_OUT: "縮小",
                TOGGLE_FULL: "切換縮放等級",
                TOGGLE_1TO1: "切換縮放等級",
                ITERATE_ZOOM: "切換縮放等級",
                ROTATE_CCW: "逆時針旋轉",
                ROTATE_CW: "順時針旋轉",
                FLIP_X: "水平翻轉",
                FLIP_Y: "垂直翻轉",
                RESET: "重設",
                TOGGLE_FS: "切換全螢幕",
                ERROR: "無法載入要求的內容。 <br/> 請稍後重試。",
                GOTO: "Go to page #%d",
                DOWNLOAD: "下載",
                TOGGLE_FULLSCREEN: "切換全螢幕",
                TOGGLE_EXPAND: "切換全螢幕e",
                TOGGLE_THUMBS: "切換縮圖",
                TOGGLE_AUTOPLAY: "切換幻燈片",
                CLOSE: "關閉",
                NEXT: "下一個",
                PREV: "上一個",
                MODAL: "使用 ESC 鍵關閉",
                ELEMENT_NOT_FOUND: "找不到 HTML 元素",
                IFRAME_ERROR: "頁面載入錯誤"
            };
            break;
        case "zh":
        case "zh-CN":
        case "zh-Hans-CN":
            Fancybox.getDefaults().l10n = {
                IMAGE_ERROR: "找不到图像",
                MOVE_UP: "上移",
                MOVE_DOWN: "下移",
                MOVE_LEFT: "左移",
                MOVE_RIGHT: "右移",
                ZOOM_IN: "放大",
                ZOOM_OUT: "缩小",
                TOGGLE_FULL: "切换缩放等级",
                TOGGLE_1TO1: "切换缩放等级",
                ITERATE_ZOOM: "切换缩放等级",
                ROTATE_CCW: "逆时针旋转",
                ROTATE_CW: "顺时针旋转",
                FLIP_X: "水平翻转",
                FLIP_Y: "垂直翻转",
                RESET: "重设",
                TOGGLE_FS: "切换全萤幕",
                ERROR: "无法加载请求的内容。 <br/> 请稍后重试。",
                GOTO: "Go to page #%d",
                DOWNLOAD: "下载",
                TOGGLE_FULLSCREEN: "切换全萤幕",
                TOGGLE_EXPAND: "切换全萤幕e",
                TOGGLE_THUMBS: "切换缩图",
                TOGGLE_AUTOPLAY: "切换幻灯片",
                CLOSE: "关闭",
                NEXT: "下一个",
                PREV: "上一个",
                MODAL: "使用 ESC 键关闭",
                ELEMENT_NOT_FOUND: "找不到 HTML 元素",
                IFRAME_ERROR: "页面加载错误"
            };
            break;
    }
    const cb = (i) => {
        let imgs = [...document.images];
        for (let e of imgs) e.style.border = "";
        imgViewIndex = i;
        let img = imgs[i];
        currentReferenceElement = img;
        img.style.border = "solid #32a1ce";
        instantScrollIntoView(img);
    };
    Fancybox.bind("[data-fancybox]", {
        Hash: false,
        idle: ${FancyboxIdle},
        fadeEffect: false,
        zoomEffect: false,
        showClass: false,
        hideClass: false,
        wheel: "${FancyboxWheel}",
        mainStyle: {
            "--fancybox-backdrop-bg": "rgba(0, 0, 0, .96)",
            "--f-toolbar-padding": "0px"
        },
        Carousel: {
            transition: "${FancyboxSlideshowTransition}",
            Autoplay: {
                autoStart: false,
                timeout: "${FancyboxSlideshowTimeoutNum}",
            },
            Thumbs: {
                type: "${FancyboxThumbnails}",
                showOnStart: ${FancyboxShowThumbs},
            },
            Toolbar: {
                display: {
                    left: ["counter"],
                    right: ["flipX", "flipY", "iterateZoom", "autoplay", "thumbs", "close"]
                }
            },
            breakpoints: {
                "(min-width: 768px)": {
                    Toolbar: {
                        display: {
                            left: ["counter"],
                            middle: ["zoomIn", "zoomOut", "iterateZoom", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY", "reset"],
                            right: ["autoplay", "fullscreen", "thumbs", "close"],
                        }
                    }
                }
            }
        },
        on: {
            ready: (ref) => {
                isOpenFancybox = true;
                cb(ref.getSlide().index);
            },
            "Carousel.change": (ref) => {
                const index = ref.getSlide().index;
                if (index == 0 && ref.getCarousel().getPages().at(-1).index == imgViewIndex) {
                    if (FancyboxAutoClose == 1) {
                        ref.close();
                    }
                }
                cb(index);
            },
            close: (ref) => {
                cb(ref.getSlide().index);
                setTimeout(() => {
                    isOpenFancybox = false;
                }, 100);
            }
        }
    });
}

let menuDiv;

function addFixedMenu() {
    menuDiv = document.createElement("div");
    menuDiv.id = "FixedMenu";
    const menuObj = [{
        id: "MenuThreadingItem"
    }, {
        id: "MenuHorizontalItem",
        text: menuLanguage.horizontal,
        cfn: () => horizontalImageLayout()
    }, {
        id: "MenuWebtoonItem",
        text: menuLanguage.webtoon,
        cfn: () => webtoonImageLayout()
    }, {
        id: "MenuRTLItem",
        text: menuLanguage.rtl,
        cfn: () => rtlImageLayout()
    }, {
        id: "MenuSmallItem",
        text: menuLanguage.small,
        cfn: () => smallImageLayout()
    }, {
        id: "MenuSinglePageItem",
        text: menuLanguage.single,
        cfn: () => singleImageLayout()
    }, {
        id: "MenuDefaultItem",
        text: menuLanguage.default,
        cfn: () => defaultImageLayout()
    }];
    const createMenu = obj => {
        let item = document.createElement("div");
        item.id = obj.id;
        item.className = "FixedMenuitem";
        item.innerText = obj.text || "";
        item.oncontextmenu = () => false;
        if (!!obj.cfn) item.addEventListener("click", obj.cfn);
        menuDiv.append(item);
    };
    menuObj.forEach(createMenu);
    let threadingSelect = document.createElement("select");
    for (let i = 1; i <= 32; i++) threadingSelect.append(new Option(DL.str_162 + i, i));
    menuDiv.querySelector("#MenuThreadingItem").append(threadingSelect);
    fragment.append(menuDiv);
    document.body.append(fragment);
    threadingSelect.value = config.threading;
    threadingSelect.addEventListener("change", () => {
        config.threading = Number(threadingSelect.value);
        saveConfig();
        if (!isM) {
            document.querySelector("#imgBox").focus();
        }
    });
}
addFixedMenu();

let btnDiv;

function addButtons() {
    btnDiv = document.createElement("div");
    btnDiv.id = "setting-btn-div";
    btnDiv.className = "hide";
    const btnObj = [{
        id: "addBtn",
        svg: svg.plus,
        cfn: increaseWidth
    }, {
        id: "reduceBtn",
        svg: svg.minus,
        cfn: reduceWidth
    }];
    const createDiv = obj => {
        let item = document.createElement("div");
        item.id = obj.id;
        item.className = "setting-btn";
        item.innerHTML = obj.svg;
        item.oncontextmenu = () => false;
        item.addEventListener("click", obj.cfn);
        btnDiv.append(item);
    };
    btnObj.forEach(createDiv);
    document.body.append(btnDiv);
}
addButtons();

if (isM) {
    document.querySelector("#MenuHorizontalItem").classList.add("hide");
    menuDiv.classList.add("hide");
    let lastScrollTop = 0;
    document.addEventListener("scroll", event => {
        if (isOpenFancybox || document.querySelector(".viewer-container .viewer-canvas>img")) return;
        let st = event.srcElement.scrollingElement.scrollTop;
        if (st > lastScrollTop) {
            menuDiv.classList.add("hide");
            if (config.ViewMode == 4) {
                btnDiv.classList.add("hide");
            }
            lastScrollTop = st;
        } else if (st < lastScrollTop - 20) {
            menuDiv.classList.remove("hide");
            if (config.ViewMode == 4) {
                btnDiv.classList.remove("hide");
            }
            lastScrollTop = st;
        }
    });
}

function toggleDirection(box, imgs) {
    if (box.style.direction == "rtl") {
        document.body.style.direction = "ltr";
        box.style.direction = "ltr";
        imgs.at(0).classList.remove("horizontal_last");
        imgs.at(0).classList.add("horizontal_first");
        imgs.at(-1).classList.remove("horizontal_first");
        imgs.at(-1).classList.add("horizontal_last");
    } else {
        document.body.style.direction = "rtl";
        box.style.direction = "rtl";
        imgs.at(0).classList.remove("horizontal_first");
        imgs.at(0).classList.add("horizontal_last");
        imgs.at(-1).classList.remove("horizontal_last");
        imgs.at(-1).classList.add("horizontal_first");
    }
}

function toggle_r_l_border(imgs) {
    for (let img of imgs) img.classList.toggle("no_r_l_border");
}

document.addEventListener("keydown", event => {
    if (isOpenFancybox || document.querySelector(".viewer-container .viewer-canvas>img") || ["F11", "F12"].some(k => event.code === k || event.key === k) || (config.ViewMode == 5 && event.shiftKey)) return;
    const imgs = [...document.images];
    if (event.code === "Numpad0" || event.code === "Digit0" || event.key === "0") return defaultImageLayout();
    if (event.code === "Numpad1" || event.code === "Digit1" || event.key === "1") return singleImageLayout();
    if (event.code === "Numpad2" || event.code === "Digit2" || event.key === "2") return smallImageLayout();
    if (event.code === "Numpad3" || event.code === "Digit3" || event.key === "3") return rtlImageLayout();
    if (event.code === "Numpad4" || event.code === "Digit4" || event.key === "4") return webtoonImageLayout();
    if (event.code === "Numpad5" || event.code === "Digit5" || event.key === "5") return horizontalImageLayout();
    if ((event.code === "Home" || event.key === "Home") || (event.code === "End" || event.key === "End")) {
        event.preventDefault();
        if (event.code === "Home" || event.key === "Home") {
            imgViewIndex = 0;
        } else {
            imgViewIndex = imgs.length - 1;
        }
        const img = imgs[imgViewIndex];
        if (config.ViewMode != 4 && ([0, 1, 3].some(m => config.ViewMode == m) && config.shadowGalleryWheel != 2)) {
            for (let e of imgs) e.style.border = "";
            img.style.border = "solid #32a1ce";
        }
        currentReferenceElement = img;
        return instantScrollIntoView(img);
    }
    if (config.ViewMode == 4 && (["NumpadAdd", "Equal"].some(k => event.code === k) || ["+", "="].some(k => event.code === k))) {
        return increaseWidth();
    }
    if (config.ViewMode == 4 && (["NumpadSubtract", "Minus"].some(k => event.code === k) || ["-", "_"].some(k => event.key === k))) {
        return reduceWidth();
    }
    if ((event.code === "KeyR" || event.key === "r" || event.key === "R") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
        let box = document.querySelector("#imgBox");
        if (config.ViewMode == 5) {
            toggleDirection(box, imgs);
            if (imgs[imgViewIndex] !== undefined) {
                return instantScrollIntoView(imgs[imgViewIndex]);
            }
        } else {
            if (box.style.direction == "rtl") {
                return (box.style.direction = "ltr");
            } else {
                return (box.style.direction = "rtl");
            }
        }
    }
    if ((event.code === "KeyB" || event.key === "b" || event.key === "B") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
        toggle_r_l_border(imgs);
        if (imgs[imgViewIndex] !== undefined) {
            return instantScrollIntoView(imgs[imgViewIndex]);
        }
        return;
    }
    if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex < 0) {
        if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
        if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
        if (loopView != 1) return;
        event.preventDefault();
        imgViewIndex = imgs.length - 1;
        const img = imgs[imgViewIndex];
        if (config.ViewMode != 4) {
            for (let e of imgs) e.style.border = "";
            img.style.border = "solid #32a1ce";
        }
        currentReferenceElement = img;
        return instantScrollIntoView(img);
    } else if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex >= 0) {
        if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
        if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
        event.preventDefault();
        imgViewIndex--;
        if (imgViewIndex < 0 && loopView != 1) {
            imgViewIndex = 0;
            return;
        }
        let img = imgs[imgViewIndex];
        if (img === undefined) {
            imgViewIndex = imgs.length - 1;
            img = imgs[imgViewIndex];
        }
        if (config.ViewMode != 4) {
            for (let e of imgs) e.style.border = "";
            if (img !== undefined) {
                img.style.border = "solid #32a1ce";
            }
        }
        currentReferenceElement = img;
        return instantScrollIntoView(img);
    } else if ((["KeyS", "KeyD", "ArrowDown", "ArrowRight"].some(k => event.code === k) || ["s", "S", "d", "D", "ArrowDown", "ArrowRight"].some(k => event.key === k)) && imgViewIndex <= imgs.length - 1) {
        if (config.ViewMode == 4 && (event.code === "ArrowDown" || event.key === "ArrowDown")) return;
        if (config.ViewMode == 5 && (event.code === "ArrowRight" || event.key === "ArrowRight")) return;
        event.preventDefault();
        imgViewIndex++;
        if (imgViewIndex > imgs.length - 1 && loopView != 1) {
            imgViewIndex = imgs.length - 1;
            return;
        }
        let img = imgs[imgViewIndex];
        if (imgViewIndex > imgs.length - 1 && category === "comic") {
            return window.close();
        } else if (imgViewIndex > imgs.length - 1) {
            imgViewIndex = 0;
        }
        if (config.ViewMode != 4) {
            for (let e of imgs) e.style.border = "";
            if (img !== undefined) {
                img.style.border = "solid #32a1ce";
            }
        }
        if (img === undefined) {
            imgViewIndex = 0;
            img = imgs[imgViewIndex];
        }
        currentReferenceElement = img;
        return instantScrollIntoView(img);
    } else if ((event.code === "Delete" || event.key === "Delete")) {
        for (const img of imgs) {
            if (!img.classList.contains("hide")) {
                img.classList.add("hide");
                break;
            }
        }
        if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
            if (config.shadowGalleryWheel != 2) {
                for (let e of imgs) e.style.border = "";
                imgs[imgViewIndex].style.border = "solid #32a1ce";
            }
            instantScrollIntoView(imgs[imgViewIndex]);
        }
        return;
    } else if ((event.code === "Enter" || event.key === "Enter")) {
        for (let e of imgs) e.classList.remove("hide");
        if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
            if (config.shadowGalleryWheel != 2) {
                for (let e of imgs) e.style.border = "";
                imgs[imgViewIndex].style.border = "solid #32a1ce";
            }
            instantScrollIntoView(imgs[imgViewIndex]);
        }
        return;
    } else if (!["KeyR", "NumpadAdd", "Equal", "NumpadSubtract", "Minus"].some(k => event.code === k) || !["r", "R", "-", "+", "=", "_"].some(k => event.key === k)) {
        imgViewIndex = -1;
    }
});

document.addEventListener("wheel", (event) => {
    if (!isOpenFancybox && !document.querySelector(".viewer-container .viewer-canvas>img") && config.ViewMode == 4 && (event.ctrlKey || event.altKey || event.shiftKey)) {
        event.preventDefault();
        event.stopPropagation();
        if (event.deltaY < 0) {
            increaseWidth();
        }
        if (event.deltaY > 0) {
            reduceWidth();
        }
    }
}, {
    passive: false
});

document.addEventListener("wheel", (event) => {
    if (event.shiftKey && config.ViewMode == 5) {
        const viewImgs = [...document.querySelectorAll("img.isView")];
        const middleIndex = Math.floor(viewImgs.length / 2 - 1);
        let img;
        if (middleIndex > -1) {
            img = viewImgs[middleIndex];
        } else {
            img = viewImgs[0];
        }
        imgViewIndex = Number(img.dataset.index);
    }
    if (!isOpenFancybox && !document.querySelector(".viewer-container .viewer-canvas>img") && ([0, 1, 3].some(m => config.ViewMode == m) && [1, 2].some(m => config.shadowGalleryWheel == m) || config.ViewMode == 5) && !event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
        event.preventDefault();
        event.stopPropagation();
        if (config.ViewMode == 5 && (config.horizontalWheel == 0 || config.horizontalWheel == 1)) {
            if (document.body.style.direction == "rtl") {
                return (document.body.scrollLeft -= event.deltaY);
            } else {
                return (document.body.scrollLeft += event.deltaY);
            }
        }
        const imgs = [...document.images];
        if (config.shadowGalleryWheel == 1 || config.ViewMode == 5) {
            if (event.deltaY < 0 && imgViewIndex < 0) {
                if (loopView != 1) return;
                imgViewIndex = imgs.length - 1;
                imgs[imgViewIndex].style.border = "solid #32a1ce";
                return instantScrollIntoView(imgs[imgViewIndex]);
            } else if (event.deltaY < 0 && imgViewIndex >= 0) {
                imgViewIndex--;
                if (imgViewIndex < 0 && loopView != 1) {
                    imgViewIndex = 0;
                    return;
                }
                if (imgViewIndex < 0) imgViewIndex = imgs.length - 1;
                if (config.ViewMode != 4) {
                    for (let e of imgs) e.style.border = "";
                    if (imgs[imgViewIndex] !== undefined) {
                        imgs[imgViewIndex].style.border = "solid #32a1ce";
                    }
                }
                return instantScrollIntoView(imgs[imgViewIndex]);
            } else if (event.deltaY > 0 && imgViewIndex <= imgs.length - 1) {
                imgViewIndex++;
                if (imgViewIndex > imgs.length - 1 && loopView != 1) {
                    imgViewIndex = imgs.length - 1;
                    return;
                }
                if (imgs[imgViewIndex] === undefined) {
                    imgViewIndex = 0;
                }
                if (config.ViewMode != 4) {
                    for (let e of imgs) e.style.border = "";
                    if (imgs[imgViewIndex] !== undefined) {
                        imgs[imgViewIndex].style.border = "solid #32a1ce";
                    }
                }
                return instantScrollIntoView(imgs[imgViewIndex]);
            } else {
                imgViewIndex = -1;
            }
        } else if (config.shadowGalleryWheel == 2) {
            if (event.deltaY < 0) {
                if (Number(currentReferenceElement?.dataset?.index) <= 0) return;
                for (let e of imgs) e.style.border = "";
                return instantScrollIntoView(getPrevRowElement());
            }
            if (event.deltaY > 0) {
                if (Number(currentReferenceElement?.dataset?.index) >= totalNumberOfElements - 1) return;
                for (let e of imgs) e.style.border = "";
                return instantScrollIntoView(getNextRowElement());
            }
        }
    }
}, {
    passive: false
});

function aspectRatio() {
    const verticalScreen = window.innerHeight / window.innerWidth > 1;
    const imgs = [...document.images];
    for (let img of imgs) {
        if (verticalScreen && img.className === "default") {
            img.style.minWidth = "98vw";
            img.style.maxWidth = "98vw";
            img.style.minHeight = "";
            img.style.maxHeight = "";
        } else if (img.className === "default") {
            img.style.minHeight = "calc(100vh - 4px)";
            img.style.maxHeight = "calc(100vh - 4px)";
            img.style.minWidth = "";
            img.style.maxWidth = "98vw";
        }
        if (config.ViewMode == 5) {
            let num = 6;
            if (devicePixelRatio > 1 && !navigator.userAgent.includes("Firefox")) {
                num = 3;
            }
            img.style.height = (document.body.clientHeight - num) + "px";
        }
    }
    if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4 && isPC) {
        if (config.shadowGalleryWheel != 2) {
            for (let e of imgs) e.style.border = "";
            imgs[imgViewIndex].style.border = "solid #32a1ce";
        }
        setTimeout(() => instantScrollIntoView(imgs[imgViewIndex]), 100);
    }
}

if (isM) {
    window.addEventListener("deviceorientation", () => {
        aspectRatio();
    });
} else {
    window.addEventListener("resize", () => {
        aspectRatio();
    });
}

function increaseWidth() {
    let imgs = [...document.images];
    if (webtoonWidth < 1900 && webtoonWidth < window.innerWidth) {
        webtoonWidth = (Number(webtoonWidth) + 50);
        config.webtoonWidth = webtoonWidth;
        saveConfig();
        for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
    } else {
        webtoonWidth = isM ? window.innerWidth : 800;
        config.webtoonWidth = webtoonWidth;
        saveConfig();
        for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
    }
}

function reduceWidth() {
    let imgs = [...document.images];
    if (webtoonWidth > 100) {
        webtoonWidth = (Number(webtoonWidth) - 50);
        config.webtoonWidth = webtoonWidth;
        saveConfig();
        for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
    } else {
        webtoonWidth = isM ? window.innerWidth : 800;
        config.webtoonWidth = webtoonWidth;
        saveConfig();
        for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
    }
}

function getNextRowElement() {
    const eles = [...document.images];
    const index = Number(currentReferenceElement.dataset.index);
    if (index >= eles.length - 1) {
        imgViewIndex = index;
        return eles.at(-1);
    }
    for (let i = index + 1, n = eles.length; i < n; i++) {
        if (eles[i].offsetTop > currentReferenceElement.offsetTop) {
            currentReferenceElement = eles[i];
            imgViewIndex = i;
            return eles[i];
        }
    }
    imgViewIndex = eles.length - 1;
    return eles.at(-1);
}

function getPrevRowElement() {
    const eles = [...document.images];
    const index = Number(currentReferenceElement.dataset.index);
    if (index <= 0) {
        imgViewIndex = 0;
        return eles.at(0);
    }
    for (let i = index - 1; i >= 0; i--) {
        if (eles[i].offsetTop < currentReferenceElement.offsetTop) {
            currentReferenceElement = eles[i];
            imgViewIndex = i;
            return eles[i];
        }
    }
    imgViewIndex = 0;
    return eles.at(0);
}

class FunctionQueue {
    constructor(workerLength, _function, parameters) {
        this.workerLength = Number(workerLength) || 2;
        this._function = _function;
        this.parameters = parameters;
        this.executing = new Set();
        this.interval = Number(options.singleThreadInterval);
        return this.run();
    }
    async run() {
        const results = [];
        for (let i = 0, n = this.parameters.length; i < n; i++) {
            const p = this._function(this.parameters[i]).then(value => value || String(i)).finally(() => this.executing.delete(p));
            this.executing.add(p);
            results.push(p);
            if (this.executing.size >= this.workerLength) {
                await Promise.race(this.executing);
            }
            if (this.workerLength == 1 && this.interval > 0) {
                await delay(this.interval * 1000);
            }
        }
        return Promise.all(results);
    }
}

function loadImgs(imgs) {
    loadQueue = null;
    loadQueue = new FunctionQueue(config.threading, simpleLoadImg, imgs);
}

function createImgElement(mode) {
    window.scrollTo({
        top: 0
    });
    const imgBox = document.querySelector("#imgBox");
    if (config.ViewMode == 3) {
        imgBox.style.direction = "rtl";
    } else {
        imgBox.style.direction = "";
    }
    if (isPC && ["comic", "hcomic"].some(c => category == c) && isVH("H") && config.ViewMode != 4 && config.ViewMode != 5) {
        imgBox.style.padding = "0 8%";
    } else {
        imgBox.style.padding = "";
    }
    imgViewIndex = -1;
    for (let item of [...document.querySelectorAll(".FixedMenuitem")]) item.classList.remove("active");
    imgBox.innerHTML = "";
    document.body.style.overflow = "hidden scroll";
    document.body.style.direction = "";
    const imgElements = newImgs.map((src, i) => {
        let img = document.createElement("img");
        img.className = mode;
        img.dataset.index = i;
        img.dataset.fancybox = "gallery";
        if ("referrerpolicy" in siteData) {
            img.setAttribute("referrerpolicy", siteData.referrerpolicy);
        }
        img.src = "${loading_bak}";
        img.dataset.src = src;
        if (thumbnailSrcArray.length > 0) {
            img.dataset.thumb = thumbnailSrcArray[i];
        } else {
            img.dataset.thumb = src;
        }
        if (config.ViewMode == 4) {
            img.style.maxWidth = webtoonWidth + "px";
        }
        return img;
    });
    fragment.append(...imgElements);
    imgBox.append(fragment);
    if (config.ViewMode == 5) {
        document.body.style.overflow = "scroll hidden";
        imgBox.style.display = "flex";
        imgBox.style.height = "100vh";
        imgBox.style.width = "fit-content";
        imgElements.at(0).classList.add("horizontal_first");
        imgElements.at(-1).classList.add("horizontal_last");
    } else {
        imgBox.style.display = "";
        imgBox.style.height = "";
        imgBox.style.width = "";
    }
    if (lightboxSwitch ==1 && lightGallery == 1) {
        ViewerJsInstance.update();
    } else if (lightboxSwitch == 1){
        setFancybox();
    }
    loadImgs(imgElements);
    aspectRatio();
    if (isPC && config.ViewMode == 4) {
        btnDiv.classList.remove("hide");
    } else {
        btnDiv.classList.add("hide");
    }
    currentReferenceElement = imgElements.at(0);
    totalNumberOfElements = imgElements.length;
    if (config.ViewMode == 5 && ["comic", "hcomic"].some(c => category == c)) {
        toggleDirection(imgBox, imgElements);
    }
    if (["comic"].some(c => category == c)) {
        toggle_r_l_border(imgElements);
    }
    fn.wait(() => imgElements.at(-1)?.offsetHeight > 100).then(() => {
        setTimeout(() => {
            aspectRatio();
            for (let img of imgElements) {
                if (config.threading > 1) {
                    fn.imagesObserver.observe(img);
                }
                if (config.ViewMode == 5) {
                    fn.imagesViewObserver.observe(img);
                }
                if (mode === "horizontal") {
                    let num = 6;
                    if (devicePixelRatio > 1 && !navigator.userAgent.includes("Firefox")) {
                        num = 3;
                    }
                    img.style.height = (document.body.clientHeight - num) + "px";
                }
            }
        }, 1000);
    });
}

function saveConfig() {
    localStorage.setItem("newWindowData", JSON.stringify(config));
}

function defaultImageLayout() {
    config.ViewMode = 0;
    saveConfig();
    createImgElement("default");
    document.querySelector("#MenuDefaultItem").classList.add("active");
}

function singleImageLayout() {
    config.ViewMode = 1;
    saveConfig();
    createImgElement("single");
    document.querySelector("#MenuSinglePageItem").classList.add("active");
}

function smallImageLayout() {
    config.ViewMode = 2;
    saveConfig();
    createImgElement("small");
    document.querySelector("#MenuSmallItem").classList.add("active");
}

function rtlImageLayout() {
    config.ViewMode = 3;
    saveConfig();
    createImgElement("default");
    document.querySelector("#MenuRTLItem").classList.add("active");
}

function webtoonImageLayout() {
    config.ViewMode = 4;
    saveConfig();
    createImgElement("webtoon");
    document.querySelector("#MenuWebtoonItem").classList.add("active");
}

function horizontalImageLayout() {
    config.ViewMode = 5;
    saveConfig();
    createImgElement("horizontal");
    document.querySelector("#MenuHorizontalItem").classList.add("active");
}

if (config.ViewMode == 1) {
    singleImageLayout();
} else if (config.ViewMode == 2) {
    smallImageLayout();
} else if (config.ViewMode == 3) {
    rtlImageLayout();
} else if (config.ViewMode == 4) {
    webtoonImageLayout();
} else if (config.ViewMode == 5) {
    horizontalImageLayout();
} else {
    defaultImageLayout();
}
`;

			//注入主要代碼
			_GM_addElement(dom.head, "script", {
				textContent: newWindowScriptCode
			});

		} else {
			alert("No Image.");
			return;
		}
	};

	const hidePageScrollbarY = () => fn.css("html,body{overflow-y:hidden !important}#pagetual-sideController{display:none}", "overflowYHidden");

	let closeGallery;
	let isChangeSize = false;
	let changeSizeTimeId;

	//創建影子畫廊
	const createShadowGallery = async (srcs_array = null) => {

		if (("fancybox" in siteData) && !("gallery" in siteData && siteData.gallery == 0) || ("gallery" in siteData && siteData.gallery == 1)) {
			return createIframeGallery();
		}

		if (checkGeting() || isOpenGallery || isOpenOptionsUI || !isValidPage) return;

		isOpenGallery = true;

		if ("SPA" in siteData) {
			lastValidPageURL = currentURL;
		}

		let srcs;
		if (isArray(srcs_array)) {
			srcs = srcs_array;
		} else if ("SPA" in siteData || siteData.repeat == 1 || siteData.infiniteCapture == 1) {
			let selector = siteData.capture || siteData.srcset || siteData.imgs;
			srcs = await getImgs(selector);
		} else if (!("capture" in siteData)) {
			globalImgArray.length > 0 ? srcs = globalImgArray : srcs = await getImgs(siteData.srcset || siteData.imgs);
		} else {
			captureSrcArray.length > 0 ? srcs = captureSrcArray : srcs = await getImgs(siteData.srcset || siteData.imgs);
		}
		if (srcs.length < 1) {
			fn.showMsg(DL.str_44);
			return (isOpenGallery = false);
		}

		fn.hm();

		const config = getConfig();
		let webtoonWidth = config.webtoonWidth;
		let totalNumberOfElements = 0;
		let imgViewIndex = -1;
		let currentReferenceElement;
		let nextButtonIsShown = false;
		let isShowAlert = false;
		let loopView = _GM_getValue("FullPictureLoadLoopView", 1);
		let isOpenChapterList = false;
		let chapterListObtained = false;

		const FullPictureLoadShadowGallery = fn.ace("bodya", "div", {
			id: "FullPictureLoadShadowGallery"
		});
		const shadow = FullPictureLoadShadowGallery.attachShadow({
			mode: "closed"
		});

		const resetWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", shadow);
			webtoonWidth = isM ? innerWidth : 800;
			config.webtoonWidth = webtoonWidth;
			saveConfig(config);
			showAlert("Reset", 0, 500);
			for (let e of imgs) e.style.maxWidth = "";
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		const increaseWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", shadow);
			if (webtoonWidth < 1900 && webtoonWidth < _unsafeWindow.innerWidth) {
				webtoonWidth = (Number(webtoonWidth) + 50);
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			} else {
				webtoonWidth = isM ? _unsafeWindow.innerWidth : 800;
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			}
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		const reduceWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", shadow);
			if (webtoonWidth > 100) {
				webtoonWidth = (Number(webtoonWidth) - 50);
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			} else {
				webtoonWidth = isM ? _unsafeWindow.innerWidth : 800;
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			}
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		closeGallery = () => {
			_unsafeWindow.removeEventListener("resize", aspectRatio);
			_unsafeWindow.removeEventListener("keydown", kEvent);
			if (!isOpenFilter) fn.remove("#overflowYHidden");
			FullPictureLoadShadowGallery?.remove();
			isOpenGallery = false;
			if (isCaptureMode) {
				updateEyeNum(srcs.length);
			}
			if ("focus" in siteData) {
				let selector = siteData.focus;
				let ele;
				if (isString(selector)) {
					if (selector.startsWith("last:")) {
						selector = selector.slice(5);
						ele = fn.gae(selector).at(-1);
					} else {
						ele = ge(selector);
					}
				} else if (isFn(selector)) {
					ele = selector();
				}
				if (!isEle(ele)) return;
				setTimeout(() => instantScrollIntoView(ele), 100);
			}
			if (("closeAF" in siteData) && isFn(siteData.closeAF)) {
				siteData.closeAF();
			}
		};

		const toggleWidthEvent = (event) => {
			if (!isOpenFancybox && config.ViewMode == 4 && (event.ctrlKey || event.altKey || event.shiftKey)) {
				event.preventDefault();
				event.stopPropagation();
				if (event.deltaY < 0) {
					increaseWidth();
				}
				if (event.deltaY > 0) {
					reduceWidth();
				}
			}
		};

		FullPictureLoadShadowGallery.addEventListener("wheel", toggleWidthEvent, {
			passive: false
		});

		const getNextRowElement = () => {
			const eles = gae("img,#next", shadow);
			const index = Number(currentReferenceElement.dataset.index);
			if (index >= eles.length - 1) {
				imgViewIndex = index;
				return eles.at(-1);
			}
			for (let i = index + 1, n = eles.length; i < n; i++) {
				if (eles[i].offsetTop > currentReferenceElement.offsetTop) {
					currentReferenceElement = eles[i];
					imgViewIndex = i;
					return eles[i];
				}
			}
			imgViewIndex = eles.length - 1;
			return eles.at(-1);
		};

		const getPrevRowElement = () => {
			const eles = gae("img,#next", shadow);
			const index = Number(currentReferenceElement.dataset.index);
			if (index <= 0) {
				imgViewIndex = 0;
				return eles.at(0);
			}
			for (let i = index - 1; i >= 0; i--) {
				if (eles[i].offsetTop < currentReferenceElement.offsetTop) {
					currentReferenceElement = eles[i];
					imgViewIndex = i;
					return eles[i];
				}
			}
			imgViewIndex = 0;
			return eles.at(0);
		};

		const toggleImage = (event) => {
			if (isOpenChapterList) return;
			if (event.shiftKey && config.ViewMode == 5) {
				const viewImgs = gae("img.isView", shadow);
				const middleIndex = Math.floor(viewImgs.length / 2 - 1);
				let img;
				if (middleIndex > -1) {
					img = viewImgs[middleIndex];
				} else {
					img = viewImgs[0];
				}
				imgViewIndex = Number(img.dataset.index);
			}
			if (!isOpenFancybox && ([0, 1, 3].some(m => config.ViewMode == m) && [1, 2].some(m => config.shadowGalleryWheel == m) || config.ViewMode == 5) && !event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
				event.preventDefault();
				event.stopPropagation();
				const imgs = gae("img", shadow);
				const next = ge("#next", shadow) || ge("#menuNext", shadow);
				const isRTL = mainElement.style.direction == "rtl";
				if (config.ViewMode == 5 && (config.horizontalWheel == 0 || config.horizontalWheel == 1)) {
					if (isString(nextLink) && (mainElement.scrollWidth - mainElement.offsetWidth) < Math.abs(mainElement.scrollLeft + (isRTL ? -2 : 2)) && event.deltaY > 0) {
						if (isShowAlert) {
							let num = Number(alertMessage.innerText.match(/\d/));
							if (num > 0) {
								showAlert(DL.str_113 + (num -= 1));
							}
							if (num <= 0) {
								showAlert(isComic ? DL.str_196 : DL.str_197, 0);
								return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
							}
						} else {
							showAlert();
						}
					} else if (isString(nextLink)) {
						hideAlert();
					}
					if (config.horizontalWheel == 0) {
						if (isRTL) {
							return (mainElement.scrollLeft -= event.deltaY);
						} else {
							return (mainElement.scrollLeft += event.deltaY);
						}
					} else if (config.horizontalWheel == 1) {
						let num;
						if (event.deltaY > 0) {
							if (config.jumpNum == 0) {
								if (isRTL) {
									num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
								} else {
									num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
								}
							} else {
								if (isRTL) {
									num = mainElement.scrollLeft - Number(config.jumpNum);
								} else {
									num = mainElement.scrollLeft + Number(config.jumpNum);
								}
							}
						} else {
							if (config.jumpNum == 0) {
								if (isRTL) {
									num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
								} else {
									num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
								}
							} else {
								if (isRTL) {
									num = mainElement.scrollLeft + Number(config.jumpNum);
								} else {
									num = mainElement.scrollLeft - Number(config.jumpNum);
								}
							}
						}
						return mainElement.scrollTo({
							left: num,
							behavior: config.behavior
						});
					}
				}
				if (config.shadowGalleryWheel == 1 || config.ViewMode == 5) {
					if (isShowAlert && event.deltaY > 0) {
						let num = Number(alertMessage.innerText.match(/\d/));
						if (num > 0) {
							showAlert(DL.str_113 + (num -= 1));
						}
						if (num <= 0) {
							showAlert(isComic ? DL.str_196 : DL.str_197, 0);
							return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
						}
					} else if (event.deltaY > 0 && imgViewIndex >= imgs.length - 1 && config.ViewMode == 5 && isString(nextLink)) {
						showAlert();
					} else if (event.deltaY < 0 && imgViewIndex < 0) {
						if (loopView != 1) return;
						nextButtonIsShown = false;
						if (config.ViewMode == 5) {
							hideAlert();
						}
						imgViewIndex = imgs.length - 1;
						imgs[imgViewIndex].style.border = "solid #32a1ce";
						return instantScrollIntoView(imgs[imgViewIndex]);
					} else if (event.deltaY < 0 && imgViewIndex >= 0) {
						nextButtonIsShown = false;
						if (config.ViewMode == 5) {
							hideAlert();
						}
						imgViewIndex--;
						if (imgViewIndex < 0 && loopView != 1) {
							imgViewIndex = 0;
							return;
						}
						if (imgViewIndex < 0) imgViewIndex = imgs.length - 1;
						if (config.ViewMode != 4) {
							for (let e of imgs) e.style.border = "";
							if (imgs[imgViewIndex] !== undefined) {
								imgs[imgViewIndex].style.border = "solid #32a1ce";
							}
						}
						return instantScrollIntoView(imgs[imgViewIndex]);
					} else if (event.deltaY > 0 && nextButtonIsShown) {
						next.style.backgroundColor = "gray";
						return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 500);
					} else if (event.deltaY > 0 && imgViewIndex <= imgs.length - 1) {
						imgViewIndex++;
						if (imgViewIndex > imgs.length - 1 && loopView != 1 && !next) {
							imgViewIndex = imgs.length - 1;
							return;
						}
						if (imgs[imgViewIndex] === undefined && next && !nextButtonIsShown) {
							nextButtonIsShown = true;
							next.style.border = "solid #32a1ce";
							for (let e of imgs) e.style.border = "";
							return instantScrollIntoView(next);
						} else if (imgs[imgViewIndex] === undefined) {
							imgViewIndex = 0;
						}
						if (config.ViewMode != 4) {
							for (let e of imgs) e.style.border = "";
							if (imgs[imgViewIndex] !== undefined) {
								imgs[imgViewIndex].style.border = "solid #32a1ce";
							}
						}
						if (imgs[imgViewIndex] !== undefined) {
							return instantScrollIntoView(imgs[imgViewIndex]);
						}
					} else {
						imgViewIndex = -1;
					}
				} else if (config.shadowGalleryWheel == 2) {
					if (event.deltaY < 0) {
						nextButtonIsShown = false;
						if (Number(currentReferenceElement?.dataset?.index) <= 0) return;
						for (let e of imgs) e.style.border = "";
						return instantScrollIntoView(getPrevRowElement());
					}
					if (event.deltaY > 0) {
						if (Number(currentReferenceElement?.dataset?.index) >= totalNumberOfElements - 1) return;
						for (let e of imgs) e.style.border = "";
						return instantScrollIntoView(getNextRowElement());
					}
				}
			}
		};

		FullPictureLoadShadowGallery.addEventListener("wheel", toggleImage, {
			passive: false
		});

		const aspectRatio = () => {
			const verticalScreen = _unsafeWindow.innerHeight / _unsafeWindow.innerWidth > 1;
			const imgs = gae("img", shadow);
			for (let img of imgs) {
				if (verticalScreen && img.className === "default") {
					img.style.maxWidth = "96vw";
					img.style.maxHeight = "";
					img.style.minWidth = "96vw";
					img.style.minHeight = "";
				} else if (img.className === "default") {
					img.style.maxHeight = "calc(100vh - 6px)";
					img.style.maxWidth = "100%";
					img.style.minHeight = "calc(100vh - 6px)";
					img.style.minWidth = "";
				}
				if (config.ViewMode == 5) {
					let num = 6;
					if (devicePixelRatio > 1 && !isFirefox) {
						num = 3;
					}
					img.style.height = (mainElement.clientHeight - num) + "px";
				}
			}
			if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
				if (config.shadowGalleryWheel != 2) {
					for (let e of imgs) e.style.border = "";
					imgs[imgViewIndex].style.border = "solid #32a1ce";
				}
				setTimeout(() => instantScrollIntoView(imgs[imgViewIndex]), 100);
			}
		};
		_unsafeWindow.addEventListener("resize", aspectRatio);

		const toggleDirection = (box, imgs) => {
			if (box.style.direction == "rtl") {
				mainElement.style.direction = "ltr";
				box.style.direction = "ltr";
				imgs.at(0).classList.remove("horizontal_last");
				imgs.at(0).classList.add("horizontal_first");
				imgs.at(-1).classList.remove("horizontal_first");
				imgs.at(-1).classList.add("horizontal_last");
			} else {
				mainElement.style.direction = "rtl";
				box.style.direction = "rtl";
				imgs.at(0).classList.remove("horizontal_first");
				imgs.at(0).classList.add("horizontal_last");
				imgs.at(-1).classList.remove("horizontal_last");
				imgs.at(-1).classList.add("horizontal_first");
			}
		};

		const toggle_r_l_border = (imgs) => {
			for (let img of imgs) img.classList.toggle("no_r_l_border");
		};

		// 影子畫廊快捷鍵
		const kEvent = (event) => {
			if (isOpenFancybox || ["F11", "F12"].some(k => event.code === k || event.key === k) || (config.ViewMode == 5 && event.shiftKey)) return;
			const imgs = gae("img", shadow);
			const next = ge("#next", shadow);
			if (event.code === "Escape" || event.key === "Escape") {
				if (isOpenChapterList) {
					isOpenChapterList = false;
					return list_main.classList.add("hide");
				}
				return closeGallery();
			}
			if (event.code === "Numpad0" || event.code === "Digit0" || event.key === "0") return defaultImageLayout();
			if (event.code === "Numpad1" || event.code === "Digit1" || event.key === "1") return singleImageLayout();
			if (event.code === "Numpad2" || event.code === "Digit2" || event.key === "2") return smallImageLayout();
			if (event.code === "Numpad3" || event.code === "Digit3" || event.key === "3") return rtlImageLayout();
			if (event.code === "Numpad4" || event.code === "Digit4" || event.key === "4") return webtoonImageLayout();
			if (event.code === "Numpad5" || event.code === "Digit5" || event.key === "5") return horizontalImageLayout();
			if ((event.code === "Home" || event.key === "Home") || (event.code === "End" || event.key === "End")) {
				event.preventDefault();
				nextButtonIsShown = false;
				if (event.code === "Home" || event.key === "Home") {
					imgViewIndex = 0;
				} else {
					imgViewIndex = imgs.length - 1;
				}
				const img = imgs[imgViewIndex];
				if (config.ViewMode != 4 && ([0, 1, 3].some(m => config.ViewMode == m) && config.shadowGalleryWheel != 2)) {
					for (let e of imgs) e.style.border = "";
					img.style.border = "solid #32a1ce";
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			}
			if (event.code === "KeyH" || event.key === "h" || event.key === "H") {
				showAlert(DL.str_223, 0);
				return (isGoToNext = true) && setTimeout(() => ("home" in siteData) ? (location.href = siteData.home) : (location.href = location.origin), 100);
			}
			if (event.code === "KeyU" || event.key === "u" || event.key === "U") {
				if ("update" in siteData) {
					showAlert(DL.str_227, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = siteData.update), 100);
				}
			}
			if (event.code === "KeyN" || event.key === "n" || event.key === "N") {
				if (isString(nextLink)) {
					showAlert(isComic ? DL.str_196 : DL.str_197, 0);
					if (isEle(next)) {
						next.style.backgroundColor = "gray";
					}
					return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
				}
			}
			if (event.code === "KeyP" || event.key === "p" || event.key === "P") {
				if (isString(prevLink)) {
					showAlert(isComic ? DL.str_221 : DL.str_222, 0);
					return (isGoToPrev = true) && setTimeout(() => (location.href = prevLink), 100);
				}
			}
			if (event.code === "KeyC" || event.key === "c" || event.key === "C") {
				if (chapterListObtained) {
					if (isOpenChapterList) {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					} else {
						list_main.classList.remove("hide");
						isOpenChapterList = true;
						const button = ge(".current-chapter", list_main);
						list_main.scrollTop = button.offsetTop - (list_main.clientHeight / 2) + button.clientHeight;
					}
				}
			}
			if (event.code === "KeyJ" || event.key === "j" || event.key === "J") {
				let num;
				if (config.ViewMode == 5) {
					const isRTL = mainElement.style.direction == "rtl";
					if (config.jumpNum == 0) {
						if (isRTL) {
							num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
						} else {
							num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
						}
					} else {
						if (isRTL) {
							num = mainElement.scrollLeft - Number(config.jumpNum);
						} else {
							num = mainElement.scrollLeft + Number(config.jumpNum);
						}
					}
					return mainElement.scrollTo({
						left: num,
						behavior: config.behavior
					});
				};
				if (config.jumpNum == 0) {
					if (_unsafeWindow.devicePixelRatio > 1 && [0, 1, 3].some(m => config.ViewMode == m)) {
						num = mainElement.scrollTop + imgs[0].offsetHeight;
					} else {
						num = mainElement.scrollTop + _unsafeWindow.innerHeight;
					}
				} else {
					num = mainElement.scrollTop + Number(config.jumpNum);
				}
				let lastTop = mainElement.scrollHeight - _unsafeWindow.innerHeight;
				if (num >= lastTop) {
					num = lastTop;
				}
				return mainElement.scrollTo({
					top: num,
					behavior: config.behavior
				});
			}
			if (event.code === "KeyK" || event.key === "k" || event.key === "K") {
				let num;
				if (config.ViewMode == 5) {
					const isRTL = mainElement.style.direction == "rtl";
					if (config.jumpNum == 0) {
						if (isRTL) {
							num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
						} else {
							num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
						}
					} else {
						if (isRTL) {
							num = mainElement.scrollLeft + Number(config.jumpNum);
						} else {
							num = mainElement.scrollLeft - Number(config.jumpNum);
						}
					}
					return mainElement.scrollTo({
						left: num,
						behavior: config.behavior
					});
				};
				if (config.jumpNum == 0) {
					if (_unsafeWindow.devicePixelRatio > 1 && [0, 1, 3].some(m => config.ViewMode == m)) {
						num = mainElement.scrollTop - imgs[0].offsetHeight;
					} else {
						num = mainElement.scrollTop - _unsafeWindow.innerHeight;
					}
				} else {
					num = mainElement.scrollTop - Number(config.jumpNum);
				}
				if (num <= 0) {
					num = 0;
				}
				return mainElement.scrollTo({
					top: num,
					behavior: config.behavior
				});
			}
			if (config.ViewMode == 4 && (["NumpadAdd", "Equal"].some(k => event.code === k) || ["+", "="].some(k => event.code === k))) {
				return increaseWidth();
			}
			if (config.ViewMode == 4 && (["NumpadSubtract", "Minus"].some(k => event.code === k) || ["-", "_"].some(k => event.key === k))) {
				return reduceWidth();
			}
			if ((event.code === "KeyR" || event.key === "r" || event.key === "R") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
				let box = ge("#imgBox", shadow);
				if (config.ViewMode == 5) {
					toggleDirection(box, imgs);
					if (isEle(imgs[imgViewIndex])) {
						return instantScrollIntoView(imgs[imgViewIndex]);
					}
				} else {
					if (box.style.direction == "rtl") {
						return (box.style.direction = "ltr");
					} else {
						return (box.style.direction = "rtl");
					}
				}
			}
			if ((event.code === "KeyB" || event.key === "b" || event.key === "B") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
				toggle_r_l_border(imgs);
				if (isEle(imgs[imgViewIndex])) {
					return instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			}
			if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex < 0) {
				if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
				if (loopView != 1) return;
				event.preventDefault();
				nextButtonIsShown = false;
				imgViewIndex = imgs.length - 1;
				const img = imgs[imgViewIndex];
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					img.style.border = "solid #32a1ce";
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex >= 0) {
				if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
				event.preventDefault();
				nextButtonIsShown = false;
				imgViewIndex--;
				if (imgViewIndex < 0 && loopView != 1) {
					imgViewIndex = 0;
					return;
				}
				let img = imgs[imgViewIndex];
				if (img === undefined) {
					imgViewIndex = imgs.length - 1;
					img = imgs[imgViewIndex];
				}
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					if (img !== undefined) {
						img.style.border = "solid #32a1ce";
					}
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((["KeyS", "KeyD", "ArrowDown", "ArrowRight"].some(k => event.code === k) || ["s", "S", "d", "D", "ArrowDown", "ArrowRight"].some(k => event.key === k)) && nextButtonIsShown) {
				if (config.ViewMode == 4 && (event.code === "ArrowDown" || event.key === "ArrowDown")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowRight" || event.key === "ArrowRight")) return;
				showAlert(isComic ? DL.str_196 : DL.str_197, 0);
				next.style.backgroundColor = "gray";
				return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 500);
			} else if ((["KeyS", "KeyD", "ArrowDown", "ArrowRight"].some(k => event.code === k) || ["s", "S", "d", "D", "ArrowDown", "ArrowRight"].some(k => event.key === k)) && imgViewIndex <= imgs.length - 1) {
				if (config.ViewMode == 4 && (event.code === "ArrowDown" || event.key === "ArrowDown")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowRight" || event.key === "ArrowRight")) return;
				event.preventDefault();
				imgViewIndex++;
				if (imgViewIndex > imgs.length - 1 && loopView != 1 && !next) {
					imgViewIndex = imgs.length - 1;
					return;
				}
				let img = imgs[imgViewIndex];
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					if (img !== undefined) {
						img.style.border = "solid #32a1ce";
					}
				}
				if (img === undefined && next && !nextButtonIsShown) {
					nextButtonIsShown = true;
					next.style.border = "solid #32a1ce";
					currentReferenceElement = next;
					return instantScrollIntoView(next);
				} else if (img === undefined) {
					imgViewIndex = 0;
					img = imgs[imgViewIndex];
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((event.code === "Delete" || event.key === "Delete")) {
				for (const img of imgs) {
					if (!img.classList.contains("hide")) {
						img.classList.add("hide");
						break;
					}
				}
				if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
					if (config.shadowGalleryWheel != 2) {
						for (let e of imgs) e.style.border = "";
						imgs[imgViewIndex].style.border = "solid #32a1ce";
					}
					instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			} else if ((event.code === "Enter" || event.key === "Enter")) {
				for (let e of imgs) e.classList.remove("hide");
				if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
					if (config.shadowGalleryWheel != 2) {
						for (let e of imgs) e.style.border = "";
						imgs[imgViewIndex].style.border = "solid #32a1ce";
					}
					instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			} else if (!["KeyR", "NumpadAdd", "Equal", "NumpadSubtract", "Minus"].some(k => event.code === k) || !["r", "R", "-", "+", "=", "_"].some(k => event.key === k)) {
				imgViewIndex = -1;
			}
		};
		_unsafeWindow.addEventListener("keydown", kEvent);

		hidePageScrollbarY();

		let placeHeight;
		if (isMobileEdge || isMobileYandex) {
			placeHeight = "54px";
		} else if (isVia || isXBrowser) {
			placeHeight = "2px";
		} else {
			placeHeight = "30px";
		}

		/**
選單淡入淡出
transform: translate(0);
transition: all .8s ease-in-out;
&:hover {
    transform: translate(138px);
    transition: all .2s ease-in-out;
}
        */
		fn.ace(shadow, "style", {
			type: "text/css",
			innerHTML: `
#shadowGallery {
    z-index: ${UI_zIndex - 3} !important;
}
p#imgBox {
    display: block;
    min-height: calc(100vh - 38px);
    padding: 0;
    margin: 0;
}
.place {
    height: ${placeHeight};
    padding: 0;
    margin: 0;
}
#FixedMenu {
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    font-weight: 500;
    font-size: 14px;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    width: ${isM ? "102px" : "150px"};
    height: auto;
    padding: 5px 5px 2px 5px;
    position: fixed;
    left: ${isM ? "0px" : "-156px"};
    bottom: 0px;
    border: #ccc 1px solid;
    border-radius: 3px;
    background-color: ${config.colorThemes == "dark" ? "#222" : "#fff"};
    z-index: ${UI_zIndex - 3};
    opacity: ${isM ? "1" : "0.5"};
    &:hover {
        left: 0px;
        opacity: 1;
    }
}
.FixedMenuitem {
    width: ${isM ? "90px" : "138px"};
    height: 24px;
    line-height: 24px;
    overflow: hidden;
    font-size: 14px;
    border: #ccc 1px solid;
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    padding: 0 5px 0 5px;
    margin: 0 2px 3px 0;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
#MenuJumpItem {
    width: 148px;
    padding: 0px;
}
.FixedMenuitem.active {
    color: #fff;
    background: #1790e6;
}
#setting-btn-div {
    width: auto;
    height: auto;
    position: fixed;
    right: ${isM ? "10px" : "30px"};
    bottom: 150px;
    z-index: ${UI_zIndex - 3};
}
.setting-btn {
    width: 48px;
    height: 48px;
    text-align: center;
    user-select:none;
    color: ${config.colorThemes == "dark" ? "#fff" : "#333"};
    margin: 5px 0;
    overflow: hidden;
    border: ${config.colorThemes == "dark" ? "rgb(200, 200, 200) 1px solid" : "#333 2px solid"};
    background: ${config.colorThemes == "dark" ? "rgba(37, 36, 44, 0.8)" : "rgba(255, 255, 255, 0.8)"};
    border-radius: 12px;
    cursor: pointer;
}
.setting-btn .icon {
    margin-top: 10px;
    width: 28px;
    height: 28px;
}
.hide {
    display: none !important;
}
img.default {
    vertical-align: middle;
    width: auto;
    height: auto;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
img.single {
    width: auto;
    height: auto;
    max-width: calc(100% - 6px);
    max-height: calc(100vh - 6px);
    display: block;
    margin: 0 auto;
    border: solid #fff;
}
img.webtoon {
    width: 100%;
    height: auto;
    max-width: 800px;
    display: block;
    margin: 0 auto;
    border: unset;
}
img.small {
    display: inline-block;
    vertical-align: middle;
    width: auto;
    height: auto;
    max-width: 31.8%;
    max-height: 33vh;
    border: solid #fff;
}
img.horizontal {
    vertical-align: middle;
    width: auto;
    height: 100%;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
.horizontal_first {
    margin-left: 1em !important;
}
.horizontal_last {
    margin-right: 1em !important;
}
.no_r_l_border {
    border-right: none !important;
    border-left: none !important;
}
#next {
    display: block;
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    padding: 10px 0;
    margin: ${isM ? "2px" : "6px 1px 6px 7px"};
    border: 4px solid #fff;
    border-radius: 12px;
    color: rgb(0, 0, 0);
    background-color: antiquewhite;
    font-size: 26px;
    line-height: 50px;
    height: 50px;
    text-decoration: unset;
    cursor: pointer;
}
#FixedMenu select {
    font-weight: normal;
    text-align: center;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    border: none;
    width: 100%;
    height: 100%;
    padding: 0 auto;
}
#FixedMenu select option {
    text-align: center;
}
#behaviorInput {
    vertical-align: middle;
    width: 16px;
    height: 16px;
    margin-top: ${isFirefox ? "2px" : "0px"};
}
#alertBox {
    width: 268px;
    min-height: 74px;
    color: #000;
    position: fixed;
    top: calc(50% - 148px);
    left: calc(50% - 154px);
    padding: 20px;
    background-color: #f9f9f9;
    border: 2px solid #999;
    z-index: ${UI_zIndex - 2};
    border-radius: 10px;
    font-size: 14px;
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
}
#hint {
    font-size: 20px;
    font-weight: bold;
}
#alertMessage {
    font-size: 16px;
    margin: 20px 0;
}
#alertBox #nextAlert {
    width: 138px;
    float: left;
    cursor: pointer;
    padding: 5px 22px;
    border: 1px solid #ffdb11;
    background-color: #ffdb11;
    border-radius: 10px 0px 0px 10px;
}
#alertBox #closeAlert {
    width: 38px;
    float: right;
    cursor: pointer;
    padding: 5px 22px;
    border: 1px solid #ebebeb;
    background-color: #ebebeb;
    border-radius: 0px 10px 10px 0px;
}
#modal-content-list {
    background-color: ${config.colorThemes == "dark" ? "#282828" : "#eee"};
    position: fixed;
    z-index: ${UI_zIndex - 3};
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    padding: 10px;
    border: 1px solid #888;
    min-width: 350px;
    max-width: 600px;
    max-height: 90%;
    overflow-y: auto;
}
.closeModal {
    position: absolute;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
}
.chapter-list-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
    padding-top: 20px;
}
.chapter-btn {
    background-color: ${config.colorThemes == "dark" ? "#3c3c3c" : "#fff"};
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    border: ${config.colorThemes == "dark" ? "none" : "1px solid #a2a2a2"};
    padding: 10px;
    cursor: pointer;
    border-radius: 5px;
    font-size: 13px;
    width: calc(33.3333% - 8px);
    box-sizing: border-box;
    text-align: center;
    overflow:hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.chapter-btn:not(.current-chapter):hover {
    background-color: #ffa64d;
    color: #fff;
}
.current-chapter {
    background-color: #1790e6;
    color: #fff;
}
#chapters-footer {
    margin: 10px 0;
    display: flex;
    justify-content: flex-end;
}
#footer_close_button {
    display: block;
    width: 100%;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    background-color: ${config.colorThemes == "dark" ? "#454d55" : "#ccc"};
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 10px;
    box-sizing: content-box;
    font-size: 16px;
    font-weight: 600;
}`
		});

		const mainElement = fn.ace(shadow, "div", {
			id: "shadowGallery",
			tabIndex: "-1"
		}, {
			inset: "0",
			width: "100vw",
			height: "100vh",
			margin: "0px",
			padding: "0px",
			outline: "none",
			border: "none",
			position: "fixed",
			opacity: "1",
			backgroundColor: "#333",
			color: "#222",
			fontSize: "14px",
			overflow: "hidden scroll",
			textAlign: "center"
		});

		let lastScrollTop = 0;
		mainElement.addEventListener("scroll", (event) => {
			if (mainElement.scrollTop > lastScrollTop) {
				if (isM) {
					menuDiv.classList.add("hide");
				}
				if (config.ViewMode == 4) {
					ge("#setting-btn-div", shadow).classList.add("hide");
				}
			} else if (mainElement.scrollTop < lastScrollTop && !nextButtonIsShown) {
				if (isM) {
					menuDiv.classList.remove("hide");
				}
				if (config.ViewMode == 4) {
					ge("#setting-btn-div", shadow).classList.remove("hide");
				}
			}
			lastScrollTop = mainElement.scrollTop;
		});

		let queue;

		function loadImgs(imgs) {
			queue = null;
			queue = new FunctionQueue(config.threading, simpleLoadImg, imgs);
		}

		async function createGalleryElement(mode) {
			mainElement.scrollTo({
				top: 0
			});
			if (!isM) {
				mainElement.focus();
			}
			imgViewIndex = -1;
			for (let item of gae(".FixedMenuitem", shadow)) item.classList.remove("active");
			mainElement.style.overflow = "hidden scroll";
			mainElement.style.direction = "";
			mainElement.innerHTML = "";
			menuDiv.style.bottom = "";
			const imgElements = srcs.map((src, i) => {
				let img = new Image();
				img.className = mode;
				img.dataset.index = i;
				img.dataset.fancybox = "gallery";
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.src = loading_bak;
				img.dataset.src = src;
				if (thumbnailSrcArray.length > 0) {
					img.dataset.thumb = thumbnailSrcArray[i];
				} else {
					img.dataset.thumb = src;
				}
				if (mode === "webtoon") {
					img.style.maxWidth = webtoonWidth + "px";
				}
				return img;
			});
			if (isM) {
				fn.ace(fragment, "p", {
					className: "place"
				});
			}
			if (mode === "horizontal") {
				imgElements.at(0).classList.add("horizontal_first");
				imgElements.at(-1).classList.add("horizontal_last");
			}
			const p = fn.ace(fragment, "p", {
				id: "imgBox"
			}, {
				direction: (config.ViewMode == 3) ? "rtl" : ""
			});
			if (isPC && isComic && isVH("H") && config.ViewMode != 4 && config.ViewMode != 5) {
				if (_unsafeWindow.devicePixelRatio > 1) {
					p.style.padding = "2px 8% 0";
				} else {
					p.style.padding = "0 8%";
				}
				p.style.margin = "0 auto";
			} else if (config.ViewMode == 5) {
				p.style.display = "flex";
				p.style.height = "100vh";
				p.style.width = "fit-content";
				mainElement.style.overflow = "scroll hidden";
				menuDiv.style.bottom = "20px";
			} else if (_unsafeWindow.devicePixelRatio > 1) {
				p.style.paddingTop = "1px";
			}
			p.append(...imgElements);
			mainElement.append(fragment);
			loadImgs(imgElements);
			aspectRatio();
			if (isPC && mode === "webtoon") {
				btnDiv.classList.remove("hide");
			} else {
				btnDiv.classList.add("hide");
			}
			currentReferenceElement = imgElements.at(0);
			totalNumberOfElements = imgElements.length;
			if (mode === "horizontal" && ["comic", "hcomic"].some(c => siteData.category == c)) {
				toggleDirection(p, imgElements);
			}
			if (["comic"].some(c => siteData.category == c)) {
				toggle_r_l_border(imgElements);
			}
			await fn.wait(() => imgElements.at(-1)?.offsetHeight > 100).then(() => {
				setTimeout(() => {
					aspectRatio();
					for (let img of imgElements) {
						if (config.threading > 1) {
							fn.imagesObserver.observe(img);
						}
						if (config.ViewMode == 5) {
							fn.imagesViewObserver.observe(img);
						}
						if (mode === "horizontal") {
							let num = 6;
							if (devicePixelRatio > 1 && !isFirefox) {
								num = 3;
							}
							img.style.height = (mainElement.clientHeight - num) + "px";
						}
					}
				}, 1000);
			});
			if (options.fancybox != 1) {
				for (let img of imgElements) {
					img.onclick = event => {
						cancelDefault(event);
						imgViewIndex = Number(img.dataset.index);
						currentReferenceElement = event.target;
						if (config.ViewMode != 4) {
							if (event?.target?.style?.border === "") {
								for (let e of imgElements) e.style.border = "";
								event.target.style.border = "solid #32a1ce";
							} else {
								for (let e of imgElements) e.style.border = "";
							}
						}
					}
				}
			}
			if (options.fancybox == 1 && isObject(_unsafeWindow.Fancybox)) {
				//影子燈箱
				const cb = (i) => {
					let imgs = gae("img", mainElement);
					for (let e of imgs) e.style.border = "";
					imgViewIndex = i;
					let img = imgs[i];
					currentReferenceElement = img;
					img.style.border = "solid #32a1ce";
					instantScrollIntoView(img);
				};
				_unsafeWindow.Fancybox.bind(mainElement, "[data-fancybox]", {
					...FancyboxOptions,
					...{
						on: {
							ready: (ref) => {
								isOpenFancybox = true;
								slideIndex = ref.getSlide().index;
								cb(slideIndex);
							},
							"Carousel.change": (ref) => {
								const index = ref.getSlide().index;
								if (index == 0 && ref.getCarousel().getPages().at(-1).index == slideIndex) {
									if (FancyboxAutoClose == 1) {
										ref.close();
									}
									if (FancyboxAutoNext == 1) {
										if (!!nextLink) {
											fn.showMsg(DL.str_34.n);
											setTimeout(() => (location.href = nextLink), 100);
										}
									}
								}
								slideIndex = index;
								cb(index);
							},
							close: (ref) => {
								document.body.classList.remove("imgbox-show", "hide-scrollbar");
								slideIndex = ref.getSlide().index;
								cb(slideIndex);
								setTimeout(() => {
									isOpenFancybox = false;
								}, 100);
							}
						}
					}
				});
			}
			if (isString(nextLink) && config.ViewMode != 5) {
				totalNumberOfElements = totalNumberOfElements + 1;
				const next = fn.ace(mainElement, "div", {
					id: "next",
					innerText: `${isComic ? DL.str_143 : DL.str_144}${isM ? "" : "( N )"}`,
					dataset: {
						url: nextLink,
						index: imgElements.length
					},
					onclick: event => {
						cancelDefault(event);
						showAlert(isComic ? DL.str_196 : DL.str_197, 0);
						next.style.backgroundColor = "gray";
						return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
					}
				});
				if (config.shadowGalleryWheel != 1 && [0, 1, 3].some(m => config.ViewMode == m) || [2, 4].some(m => config.ViewMode == m)) {
					let isEventAdded = false;
					const nextObserver = new IntersectionObserver((entries, observer) => {
						for (let entry of entries) {
							if (entry.isIntersecting) {
								nextButtonIsShown = true;
								next.style.border = "solid #32a1ce";
								if (isPC) {
									showAlert();
								}
								if (!isEventAdded) {
									isEventAdded = true;
									FullPictureLoadShadowGallery.addEventListener("wheel", (event) => {
										if (isOpenFancybox || event.ctrlKey || event.altKey || event.shiftKey || event.metaKey) return;
										if (event.deltaY < 0) {
											next.style.border = "";
											nextButtonIsShown = false;
											hideAlert();
										} else if (event.deltaY > 0 && nextButtonIsShown) {
											let num = Number(alertMessage.innerText.match(/\d/));
											if (num > 0) {
												showAlert(DL.str_113 + (num -= 1));
											}
											if (num <= 0) {
												showAlert(isComic ? DL.str_196 : DL.str_197, 0);
												next.style.backgroundColor = "gray";
												return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
											}
										}
									}, {
										passive: true
									});
								}
							} else {
								next.style.border = "";
								nextButtonIsShown = false;
								hideAlert();
							}
						}
					}, {
						threshold: 0.9,
					});
					setTimeout(() => {
						nextObserver.observe(next);
					}, 1000);
				}
			}
			if (isM) {
				fn.ace(mainElement, "p", {
					className: "place"
				});
			}
		}

		let menuDiv;

		function addFixedMenu() {
			menuDiv = fn.ace(shadow, "div", {
				id: "FixedMenu"
			});
			const menuObj = [{
				id: "MenuCancelItem",
				text: DL.str_142,
				cfn: () => closeGallery()
			}, {
				id: "MenuSettingsItem",
				text: DL.str_85.replace(/\(.\)/, ""),
				cfn: () => createPictureLoadOptionsShadowElement()
			}, {
				id: "MenuFavorItem",
				text: DL.str_128.replace(/\(.\)/, ""),
				cfn: () => createFavorShadowElement()
			}, {
				id: "MenuThreadingItem"
			}, {
				id: "MenuBehaviorItem"
			}, {
				id: "MenuJumpItem",
			}, {
				id: "menuHome",
				text: isM ? DL.str_217 : DL.str_217 + "( H )",
				cfn: () => {
					showAlert(DL.str_223, 0);
					return (isGoToNext = true) && setTimeout(() => ("home" in siteData) ? (location.href = siteData.home) : (location.href = location.origin), 100);
				}
			}, {
				id: "menuUpdate",
				hide: 1,
				text: DL.str_226,
				cfn: () => {
					showAlert(DL.str_227, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = siteData.update), 200)
				}
			}, {
				id: "menuList",
				hide: 1,
				text: DL.str_216,
				cfn: () => {
					list_main.classList.remove("hide");
					isOpenChapterList = true;
					const button = ge(".current-chapter", list_main);
					list_main.scrollTop = button.offsetTop - (list_main.clientHeight / 2) + button.clientHeight;
				}
			}, {
				id: "menuPrev",
				text: `${isComic ? DL.str_219 : DL.str_220}${isM ? "" : "( P )"}`,
				cfn: () => {
					showAlert(isComic ? DL.str_221 : DL.str_222, 0);
					return (isGoToPrev = true) && setTimeout(() => (location.href = prevLink), 200);
				}
			}, {
				id: "menuNext",
				text: `${isComic ? DL.str_143 : DL.str_144}${isM ? "" : "( N )"}`,
				cfn: () => {
					showAlert(isComic ? DL.str_196 : DL.str_197, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200)
				}
			}, {
				id: "MenuHorizontalItem",
				text: DL.galleryMenu.horizontal,
				cfn: () => horizontalImageLayout()
			}, {
				id: "MenuWebtoonItem",
				text: DL.galleryMenu.webtoon,
				cfn: () => webtoonImageLayout()
			}, {
				id: "MenuRTLItem",
				text: DL.galleryMenu.rtl,
				cfn: () => rtlImageLayout()
			}, {
				id: "MenuSmallItem",
				text: DL.galleryMenu.small,
				cfn: () => smallImageLayout()
			}, {
				id: "MenuSinglePageItem",
				text: DL.galleryMenu.single,
				cfn: () => singleImageLayout()
			}, {
				id: "MenuDefaultItem",
				text: DL.galleryMenu.default,
				cfn: () => defaultImageLayout()
			}];
			const createMenu = obj => {
				if (!isString(nextLink) && obj.id == "menuNext") return;
				if (!isString(prevLink) && obj.id == "menuPrev") return;
				fn.ace(menuDiv, "div", {
					id: obj.id,
					className: ("hide" in obj) ? "FixedMenuitem hide" : "FixedMenuitem",
					innerText: ("text" in obj) ? obj.text : "",
					oncontextmenu: () => false,
					onclick: ("cfn" in obj) ? obj.cfn : null
				});
			};
			menuObj.forEach(createMenu);

			let threadingSelect = fn.ce("select", {
				onchange: () => {
					config.threading = Number(threadingSelect.value);
					saveConfig(config);
					if (!isM) {
						mainElement.focus();
					}
				}
			});
			for (let i = 1; i <= 32; i++) threadingSelect.append(new Option(DL.str_162 + i, i));
			threadingSelect.value = config.threading;
			ge("#MenuThreadingItem", menuDiv).append(threadingSelect);

			if (isPC) {
				let jumpSelect = fn.ce("select", {
					onchange: () => {
						config.jumpNum = jumpSelect.value;
						saveConfig(config);
						if (!isM) {
							mainElement.focus();
						}
					}
				});
				for (let i = 0; i <= 100; i++) {
					let option = new Option(i == 0 ? `${DL.str_150}${DL.str_152}` : `${DL.str_150}${i * 50}px`, i == 0 ? i : i * 50);
					jumpSelect.append(option);
				}
				jumpSelect.value = config.jumpNum;
				ge("#MenuJumpItem", menuDiv).append(jumpSelect);

				let behaviorDiv = ge("#MenuBehaviorItem", menuDiv);
				let behaviorInput = fn.ace(behaviorDiv, "input", {
					id: "behaviorInput",
					type: "checkbox",
					checked: config.behavior == "smooth" ? true : false,
					onchange: () => {
						config.behavior = behaviorInput.checked == true ? "smooth" : "instant";
						saveConfig(config);
						if (!isM) {
							mainElement.focus();
						}
					}
				});
				let behaviorLabel = fn.ace(behaviorDiv, "label", {
					innerText: DL.str_151
				});
			}
			if (isM) {
				menuDiv.classList.add("hide");
				for (let e of gae("#MenuBehaviorItem,#MenuJumpItem,#MenuHorizontalItem", menuDiv)) e.classList.add("hide");
			}
		}
		addFixedMenu();

		if ("update" in siteData) {
			ge("#menuUpdate", menuDiv).classList.remove("hide");
		}

		let list_main;

		if ("chapters" in siteData) {
			// 創建目錄
			const get_chapters = siteData.chapters;
			const createChapterList = async () => {
				let chapterListData = [];
				if (isObject(get_chapters)) {
					chapterListData = await fn.getChapters(get_chapters);
				} else if (isFn(get_chapters)) {
					chapterListData = await get_chapters();
				}
				if (!isArray(chapterListData) || !chapterListData?.length) return;
				if (isNumber(chapterListData?.length)) {
					if (chapterListData.length < 2) return;
				}
				chapterListObtained = true;
				const tempURLs = new Set();
				chapterListData = chapterListData.filter(({
					url
				}) => {
					if (tempURLs.has(url) || url == "#") {
						return false;
					} else {
						tempURLs.add(url);
					}
					return true;
				});
				ge("#menuList", menuDiv).classList.remove("hide");
				list_main = fn.ace(shadow, "div", {
					id: "modal-content-list",
					className: "hide"
				});
				fn.ace(list_main, "span", {
					id: "closeModal",
					className: "closeModal",
					innerText: `× ${DL.str_132}`,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				const list_container = fn.ace(list_main, "div", {
					id: "chapterListContainer",
					className: "chapter-list-container"
				});
				const pathname = decodeURIComponent(fn.clp());
				const search = fn.cls();
				let isCurrent = false;
				const list = chapterListData.map(({
					text,
					url
				}) => {
					const button = fn.ce("button", {
						className: "chapter-btn",
						innerText: text,
						dataset: {
							url
						}
					});
					if ("checkCurrentChapter" in siteData) {
						isCurrent = siteData.checkCurrentChapter(url, text);
					}
					if (
						isCurrent ||
						search && url.endsWith(search) ||
						!search && decodeURIComponent(url).endsWith(pathname) ||
						search.includes("page=") && url.includes(pathname)
					) {
						button.classList.add("current-chapter");
					} else {
						button.addEventListener("click", (event) => {
							cancelDefault(event);
							closeGallery();
							fn.showMsg(DL.str_218, 0);
							return (isGoToNext = true) && setTimeout(() => (location.href = button.dataset.url), 200);
						});
					}
					return button;
				});
				fragment.append(...list);
				list_container.append(fragment);
				const footer = fn.ace(list_main, "div", {
					id: "chapters-footer"
				});
				fn.ace(footer, "button", {
					id: "footer_close_button",
					innerText: DL.str_132,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				mainElement.addEventListener("click", () => {
					if (isOpenChapterList) {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
			};
			createChapterList();
		}

		let btnDiv;

		function addButtons() {
			btnDiv = fn.ace(shadow, "div", {
				id: "setting-btn-div",
				className: "hide"
			});
			const btnObj = [{
				id: "resetBtn",
				svg: svg.reset,
				cfn: resetWidth
			}, {
				id: "addBtn",
				svg: svg.plus,
				cfn: increaseWidth
			}, {
				id: "reduceBtn",
				svg: svg.minus,
				cfn: reduceWidth
			}];
			const createDiv = obj => fn.ace(btnDiv, "div", {
				id: obj.id,
				className: "setting-btn",
				innerHTML: obj.svg,
				oncontextmenu: () => false,
				onclick: obj.cfn
			});
			btnObj.forEach(createDiv);
		}
		addButtons();

		let alertHtml = `
<div id="alertBox" class="hide">
    <div id="hint">${DL.str_112}</div>
    <p id="alertMessage">${DL.str_113}3</p>
    <div id="nextAlert">${isComic ? DL.str_143 : DL.str_144}( N )</div>
    <div id="closeAlert">${DL.str_132}</div>
</div>`;
		let alertNode = fn.html(alertHtml);
		shadow.append(alertNode);

		let alertDiv = ge("#alertBox", shadow);
		let alertMessage = ge("#alertMessage", alertDiv);
		let alertNext = ge("#nextAlert", alertDiv);
		let alertClose = ge("#closeAlert", alertDiv);
		let alertTid;
		const showAlert = (text = DL.str_113 + "3", button = 1, time = 0) => {
			isShowAlert = true;
			if (getType(alertTid) == "Number") {
				clearTimeout(alertTid);
			}
			alertMessage.innerText = text;
			for (let e of [alertNext, alertClose]) button ? e.classList.remove("hide") : e.classList.add("hide");
			alertDiv.classList.remove("hide");
			if (time) {
				alertTid = setTimeout(() => hideAlert(), time);
			}
		};
		const hideAlert = () => {
			isShowAlert = false;
			alertMessage.innerText = DL.str_113 + "3";
			alertDiv.classList.add("hide");
		};
		alertNext.addEventListener("click", event => {
			cancelDefault(event);
			showAlert(isComic ? DL.str_196 : DL.str_197, 0);
			return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
		});
		alertClose.addEventListener("click", hideAlert);

		function defaultImageLayout() {
			config.ViewMode = 0;
			saveConfig(config);
			createGalleryElement("default");
			ge("#MenuDefaultItem", shadow).classList.add("active");
		}

		function singleImageLayout() {
			config.ViewMode = 1;
			saveConfig(config);
			createGalleryElement("single");
			ge("#MenuSinglePageItem", shadow).classList.add("active");
		}

		function smallImageLayout() {
			config.ViewMode = 2;
			saveConfig(config);
			createGalleryElement("small");
			ge("#MenuSmallItem", shadow).classList.add("active");
		}

		function rtlImageLayout() {
			config.ViewMode = 3;
			saveConfig(config);
			createGalleryElement("default");
			ge("#MenuRTLItem", shadow).classList.add("active");
		}

		function webtoonImageLayout() {
			config.ViewMode = 4;
			saveConfig(config);
			createGalleryElement("webtoon");
			ge("#MenuWebtoonItem", shadow).classList.add("active");
		}

		function horizontalImageLayout() {
			config.ViewMode = 5;
			saveConfig(config);
			createGalleryElement("horizontal");
			ge("#MenuHorizontalItem", shadow).classList.add("active");
		}

		if (config.ViewMode == 1) {
			singleImageLayout();
		} else if (config.ViewMode == 2) {
			smallImageLayout();
		} else if (config.ViewMode == 3) {
			rtlImageLayout();
		} else if (config.ViewMode == 4) {
			webtoonImageLayout();
		} else if (config.ViewMode == 5) {
			horizontalImageLayout();
		} else {
			defaultImageLayout();
		}

	};

	//創建框架畫廊
	const createIframeGallery = async (srcs_array = null) => {

		if (checkGeting() || isOpenGallery || isOpenOptionsUI || !isValidPage) return;

		isOpenGallery = true;

		if ("SPA" in siteData) {
			lastValidPageURL = currentURL;
		}

		let srcs;
		if (isArray(srcs_array)) {
			srcs = srcs_array;
		} else if ("SPA" in siteData || siteData.repeat == 1 || siteData.infiniteCapture == 1) {
			let selector = siteData.capture || siteData.srcset || siteData.imgs;
			srcs = await getImgs(selector);
		} else if (!("capture" in siteData)) {
			globalImgArray.length > 0 ? srcs = globalImgArray : srcs = await getImgs(siteData.srcset || siteData.imgs);
		} else {
			captureSrcArray.length > 0 ? srcs = captureSrcArray : srcs = await getImgs(siteData.srcset || siteData.imgs);
		}
		if (srcs.length < 1) {
			fn.showMsg(DL.str_44);
			return (isOpenGallery = false);
		}

		fn.hm();

		const config = getConfig();
		let webtoonWidth = config.webtoonWidth;
		let totalNumberOfElements = 0;
		let imgViewIndex = -1;
		let currentReferenceElement;
		let nextButtonIsShown = false;
		let isShowAlert = false;
		let dNum = 0;
		let loopView = _GM_getValue("FullPictureLoadLoopView", 1);
		let isOpenChapterList = false;
		let chapterListObtained = false;

		const iframe = fn.ace("bodya", "iframe", {
			id: "FullPictureLoadIframeGallery",
			sandbox: "allow-modals allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts"
		}, {
			inset: "0",
			width: "100vw",
			height: "100vh",
			minWidth: "100vw",
			minHeight: "100vh",
			maxWidth: "100vw",
			maxHeight: "100vh",
			borderWidth: "0",
			margin: "auto",
			padding: "0",
			position: "fixed",
			opacity: "1",
			backgroundColor: "#333",
			color: "#222"
		});

		await new Promise((resolve) => {
			iframe.onload = resolve;
			iframe.src = "about:blank";
		});

		const win = iframe.contentWindow;
		const dom = iframe.contentDocument;

		_GM_addElement(dom.body, "script", {
			textContent: FancyboxV5JS
		});
		_GM_addElement(dom.head, "style", {
			textContent: FancyboxV5Css + `
.fancybox__container {
    z-index: ${UI_zIndex} !important;
}`
		});

		const resetWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", mainElement);
			webtoonWidth = isM ? innerWidth : 800;
			config.webtoonWidth = webtoonWidth;
			saveConfig(config);
			showAlert("Reset", 0, 500);
			for (let e of imgs) e.style.maxWidth = "";
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		const increaseWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", mainElement);
			if (webtoonWidth < 1900 && webtoonWidth < win.innerWidth) {
				webtoonWidth = (Number(webtoonWidth) + 50);
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			} else {
				webtoonWidth = isM ? win.innerWidth : 800;
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			}
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		const reduceWidth = () => {
			if (getType(changeSizeTimeId) == "Number") {
				clearTimeout(changeSizeTimeId);
			}
			isChangeSize = true;
			let imgs = gae("img", mainElement);
			if (webtoonWidth > 100) {
				webtoonWidth = (Number(webtoonWidth) - 50);
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			} else {
				webtoonWidth = isM ? win.innerWidth : 800;
				config.webtoonWidth = webtoonWidth;
				saveConfig(config);
				showAlert(config.webtoonWidth, 0, 500);
				for (let e of imgs) e.style.maxWidth = webtoonWidth + "px";
			}
			changeSizeTimeId = setTimeout(() => (isChangeSize = false), 1000);
		};

		closeGallery = () => {
			if (ge("meta[property='og:site_name'][content=禁漫天堂]")) {
				_unsafeWindow.removeEventListener("keydown", kEvent);
			}
			_unsafeWindow.removeEventListener("resize", aspectRatio);
			if (!isOpenFilter) fn.remove("#overflowYHidden");
			iframe.remove();
			isOpenGallery = false;
			if (isCaptureMode) {
				updateEyeNum(srcs.length);
			}
			if ("focus" in siteData) {
				let selector = siteData.focus;
				let ele;
				if (isString(selector)) {
					if (selector.startsWith("last:")) {
						selector = selector.slice(5);
						ele = fn.gae(selector).at(-1);
					} else {
						ele = ge(selector);
					}
				} else if (isFn(selector)) {
					ele = selector();
				}
				if (!isEle(ele)) return;
				setTimeout(() => instantScrollIntoView(ele), 100);
			}
			if (("closeAF" in siteData) && isFn(siteData.closeAF)) {
				siteData.closeAF();
			}
		};

		const toggleWidthEvent = (event) => {
			if (!isOpenFancybox && config.ViewMode == 4 && (event.ctrlKey || event.altKey || event.shiftKey)) {
				event.preventDefault();
				event.stopPropagation();
				if (event.deltaY < 0) {
					increaseWidth();
				}
				if (event.deltaY > 0) {
					reduceWidth();
				}
			}
		};

		dom.addEventListener("wheel", toggleWidthEvent, {
			passive: false
		});

		const getNextRowElement = () => {
			const eles = gae("img,#next", mainElement);
			const index = Number(currentReferenceElement.dataset.index);
			if (index >= eles.length - 1) {
				imgViewIndex = index;
				return eles.at(-1);
			}
			for (let i = index + 1, n = eles.length; i < n; i++) {
				if (eles[i].offsetTop > currentReferenceElement.offsetTop) {
					currentReferenceElement = eles[i];
					imgViewIndex = i;
					return eles[i];
				}
			}
			imgViewIndex = eles.length - 1;
			return eles.at(-1);
		};

		const getPrevRowElement = () => {
			const eles = gae("img,#next", mainElement);
			const index = Number(currentReferenceElement.dataset.index);
			if (index <= 0) {
				imgViewIndex = 0;
				return eles.at(0);
			}
			for (let i = index - 1; i >= 0; i--) {
				if (eles[i].offsetTop < currentReferenceElement.offsetTop) {
					currentReferenceElement = eles[i];
					imgViewIndex = i;
					return eles[i];
				}
			}
			imgViewIndex = 0;
			return eles.at(0);
		};

		const toggleImage = (event) => {
			if (isOpenChapterList) return;
			if (event.shiftKey && config.ViewMode == 5) {
				const viewImgs = gae("img.isView", mainElement);
				const middleIndex = Math.floor(viewImgs.length / 2 - 1);
				let img;
				if (middleIndex > -1) {
					img = viewImgs[middleIndex];
				} else {
					img = viewImgs[0];
				}
				imgViewIndex = Number(img.dataset.index);
			}
			if (!isOpenFancybox && ([0, 1, 3].some(m => config.ViewMode == m) && [1, 2].some(m => config.shadowGalleryWheel == m) || config.ViewMode == 5) && !event.ctrlKey && !event.altKey && !event.shiftKey && !event.metaKey) {
				event.preventDefault();
				event.stopPropagation();
				const imgs = gae("img", mainElement);
				const next = ge("#next", mainElement);
				const isRTL = mainElement.style.direction == "rtl";
				if (config.ViewMode == 5 && (config.horizontalWheel == 0 || config.horizontalWheel == 1)) {
					if (isString(nextLink) && (mainElement.scrollWidth - mainElement.offsetWidth) < Math.abs(mainElement.scrollLeft + (isRTL ? -2 : 2)) && event.deltaY > 0) {
						if (isShowAlert) {
							let num = Number(alertMessage.innerText.match(/\d/));
							if (num > 0) {
								showAlert(DL.str_113 + (num -= 1));
							}
							if (num <= 0) {
								showAlert(isComic ? DL.str_196 : DL.str_197, 0);
								return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
							}
						} else {
							showAlert();
						}
					} else if (isString(nextLink)) {
						hideAlert();
					}
					if (config.horizontalWheel == 0) {
						if (isRTL) {
							return (mainElement.scrollLeft -= event.deltaY);
						} else {
							return (mainElement.scrollLeft += event.deltaY);
						}
					} else if (config.horizontalWheel == 1) {
						let num;
						if (event.deltaY > 0) {
							if (config.jumpNum == 0) {
								if (isRTL) {
									num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
								} else {
									num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
								}
							} else {
								if (isRTL) {
									num = mainElement.scrollLeft - Number(config.jumpNum);
								} else {
									num = mainElement.scrollLeft + Number(config.jumpNum);
								}
							}
						} else {
							if (config.jumpNum == 0) {
								if (isRTL) {
									num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
								} else {
									num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
								}
							} else {
								if (isRTL) {
									num = mainElement.scrollLeft + Number(config.jumpNum);
								} else {
									num = mainElement.scrollLeft - Number(config.jumpNum);
								}
							}
						}
						return mainElement.scrollTo({
							left: num,
							behavior: config.behavior
						});
					}
				}
				if (config.shadowGalleryWheel == 1 || config.ViewMode == 5) {
					if (isShowAlert && event.deltaY > 0) {
						let num = Number(alertMessage.innerText.match(/\d/));
						if (num > 0) {
							showAlert(DL.str_113 + (num -= 1));
						}
						if (num <= 0) {
							showAlert(isComic ? DL.str_196 : DL.str_197, 0);
							return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
						}
					} else if (event.deltaY > 0 && imgViewIndex >= imgs.length - 1 && config.ViewMode == 5 && isString(nextLink)) {
						showAlert();
					} else if (event.deltaY < 0 && imgViewIndex < 0) {
						if (loopView != 1) return;
						nextButtonIsShown = false;
						if (config.ViewMode == 5) {
							hideAlert();
						}
						imgViewIndex = imgs.length - 1;
						imgs[imgViewIndex].style.border = "solid #32a1ce";
						return instantScrollIntoView(imgs[imgViewIndex]);
					} else if (event.deltaY < 0 && imgViewIndex >= 0) {
						nextButtonIsShown = false;
						if (config.ViewMode == 5) {
							hideAlert();
						}
						imgViewIndex--;
						if (imgViewIndex < 0 && loopView != 1) {
							imgViewIndex = 0;
							return;
						}
						if (imgViewIndex < 0) imgViewIndex = imgs.length - 1;
						if (config.ViewMode != 4) {
							for (let e of imgs) e.style.border = "";
							if (imgs[imgViewIndex] !== undefined) {
								imgs[imgViewIndex].style.border = "solid #32a1ce";
							}
						}
						return instantScrollIntoView(imgs[imgViewIndex]);
					} else if (event.deltaY > 0 && nextButtonIsShown) {
						next.style.backgroundColor = "gray";
						return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 500);
					} else if (event.deltaY > 0 && imgViewIndex <= imgs.length - 1) {
						imgViewIndex++;
						if (imgViewIndex > imgs.length - 1 && loopView != 1 && !next) {
							imgViewIndex = imgs.length - 1;
							return;
						}
						if (imgs[imgViewIndex] === undefined && next && !nextButtonIsShown) {
							nextButtonIsShown = true;
							next.style.border = "solid #32a1ce";
							for (let e of imgs) e.style.border = "";
							return instantScrollIntoView(next);
						} else if (imgs[imgViewIndex] === undefined) {
							imgViewIndex = 0;
						}
						if (config.ViewMode != 4) {
							for (let e of imgs) e.style.border = "";
							if (imgs[imgViewIndex] !== undefined) {
								imgs[imgViewIndex].style.border = "solid #32a1ce";
							}
						}
						if (imgs[imgViewIndex] !== undefined) {
							return instantScrollIntoView(imgs[imgViewIndex]);
						}
					} else {
						imgViewIndex = -1;
					}
				} else if (config.shadowGalleryWheel == 2) {
					if (event.deltaY < 0) {
						nextButtonIsShown = false;
						if (Number(currentReferenceElement?.dataset?.index) <= 0) return;
						for (let e of imgs) e.style.border = "";
						return instantScrollIntoView(getPrevRowElement());
					}
					if (event.deltaY > 0) {
						if (Number(currentReferenceElement?.dataset?.index) >= totalNumberOfElements - 1) return;
						for (let e of imgs) e.style.border = "";
						return instantScrollIntoView(getNextRowElement());
					}
				}
			}
		};

		dom.addEventListener("wheel", toggleImage, {
			passive: false
		});

		const aspectRatio = () => {
			const verticalScreen = win.innerHeight / win.innerWidth > 1;
			const imgs = gae("img", mainElement);
			for (let img of imgs) {
				if (verticalScreen && img.className === "default") {
					img.style.maxWidth = "96vw";
					img.style.maxHeight = "";
					img.style.minWidth = "96vw";
					img.style.minHeight = "";
				} else if (img.className === "default") {
					img.style.maxHeight = "calc(100vh - 6px)";
					img.style.maxWidth = "100%";
					img.style.minHeight = "calc(100vh - 6px)";
					img.style.minWidth = "";
				}
				if (config.ViewMode == 5) {
					let num = 6;
					if (devicePixelRatio > 1 && !isFirefox) {
						num = 3;
					}
					img.style.height = (mainElement.clientHeight - num) + "px";
				}
			}
			if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
				if (config.shadowGalleryWheel != 2) {
					for (let e of imgs) e.style.border = "";
					imgs[imgViewIndex].style.border = "solid #32a1ce";
				}
				setTimeout(() => instantScrollIntoView(imgs[imgViewIndex]), 100);
			}
		};
		_unsafeWindow.addEventListener("resize", aspectRatio);

		const toggleDirection = (box, imgs) => {
			if (box.style.direction == "rtl") {
				mainElement.style.direction = "ltr";
				box.style.direction = "ltr";
				imgs.at(0).classList.remove("horizontal_last");
				imgs.at(0).classList.add("horizontal_first");
				imgs.at(-1).classList.remove("horizontal_first");
				imgs.at(-1).classList.add("horizontal_last");
			} else {
				mainElement.style.direction = "rtl";
				box.style.direction = "rtl";
				imgs.at(0).classList.remove("horizontal_first");
				imgs.at(0).classList.add("horizontal_last");
				imgs.at(-1).classList.remove("horizontal_last");
				imgs.at(-1).classList.add("horizontal_first");
			}
		};

		const toggle_r_l_border = (imgs) => {
			for (let img of imgs) img.classList.toggle("no_r_l_border");
		};

		// 框架畫廊快捷鍵
		const kEvent = (event) => {
			if (isOpenFancybox || ["F11", "F12"].some(k => event.code === k || event.key === k) || (config.ViewMode == 5 && event.shiftKey)) return;
			const imgs = gae("img", mainElement);
			const next = ge("#next", mainElement) || ge("#menuNext", menuDiv);
			if (event.code === "Escape" || event.key === "Escape") {
				if (isOpenChapterList) {
					isOpenChapterList = false;
					return list_main.classList.add("hide");
				}
				return closeGallery();
			}
			if (event.code === "Numpad0" || event.code === "Digit0" || event.key === "0") return defaultImageLayout();
			if (event.code === "Numpad1" || event.code === "Digit1" || event.key === "1") return singleImageLayout();
			if (event.code === "Numpad2" || event.code === "Digit2" || event.key === "2") return smallImageLayout();
			if (event.code === "Numpad3" || event.code === "Digit3" || event.key === "3") return rtlImageLayout();
			if (event.code === "Numpad4" || event.code === "Digit4" || event.key === "4") return webtoonImageLayout();
			if (event.code === "Numpad5" || event.code === "Digit5" || event.key === "5") return horizontalImageLayout();
			if ((event.code === "Home" || event.key === "Home") || (event.code === "End" || event.key === "End")) {
				event.preventDefault();
				nextButtonIsShown = false;
				if (event.code === "Home" || event.key === "Home") {
					imgViewIndex = 0;
				} else {
					imgViewIndex = imgs.length - 1;
				}
				const img = imgs[imgViewIndex];
				if (config.ViewMode != 4 && ([0, 1, 3].some(m => config.ViewMode == m) && config.shadowGalleryWheel != 2)) {
					for (let e of imgs) e.style.border = "";
					img.style.border = "solid #32a1ce";
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			}
			if (event.code === "KeyH" || event.key === "h" || event.key === "H") {
				showAlert(DL.str_223, 0);
				return (isGoToNext = true) && setTimeout(() => ("home" in siteData) ? (location.href = siteData.home) : (location.href = location.origin), 100);
			}
			if (event.code === "KeyU" || event.key === "u" || event.key === "U") {
				if ("update" in siteData) {
					showAlert(DL.str_227, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = siteData.update), 100);
				}
			}
			if (event.code === "KeyN" || event.key === "n" || event.key === "N") {
				if (isString(nextLink)) {
					showAlert(isComic ? DL.str_196 : DL.str_197, 0);
					if (isEle(next)) {
						next.style.backgroundColor = "gray";
					}
					return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
				}
			}
			if (event.code === "KeyP" || event.key === "p" || event.key === "P") {
				if (isString(prevLink)) {
					showAlert(isComic ? DL.str_221 : DL.str_222, 0);
					return (isGoToPrev = true) && setTimeout(() => (location.href = prevLink), 100);
				}
			}
			if (event.code === "KeyC" || event.key === "c" || event.key === "C") {
				if (chapterListObtained) {
					if (isOpenChapterList) {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					} else {
						list_main.classList.remove("hide");
						isOpenChapterList = true;
						const button = ge(".current-chapter", list_main);
						list_main.scrollTop = button.offsetTop - (list_main.clientHeight / 2) + button.clientHeight;
					}
				}
			}
			if (event.code === "KeyJ" || event.key === "j" || event.key === "J") {
				let num;
				if (config.ViewMode == 5) {
					const isRTL = mainElement.style.direction == "rtl";
					if (config.jumpNum == 0) {
						if (isRTL) {
							num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
						} else {
							num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
						}
					} else {
						if (isRTL) {
							num = mainElement.scrollLeft - Number(config.jumpNum);
						} else {
							num = mainElement.scrollLeft + Number(config.jumpNum);
						}
					}
					return mainElement.scrollTo({
						left: num,
						behavior: config.behavior
					});
				};
				if (config.jumpNum == 0) {
					if (_unsafeWindow.devicePixelRatio > 1 && [0, 1, 3].some(m => config.ViewMode == m)) {
						num = mainElement.scrollTop + imgs[0].offsetHeight;
					} else {
						num = mainElement.scrollTop + win.innerHeight;
					}
				} else {
					num = mainElement.scrollTop + Number(config.jumpNum);
				}
				let lastTop = mainElement.scrollHeight - win.innerHeight;
				if (num >= lastTop) {
					num = lastTop;
				}
				return mainElement.scrollTo({
					top: num,
					behavior: config.behavior
				});
			}
			if (event.code === "KeyK" || event.key === "k" || event.key === "K") {
				let num;
				if (config.ViewMode == 5) {
					const isRTL = mainElement.style.direction == "rtl";
					if (config.jumpNum == 0) {
						if (isRTL) {
							num = mainElement.scrollLeft + _unsafeWindow.innerWidth;
						} else {
							num = mainElement.scrollLeft - _unsafeWindow.innerWidth;
						}
					} else {
						if (isRTL) {
							num = mainElement.scrollLeft + Number(config.jumpNum);
						} else {
							num = mainElement.scrollLeft - Number(config.jumpNum);
						}
					}
					return mainElement.scrollTo({
						left: num,
						behavior: config.behavior
					});
				};
				if (config.jumpNum == 0) {
					if (_unsafeWindow.devicePixelRatio > 1 && [0, 1, 3].some(m => config.ViewMode == m)) {
						num = mainElement.scrollTop - imgs[0].offsetHeight;
					} else {
						num = mainElement.scrollTop - win.innerHeight;
					}
				} else {
					num = mainElement.scrollTop - Number(config.jumpNum);
				}
				if (num <= 0) {
					num = 0;
				}
				return mainElement.scrollTo({
					top: num,
					behavior: config.behavior
				});
			}
			if (config.ViewMode == 4 && (["NumpadAdd", "Equal"].some(k => event.code === k) || ["+", "="].some(k => event.code === k))) {
				return increaseWidth();
			}
			if (config.ViewMode == 4 && (["NumpadSubtract", "Minus"].some(k => event.code === k) || ["-", "_"].some(k => event.key === k))) {
				return reduceWidth();
			}
			if ((event.code === "KeyR" || event.key === "r" || event.key === "R") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
				let box = ge("#imgBox", mainElement);
				if (config.ViewMode == 5) {
					toggleDirection(box, imgs);
					if (isEle(imgs[imgViewIndex])) {
						return instantScrollIntoView(imgs[imgViewIndex]);
					}
				} else {
					if (box.style.direction == "rtl") {
						return (box.style.direction = "ltr");
					} else {
						return (box.style.direction = "rtl");
					}
				}
			}
			if ((event.code === "KeyB" || event.key === "b" || event.key === "B") && [0, 2, 3, 5].some(m => config.ViewMode == m)) {
				toggle_r_l_border(imgs);
				if (isEle(imgs[imgViewIndex])) {
					return instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			}
			if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex < 0) {
				if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
				if (loopView != 1) return;
				event.preventDefault();
				nextButtonIsShown = false;
				imgViewIndex = imgs.length - 1;
				const img = imgs[imgViewIndex];
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					img.style.border = "solid #32a1ce";
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((["KeyW", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.code === k) || ["w", "W", "a", "A", "KeyA", "ArrowUp", "ArrowLeft"].some(k => event.key === k)) && imgViewIndex >= 0) {
				if (config.ViewMode == 4 && (event.code === "ArrowUp" || event.key === "ArrowUp")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowLeft" || event.key === "ArrowLeft")) return;
				event.preventDefault();
				nextButtonIsShown = false;
				imgViewIndex--;
				if (imgViewIndex < 0 && loopView != 1) {
					imgViewIndex = 0;
					return;
				}
				let img = imgs[imgViewIndex];
				if (img === undefined) {
					imgViewIndex = imgs.length - 1;
					img = imgs[imgViewIndex];
				}
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					if (img !== undefined) {
						img.style.border = "solid #32a1ce";
					}
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((["KeyS", "KeyD", "ArrowDown", "ArrowRight"].some(k => event.code === k) || ["s", "S", "d", "D", "ArrowDown", "ArrowRight"].some(k => event.key === k)) && nextButtonIsShown) {
				if (config.ViewMode == 4 && (event.code === "ArrowDown" || event.key === "ArrowDown")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowRight" || event.key === "ArrowRight")) return;
				showAlert(isComic ? DL.str_196 : DL.str_197, 0);
				next.style.backgroundColor = "gray";
				return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 500);
			} else if ((["KeyS", "KeyD", "ArrowDown", "ArrowRight"].some(k => event.code === k) || ["s", "S", "d", "D", "ArrowDown", "ArrowRight"].some(k => event.key === k)) && imgViewIndex <= imgs.length - 1) {
				if (config.ViewMode == 4 && (event.code === "ArrowDown" || event.key === "ArrowDown")) return;
				if (config.ViewMode == 5 && (event.code === "ArrowRight" || event.key === "ArrowRight")) return;
				event.preventDefault();
				imgViewIndex++;
				if (imgViewIndex > imgs.length - 1 && loopView != 1 && !next) {
					imgViewIndex = imgs.length - 1;
					return;
				}
				let img = imgs[imgViewIndex];
				if (config.ViewMode != 4) {
					for (let e of imgs) e.style.border = "";
					if (img !== undefined) {
						img.style.border = "solid #32a1ce";
					}
				}
				if (img === undefined && next && !nextButtonIsShown) {
					nextButtonIsShown = true;
					next.style.border = "solid #32a1ce";
					currentReferenceElement = next;
					return instantScrollIntoView(next);
				} else if (img === undefined) {
					imgViewIndex = 0;
					img = imgs[imgViewIndex];
				}
				currentReferenceElement = img;
				return instantScrollIntoView(img);
			} else if ((event.code === "Delete" || event.key === "Delete")) {
				for (const img of imgs) {
					if (!img.classList.contains("hide")) {
						img.classList.add("hide");
						break;
					}
				}
				if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
					if (config.shadowGalleryWheel != 2) {
						for (let e of imgs) e.style.border = "";
						imgs[imgViewIndex].style.border = "solid #32a1ce";
					}
					instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			} else if ((event.code === "Enter" || event.key === "Enter")) {
				for (let e of imgs) e.classList.remove("hide");
				if (imgs[imgViewIndex] !== undefined && config.ViewMode != 4) {
					if (config.shadowGalleryWheel != 2) {
						for (let e of imgs) e.style.border = "";
						imgs[imgViewIndex].style.border = "solid #32a1ce";
					}
					instantScrollIntoView(imgs[imgViewIndex]);
				}
				return;
			} else if (!["KeyR", "NumpadAdd", "Equal", "NumpadSubtract", "Minus"].some(k => event.code === k) || !["r", "R", "-", "+", "=", "_"].some(k => event.key === k)) {
				imgViewIndex = -1;
			}
		};
		if (ge("meta[property='og:site_name'][content=禁漫天堂]")) {
			_unsafeWindow.addEventListener("keydown", kEvent);
		} else {
			dom.addEventListener("keydown", kEvent);
		}

		hidePageScrollbarY();

		let placeHeight;
		if (isMobileEdge || isMobileYandex) {
			placeHeight = "54px";
		} else if (isVia || isXBrowser) {
			placeHeight = "2px";
		} else {
			placeHeight = "30px";
		}

		_GM_addElement(dom.head, "style", {
			textContent: `
#iframeGallery {
    z-index: ${UI_zIndex - 3} !important;
}
p#imgBox {
    display: block;
    min-height: calc(100vh - 38px);
    padding: 0;
    margin: 0;
}
.place {
    height: ${placeHeight};
    padding: 0;
    margin: 0;
}
#FixedMenu {
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    font-weight: 500;
    font-size: 14px;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    width: ${isM ? "102px" : "150px"};
    height: auto;
    padding: 5px 5px 2px 5px;
    position: fixed;
    left: ${isM ? "0px" : "-156px"};
    bottom: ${isM ? "54px" : "0px"};
    border: #ccc 1px solid;
    border-radius: 3px;
    background-color: ${config.colorThemes == "dark" ? "#222" : "#fff"};
    z-index: ${UI_zIndex - 3};
    opacity: ${isM ? "1" : "0.5"};
    &:hover {
        left: 0px;
        opacity: 1;
    }
}
.FixedMenuitem {
    width: ${isM ? "90px" : "138px"};
    height: 24px;
    line-height: 24px;
    overflow: hidden;
    font-size: 14px;
    border: #ccc 1px solid;
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    padding: 0 5px 0 5px;
    margin: 0 2px 3px 0;
    cursor: pointer;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
#MenuJumpItem {
    width: 148px;
    padding: 0px;
}
.FixedMenuitem.active {
    color: #fff;
    background: #1790e6;
}
#setting-btn-div {
    width: auto;
    height: auto;
    position: fixed;
    right: ${isM ? "10px" : "30px"};
    bottom: 150px;
    z-index: ${UI_zIndex - 3};
}
.setting-btn {
    width: 48px;
    height: 48px;
    text-align: center;
    user-select:none;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    margin: 5px 0;
    overflow: hidden;
    border: ${config.colorThemes == "dark" ? "rgb(200, 200, 200) 1px solid" : "rgb(51, 51, 51) 2px solid"};
    background: ${config.colorThemes == "dark" ? "rgba(37, 36, 44, 0.8)" : "rgba(255, 255, 255, 0.8)"};
    border-radius: 12px;
    cursor: pointer;
}
.setting-btn .icon {
    margin-top: 10px;
    width: 28px;
    height: 28px;
}
.hide {
    display: none !important;
}
img.default {
    vertical-align: middle;
    width: auto;
    height: auto;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
img.single {
    width: auto;
    height: auto;
    max-width: calc(100% - 6px);
    max-height: calc(100vh - 6px);
    display: block;
    margin: 0 auto;
    border: solid #fff;
}
img.webtoon {
    width: 100%;
    height: auto;
    max-width: 800px;
    display: block;
    margin: 0 auto;
    border: unset;
}
img.small {
    display: inline-block;
    vertical-align: middle;
    width: auto;
    height: auto;
    max-width: 31.8%;
    max-height: 33vh;
    border: solid #fff;
}
img.horizontal {
    vertical-align: middle;
    width: auto;
    height: 100%;
    object-fit: contain;
    border: solid #fff;
    background-color: #fff;
}
.horizontal_first {
    margin-left: 1em !important;
}
.horizontal_last {
    margin-right: 1em !important;
}
.no_r_l_border {
    border-right: none !important;
    border-left: none !important;
}
#next {
    display: block;
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    padding: 10px 0;
    margin: ${isM ? "2px" : "6px 1px 6px 7px"};
    border: solid #fff;
    border-radius: 12px;
    color: rgb(0, 0, 0);
    background-color: antiquewhite;
    font-size: 26px;
    line-height: 50px;
    height: 50px;
    text-decoration: unset;
    cursor: pointer;
}
#FixedMenu select {
    font-weight: normal;
    text-align: center;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    background-color: ${config.colorThemes == "dark" ? "#333" : "#f6f6f6"};
    border: none;
    width: 100%;
    height: 100%;
    padding: 0 auto;
}
#FixedMenu select option {
    text-align: center;
}
#behaviorInput {
    vertical-align: middle;
    width: 16px;
    height: 16px;
    margin-top: ${isFirefox ? "2px" : "0px"};
}
#alertBox {
    width: 268px;
    min-height: 74px;
    color: #000;
    position: fixed;
    top: calc(50% - 148px);
    left: calc(50% - 154px);
    padding: 20px;
    background-color: #f9f9f9;
    border: 2px solid #999;
    z-index: ${UI_zIndex - 2};
    border-radius: 10px;
    font-size: 14px;
    text-align: center;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
}
#hint {
    font-size: 20px;
    font-weight: bold;
}
#alertMessage {
    font-size: 16px;
    margin: 20px 0;
}
#alertBox #nextAlert {
    width: 138px;
    float: left;
    cursor: pointer;
    padding: 5px 22px;
    border: 1px solid #ffdb11;
    background-color: #ffdb11;
    border-radius: 10px 0px 0px 10px;
}
#alertBox #closeAlert {
    width: 38px;
    float: right;
    cursor: pointer;
    padding: 5px 22px;
    border: 1px solid #ebebeb;
    background-color: #ebebeb;
    border-radius: 0px 10px 10px 0px;
}
#modal-content-list {
    background-color: ${config.colorThemes == "dark" ? "#282828" : "#eee"};
    position: fixed;
    z-index: ${UI_zIndex - 3};
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    padding: 10px;
    border: 1px solid #888;
    min-width: 350px;
    max-width: 600px;
    max-height: 90%;
    overflow-y: auto;
}
.closeModal {
    position: absolute;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
}
.chapter-list-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
    padding-top: 20px;
}
.chapter-btn {
    background-color: ${config.colorThemes == "dark" ? "#3c3c3c" : "#fff"};
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    border: ${config.colorThemes == "dark" ? "none" : "1px solid #a2a2a2"};
    padding: 10px;
    cursor: pointer;
    border-radius: 5px;
    font-size: 13px;
    width: calc(33.3333% - 8px);
    box-sizing: border-box;
    text-align: center;
    overflow:hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.chapter-btn:not(.current-chapter):hover {
    background-color: #ffa64d;
    color: #fff;
}
.current-chapter {
    background-color: #1790e6;
    color: #fff;
}
#chapters-footer {
    margin: 10px 0;
    display: flex;
    justify-content: flex-end;
}
#footer_close_button {
    display: block;
    width: 100%;
    color: ${config.colorThemes == "dark" ? "#fff" : "#000"};
    background-color: ${config.colorThemes == "dark" ? "#454d55" : "#ccc"};
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 10px;
    box-sizing: content-box;
    font-size: 16px;
    font-weight: 600;
}
                `
		});

		const mainElement = fn.ace(dom.body, "div", {
			id: "iframeGallery",
			tabIndex: "-1"
		}, {
			inset: "0",
			width: "100vw",
			height: "100vh",
			margin: "0px",
			padding: "0px",
			position: "fixed",
			opacity: "1",
			backgroundColor: "#333",
			color: "#222",
			fontSize: "14px",
			overflow: "hidden scroll",
			textAlign: "center"
		});

		let lastScrollTop = 0;
		mainElement.addEventListener("scroll", (event) => {
			if (mainElement.scrollTop > lastScrollTop) {
				if (isM) {
					menuDiv.classList.add("hide");
				}
				if (config.ViewMode == 4) {
					ge("#setting-btn-div", dom).classList.add("hide");
				}
			} else if (mainElement.scrollTop < lastScrollTop && !nextButtonIsShown) {
				if (isM) {
					menuDiv.classList.remove("hide");
				}
				if (config.ViewMode == 4) {
					ge("#setting-btn-div", dom).classList.remove("hide");
				}
			}
			lastScrollTop = mainElement.scrollTop;
		});

		let queue;

		function loadImgs(imgs) {
			queue = null;
			queue = new FunctionQueue(config.threading, simpleLoadImg, imgs);
		}

		async function createGalleryElement(mode) {
			mainElement.scrollTo({
				top: 0
			});
			if (!isM) {
				mainElement.focus();
			}
			imgViewIndex = -1;
			for (let item of gae(".FixedMenuitem", dom)) item.classList.remove("active");
			mainElement.style.overflow = "hidden scroll";
			mainElement.style.direction = "";
			mainElement.innerHTML = "";
			menuDiv.style.bottom = "";
			const imgElements = srcs.map((src, i) => {
				let img = new Image();
				img.className = mode;
				img.dataset.index = i;
				img.dataset.fancybox = "gallery";
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.src = loading_bak;
				img.dataset.src = src;
				if (thumbnailSrcArray.length > 0) {
					img.dataset.thumb = thumbnailSrcArray[i];
				} else {
					img.dataset.thumb = src;
				}
				if (mode === "webtoon") {
					img.style.maxWidth = webtoonWidth + "px";
				}
				return img;
			});
			if (isM) {
				fn.ace(fragment, "p", {
					className: "place"
				});
			}
			if (mode === "horizontal") {
				imgElements.at(0).classList.add("horizontal_first");
				imgElements.at(-1).classList.add("horizontal_last");
			}
			const p = fn.ace(fragment, "p", {
				id: "imgBox"
			}, {
				direction: (config.ViewMode == 3) ? "rtl" : ""
			});
			if (isPC && isComic && isVH("H") && config.ViewMode != 4 && config.ViewMode != 5) {
				if (_unsafeWindow.devicePixelRatio > 1) {
					p.style.padding = "2px 8% 0";
				} else {
					p.style.padding = "0 8%";
				}
				p.style.margin = "0 auto";
			} else if (config.ViewMode == 5) {
				p.style.display = "flex";
				p.style.height = "100vh";
				p.style.width = "fit-content";
				mainElement.style.overflow = "scroll hidden";
				menuDiv.style.bottom = "20px";
			} else if (_unsafeWindow.devicePixelRatio > 1) {
				p.style.paddingTop = "1px";
			}
			p.append(...imgElements);
			mainElement.append(fragment);
			loadImgs(imgElements);
			aspectRatio();
			if (isPC && mode === "webtoon") {
				btnDiv.classList.remove("hide");
			} else {
				btnDiv.classList.add("hide");
			}
			currentReferenceElement = imgElements.at(0);
			totalNumberOfElements = imgElements.length;
			if (mode === "horizontal" && ["comic", "hcomic"].some(c => siteData.category == c)) {
				toggleDirection(p, imgElements);
			}
			if (["comic"].some(c => siteData.category == c)) {
				toggle_r_l_border(imgElements);
			}
			await fn.wait(() => imgElements.at(-1)?.offsetHeight > 100).then(() => {
				setTimeout(() => {
					aspectRatio();
					for (let img of imgElements) {
						if (config.threading > 1) {
							fn.imagesObserver.observe(img);
						}
						if (config.ViewMode == 5) {
							fn.imagesViewObserver.observe(img);
						}
						if (mode === "horizontal") {
							let num = 6;
							if (devicePixelRatio > 1 && !isFirefox) {
								num = 3;
							}
							img.style.height = (mainElement.clientHeight - num) + "px";
						}
					}
				}, 1000);
			});
			if (options.fancybox != 1) {
				for (let img of imgElements) {
					img.onclick = event => {
						cancelDefault(event);
						imgViewIndex = Number(img.dataset.index);
						currentReferenceElement = event.target;
						if (config.ViewMode != 4) {
							if (event?.target?.style?.border === "") {
								for (let e of imgElements) e.style.border = "";
								event.target.style.border = "solid #32a1ce";
							} else {
								for (let e of imgElements) e.style.border = "";
							}
						}
					}
				}
			}
			if (options.fancybox == 1) {
				//框架燈箱
				const cb = (i) => {
					imgViewIndex = i;
					for (let e of imgElements) e.style.border = "";
					let img = imgElements[imgViewIndex];
					currentReferenceElement = img;
					img.style.border = "solid #32a1ce";
					instantScrollIntoView(img);
				};
				for (let img of imgElements) {
					img.addEventListener("click", (event) => {
						cancelDefault(event);
						const Fancybox = win.Fancybox;
						if (Fancyboxl10nV5() != "EN") {
							Fancybox.defaults.l10n = Fancyboxl10nV5();
						}
						const index = Number(event.target.dataset.index);
						Fancybox.fromNodes(imgElements, {
							Hash: false,
							idle: FancyboxIdle,
							animated: false,
							showClass: false,
							hideClass: false,
							wheel: FancyboxWheel,
							startIndex: index,
							Images: {
								Panzoom: {
									maxScale: 4
								},
								zoom: false
							},
							Slideshow: {
								timeout: FancyboxSlideshowTimeoutNum,
							},
							Carousel: {
								...Fancybox.defaults.Carousel,
								transition: FancyboxSlideshowTransition
							},
							Thumbs: {
								showOnStart: FancyboxShowThumbs
							},
							Toolbar: {
								display: {
									left: ["infobar"],
									middle: isM ? ["flipX", "flipY"] : ["zoomIn", "zoomOut", "iterateZoom", "toggle1to1", "rotateCCW", "rotateCW", "flipX", "flipY", "fitX", "fitY", "reset"],
									right: ["slideshow", "fullscreen", "thumbs", "close"]
								}
							},
							on: {
								done: (fancybox, slide) => {
									isOpenFancybox = true;
									if (fancybox.isCurrentSlide(slide)) {
										cb(slide.index);
									} else {
										cb(fancybox.getSlide().index);
									}
									if (fancybox.carousel.page == 0 && (fancybox.carousel.prevPage == fancybox.carousel.pages.at(-1).index)) {
										if (FancyboxAutoClose == 1) {
											fancybox.close();
										}
										if (FancyboxAutoNext == 1) {
											if (!!nextLink) {
												closeGallery();
												fn.showMsg(DL.str_34.n);
												setTimeout(() => (location.href = nextLink), 100);
											}
										}
									}
								},
								close: fancybox => {
									cb(fancybox.getSlide().index);
									setTimeout(() => {
										isOpenFancybox = false;
									}, 100);
								}
							}
						});
					});
				}
			}
			if (isString(nextLink) && config.ViewMode != 5) {
				totalNumberOfElements = totalNumberOfElements + 1;
				const next = fn.ace(mainElement, "div", {
					id: "next",
					innerText: `${isComic ? DL.str_143 : DL.str_144}${isM ? "" : "( N )"}`,
					dataset: {
						url: nextLink,
						index: imgElements.length
					},
					onclick: event => {
						cancelDefault(event);
						showAlert(isComic ? DL.str_196 : DL.str_197, 0);
						next.style.backgroundColor = "gray";
						return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
					}
				});
				if (config.shadowGalleryWheel != 1 && [0, 1, 3].some(m => config.ViewMode == m) || [2, 4].some(m => config.ViewMode == m)) {
					let isEventAdded = false;
					const nextObserver = new IntersectionObserver((entries, observer) => {
						for (let entry of entries) {
							if (entry.isIntersecting) {
								nextButtonIsShown = true;
								next.style.border = "solid #32a1ce";
								if (isPC) {
									showAlert();
								}
								if (!isEventAdded) {
									isEventAdded = true;
									dom.addEventListener("wheel", (event) => {
										if (isOpenFancybox || event.ctrlKey || event.altKey || event.shiftKey || event.metaKey) return;
										if (event.deltaY < 0) {
											next.style.border = "";
											nextButtonIsShown = false;
											hideAlert();
										} else if (event.deltaY > 0 && nextButtonIsShown) {
											let num = Number(alertMessage.innerText.match(/\d/));
											if (num > 0) {
												showAlert(DL.str_113 + (num -= 1));
											}
											if (num <= 0) {
												showAlert(isComic ? DL.str_196 : DL.str_197, 0);
												next.style.backgroundColor = "gray";
												return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
											}
										}
									}, {
										passive: true
									});
								}
							} else {
								next.style.border = "";
								nextButtonIsShown = false;
								hideAlert();
							}
						}
					}, {
						threshold: 0.9,
					});
					setTimeout(() => {
						nextObserver.observe(next);
					}, 1000);
				}
			}
			if (isM) {
				fn.ace(mainElement, "p", {
					className: "place"
				});
			}
		}

		let btnDiv;

		function addButtons() {
			btnDiv = fn.ace(dom.body, "div", {
				id: "setting-btn-div",
				className: "hide"
			});
			const btnObj = [{
				id: "resetBtn",
				svg: svg.reset,
				cfn: resetWidth
			}, {
				id: "addBtn",
				svg: svg.plus,
				cfn: increaseWidth
			}, {
				id: "reduceBtn",
				svg: svg.minus,
				cfn: reduceWidth
			}];
			const createDiv = obj => fn.ace(btnDiv, "div", {
				id: obj.id,
				className: "setting-btn",
				innerHTML: obj.svg,
				oncontextmenu: () => false,
				onclick: obj.cfn
			});
			btnObj.forEach(createDiv);
		}
		addButtons();

		let alertHtml = `
<div id="alertBox" class="hide">
    <div id="hint">${DL.str_112}</div>
    <p id="alertMessage">${DL.str_113}3</p>
    <div id="nextAlert">${isComic ? DL.str_143 : DL.str_144}( N )</div>
    <div id="closeAlert">${DL.str_132}</div>
</div>
        `;
		let alertNode = fn.html(alertHtml);
		dom.body.append(alertNode);

		let alertDiv = ge("#alertBox", dom);
		let alertMessage = ge("#alertMessage", alertDiv);
		let alertNext = ge("#nextAlert", alertDiv);
		let alertClose = ge("#closeAlert", alertDiv);
		let alertTid;
		const showAlert = (text = DL.str_113 + "3", button = 1, time = 0) => {
			isShowAlert = true;
			if (getType(alertTid) == "Number") {
				clearTimeout(alertTid);
			}
			alertMessage.innerText = text;
			for (let e of [alertNext, alertClose]) button ? e.classList.remove("hide") : e.classList.add("hide");
			alertDiv.classList.remove("hide");
			if (time) {
				alertTid = setTimeout(() => hideAlert(), time);
			}
		};
		const hideAlert = () => {
			isShowAlert = false;
			alertMessage.innerText = DL.str_113 + "3";
			alertDiv.classList.add("hide");
		};
		alertNext.addEventListener("click", event => {
			cancelDefault(event);
			showAlert(isComic ? DL.str_196 : DL.str_197, 0);
			return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 100);
		});
		alertClose.addEventListener("click", hideAlert);

		let menuDiv;

		function addFixedMenu() {
			menuDiv = fn.ace(dom.body, "div", {
				id: "FixedMenu"
			});
			const menuObj = [{
				id: "MenuCancelItem",
				text: DL.str_142,
				cfn: () => closeGallery()
			}, {
				id: "MenuSettingsItem",
				text: DL.str_85.replace(/\(.\)/, ""),
				cfn: () => createPictureLoadOptionsShadowElement()
			}, {
				id: "MenuFavorItem",
				text: DL.str_128.replace(/\(.\)/, ""),
				cfn: () => createFavorShadowElement()
			}, {
				id: "MenuThreadingItem"
			}, {
				id: "MenuBehaviorItem"
			}, {
				id: "MenuJumpItem",
			}, {
				id: "menuHome",
				text: isM ? DL.str_217 : DL.str_217 + "( H )",
				cfn: () => {
					showAlert(DL.str_223, 0);
					return (isGoToNext = true) && setTimeout(() => ("home" in siteData) ? (location.href = siteData.home) : (location.href = location.origin), 100);
				}
			}, {
				id: "menuUpdate",
				hide: 1,
				text: DL.str_226,
				cfn: () => {
					showAlert(DL.str_227, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = siteData.update), 200)
				}
			}, {
				id: "menuList",
				hide: 1,
				text: DL.str_216,
				cfn: () => {
					list_main.classList.remove("hide");
					isOpenChapterList = true;
					const button = ge(".current-chapter", list_main);
					list_main.scrollTop = button.offsetTop - (list_main.clientHeight / 2) + button.clientHeight;
				}
			}, {
				id: "menuPrev",
				text: `${isComic ? DL.str_219 : DL.str_220}${isM ? "" : "( P )"}`,
				cfn: () => {
					showAlert(isComic ? DL.str_221 : DL.str_222, 0);
					return (isGoToPrev = true) && setTimeout(() => (location.href = prevLink), 200);
				}
			}, {
				id: "menuNext",
				text: `${isComic ? DL.str_143 : DL.str_144}${isM ? "" : "( N )"}`,
				cfn: () => {
					showAlert(isComic ? DL.str_196 : DL.str_197, 0);
					return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
				}
			}, {
				id: "MenuHorizontalItem",
				text: DL.galleryMenu.horizontal,
				cfn: () => horizontalImageLayout()
			}, {
				id: "MenuWebtoonItem",
				text: DL.galleryMenu.webtoon,
				cfn: () => webtoonImageLayout()
			}, {
				id: "MenuRTLItem",
				text: DL.galleryMenu.rtl,
				cfn: () => rtlImageLayout()
			}, {
				id: "MenuSmallItem",
				text: DL.galleryMenu.small,
				cfn: () => smallImageLayout()
			}, {
				id: "MenuSinglePageItem",
				text: DL.galleryMenu.single,
				cfn: () => singleImageLayout()
			}, {
				id: "MenuDefaultItem",
				text: DL.galleryMenu.default,
				cfn: () => defaultImageLayout()
			}];
			const createMenu = obj => {
				if (!isString(nextLink) && obj.id == "menuNext") return;
				if (!isString(prevLink) && obj.id == "menuPrev") return;
				fn.ace(menuDiv, "div", {
					id: obj.id,
					className: ("hide" in obj) ? "FixedMenuitem hide" : "FixedMenuitem",
					innerText: ("text" in obj) ? obj.text : "",
					oncontextmenu: () => false,
					onclick: ("cfn" in obj) ? obj.cfn : null
				});
			};
			menuObj.forEach(createMenu);

			let threadingSelect = fn.ce("select", {
				onchange: () => {
					config.threading = Number(threadingSelect.value);
					saveConfig(config);
					if (!isM) {
						mainElement.focus();
					}
				}
			});
			for (let i = 1; i <= 32; i++) threadingSelect.append(new Option(DL.str_162 + i, i));
			threadingSelect.value = config.threading;
			ge("#MenuThreadingItem", menuDiv).append(threadingSelect);

			if (isPC) {
				let jumpSelect = fn.ce("select", {
					onchange: () => {
						config.jumpNum = jumpSelect.value;
						saveConfig(config);
						if (!isM) {
							mainElement.focus();
						}
					}
				});
				for (let i = 0; i <= 100; i++) {
					let option = new Option(i == 0 ? `${DL.str_150}${DL.str_152}` : `${DL.str_150}${i * 50}px`, i == 0 ? i : i * 50);
					jumpSelect.append(option);
				}
				jumpSelect.value = config.jumpNum;
				ge("#MenuJumpItem", menuDiv).append(jumpSelect);

				let behaviorDiv = ge("#MenuBehaviorItem", menuDiv);
				let behaviorInput = fn.ace(behaviorDiv, "input", {
					id: "behaviorInput",
					type: "checkbox",
					checked: config.behavior == "smooth" ? true : false,
					onchange: () => {
						config.behavior = behaviorInput.checked == true ? "smooth" : "instant";
						saveConfig(config);
						if (!isM) {
							mainElement.focus();
						}
					}
				});
				let behaviorLabel = fn.ace(behaviorDiv, "label", {
					innerText: DL.str_151
				});
			}
			if (isM) {
				menuDiv.classList.add("hide");
				for (let e of gae("#MenuBehaviorItem,#MenuJumpItem,#MenuHorizontalItem", menuDiv)) e.classList.add("hide");
			}
		}
		addFixedMenu();

		if ("update" in siteData) {
			ge("#menuUpdate", menuDiv).classList.remove("hide");
		}

		let list_main;

		if ("chapters" in siteData) {
			// 創建目錄
			const get_chapters = siteData.chapters;
			const createChapterList = async () => {
				let chapterListData = [];
				if (isObject(get_chapters)) {
					chapterListData = await fn.getChapters(get_chapters);
				} else if (isFn(get_chapters)) {
					chapterListData = await get_chapters();
				}
				if (!isArray(chapterListData) || !chapterListData?.length) return;
				if (isNumber(chapterListData?.length)) {
					if (chapterListData.length < 2) return;
				}
				chapterListObtained = true;
				const tempURLs = new Set();
				chapterListData = chapterListData.filter(({
					url
				}) => {
					if (tempURLs.has(url) || url == "#") {
						return false;
					} else {
						tempURLs.add(url);
					}
					return true;
				});
				ge("#menuList", menuDiv).classList.remove("hide");
				list_main = fn.ace(dom.body, "div", {
					id: "modal-content-list",
					className: "hide"
				});
				fn.ace(list_main, "span", {
					id: "closeModal",
					className: "closeModal",
					innerText: `× ${DL.str_132}`,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				const list_container = fn.ace(list_main, "div", {
					id: "chapterListContainer",
					className: "chapter-list-container"
				});
				const pathname = decodeURIComponent(fn.clp());
				const search = fn.cls();
				let isCurrent = false;
				const list = chapterListData.map(({
					text,
					url
				}) => {
					const button = fn.ce("button", {
						className: "chapter-btn",
						innerText: text,
						dataset: {
							url
						}
					});
					if ("checkCurrentChapter" in siteData) {
						isCurrent = siteData.checkCurrentChapter(url, text);
					}
					if (
						isCurrent ||
						search && url.endsWith(search) ||
						!search && decodeURIComponent(url).endsWith(pathname) ||
						search.includes("page=") && url.includes(pathname)
					) {
						button.classList.add("current-chapter");
					} else {
						button.addEventListener("click", (event) => {
							cancelDefault(event);
							closeGallery();
							fn.showMsg(DL.str_218, 0);
							return (isGoToNext = true) && setTimeout(() => (location.href = button.dataset.url), 200);
						});
					}
					return button;
				});
				fragment.append(...list);
				list_container.append(fragment);
				const footer = fn.ace(list_main, "div", {
					id: "chapters-footer"
				});
				fn.ace(footer, "button", {
					id: "footer_close_button",
					innerText: DL.str_132,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				mainElement.addEventListener("click", () => {
					if (isOpenChapterList) {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
			};
			createChapterList();
		}

		function defaultImageLayout() {
			config.ViewMode = 0;
			saveConfig(config);
			createGalleryElement("default");
			ge("#MenuDefaultItem", dom).classList.add("active");
		}

		function singleImageLayout() {
			config.ViewMode = 1;
			saveConfig(config);
			createGalleryElement("single");
			ge("#MenuSinglePageItem", dom).classList.add("active");
		}

		function smallImageLayout() {
			config.ViewMode = 2;
			saveConfig(config);
			createGalleryElement("small");
			ge("#MenuSmallItem", dom).classList.add("active");
		}

		function rtlImageLayout() {
			config.ViewMode = 3;
			saveConfig(config);
			createGalleryElement("default");
			ge("#MenuRTLItem", dom).classList.add("active");
		}

		function webtoonImageLayout() {
			config.ViewMode = 4;
			saveConfig(config);
			createGalleryElement("webtoon");
			ge("#MenuWebtoonItem", dom).classList.add("active");
		}

		function horizontalImageLayout() {
			config.ViewMode = 5;
			saveConfig(config);
			createGalleryElement("horizontal");
			ge("#MenuHorizontalItem", dom).classList.add("active");
		}

		if (config.ViewMode == 1) {
			singleImageLayout();
		} else if (config.ViewMode == 2) {
			smallImageLayout();
		} else if (config.ViewMode == 3) {
			rtlImageLayout();
		} else if (config.ViewMode == 4) {
			webtoonImageLayout();
		} else if (config.ViewMode == 5) {
			horizontalImageLayout();
		} else {
			defaultImageLayout();
		}

	};

	const getFileSize = (src, element = null, label = null) => {
		const config = getConfig();
		if (config.noSize == 1) return;
		return fn.xhrHEAD(src, {
			headers: {
				referer: getReferer(src)
			}
		}).then(res => {
			//console.log(res);
			if (src != res.finalUrl) {
				return getFileSize(res.finalUrl, element);
			}
			const contentLength = res?.responseHeaders?.split("\r\n")?.find(s => s.startsWith("content-length:"));
			//console.log(contentLength);
			if (contentLength) {
				let [num] = contentLength.match(/\d+/);
				if (num.length > 6) {
					num = (num / 1000000).toFixed(1);
					if (isEle(element)) {
						element.innerText = element.innerText + " | Size: " + num + " MB";
					}
					return num + " MB";
				} else {
					num = Math.floor(num / 1000);
					if (isEle(element)) {
						element.innerText = element.innerText + " | Size: " + num + " kB";
					}
					return num + " kB";
				}
			} else {
				const config = getConfig();
				if (config.noSize != 1) {
					config.noSize = 1;
					saveConfig(config);
					if (isEle(label)) {
						label.classList.add("line-through");
					}
				}
			}
		});
	};

	let GalleryInIcon = _GM_getValue("GalleryInIcon", 0);
	let closeFilter;

	//創建篩選下載
	const createFilterUI = async (enterGallery = 0) => {

		if (checkGeting() || isDragging || isOpenFilter || !isValidPage) return;

		isOpenFilter = true;

		if ("SPA" in siteData) {
			lastValidPageURL = currentURL;
		}

		let full_srcs;
		let isViewMobileGallery = false;
		let Viewer;
		let ViewerJsInstance;
		let ViewerJsInstance_G;
		let f_queue;
		let g_queue;
		if ("SPA" in siteData || siteData.repeat == 1 || siteData.infiniteCapture == 1) {
			let selector = siteData.capture || siteData.srcset || siteData.imgs;
			full_srcs = await getImgs(selector);
		} else if (!("capture" in siteData)) {
			globalImgArray.length > 0 ? full_srcs = globalImgArray : full_srcs = await getImgs(siteData.srcset || siteData.imgs);
		} else {
			captureSrcArray.length > 0 ? full_srcs = captureSrcArray : full_srcs = await getImgs(siteData.srcset || siteData.imgs);
		}
		if (full_srcs.length < 1) {
			fn.showMsg(DL.str_44);
			return (isOpenFilter = false);
		}
		let srcs;
		let g_srcs;
		const config = getConfig();
		const extensions = {
			jpg: 0,
			png: 0,
			gif: 0,
			webp: 0,
			bmp: 0,
			svg: 0,
			ico: 0,
			avif: 0,
			tiff: 0
		};
		let image_size = Number(_GM_getValue("image_size", -1));
		let exclude_ex_config = _GM_getValue("exclude_ex_config", extensions);
		exclude_ex_config = Object.assign(extensions, exclude_ex_config);
		let threading = Number(config.threading);
		let colorThemes = config.colorThemes;
		let showSize = config.showSize;
		let move = config.move;
		let isOpenChapterList = false;
		let chapterListObtained = false;

		const exclude_ex_fn = () => {
			if (Object.values(exclude_ex_config).some(v => v == 1)) {
				srcs = full_srcs.filter(src => {
					if (exclude_ex_config.jpg == 1) {
						if (/\.jpe?g/i.test(src) || src.startsWith("data:image/jpeg")) {
							return false;
						}
					}
					if (exclude_ex_config.png == 1) {
						if (/\.png/i.test(src) || src.startsWith("data:image/png")) {
							return false;
						}
					}
					if (exclude_ex_config.gif == 1) {
						if (/\.gif/i.test(src) || src.startsWith("data:image/gif")) {
							return false;
						}
					}
					if (exclude_ex_config.webp == 1) {
						if (/\.webp/i.test(src) || src.startsWith("data:image/webp")) {
							return false;
						}
					}
					if (exclude_ex_config.bmp == 1) {
						if (/\.bmp/i.test(src) || src.startsWith("data:image/bmp")) {
							return false;
						}
					}
					if (exclude_ex_config.svg == 1) {
						if (/\.svg/i.test(src) || src.startsWith("data:image/svg")) {
							return false;
						}
					}
					if (exclude_ex_config.ico == 1) {
						if (/\.ico/i.test(src) || src.startsWith("data:image/x-icon")) {
							return false;
						}
					}
					if (exclude_ex_config.avif == 1) {
						if (/\.avif/i.test(src) || src.startsWith("data:image/avif")) {
							return false;
						}
					}
					if (exclude_ex_config.tiff == 1) {
						if (/\.tiff?/i.test(src) || src.startsWith("data:image/tiff")) {
							return false;
						}
					}
					return true;
				});
				g_srcs = srcs;
			} else {
				srcs = full_srcs;
				g_srcs = srcs;
			}
		};
		exclude_ex_fn();

		const update_g_srcs = () => {
			g_srcs = gae(".select+.image", main).map(img => img.dataset.src);
		};

		if (!("Viewer" in _unsafeWindow)) {
			_GM_addElement(document.head, "style", {
				textContent: ViewerJsCss
			});
			_GM_addElement(document.head, "script", {
				textContent: ViewerJs
			});
		}

		const shadowElement = fn.ace("bodya", "div", {
			id: "FullPictureLoadFilterDownload"
		});
		const shadow = shadowElement.attachShadow({
			mode: "closed"
		});
		hidePageScrollbarY();

		fn.ace(shadow, "style", {
			type: "text/css",
			innerHTML: `
#main {
    font-size: 14px !important;
    line-height: 20px !important;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-weight: 500 !important;
    text-align: left;
    color: black;
    inset: 0px;
    width: 100%;
    height: 100%;
    margin: 0px;
    padding: 0px;
    outline: none;
    border: none;
    position: fixed;
    opacity: 1;
    z-index: 2147483641;
    background-color: rgb(240, 240, 240);
    overflow: hidden auto;
}
#main.dark {
    color: white;
    background-color: #333;
}
input,select {
    color: #000;
    background-color: #fff;
    border: 1px solid;
}
input.dark,select.dark {
    color: #fff;
    background-color: #333;
    border: 1px solid #575757;
}
.show {
    display: block !important;
}
.hide {
    display: none !important;
}
.row {
    display: block;
    margin: ${isM && isFirefox ? "2px" : "5px"};
    padding: 0 0 0 5px;
    border: #000 1px solid;
    border-radius: 5px;
}
.row.dark {
    border: rgb(0, 204, 255) 1px solid;
}
#title {
    display: block;
    margin: 4px auto 0 auto;
}
.buttons {
    display: block;
    margin: 0 auto 4px auto;
}
label {
    user-select: none;
}
#label-title {
    display: inline-block;
    width: 48px;
}
button#close {
    display: inline-block;
    width: 52px;
}
.number {
    display: inline-block;
    margin-top: 4px;
    padding: ${isM ? "0 0 0 2px" : "0 0 0 4px"};
    border-left: #000 1px solid;
}
.number.dark{
    border-left: rgb(0, 204, 255) 1px solid;
}
.close {
    margin: 0 5px;
}
#inputTitle {
    width: calc(100% - 130px);
}
button {
    cursor: pointer;
}
.buttons button {
    margin-top: 4px;
}
#title button.dark,
.buttons button.dark {
    color: #fff;
    border-color: rgb(81 91 105);
    border-style: solid;
    background-color: rgb(81 91 105);
    border-radius: .5rem;
}
.buttons button.mode.active {
    color: #fff;
    border-color: #1790e6;
    border-style: solid;
    background-color: #1790e6;
    border-radius: .5rem;
}
#imgBox {
    text-align: center;
    /*min-height: calc(100vh - 120px);*/
}
ul#image-list {
    display: block;
    max-width: 100%;
    margin: ${isM ? "0 0 0 -1px" : "0 0 0 -2px"};
    padding: 4px 0 0 0;
}
.image-item:has(.error) {
    background-image: url("${svg.imageError}");
}
li.image-item {
    list-style: none;
    position: relative;
    display: inline-flex;
    width: 200px;
    height: 200px;
    margin: 0 4px 4px 0;
    padding: 0px;
    background-color: #fff;
    border: #000 1px solid;
    border-radius: 2px;
}
li.image-item.dark {
    background-color: #333;
    border: rgb(0, 204, 255) 1px solid;
}
li img.image {
    display: block;
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: 100%;
    margin: 0px auto;
    object-fit: contain;
}
li input.check {
    position: absolute;
    top: 2px;
    left: 2px;
}
li.image-item p {
    position: absolute;
    font-size: 12px;
    line-height: 14px;
    width: 100%;
    height: 14px;
    bottom: 0px;
    margin: 0px;
    padding: 0px;
    background-color: rgba(163, 194, 194, 0.8);
}
li.image-item p.dark {
    background-color: rgba(82, 82, 122, 0.8);
}
#size,#move,#auto-exclude-error {
    width: 17px;
    height: 17px;
    vertical-align: sub;
    margin: 0 4px 0 -4px;
}
li.line-through:has(>#size) {
    text-decoration: line-through;
}
#exclude,#more {
    position: relative;
}
#excludeList {
    display: none;
    list-style-type: none;
    top: 28px;
    left: 8px;
    width: 60px;
    text-align: center;
    border: #ccc 1px solid;
    border-radius: 3px;
    position: absolute;
    z-index: ${UI_zIndex - 4};
    background-color: #fff;
    margin: 0;
    padding: 0;
}
#excludeList.dark {
    color: #fff;
    background-color: #333;
}
.excludeItem {
    list-style: none;
    color: black;
    border: #ccc 1px solid;
    background-color: #f6f6f6;
    padding: 2px;
    margin: 2px;
}
.excludeItem.dark {
    color: #fff;
    background-color: #333;
    border: #eee 1px solid;
}
.excludeItem.active {
    color: #fff;
    background: #1790e6;
    text-decoration: line-through;
}
#excludeNum {
    display: none;
    color: white;
    font-size: 12px;
    line-height: 16px;
    text-align: center;
    background-color: #1790e6;
    position: absolute;
    top: -6px;
    left: 1px;
    width: 16px;
    height: 16px;
    border-radius: 8px;
    margin: 0;
    padding: 0;
    z-index: ${UI_zIndex - 4};
}
#more-menu {
    display: none;
    list-style-type: none;
    top: 28px;
    left: ${isCh ? "-13px" : "-26px"};
    width: ${isCh ? "100px" : "150px"};
    text-align: center;
    border: #ccc 1px solid;
    border-radius: 3px;
    position: absolute;
    z-index: ${UI_zIndex - 4};
    background-color: #fff;
    margin: 0;
    padding: 0;
}
#more-menu.dark {
    color: #fff;
    background-color: #333;
}
.more-item {
    list-style: none;
    color: black;
    border: #ccc 1px solid;
    background-color: #f6f6f6;
    padding: 2px;
    margin: 4px;
}
.more-item.dark {
    color: #fff;
    background-color: #333;
    border: #eee 1px solid;
}
img.single {
    width: auto;
    height: auto;
    max-width: calc(100% - 6px);
    max-height: calc(100vh - 6px);
    display: block;
    margin: 0 auto;
    border: solid #fff;
}
img.webtoon {
    width: 100%;
    height: auto;
    max-width: 800px;
    display: block;
    margin: 0 auto;
    border: unset;
}
#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,#list,a#next,a#prev,#scroll_U,#scroll_D,a#settings {
    position: fixed;
    z-index: ${UI_zIndex - 4};
    color: rgba(143, 143, 143);
    font-size: 40px;
    width: 48px;
    height: 48px;
    text-align: center;
    /*align-content: center;*/
    overflow: hidden;
    border: #555 1px solid;
    background: rgba(255, 255, 255, 0.8);
    border-radius: 12px;
    opacity: 0.8;
    backdrop-filter: saturate(5) blur(100px);
}
#homePage,a#favor,a#close {
    left: 20px;
}
#scroll_U,#scroll_D,a#settings {
    right: ${isPC ? "30px" : "20px"};
}
a#next {
    left: calc(50% + 40px);
    transform: rotate(90deg);
}
a#prev {
    left: calc(50% - 88px);
    transform: rotate(270deg);
}
a.mobile_toggle_filter_gallery_btn,a#download,#list {
    left: calc(50% - 24px);
}
#homePage,a.mobile_toggle_filter_gallery_btn,#scroll_U {
    bottom: 160px;
}
a#favor,#scroll_D,#list,a#next,a#prev {
    bottom: 100px;
}
#scroll_D {
    transform: rotate(180deg);
}
a#close,a#download,a#settings {
    bottom: 40px;
}
#homePage.dark,a#favor.dark,a#close.dark,a.mobile_toggle_filter_gallery_btn.dark,a#download.dark,#list.dark,a#next.dark,a#prev.dark,#scroll_U.dark,#scroll_D.dark,a#settings.dark {
    color: rgba(255, 255, 255, 0.8);
    border: rgb(0, 204, 255) 1px solid;
    background: rgb(37, 36, 44, 0.8);
    opacity: 0.8;
}
svg.icon {
    width: 40px;
    height: 40px;
    margin-top: 4px;
}
div#next {
    display: block;
    text-align: center;
    margin: 5px;
    padding: 10px 0;
    border: solid #bbb;
    border-radius: 6px;
    color: rgb(0, 0, 0);
    background-color: #7cffcb;
    background-image: linear-gradient(315deg, #7cffcb 0%, #74f2ce 74%);
    font-size: 26px;
    line-height: 40px;
    height: 40px;
    text-decoration: unset;
    cursor: pointer;
}
div#next.dark {
    border: solid #7cffcb;
}
#modal-content-list {
    background-color: #eee;
    position: fixed;
    z-index: ${UI_zIndex - 3};
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    padding: 10px;
    border: 1px solid #888;
    min-width: 350px;
    max-width: 600px;
    max-height: 76%;
    overflow-y: auto;
}
#modal-content-list.dark {
    background-color: #282828;
}
.closeModal {
    position: absolute;
    color: #000;
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
}
.closeModal.dark {
    color: #fff;
}
.chapter-list-container {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 20px;
    padding-top: 20px;
}
.chapter-btn {
    background-color: #fff;
    color: #000;
    border: 1px solid #a2a2a2;
    padding: 10px;
    cursor: pointer;
    border-radius: 5px;
    font-size: 13px;
    width: calc(33.3333% - 8px);
    box-sizing: border-box;
    text-align: center;
    overflow:hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}
.chapter-btn.dark {
    background-color: #3c3c3c;
    color: #fff;
    border: none;
}
.current-chapter,
.current-chapter.dark{
    background-color: #1790e6;
    color: #fff;
}
#chapters-footer {
    margin: 10px 0;
    display: flex;
    justify-content: flex-end;
}
#footer_close_button {
    display: block;
    width: 100%;
    color: #000;
    background-color: #ccc;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    padding: 10px;
    box-sizing: content-box;
    font-size: 16px;
    font-weight: 600;
}
#footer_close_button.dark {
    color: #fff;
    background-color: #454d55;
}
@media (max-width: 873px) {
    li.image-item {
        width: 194px;
        height: 194px;
    }
}
@media (max-width: 820px) {
    li.image-item {
        width: 194px;
        height: 194px;
    }
}
@media (max-width: 768px) {
    li.image-item {
        width: 181px;
        height: 181px;
    }
}
@media (max-width: 712px) {
    li.image-item {
        width: 167px;
        height: 167px;
    }
}
@media (max-width: 414px) {
    li.image-item {
        width: 192px;
        height: 192px;
    }
}
@media (max-width: 412px) {
    li.image-item {
        width: 191px;
        height: 191px;
    }
}
@media (max-width: 400px) {
    li.image-item {
        width: 182px;
        height: 182px;
    }
}
@media (max-width: 393px) {
    li.image-item {
        width: 182px;
        height: 182px;
    }
}
@media (max-width: 390px) {
    li.image-item {
        width: 180px;
        height: 180px;
    }
}
@media (max-width: 375px) {
    li.image-item {
        width: 173px;
        height: 173px;
    }
}
@media (max-width: 360px) {
    li.image-item {
        width: 165px;
        height: 165px;
    }
}
@media (max-width: 320px) {
    li.image-item {
        width: 145px;
        height: 145px;
    }
}`
		});

		const main = fn.ace(shadow, "div", {
			id: "main",
			tabIndex: "-1",
			innerHTML: `
<div id="filter_top" class="row">
    <div id="title">
        <label id="label-title">${DL.str_153}</label>
        <input type="text" id="inputTitle">
        <button id="close" class="close">${DL.str_132}</button>
    </div>
    <div class="buttons">
        <button class="mobile_toggle_filter_gallery_btn hide">${DL.str_188}</button>
        <button id="shadow_gallery">${DL.str_141.replace(/\(.\)/, "")}</button>
        <button id="tab_gallery">${DL.str_106.replace(/\(.\)/, "")}</button>
        <button id="favor">${DL.str_128.replace(/\(.\)/, "")}</button>
        <button id="exclude-error">${DL.str_184}</button>
        <button id="select-all">${DL.str_154}</button>
        <button id="unselect-all">${DL.str_155}</button>
        <button id="reverse-selection">${DL.str_170}</button>
        <button id="reload">${DL.str_156}</button>
        <button id="download">${DL.str_157}</button>
        <label class="number">${DL.str_169}<select id="colorThemes"></select></label>
        <label class="number">${DL.str_206}<select id="imageSize"></select></label>
        <label id="label-threading" class="number">${DL.str_161}<select id="threading"></select></label>
        <label id="exclude" class="number">${DL.str_183} ▼<p id=excludeNum>0</p><ul id="excludeList"></ul></label>
        <label class="number">${DL.str_167}<select id="width"></select></label>
        <label class="number">${DL.str_168}<select id="height"></select></label>
        <label id="filterNumber" class="number">${DL.str_166 + srcs.length}</label>
        <label id="total" class="number">${DL.str_165 + srcs.length}</label>
        <label id="more" class="number">${DL.str_186} ☰
            <ul id="more-menu">
                <li id="combineDownload" class="more-item" title="${DL.str_237}">${DL.str_181}</li>
                <li id="copy" class="more-item">${DL.str_105.replace(/\(.\)/, "")}</li>
                <li id="export" class="more-item">${DL.str_104.replace(/\(.\)/, "")}</li>
                <li id="export_json" class="more-item">${DL.str_193}</li>
                <li id="copy_md" class="more-item">${DL.str_194}</li>
                <li id="export_md" class="more-item">${DL.str_195}</li>
                <li id="reverse_sort" class="more-item">${DL.str_239}</li>
                <li class="more-item" title="${DL.str_173}"><input id="move" type="checkbox"></input>${DL.str_172}</li>
                <li class="more-item"><input id="auto-exclude-error" type="checkbox"></input>${DL.str_185}</li>
                <li class="more-item"><input id="size" type="checkbox"></input>${DL.str_171}</li>
                <li id="settings" class="more-item">${DL.str_85.replace(/\(.\)/, "")}</li>
            </ul>
        </label>
    </div>
</div>
<div id="imgBox" class="row">
    <ul id="image-list"></ul>
</div>
<div id="filter_bottom" class="row">
    <div class="buttons">
        <button id="settings">${DL.str_85.replace(/\(.\)/, "")}</button>
        <button class="mobile_toggle_filter_gallery_btn hide">${DL.str_188}</button>
        <button id="shadow_gallery">${DL.str_141.replace(/\(.\)/, "")}</button>
        <button id="tab_gallery">${DL.str_106.replace(/\(.\)/, "")}</button>
        <button id="favor">${DL.str_128.replace(/\(.\)/, "")}</button>
        <button id="copy">${DL.str_105.replace(/\(.\)/, "")}</button>
        <button id="export">${DL.str_104.replace(/\(.\)/, "")}</button>
        <button id="select-all">${DL.str_154}</button>
        <button id="unselect-all">${DL.str_155}</button>
        <button id="reverse-selection">${DL.str_170}</button>
        <button id="reverse_sort">${DL.str_239}</button>
        <button id="exclude-error">${DL.str_184}</button>
        <button id="reload">${DL.str_156}</button>
        <button id="combineDownload" title="${DL.str_237}">${DL.str_181}</button>
        <button id="download">${DL.str_157}</button>
        <button id="close">${DL.str_132}</button>
    </div>
</div>
<div id="gallery_top" class="row hide">
    <div class="buttons">
        <button class="mobile_toggle_filter_gallery_btn">${DL.str_158.replace(/\(.\)/, "")}</button>
        <button id="favor">${DL.str_128.replace(/\(.\)/, "")}</button>
        <button id="single" class="mode">${DL.str_189}</button>
        <button id="webtoon" class="mode">${DL.str_190}</button>
        <button id="close">${DL.str_132}</button>
    </div>
</div>
<div id="gallery_imgBox" class="hide"></div>
<div id="gallery_bottom" class="row hide">
    <div class="buttons">
        <button class="mobile_toggle_filter_gallery_btn">${DL.str_158.replace(/\(.\)/, "")}</button>
        <button id="favor">${DL.str_128.replace(/\(.\)/, "")}</button>
        <button id="single" class="mode">${DL.str_189}</button>
        <button id="webtoon" class="mode">${DL.str_190}</button>
        <button id="close">${DL.str_132}</button>
    </div>
</div>
<a id="homePage" class="hide" href="javascript:void(0);">
  ${svg.home}
</a>
<a id="favor" class="hide" href="javascript:void(0);">
  ${svg.heart}
</a>
<a id="close" class="hide" href="javascript:void(0);">
  ${svg.x}
</a>
<a class="mobile_toggle_filter_gallery_btn hide" href="javascript:void(0);">
  ${svg.control}
</a>
<a id="download" class="hide" href="javascript:void(0);">
  ${svg.download}
</a>
<a id="list" class="hide" href="javascript:void(0);">
  ${svg.list}
</a>
<a id="settings" class="hide" href="javascript:void(0);">
  ${svg.gear}
</a>`
		});

		const UDNP_Buttons = ["scroll_U", "scroll_D", "next", "prev"].map(id => {
			let html = `
<a id="${id}" class="hide" href="javascript:void(0);">
  ${svg.arrow}
</a>
            `;
			return fn.html(html);
		});
		main.append(...UDNP_Buttons);

		ge("#homePage", main).addEventListener("click", event => {
			cancelDefault(event);
			fn.showMsg(DL.str_223, 0);
			return (isGoToNext = true) && ("home" in siteData) ? (location.href = siteData.home) : (location.href = location.origin);
		});
		ge("#list", main).addEventListener("click", event => {
			cancelDefault(event);
			list_main.classList.remove("hide");
			isOpenChapterList = true;
			const button = ge(".current-chapter", list_main);
			list_main.scrollTop = button.offsetTop - (list_main.clientHeight / 2) + button.clientHeight;
		});
		ge("a#next", main).addEventListener("click", event => {
			cancelDefault(event);
			fn.showMsg(DL.str_34.n, 0);
			return (isGoToNext = true) && (location.href = nextLink);
		});
		ge("a#prev", main).addEventListener("click", event => {
			cancelDefault(event);
			if (isString(prevLink)) {
				fn.showMsg(DL.str_34.p, 0);
				return (isGoToPrev = true) && (location.href = prevLink);
			} else if (prevLink == 1) {
				fn.showMsg(DL.str_34.p);
				return history.back();
			}
		});
		ge("#scroll_U", main).addEventListener("click", event => {
			cancelDefault(event);
			instantScrollIntoView(ge(isViewMobileGallery ? "#gallery_top" : "#filter_top", main));
		});
		ge("#scroll_D", main).addEventListener("click", event => {
			cancelDefault(event);
			instantScrollIntoView(ge(isViewMobileGallery ? "#gallery_bottom" : "#filter_bottom", main));
		});

		let lastScrollTop = 0;
		main.addEventListener("scroll", event => {
			let imgBox;
			if (isViewMobileGallery) {
				imgBox = ge("#gallery_imgBox", main);
			} else {
				imgBox = ge("#imgBox", main);
			}
			if (isViewMobileGallery) {
				if (main.scrollTop > lastScrollTop) {
					for (let e of gae("#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,#list,a#next,a#prev,a#settings", main)) e.classList.add("hide");
				} else if (main.scrollTop < lastScrollTop) {
					if (chapterListObtained) {
						for (let e of gae("#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,#list,a#settings", main)) e.classList.remove("hide");
					} else {
						for (let e of gae("#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,a#settings", main)) e.classList.remove("hide");
					}
					if (isString(nextLink)) {
						ge("a#next", main).classList.remove("hide");
					}
					if (isString(prevLink)) {
						ge("a#prev", main).classList.remove("hide");
					}
				}
			}
			if (main.scrollTop > lastScrollTop) {
				for (let e of gae("#scroll_U,#scroll_D", main)) e.classList.add("hide");
			} else if (
				isPC && main.scrollTop < lastScrollTop && imgBox.offsetHeight > (innerHeight * 1.5) ||
				(isM || isMobileDeviceUA) && main.scrollTop < lastScrollTop
			) {
				for (let e of gae("#scroll_U,#scroll_D", main)) e.classList.remove("hide");
			}
			lastScrollTop = main.scrollTop;
		});

		closeFilter = () => {
			if (isCaptureMode) {
				updateEyeNum(full_srcs.length);
			}
			fn.remove("#overflowYHidden");
			shadowElement.remove();
			isOpenFilter = false;
			ViewerJsInstance?.destroy();
			ViewerJsInstance_G?.destroy();
		};

		const ui_selector = "#main,input,select,.row,.number,button:not(.chapter-btn),.image-item,.image-item p,#excludeList,.excludeItem,#more-menu,.more-item,#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,#list,a#next,a#prev,#scroll_U,#scroll_D,a#settings,#next,#modal-content-list,.closeModal,.chapter-btn,#footer_close_button";
		let inputs = [];
		let startInput;
		const updateInputs = (ul) => {
			inputs = gae("input", ul).map((input, index) => {
				input.dataset.index = index;
				return input;
			});
			startInput = null;
		};

		//參考https://syj0905.github.io/drag-drop-demo/
		//還原成原生JavaScript寫法
		const drag_sort_start = (event) => {
			const dragEle = event.target.closest("li");
			const list = event.target.closest("ul");
			const index = [...list.childNodes].indexOf(dragEle);
			event.dataTransfer.setData("text/plain", index);
		};

		const drop_sort = (event) => {
			const oldIndex = event.dataTransfer.getData("text/plain");
			const dropEle = event.target.closest("li");
			const list = event.target.closest("ul");
			const nodes = [...list.childNodes];
			const newIndex = nodes.indexOf(dropEle);
			const dragEle = nodes.at(oldIndex);
			if (newIndex < oldIndex) {
				dropEle.before(dragEle);
			} else if (newIndex > oldIndex) {
				dropEle.after(dragEle);
			}
			updateInputs(list);
		};

		let moreE = ge("#more", main);
		let moreMenu = ge("#more-menu", main);
		moreE.addEventListener("click", (event) => {
			if (event.target.id == "more") {
				cancelDefault(event);
				moreE.classList.toggle("active");
				moreMenu.classList.toggle("show");
			}
		});
		ge("#export_json", main).addEventListener("click", event => {
			cancelDefault(event);
			const srcs = gae(".select+.image", main).map(img => img.dataset.src);
			if (srcs.length == 0) return;
			const text = ge("#inputTitle", main).value;
			exportJsonFormat(srcs, text);
		});
		ge("#copy_md", main).addEventListener("click", event => {
			cancelDefault(event);
			const srcs = gae(".select+.image", main).map(img => img.dataset.src);
			if (srcs.length == 0) return;
			const text = ge("#inputTitle", main).value;
			copyMarkdownFormat(srcs, text);
		});
		ge("#export_md", main).addEventListener("click", event => {
			cancelDefault(event);
			const srcs = gae(".select+.image", main).map(img => img.dataset.src);
			if (srcs.length == 0) return;
			const text = ge("#inputTitle", main).value;
			exportMarkdownFormat(srcs, text);
		});

		if (isM || isMobileDeviceUA) {
			ge("li:has(>#move)", main).classList.add("hide");
			for (let e of gae("button.mobile_toggle_filter_gallery_btn", main)) e.classList.remove("hide");
		}

		let excludeE = ge("#exclude", main);
		let excludeList = ge("#excludeList", main);
		excludeE.addEventListener("click", (event) => {
			cancelDefault(event);
			excludeE.classList.toggle("active");
			excludeList.classList.toggle("show");
			excludeE.firstChild.textContent = DL.str_183 + (excludeE.classList.contains("active") ? " ▲" : " ▼");
		});
		for (let [k, v] of Object.entries(exclude_ex_config)) {
			const li = fn.ce("li", {
				className: "excludeItem",
				innerText: k.toUpperCase()
			});
			if (v == 1) {
				li.classList.add("active");
			}
			li.addEventListener("click", (event) => {
				cancelDefault(event);
				if (li.classList.contains("active")) {
					li.classList.remove("active");
					Reflect.set(exclude_ex_config, k, 0);
				} else {
					li.classList.add("active");
					Reflect.set(exclude_ex_config, k, 1);
				}
				_GM_setValue("exclude_ex_config", exclude_ex_config);
				exclude_ex_fn();
				addLis();
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
				widthSelect.value = 0;
				heightSelect.value = 0;
				ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
				let excludeActives = gae(".active", excludeE).length;
				let p = ge("#excludeNum", main);
				if (excludeActives > 0) {
					p.classList.add("show");
					p.innerText = excludeActives;
				} else {
					p.classList.remove("show");
				}
			});
			fragment.append(li);
		}
		excludeList.append(fragment);
		let excludeActives = gae(".active", excludeE).length;
		if (excludeActives > 0) {
			let p = ge("#excludeNum", main);
			p.classList.add("show");
			p.innerText = excludeActives;
		}

		let colorSelect = ge("#colorThemes", main);
		for (let [k, v] of Object.entries(DL.colorThemes)) colorSelect.append(new Option(v, k));

		colorSelect.value = config.colorThemes;
		colorSelect.addEventListener("change", () => {
			config.colorThemes = colorSelect.value;
			saveConfig(config);
			colorThemes = config.colorThemes;
			for (let e of gae(ui_selector, shadow)) e.classList.toggle("dark");
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		});

		let imageSizeSelect = ge("#imageSize", main);
		for (let i = -1; i <= 520; i++) imageSizeSelect.append(new Option(i < 0 ? DL.str_207 : i + 100, i));

		imageSizeSelect.value = image_size;
		imageSizeSelect.addEventListener("change", () => {
			image_size = Number(imageSizeSelect.value);
			_GM_setValue("image_size", image_size);
			if (image_size < 0) {
				for (let item of gae("#image-list .image-item", main)) {
					item.style.width = "";
					item.style.height = "";
				}
			} else {
				for (let item of gae("#image-list .image-item", main)) {
					item.style.width = image_size + 100 + "px";
					item.style.height = image_size + 100 + "px";
				}
			}
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		});

		if (colorThemes === "dark") {
			for (let e of gae(ui_selector, shadow)) e.classList.add("dark");
		}

		let widthNum = 0;
		let heightNum = 0;
		const updateFilterList = () => {
			let num = 0;
			for (let img of gae("#image-list img", main)) {
				if (!/^(blob|data)/.test(img.src) || img.classList.contains("loaded")) {
					const input = img.previousElementSibling;
					const parent = img.parentElement;
					let cw = img.naturalWidth >= widthNum;
					let ch = img.naturalHeight >= heightNum;
					if (cw && ch) {
						input.checked = true;
						input.classList.add("select");
						parent.classList.remove("hide");
						num += 1;
					} else {
						input.checked = false;
						input.classList.remove("select");
						parent.classList.add("hide");
					}
				}
			}
			ge("#filterNumber", main).innerText = DL.str_166 + num;
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		};

		let widthSelect = ge("#width", main);
		for (let i = 0; i <= 40; i++) {
			let option = new Option(i == 0 ? "All" : i * 100, i);
			fragment.append(option);
		}
		widthSelect.append(fragment);
		widthSelect.addEventListener("change", () => {
			widthNum = Number(widthSelect.value) * 100;
			updateFilterList();
			if (isM || isMobileDeviceUA) {
				update_g_srcs();
				addGalleryImgs();
			}
		});

		let heightSelect = ge("#height", main);
		for (let i = 0; i <= 40; i++) {
			let option = new Option(i == 0 ? "All" : i * 100, i);
			fragment.append(option);
		}
		heightSelect.append(fragment);
		heightSelect.addEventListener("change", () => {
			heightNum = Number(heightSelect.value) * 100;
			updateFilterList();
			if (isM || isMobileDeviceUA) {
				update_g_srcs();
				addGalleryImgs();
			}
		});

		let threadingSelect = ge("#threading", main);
		for (let i = 1; i <= 32; i++) fragment.append(new Option(i, i));
		threadingSelect.append(fragment);
		threadingSelect.value = config.threading;
		threadingSelect.addEventListener("change", () => {
			config.threading = Number(threadingSelect.value);
			saveConfig(config);
			addLis();
			if (isM || isMobileDeviceUA) {
				update_g_srcs();
				addGalleryImgs();
			}
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		});

		let titleReplace = fn.dt({
			s: "title"
		});
		ge("#inputTitle", main).value = (apiCustomTitle || customTitle || titleReplace);
		if (("SPA" in siteData) && ("customTitle" in siteData)) {
			ge("#inputTitle", main).value = await getTitle(siteData.customTitle);
		}
		for (let button of gae("#close", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				if (isCaptureMode) {
					updateEyeNum(full_srcs.length);
				}
				fn.remove("#overflowYHidden");
				shadowElement.remove();
				isOpenFilter = false;
				ViewerJsInstance?.destroy();
				ViewerJsInstance_G?.destroy();
			});
		}
		for (let button of gae("#settings", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				createPictureLoadOptionsShadowElement();
			});
		}
		for (let button of gae(".mobile_toggle_filter_gallery_btn", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let e of gae("#gallery_imgBox,.row", main)) e.classList.toggle("hide");
				isViewMobileGallery ? isViewMobileGallery = false : isViewMobileGallery = true;
				if (!isViewMobileGallery) {
					for (let e of gae("#homePage,a#favor,a#close,a.mobile_toggle_filter_gallery_btn,a#download,#list,a#next,a#prev,a#settings", main)) e.classList.add("hide");
				}
				const button = ge("#scroll_U", main);
				EClick(button);
			});
		}
		for (let e of gae("#" + config.MobileViewMode, main)) e.classList.add("active");
		for (let button of gae("button.mode", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let e of gae("button.mode", main)) e.classList.remove("active");
				for (let e of gae("#" + button.id, main)) e.classList.add("active");
				config.MobileViewMode = button.id;
				saveConfig(config);
				for (let e of gae("#gallery_imgBox img", main)) e.className = button.id;
			});
		}
		for (let button of gae("#shadow_gallery", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				if (event.ctrlKey || event.altKey || event.shiftKey) {
					createIframeGallery(srcs);
				} else {
					createShadowGallery(srcs);
				}
			});
		}
		for (let button of gae("#tab_gallery", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				newTabView(srcs);
			});
		}
		for (let button of gae("#favor", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				createFavorShadowElement();
			});
		}
		for (let button of gae("#copy", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				if (srcs.length == 0) return;
				const text = ge("#inputTitle", main).value;
				copyImgSrcTextB(srcs, text);
			});
		}
		for (let button of gae("#export", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				if (srcs.length == 0) return;
				const text = ge("#inputTitle", main).value;
				exportImgSrcText(srcs, text);
			});
		}
		for (let button of gae("#select-all", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let input of gae("input.check", main)) {
					input.checked = true;
					input.classList.add("select");
					ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
				}
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
			});
		}
		for (let button of gae("#unselect-all", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let input of gae("input.check", main)) {
					input.checked = false;
					input.classList.remove("select");
					ge("#filterNumber", main).innerText = DL.str_166 + "0";
				}
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
			});
		}
		for (let button of gae("#reverse-selection", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let input of gae("input.check", main)) {
					if (input.checked) {
						input.checked = false;
						input.classList.remove("select");
					} else {
						input.checked = true;
						input.classList.add("select");
					}
					const selects = gae(".select+.image", main);
					ge("#filterNumber", main).innerText = DL.str_166 + selects.length;
				}
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
			});
		}
		for (let button of gae("#exclude-error", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				for (let img of gae("#image-list img.error", main)) {
					img.previousElementSibling.checked = false;
					img.previousElementSibling.classList.remove("select");
					img.parentElement.classList.add("hide");
				}
				const selects = gae(".select+.image", main);
				ge("#filterNumber", main).innerText = DL.str_166 + selects.length;
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
			});
		}
		for (let button of gae("#reload", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				widthSelect.value = 0;
				heightSelect.value = 0;
				ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
				addLis();
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
			});
		}
		for (let button of gae("#combineDownload", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				if (srcs.length == 0) return;
				combineDownloadSwitch = true;
				const text = ge("#inputTitle", main).value;
				DownloadFn(srcs, text);
			});
		}
		for (let button of gae("#download", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const srcs = gae(".select+.image", main).map(img => img.dataset.src);
				if (srcs.length == 0) return;
				const text = ge("#inputTitle", main).value;
				DownloadFn(srcs, text);
			});
		}
		for (let button of gae("#reverse_sort", main)) {
			button.addEventListener("click", event => {
				cancelDefault(event);
				const lis = gae("#image-list li", main).reverse();
				fragment.append(...lis);
				const ul = ge("#image-list", main);
				ul.innerHTML = "";
				ul.append(fragment);
				updateInputs(ul);
			});
		}

		let inputAEE = ge("#auto-exclude-error", main);
		inputAEE.checked = config.aee == 0 ? false : true;
		inputAEE.addEventListener("change", () => {
			config.aee = inputAEE.checked ? 1 : 0;
			saveConfig(config);
			widthSelect.value = 0;
			heightSelect.value = 0;
			ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
			addLis();
			if (isM || isMobileDeviceUA) {
				update_g_srcs();
				addGalleryImgs();
			}
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		});
		let inputSize = ge("#size", main);
		if (config.noSize == 1) {
			inputSize.parentNode.classList.add("line-through");
		}
		inputSize.checked = showSize == 1 ? true : false;
		inputSize.addEventListener("change", () => {
			showSize = inputSize.checked ? 1 : 0;
			config.showSize = showSize;
			saveConfig(config);
			widthSelect.value = 0;
			heightSelect.value = 0;
			ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
			addLis();
			if (isM || isMobileDeviceUA) {
				update_g_srcs();
				addGalleryImgs();
			}
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
		});
		let inputMove = ge("#move", main);
		if (inputMove) {
			inputMove.checked = move == 1 ? true : false;
			inputMove.addEventListener("change", () => {
				move = inputMove.checked ? 1 : 0;
				config.move = move;
				saveConfig(config);
				widthSelect.value = 0;
				heightSelect.value = 0;
				ge("#filterNumber", main).innerText = DL.str_166 + srcs.length;
				addLis();
				if (isM || isMobileDeviceUA) {
					update_g_srcs();
					addGalleryImgs();
				}
				if (!isM && !isMobileDeviceUA) {
					main.focus();
				}
			});
		}
		const imageList = ge("#image-list", main);
		const ViewerOptions = {
			container: "html",
			navbar: false,
			title: false,
			initialCoverage: 0.99,
			interval: FancyboxSlideshowTimeoutNum,
			url: "data-src",
			ready: () => {
				for (let e of gae("html>.viewer-container")) e.removeAttribute("style");
			},
			viewed: (event) => instantScrollIntoView(event.detail.originalImage)
		};
		if (options.fancybox == 1 && ("Viewer" in _unsafeWindow)) {
			Viewer = _unsafeWindow.Viewer;
			ViewerJsInstance = new Viewer(imageList, ViewerOptions);
		}

		const addLis = () => {
			ge("#total", main).innerText = DL.str_165 + srcs.length;
			imageList.innerHTML = "";
			const loadImgList = [];
			inputs = [];
			for (const [index, src] of srcs.entries()) {
				const input = fn.ce("input", {
					className: "check select",
					dataset: {
						index
					},
					type: "checkbox",
					checked: true,
					onchange: () => {
						if (input.checked == true) {
							input.classList.add("select");
						} else {
							input.classList.remove("select");
						}
						const selects = gae(".select+.image", main);
						ge("#filterNumber", main).innerText = DL.str_166 + selects.length;
						if (isM || isMobileDeviceUA) {
							update_g_srcs();
							addGalleryImgs();
						}
					},
					onclick: event => {
						if ((event.ctrlKey || event.altKey || event.shiftKey) && isEle(startInput)) {
							let startNum = Number(startInput.dataset.index);
							let endNum = Number(event.target.dataset.index);
							if (startNum < endNum) {
								for (let i = startNum; i <= endNum; i++) {
									if (!inputs[i]?.parentElement?.classList.contains("hide")) {
										inputs[i].checked = true;
										inputs[i].classList.add("select");
									}
								}
							} else if (startNum > endNum) {
								for (let i = startNum; i >= endNum; i--) {
									if (!inputs[i]?.parentElement?.classList.contains("hide")) {
										inputs[i].checked = true;
										inputs[i].classList.add("select");
									}
								}
							}
							const selects = gae(".select+.image", main);
							ge("#filterNumber", main).innerText = DL.str_166 + selects.length;
						} else {
							startInput = event.target;
						}
					}
				});
				inputs.push(input);
				const img = new Image();
				img.className = "image";
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.dataset.index = index;
				img.src = loading_bak;
				img.dataset.src = src;
				img.onload = () => {
					if (img.classList.contains("loaded")) {
						if (move == 0 || isM || isMobileDeviceUA) {
							p.innerText = img.naturalWidth + " x " + img.naturalHeight;
						} else {
							p.innerText = (index + 1) + "P | " + img.naturalWidth + " x " + img.naturalHeight;
						}
						if (config.noSize != 1 && showSize != 0) {
							getFileSize(img.src, p, inputSize.parentNode);
						}
					}
					img.classList.remove("error");
				};
				img.onerror = (error) => {
					if (siteData?.name == "梦想岛") {
						if (!("load_jpg" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".jpg");
							error.target.dataset.load_jpg = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						} else if (!("load_png" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".png");
							error.target.dataset.load_png = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						} else if (!("load_jpeg" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".jpeg");
							error.target.dataset.load_jpeg = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						}
					}
					if (config.aee == 1) {
						input.checked = false;
						input.classList.remove("select");
						li.classList.add("hide");
						const selects = gae(".select+.image", main);
						ge("#filterNumber", main).innerText = DL.str_166 + selects.length;
						if (isM || isMobileDeviceUA) {
							update_g_srcs();
							addGalleryImgs();
						}
					}
					if (move == 0 || isM || isMobileDeviceUA) {
						p.innerText = "? x ?";
					} else {
						p.innerText = (index + 1) + "P | ? x ?";
					}
				};
				loadImgList.push(img);
				const p = fn.ce("p", {
					innerText: (move == 0 || isM || isMobileDeviceUA) ? "? x ?" : (index + 1) + "P | ? x ?"
				});
				const li = fn.ce("li", {
					className: "image-item"
				});
				if (image_size > -1) {
					li.style.width = image_size + 100 + "px";
					li.style.height = image_size + 100 + "px";
				}
				if (colorThemes === "dark") {
					p.classList.add("dark");
					li.classList.add("dark");
				}
				li.append(input);
				li.append(img);
				li.append(p);
				if (move != 0 && isPC) {
					li.setAttribute("draggable", true);
					li.addEventListener("dragstart", drag_sort_start);
					li.addEventListener("drop", drop_sort);
					li.addEventListener("dragenter", cancelDefault);
					li.addEventListener("dragover", cancelDefault);
				}
				fragment.append(li);
			}
			imageList.append(fragment);
			const imgBox = ge("#imgBox", main);
			if (imgBox.offsetHeight > (innerHeight * 1.5)) {
				for (let e of gae("#scroll_U,#scroll_D", main)) e.classList.remove("hide");
			}
			if (Viewer && ViewerJsInstance) {
				ViewerJsInstance.update();
			}
			if (!isM && !isMobileDeviceUA) {
				main.focus();
			}
			setTimeout(() => {
				f_queue = null;
				f_queue = new FunctionQueue(config.threading, simpleLoadImg, loadImgList);
			}, 200);
		};
		addLis();

		if (GalleryInIcon == 1 && options.shadowGallery == 1) {
			let button = ge("#shadow_gallery", main);
			EClick(button);
		}
		if (isPC && !isMobileDeviceUA) return;

		const gallery_imgBox = ge("#gallery_imgBox", main);
		if (options.fancybox == 1 && ("Viewer" in _unsafeWindow)) {
			ViewerJsInstance_G = new Viewer(gallery_imgBox, ViewerOptions);
		}
		const addGalleryImgs = () => {
			gallery_imgBox.innerHTML = "";
			const loadImgList = [];
			for (const [index, src] of g_srcs.entries()) {
				const img = new Image();
				img.className = ge("button.mode.active", main).id;
				if ("referrerpolicy" in siteData) {
					img.setAttribute("referrerpolicy", siteData.referrerpolicy);
				}
				img.dataset.index = index;
				img.src = loading_bak;
				img.dataset.src = src;
				img.onerror = (error) => {
					if (siteData?.name == "梦想岛") {
						if (!("load_jpg" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".jpg");
							error.target.dataset.load_jpg = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						} else if (!("load_png" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".png");
							error.target.dataset.load_png = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						} else if (!("load_jpeg" in error.target.dataset)) {
							let src = error.target.dataset.src.replace(/\.\w+$/i, ".jpeg");
							error.target.dataset.load_jpeg = 1;
							error.target.dataset.src = src;
							error.target.src = src;
						}
					}
				};
				loadImgList.push(img);
				fragment.append(img);
			}
			if (isString(nextLink)) {
				const next = fn.ace(fragment, "div", {
					id: "next",
					innerText: `${isComic ? DL.str_143 : DL.str_144}`,
					dataset: {
						url: nextLink
					},
					onclick: event => {
						cancelDefault(event);
						fn.showMsg(DL.str_34.n, 0);
						return (isGoToNext = true) && setTimeout(() => (location.href = nextLink), 200);
					}
				});
				if (colorThemes === "dark") {
					next.classList.add("dark");
				}
			}
			gallery_imgBox.append(fragment);
			if (Viewer && ViewerJsInstance_G) {
				ViewerJsInstance_G.update();
			}
			g_queue = null;
			g_queue = new FunctionQueue(config.threading, simpleLoadImg, loadImgList);
		};
		addGalleryImgs();
		if (enterGallery || options.mobileGallery == 1) {
			let button = ge(".mobile_toggle_filter_gallery_btn", main);
			EClick(button);
			if (gallery_imgBox.offsetHeight > innerHeight) {
				for (let e of gae("#scroll_U,#scroll_D", main)) e.classList.remove("hide");
			}
		}

		let list_main;

		if ("chapters" in siteData) {
			// 創建目錄
			const get_chapters = siteData.chapters;
			const createChapterList = async () => {
				let chapterListData = [];
				if (isObject(get_chapters)) {
					chapterListData = await fn.getChapters(get_chapters);
				} else if (isFn(get_chapters)) {
					chapterListData = await get_chapters();
				}
				if (!isArray(chapterListData) || !chapterListData?.length) return;
				if (isNumber(chapterListData?.length)) {
					if (chapterListData.length < 2) return;
				}
				chapterListObtained = true;
				const tempURLs = new Set();
				chapterListData = chapterListData.filter(({
					url
				}) => {
					if (tempURLs.has(url) || url == "#") {
						return false;
					} else {
						tempURLs.add(url);
					}
					return true;
				});
				list_main = fn.ace(shadow, "div", {
					id: "modal-content-list",
					className: config.colorThemes == "dark" ? "hide dark" : "hide"
				});
				fn.ace(list_main, "span", {
					className: config.colorThemes == "dark" ? "closeModal dark" : "closeModal",
					innerText: `× ${DL.str_132}`,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				const list_container = fn.ace(list_main, "div", {
					id: "chapterListContainer",
					className: "chapter-list-container"
				});
				const pathname = decodeURIComponent(fn.clp());
				const search = fn.cls();
				let isCurrent = false;
				let currentButton;
				const list = chapterListData.map(({
					text,
					url
				}) => {
					const button = fn.ce("button", {
						className: config.colorThemes == "dark" ? "chapter-btn dark" : "chapter-btn",
						innerText: text,
						dataset: {
							url
						}
					});
					if ("checkCurrentChapter" in siteData) {
						isCurrent = siteData.checkCurrentChapter(url, text);
					}
					if (
						isCurrent ||
						search && url.endsWith(search) ||
						!search && decodeURIComponent(url).endsWith(pathname) ||
						search.includes("page=") && url.includes(pathname)
					) {
						button.classList.add("current-chapter");
						currentButton = button;
					} else {
						button.addEventListener("click", (event) => {
							cancelDefault(event);
							//closeFilter();
							fn.showMsg(DL.str_218, 0);
							return (isGoToNext = true) && setTimeout(() => (location.href = button.dataset.url), 200);
						});
					}
					return button;
				});
				fragment.append(...list);
				list_container.append(fragment);
				const footer = fn.ace(list_main, "div", {
					id: "chapters-footer"
				});
				fn.ace(footer, "button", {
					id: "footer_close_button",
					className: config.colorThemes == "dark" ? "dark" : "",
					innerText: DL.str_132,
					onclick: () => {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				main.addEventListener("click", () => {
					if (isOpenChapterList) {
						list_main.classList.add("hide");
						isOpenChapterList = false;
					}
				});
				let prev_url = currentButton?.previousElementSibling?.dataset?.url;
				if (!isString(prevLink) && isString(prev_url) && prev_url != nextLink) {
					prevLink = prev_url;
				}
			};
			createChapterList();
		}
	};

	const getXY = (event) => {
		let x, y;
		if (event.type.includes("mouse")) {
			x = event.clientX;
			y = event.clientY;
		} else {
			x = event.changedTouches[0].clientX;
			y = event.changedTouches[0].clientY;
		}
		return {
			x: x,
			y: y
		}
	};

	//創建新分頁檢視眼睛圖示按鈕和圖片數量元素
	let viewImgDown = false;
	let isDragging = false;
	let isAddViewImgDraggEvent = false;
	let startX, startY, startLeft, startTop;
	let eventViewImg, eventMenu;
	let EyeNumElement;
	let eye_icon_top = _GM_getValue("eye_icon_top", "auto");
	let eye_icon_bottom = _GM_getValue("eye_icon_bottom", "24px");
	let eye_icon_left = _GM_getValue("eye_icon_left", "auto");
	let eye_icon_right = _GM_getValue("eye_icon_right", "24px");
	let eye_menu_top = _GM_getValue("eye_menu_top", "auto");
	let eye_menu_bottom = _GM_getValue("eye_menu_bottom", "22px");
	let eye_menu_left = _GM_getValue("eye_menu_left", "auto");
	let eye_menu_right = _GM_getValue("eye_menu_right", "64px");

	const eyeObserver = new IntersectionObserver((entries, observer) => {
		for (let entry of entries) {
			if (!entry.isIntersecting) {
				entry.target;
				entry.target.style.top = "auto";
				entry.target.style.bottom = "24px";
				entry.target.style.left = "auto";
				entry.target.style.right = "24px";
				eventMenu.style.top = "auto";
				eventMenu.style.bottom = "22px";
				eventMenu.style.left = "auto";
				eventMenu.style.right = "64px";
			}
		}
	});

	const addNewTabViewButton = () => {
		if (ge("#FullPictureLoadEye") || FullPictureLoadShowEye == 0) return;
		isAddNewTabViewButton = true;
		if ("page" in siteData && isFn(siteData.page)) {
			if (!siteData.page()) return;
		}
		let img = fn.ace("buttons", "img", {
			id: "FullPictureLoadEye",
			src: icon.eye,
			oncontextmenu: () => false,
			onclick: event => {
				cancelDefault(event);
				newTabView();
			}
		}, {
			top: eye_icon_top,
			bottom: eye_icon_bottom,
			left: eye_icon_left,
			right: eye_icon_right
		});
		eventViewImg = img;
		let menuDiv = fn.ace("buttons", "div", {
			id: "FullPictureLoadFixedMenuB",
		}, {
			top: eye_menu_top,
			bottom: eye_menu_bottom,
			left: eye_menu_left,
			right: eye_menu_right
		});
		EyeNumElement = fn.ace(menuDiv, "div", {
			id: "FullPictureLoadCaptureNum",
			innerText: "0",
			onclick: async event => {
				cancelDefault(event);
				let selector = siteData.capture || siteData.srcset || siteData.imgs;
				let srcArr = await getImgs(selector);
				if (srcArr.length == 0) return fn.showMsg(DL.str_44);
				let titleText = apiCustomTitle ?? customTitle ?? document.title;
				let picNum = srcArr.length;
				let fileName = `${titleText}[${picNum}P]_MediaURLs.txt`;
				if (videoSrcArray.length > 0) {
					srcArr = srcArr.concat(videoSrcArray);
					fileName = `${titleText}[${picNum}P + ${videoSrcArray.length}V]_MediaURLs.txt`;
				}
				let str = srcArr.join("\n");
				let blob = new Blob([str], {
					type: "text/plain",
					endings: "native"
				});
				saveData(blob, fileName);
				fn.showMsg(`${DL.str_101}`);
			}
		});
		eventMenu = menuDiv;
		eyeObserver.observe(img);

		const downEvent = (event) => {
			const obj = getXY(event);
			viewImgDown = true;
			startX = obj.x;
			startY = obj.y;
			startLeft = eventViewImg.offsetLeft;
			startTop = eventViewImg.offsetTop;
		};

		const moveEvent = (event) => {
			if (!viewImgDown) return;
			cancelDefault(event);
			const obj = getXY(event);
			isDragging = true;
			const dx = obj.x - startX;
			const dy = obj.y - startY;
			eye_icon_top = "auto";
			eye_icon_bottom = (_unsafeWindow.innerHeight - (startTop + dy + (isM ? 16 : 32))) + "px";
			eye_icon_left = "auto";
			eye_icon_right = (_unsafeWindow.innerWidth - (startLeft + dx + (isM ? 16 : 48))) + "px";
			_GM_setValue("eye_icon_top", eye_icon_top);
			_GM_setValue("eye_icon_bottom", eye_icon_bottom);
			_GM_setValue("eye_icon_left", eye_icon_left);
			_GM_setValue("eye_icon_right", eye_icon_right)
			eventViewImg.style.top = eye_icon_top;
			eventViewImg.style.bottom = eye_icon_bottom;
			eventViewImg.style.left = eye_icon_left;
			eventViewImg.style.right = eye_icon_right;
			eye_menu_top = "auto";
			eye_menu_bottom = (_unsafeWindow.innerHeight - (startTop + dy + (isM ? -16 : 0) + (eventMenu.offsetHeight - ((eventMenu.offsetHeight - eventViewImg.offsetHeight) / 2)))) + "px";
			eye_menu_left = "auto";
			eye_menu_right = (_unsafeWindow.innerWidth - (startLeft + dx + (isM ? -24 : 8))) + "px";
			_GM_setValue("eye_menu_top", eye_menu_top);
			_GM_setValue("eye_menu_bottom", eye_menu_bottom);
			_GM_setValue("eye_menu_left", eye_menu_left);
			_GM_setValue("eye_menu_right", eye_menu_right);
			eventMenu.style.opacity = "0";
			eventMenu.style.top = eye_menu_top;
			eventMenu.style.bottom = eye_menu_bottom;
			eventMenu.style.left = eye_menu_left;
			eventMenu.style.right = eye_menu_right;
		};

		const upEvent = (event) => {
			eventMenu.style.opacity = "1";
			viewImgDown = false;
			setTimeout(() => {
				isDragging = false;
			}, 100);
		};

		if (isM) {
			img.addEventListener("touchstart", downEvent, {
				passive: false,
				capture: true
			});
			if (!isAddViewImgDraggEvent) {
				isAddViewImgDraggEvent = true;
				document.addEventListener("touchmove", moveEvent, {
					passive: false,
					capture: true
				});
				document.addEventListener("touchend", upEvent);
			}
		} else {
			img.addEventListener("mousedown", downEvent);
			if (!isAddViewImgDraggEvent) {
				isAddViewImgDraggEvent = true;
				document.addEventListener("mousemove", moveEvent);
				document.addEventListener("mouseup", upEvent);
			}
		}

	};

	const updateEyeNum = (num) => {
		if (isEle(EyeNumElement)) {
			let text;
			if (videoSrcArray.length) {
				text = `${num}P | ${videoSrcArray.length}V`;
			} else {
				text = num;
			}
			EyeNumElement.innerText = text;
		}
	};

	//清除圖片縮放級別
	const cancelZoom = () => {
		if (isFetching || !siteData.insertImg || isOpenOptionsUI) return;
		if (ge(".FullPictureLoadImage:not(.small)")) {
			options.zoom = 0;
			let jsonStr = JSON.stringify(options);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
			for (let img of gae(".FullPictureLoadImage:not(.small)")) {
				img.style.width = "";
				let pE = img.parentNode;
				if (pE.nodeName === "A") {
					pE.style.width = "";
				}
			}
			fn.showMsg(DL.str_61);
		}
	};

	//創建腳本在頁面左下的功能按鈕
	let imgDown = false;
	let isAddDraggEvent = false;
	let eventImg;
	let icon_top = _GM_getValue("icon_top", "auto");
	let icon_bottom = _GM_getValue("icon_bottom", "24px");
	let icon_left = _GM_getValue("icon_left", "24px");
	let icon_right = _GM_getValue("icon_right", "auto");

	const iconObserver = new IntersectionObserver((entries, observer) => {
		for (let entry of entries) {
			if (!entry.isIntersecting) {
				entry.target.style.top = "auto";
				entry.target.style.bottom = "24px";
				entry.target.style.left = "24px";
				entry.target.style.right = "auto";
			}
		}
	});

	const addFullPictureLoadButton = () => {
		if (ge("#FullPictureLoad")) return;
		isAddFullPictureLoadButton = true;
		if ("page" in siteData && isFn(siteData.page)) {
			if (!siteData.page()) return;
		}
		let img = fn.ace("buttons", "img", {
			id: "FullPictureLoad",
			className: "FullPictureLoadFixedBtn",
			src: icon.main,
			onclick: event => {
				cancelDefault(event);
				createFilterUI();
			}
		}, {
			top: icon_top,
			bottom: icon_bottom,
			left: icon_left,
			right: icon_right,
		});
		if (!isSimpleMode) {
			img.setAttribute("title", DL.str_47);
			img.oncontextmenu = () => false;
			img.addEventListener("mousedown", event => {
				if (event.button == 1) {
					cancelDefault(event);
					exportImgSrcText();
				}
				if (event.button == 2) {
					cancelDefault(event);
					copyImgSrcText();
				}
			});
		}
		eventImg = img;
		iconObserver.observe(img);

		if ("insertImg" in siteData) {
			fn.ace("buttons", "img", {
				id: "FullPictureLoadGoToFirstImage",
				className: "FullPictureLoadFixedBtn",
				src: icon.arrow_u,
				title: DL.str_62,
				oncontextmenu: () => false,
				onclick: event => {
					cancelDefault(event);
					goToImg("first");
				}
			}, {
				display: "none"
			});
			fn.ace("buttons", "img", {
				id: "FullPictureLoadGoToLastImage",
				className: "FullPictureLoadFixedBtn",
				src: icon.arrow_u,
				title: DL.str_63,
				oncontextmenu: () => false,
				onclick: event => {
					cancelDefault(event);
					goToImg("last");
				}
			}, {
				display: "none"
			});
		}

		const downEvent = (event) => {
			const obj = getXY(event);
			imgDown = true;
			startX = obj.x;
			startY = obj.y;
			startLeft = eventImg.offsetLeft;
			startTop = eventImg.offsetTop;
		};

		const moveEvent = (event) => {
			if (!imgDown) return;
			cancelDefault(event);
			const obj = getXY(event);
			isDragging = true;
			const dx = obj.x - startX;
			const dy = obj.y - startY;
			icon_top = "auto";
			icon_bottom = (_unsafeWindow.innerHeight - (startTop + dy + (isM ? 16 : 32))) + "px";
			icon_left = (startLeft + dx - (isM ? 16 : 0)) + "px";
			icon_right = "auto";
			_GM_setValue("icon_top", icon_top);
			_GM_setValue("icon_bottom", icon_bottom);
			_GM_setValue("icon_left", icon_left);
			_GM_setValue("icon_right", icon_right);
			eventImg.style.top = icon_top;
			eventImg.style.bottom = icon_bottom;
			eventImg.style.left = icon_left;
			eventImg.style.right = icon_right;
		};

		const upEvent = (event) => {
			imgDown = false;
			setTimeout(() => {
				isDragging = false;
			}, 100);
		};

		if (isM) {
			img.addEventListener("touchstart", downEvent, {
				passive: false,
				capture: true
			});
			if (!isAddDraggEvent) {
				isAddDraggEvent = true;
				document.addEventListener("touchmove", moveEvent, {
					passive: false,
					capture: true
				});
				document.addEventListener("touchend", upEvent);
			}
		} else {
			img.addEventListener("mousedown", downEvent);
			if (!isAddDraggEvent) {
				isAddDraggEvent = true;
				document.addEventListener("mousemove", moveEvent);
				document.addEventListener("mouseup", upEvent);
			}
		}

	};

	//創建浮動選單
	const addFullPictureLoadFixedMenu = () => {
		if (ge("#FullPictureLoadFixedMenu")) return;
		isAddFullPictureLoadFixedMenu = true;
		if ("page" in siteData && isFn(siteData.page)) {
			if (!siteData.page()) return;
		}
		let menu = fn.ace("bodya", "div", {
			id: "FullPictureLoadFixedMenu",
			onmouseenter: () => {
				isOpenMenu = true;
				for (let e of fn.gae(".itemNoShow", menu)) {
					e.classList.remove("itemNoShow");
					e.classList.add("itemShow");
					e.width = "122px";
				}
				menu.style.width = "134px";
				menu.lastChild.width = "122px";
				menu.lastChild.innerText = DL.str_134;
			},
			onmouseleave: () => {
				for (let e of fn.gae(".itemShow", menu)) {
					e.classList.remove("itemShow");
					e.classList.add("itemNoShow");
					e.width = "44px";
				}
				menu.style.width = "54px";
				menu.lastChild.width = "44px";
				menu.lastChild.innerText = DL.str_133;
				setTimeout(() => (isOpenMenu = false), 200);
			}
		}, {
			width: "54px"
		});
		const menuObj = [{
			text: DL.str_128,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				createFavorShadowElement();
			}
		}, {
			no_s: 1,
			name: "shadowGallery",
			text: DL.str_141,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				createShadowGallery();
			}
		}, {
			no_s: 1,
			name: "newTabView",
			text: DL.str_106,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				newTabView();
			}
		}, {
			text: DL.str_158,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				createFilterUI();
			}
		}, {
			no_s: 1,
			text: DL.str_107,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				fastDownloadSwitch = true;
				DownloadFn();
			}
		}, {
			no_s: 1,
			text: DL.str_174,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				exportJsonFormat();
			}
		}, {
			no_s: 1,
			text: DL.str_176,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				exportMarkdownFormat();
			}
		}, {
			no_s: 1,
			text: DL.str_178,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				copyMarkdownFormat();
			}
		}, {
			no_s: 1,
			text: DL.str_104,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				exportImgSrcText();
			}
		}, {
			no_s: 1,
			text: DL.str_105,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				copyImgSrcTextB();
			}
		}, {
			no_s: 1,
			name: "fn",
			text: DL.str_159,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				siteData.fn();
			}
		}, {
			no_s: 1,
			name: "zoom",
			text: DL.str_88,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				fn.clearSetTimeout();
				cancelZoom();
			}
		}, {
			no_s: 1,
			name: "zoom",
			text: DL.str_87,
			title: DL.str_136,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				fn.clearSetTimeout();
				reduceZoom();
			},
			mfn: event => {
				if (event.button == 2) {
					cancelDefault(event);
					increaseZoom();
				}
			}
		}, {
			no_s: 1,
			name: "toggleImgMode",
			text: DL.str_86,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				toggleImgMode();
			}
		}, {
			no_s: 1,
			name: "insert",
			id: "insertImgMenu",
			text: DL.str_160,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				fn.immediateInsertImg("yes");
			}
		}, {
			text: DL.str_85,
			show: 0,
			cfn: event => {
				cancelDefault(event);
				createPictureLoadOptionsShadowElement();
			}
		}, {
			text: DL.str_133,
			show: 1
		}];
		const createMenu = obj => {
			if (
				!("insertImg" in siteData) && obj.name === "insert" ||
				!("fn" in siteData) && obj.name === "fn" ||
				!siteData.insertImg && ["toggleImgMode", "zoom"].some(e => e === obj.name) ||
				"newTabView" === obj.name && siteData.eye === 0 ||
				isSimpleMode && ("no_s" in obj)
			) return;
			let item = fn.ace(fragment, "div", {
				id: ("id" in obj) ? obj.id : "",
				title: ("title" in obj) ? obj.title : "",
				innerText: obj.text,
				oncontextmenu: () => false,
				onclick: ("cfn" in obj) ? obj.cfn : null,
				onmousedown: ("mfn" in obj) ? obj.mfn : null,
			});
			if (obj.show === 0) item.classList.add("itemNoShow");
			if (["toggleImgMode", "zoom"].some(e => e === obj.name)) {
				item.classList.add(obj.name);
				item.style.display = "none";
			};
		};
		[...menuObj].forEach(createMenu);
		menu.append(fragment);
	};

	//元素模擬點擊
	const EClick = obj => {
		const event = new MouseEvent("click", {
			bubbles: true,
			cancelable: true,
			view: _unsafeWindow
		});
		if (isEle(obj)) {
			obj.dispatchEvent(event);
		} else if (isString(obj)) {
			let ele = fn.ge(obj);
			if (isEle(ele)) {
				ele.dispatchEvent(event);
			} else {
				if (!("loopClick" in siteData)) {
					console.error("EClick點擊元素參數錯誤", obj);
				}
			}
		}
	};

	//創建返回頂部按鈕
	const addReturnTopButton = () => {
		if (ge("FullPictureLoadImageReturnTop")) return;
		let a = fn.ace("buttons", "a", {
			href: "javascript:void(0);",
			onclick: () => window.scrollTo({
				top: 0,
				behavior: 'smooth'
			})
		});
		fn.ace(a, "img", {
			src: icon.top,
			className: "FullPictureLoadImageReturnTop"
		});
	};

	//列出一般圖片站
	const photoData = customData.filter(item => item.category === "photo");
	//列出寫真站
	const nsfw1Data = customData.filter(item => item.category === "nsfw1");
	//列出老司機站
	const nsfw2Data = customData.filter(item => item.category === "nsfw2");
	//列出漫畫站
	const comicData = customData.filter(item => item.category === "comic");
	//列出H漫站
	const hcomicData = customData.filter(item => item.category === "hcomic");
	//列出自動翻頁
	const autoPagerData = customData.filter(item => item.category.includes("autoPager"));
	//列出去廣告規則
	const AD_Data = customData.filter(item => item.category === "ad");
	//列出未分類
	const noneData = customData.filter(item => item.category === "none");

	let topDistance = () => {};

	//創建腳本選項元素
	const createPictureLoadOptionsShadowElement = () => {

		if (isOpenOptionsUI) return;

		isOpenOptionsUI = true;

		const config = getConfig();

		const mainElement = fn.ace("bodya", "div", {
			id: "FullPictureLoadOptionsShadowElement",
			style: "display: initial !important;position: fixed !important;"
		});
		const shadow = mainElement.attachShadow({
			mode: "closed"
		});

		fn.ace(shadow, "style", {
			type: "text/css",
			innerHTML: `
#FullPictureLoadOptions {
    font-size: 14px;
    line-height: initial;
    user-select: none;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    text-align: center;
    width: 374px;
    height: auto;
    position: fixed;
    top: 10%;
    left: calc((100% - 376px) / 2);
    border: 1px solid #a0a0a0;
    border-radius: 3px;
    box-shadow: -2px 2px 5px rgb(0 0 0 / 30%);
    background-color: #eee;
    padding-bottom: 6px;
    z-index: ${UI_zIndex - 1};
}

#FullPictureLoadOptions label {
    margin: 0px;
    padding: 0px;
}

#FullPictureLoadOptions select {
    border: 1px solid #a0a0a0;
    background-color: transparent;
    border-radius: 0px;
    min-width: 60px;
    height: unset;
    -webkit-box-shadow: unset;
    box-shadow: unset;
    -webkit-appearance: auto;
    appearance: auto;
    background-image: unset;
    display: inline-block;
    margin: 0px;
    padding: ${isFirefox ? "0 0 0 4px" : "0px"};
}

#FullPictureLoadOptions *:not(.row,.item,#mypopover) {
    font: unset;
    font-weight: 500;
    color: #000;
    float: none;
    line-height: 22px;
    margin-bottom: 0px;
    padding: 1px 4px;
    width: auto;
}

#FullPictureLoadOptions #title {
    padding: 4px 4px 0px 4px;
}

#FullPictureLoadOptions button {
    width: auto;
    height: 26px;
    line-height: 20px;
    min-width: 102px;
    max-width: 110px;
    min-height: unset;
    max-height: 26px;
    margin: 0 2px 4px 2px;
    display: inline-block;
    color: #000000;
    border: 1px solid #a0a0a0;
    background-color: transparent;
    border-radius: unset;
}

#FullPictureLoadOptions input {
    width: 16px !important;
    height: 17px;
    margin: 4px 0px 0 6px;
    position: unset;
    opacity: 1;
    pointer-events: auto;
    border: 1px solid #a0a0a0;
    border-radius: unset;
    background-color: transparent;
    outline: unset;
    display: unset;
    -webkit-appearance: auto;
}

#FullPictureLoadOptions p {
    width: calc(100% - 16px);
    text-align: center;
    margin-block-start: 0px;
    margin-block-end: 0px;
    margin-inline-start: 0px;
    margin-inline-end: 0px;
}

#FullPictureLoadOptions .tip {
    color: #0075ff !important;
    cursor: help;
}

#FullPictureLoadOptions #tabs {
    padding: 0 0 0 10px;
}

#FullPictureLoadOptions .tab {
    cursor: pointer;
    background-color: #ccc;
    border-top-left-radius: 6px;
    border-top-right-radius: 6px;
    padding: 4px;
    color: #333;
    border-bottom: 3px solid rgb(90, 100, 80);
    overflow: hidden;
}

#FullPictureLoadOptions .tab.active {
    padding: 4px 8px;
    background-color: rgb(255, 255, 255);
    color: rgb(51, 51, 51);
    font-weight: bold;
    border-bottom: 3px solid rgb(255, 111, 97);
}

#FullPictureLoadOptions .tab.active::before {
    content: "⭐";
    font-size: 1em;
    padding-right: 2px;
}

#FullPictureLoadOptions .hide {
    display: none !important;
}

#FullPictureLoadOptions .row {
    text-align: left;
    margin: 5px 0px;
    padding: 4px 0 0 4px;
}

#FullPictureLoadOptions .set {
    min-height: 170px;
}

#FullPictureLoadOptions .item {
    /*width: 354px;*/
    margin-bottom: 4px;
    display: flex;
}

#FullPictureLoadOptions .ml {
    margin-left: 3px;
}

#mypopover {
    text-align: left;
    font-size: 11px;
    background-color: #eee;
    border: 1px solid #a0a0a0;
    box-shadow: -2px 2px 5px rgb(0 0 0 / 30%);
}`
		});

		const main = fn.ace(shadow, "div", {
			id: "FullPictureLoadOptions",
			innerHTML: `
<div style="width: 100%;">
    <p id="title">${DL.str_68}</p>
</div>
<div id="tabs" class="row">
    <span id="page_tab" class="tab active">${DL.tab.p}</span>
    <span id="gallery_tab" class="tab">${DL.tab.g}</span>
    <span id="lightbox_tab" class="tab">${DL.tab.l}</span>
    <span id="download_tab" class="tab">${DL.tab.d}</span>
    <span id="other_tab" class="tab">${DL.tab.o}</span>
</div>
<div id="page" class="row set">
    <div id="iconDIV" class="item">
        <input id="icon" type="checkbox">
        <label>${DL.str_69}</label>
    </div>
    <div id="ShowEyeDIV" class="item" style="display: none;">
        <input id="ShowEye" type="checkbox">
        <label>${DL.str_123}</label>
    </div>
    <div id="ShowFixedMenuDIV" class="item">
        <input id="ShowFixedMenu" type="checkbox">
        <label>※ ${DL.str_117}</label>
    </div>
    <div class="item ml">
        <label>${DL.str_108}</label>
        <select id="MsgPos"></select>
    </div>
    <div id="AutoInsertImgDIV" class="item">
        <input id="AutoInsertImg" type="checkbox">
        <label>${DL.str_139}</label>
    </div>
    <div id="GoToFirstDIV" class="item">
        <input id="GoToFirst" type="checkbox">
        <label>※ ${DL.str_115}</label>
    </div>
    <div id="noPageNavDIV" class="item">
        <input id="noPageNav" type="checkbox">
        <label>※ ${DL.str_121}</label>
    </div>
    <div id="ZoomDIV" class="item ml">
        <label>${DL.str_79}</label>
        <select id="Zoom"></select>
    </div>
    <div id="viewModeDIV" class="item">
        <input id="viewMode" type="checkbox">
        <label>※ ${DL.str_103}</label>
    </div>
    <div id="ColumnDIV" class="item ml">
        <label>${DL.str_80}</label>
        <select id="Column" title="${DL.str_81}"></select>
    </div>
    <div id="InfiniteDIV" class="item">
        <input id="InfiniteMode" type="checkbox">
        <label>${DL.str_122}</label>
    </div>
</div>
<div id="gallery" class="row set hide">
    <div id="ShadowGalleryModeDIV" class="item">
        <input id="ShadowGalleryMode" type="checkbox">
        <label>${DL.str_140}</label>
    </div>
    <div id="MobileGalleryModeDIV" class="item">
        <input id="MobileGalleryMode" type="checkbox">
        <label>${DL.str_192}</label>
    </div>
    <div id="GalleryInIconDIV" class="item">
        <input id="GalleryInIcon" type="checkbox">
        <label>※ ${DL.str_77}</label>
    </div>
    <div id="ShadowGalleryloopViewDIV" class="item">
        <input id="loopView" type="checkbox">
        <label>${DL.str_182}</label>
    </div>
    <div id="ShadowGalleryWheelDIV" class="item ml">
        <label>${DL.str_147}</label>
        <select id="ShadowGalleryWheel"></select>
    </div>
    <div id="horizontalWheelDIV" class="item ml">
        <label>${DL.str_198}</label>
        <select id="horizontalWheel"></select>
    </div>
</div>
<div id="lightbox" class="row set hide">
    <div id="FancyboxDIV" class="item">
        <input id="Fancybox" type="checkbox">
        <label>${DL.str_78}</label>
    </div>
    <div id="FancyboxIdleDIV" class="item ml">
        <label>※ ${DL.str_119}:</label>
        <select id="FancyboxIdle"></select>
    </div>
    <div id="FancyboxWheelDIV" class="item ml">
        <label>※ ${DL.str_146}</label>
        <select id="FancyboxWheel"></select>
    </div>
    <div id="FancyboxSlideshowTimeoutDIV" class="item ml">
        <label>※ ${DL.str_145}</label>
        <select id="FancyboxSlideshowTimeout"></select>
    </div>
    <div id="FancyboxTransitionDIV" class="item ml">
        <label>※ ${DL.str_148}</label>
        <select id="FancyboxTransition"></select>
    </div>
    <div class="item">
        <input id="FancyboxShowThumbs" type="checkbox">
        <label>※ ${DL.str_240}</label>
    </div>
    <div id="FancyboxThumbnailsDIV" class="item ml">
        <label>※ ${DL.str_241}:</label>
        <select id="FancyboxThumbnails"></select>
    </div>
    <div class="item">
        <input id="FancyboxAutoClose" type="checkbox">
        <label>※ ${DL.str_210}</label>
    </div>
    <div class="item">
        <input id="FancyboxAutoNext" type="checkbox">
        <label>※ ${DL.str_211}</label>
    </div>
    <div class="item">
        <input id="Viewer" type="checkbox">
        <label>${DL.str_120}</label>
    </div>
</div>
<div id="download" class="row set hide">
    <div class="item ml" title="${DL.str_215}">
        <label>※ ${DL.str_214}:</label>
        <select id="DownloadAPI"></select>
        <span id="DownloadAPITIP" class="tip">${DL.str_203}</span>
    </div>
    <div id="AutoDownloadDIV" class="item" title="${DL.str_74}">
        <input id="AutoDownload" type="checkbox">
        <label>${DL.str_73}</label>
        <span id="AutoDownloadTIP" class="tip">${DL.str_203}</span>
    </div>
    <div id="CountdownDIV" class="item ml">
        <label>${DL.str_75}</label>
        <select id="Countdown"></select>
    </div>
    <div class="item ml">
        <label>${DL.str_70}</label>
        <select id="Threading"></select>
    </div>
    <div class="item ml">
        <label>${DL.str_238}</label>
        <select id="SingleThreadInterval"></select>
    </div>
    <div class="item ml">
        <label>${DL.str_231}</label>
        <select id="Retry"></select>
    </div>
    <div class="item ml">
        <label>${DL.str_232}</label>
        <select id="Interval"></select>
    </div>
    <div class="item ml" title="${DL.str_237}\n${DL.str_233}:\nhttps://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/canvas\nhttps://jhildenbiddle.github.io/canvas-size/#/?id=test-results">
        <label>${DL.str_234}:</label>
        <select id="Limit"></select>
        <span id="LimitTIP" class="tip">${DL.str_203}</span>
    </div>
    <div class="item">
        <input id="Zip" type="checkbox">
        <label>${DL.str_71}</label>
    </div>
    <div class="item">
        <input id="zipFolder" type="checkbox">
        <label>※ ${DL.str_187}</label>
    </div>
    <div class="item ml">
        <label>※ ${DL.str_72}</label>
        <select id="Extension"></select>
    </div>
    <div class="item">
        <input id="ConvertWEBP" type="checkbox">
        <label>※ ${DL.str_110}</label>
    </div>
    <div class="item">
        <input id="ConvertAVIF" type="checkbox">
        <label>※ ${DL.str_200}</label>
    </div>
    <div class="item ml">
        <label>※ ${DL.str_201}:</label>
        <select id="Quality"></select>
    </div>
    <div id="CustomDownloadVideoDIV" class="item" style="display: none;">
        <input id="CustomDownloadVideo" type="checkbox">
        <label>${DL.str_124}</label>
    </div>
</div>
<div id="other" class="row set hide">
    <div class="item ml">
        <label>${DL.str_00}:</label>
        <select id="language"></select>
    </div>
    <div class="item">
        <input id="FavorNewTab" type="checkbox">
        <label>※ ${DL.str_50}</label>
    </div>
    <div id="autoExportDIV" class="item">
        <input id="autoExport" type="checkbox">
        <label>${DL.str_180}</label>
    </div>
    <div id="ComicDIV" class="item" style="display: none;">
        <input id="Comic" type="checkbox">
        <label>${DL.str_76}</label>
    </div>
    <div id="DoubleDIV" class="item">
        <input id="Double" type="checkbox">
        <label>※ ${DL.str_199}</label>
    </div>
    <div id="YinawDIV" class="item">
        <input id="Yinaw" type="checkbox">
        <label>※ 壹纳网使用原始新浪图床链接</label>
    </div>
    <div id="EHentaiDIV" class="item">
        <input id="EHentai" type="checkbox">
        <label>※ ${DL.str_114}</label>
    </div>
    <div id="ManhuaguiDIV" class="item ml">
        <label>※ Manhuagui漫画柜图片服务器</label>
        <select id="Manhuagui"></select>
    </div>
    <div id="HitomiDIV" class="item ml">
        <label>※ ${DL.str_202}</label>
        <select id="Hitomi"></select>
    </div>
    <div id="CDNDIV" class="item ml">
        <label>${DL.str_208}:</label>
        <select id="cdn"></select>
    </div>
</div>
<button id="CancelBtn">${(isOpenGallery || isOpenFilter || isAutoPager) ? DL.str_82.replace(" (Esc)", "") : DL.str_82}</button>
<button id="ResetBtn">${DL.str_83}</button>
<button id="SaveBtn">${DL.str_84}</button>
<div id="mypopover" popover></div>`
		});

		const tab_toggle = (event, id) => {
			cancelDefault(event);
			for (let e of gae(".tab", main)) e.classList.remove("active");
			for (let e of gae(".set", main)) e.classList.add("hide");
			event.target.classList.add("active");
			ge(id, main).classList.remove("hide");
			topDistance();
		};

		ge("#page_tab", main).addEventListener("click", event => tab_toggle(event, "#page"));
		ge("#gallery_tab", main).addEventListener("click", event => tab_toggle(event, "#gallery"));
		ge("#lightbox_tab", main).addEventListener("click", event => tab_toggle(event, "#lightbox"));
		ge("#download_tab", main).addEventListener("click", event => tab_toggle(event, "#download"));
		ge("#other_tab", main).addEventListener("click", event => tab_toggle(event, "#other"));

		if (isM && ("popover" in HTMLElement.prototype)) {
			let popover = ge("#mypopover", main);
			for (let tip of gae(".tip", main)) {
				tip.addEventListener("click", event => {
					let text = event.target.closest("div").title;
					popover.innerText = text;
					popover.togglePopover();
				});
			}
		}

		const languageSelect = ge("#language", main);
		for (let v of ["UI", "zh", "TW", "EN"]) {
			let option;
			if (v == "UI") {
				option = new Option("Browser UI", v);
			} else if (v == "zh") {
				option = new Option("CN", v);
			} else {
				option = new Option(v.toUpperCase(), v);
			}
			languageSelect.append(option);
		}

		let lv;
		if (_GM_getValue("language") == "zh") {
			lv = "zh";
		} else if (_GM_getValue("language") == "TW") {
			lv = "TW";
		} else if (_GM_getValue("language") == "EN") {
			lv = "EN";
		} else {
			lv = "UI";
		}

		const MsgPosSelect = ge("#MsgPos", main);
		for (let [i, v] of Object.entries(Object.values(DL.str_109))) MsgPosSelect.append(new Option(v, i));

		const ZoomSelect = ge("#Zoom", main);
		for (let i = 0; i < 11; i++) ZoomSelect.append(new Option(i == 0 ? "Auto" : i + "0%", i));

		const ColumnSelect = ge("#Column", main);
		for (let i = 2; i <= 6; i++) ColumnSelect.append(new Option(i, i));

		const ShadowGalleryWheelSelect = ge("#ShadowGalleryWheel", main);
		for (let [i, v] of Object.entries(Object.values(DL.ShadowGalleryWheel))) ShadowGalleryWheelSelect.append(new Option(v, i));

		const horizontalWheelSelect = ge("#horizontalWheel", main);
		for (let [i, v] of Object.entries(Object.values(DL.horizontalWheel))) horizontalWheelSelect.append(new Option(v, i));

		const FancyboxWheelSelect = ge("#FancyboxWheel", main);
		for (let [i, v] of Object.entries(Object.values(DL.FancyboxWheel))) FancyboxWheelSelect.append(new Option(v, i));

		const FancyboxIdleSelect = ge("#FancyboxIdle", main);
		for (let i = 0; i <= 60; i++) FancyboxIdleSelect.append(new Option(i == 0 ? "No" : i, i));

		const FancyboxSlideshowTimeoutSelect = ge("#FancyboxSlideshowTimeout", main);
		for (let i = 0; i < 61; i++) FancyboxSlideshowTimeoutSelect.append(new Option(i == 0 ? "500 ms" : i + " sec", i));

		const FancyboxTransitionSelect = ge("#FancyboxTransition", main);
		for (let [k, v] of Object.entries(DL.FancyboxTransition)) FancyboxTransitionSelect.append(new Option(v, k));

		const FancyboxThumbnailsSelect = ge("#FancyboxThumbnails", main);
		for (let [t, v] of [
				["Modern", "modern"],
				["Classic", "classic"],
				["Scrollable", "scrollable"]
			]) FancyboxThumbnailsSelect.append(new Option(t, v));

		const CountdownSelect = ge("#Countdown", main);
		for (let i = 1; i <= 60; i++) CountdownSelect.append(new Option(i, i));

		const DownloadAPISelect = ge("#DownloadAPI", main);
		for (let [t, v] of [
				[DL.str_207, "default"],
				["Fetch API", "fetch"],
				["XMLHttpRequest", "xhr"]
			]) DownloadAPISelect.append(new Option(t, v));

		const ThreadingSelect = ge("#Threading", main);
		for (let i = 1; i <= 32; i++) ThreadingSelect.append(new Option(i, i));

		const SingleThreadIntervalSelect = ge("#SingleThreadInterval", main);
		for (let i = 0; i <= 9; i++) SingleThreadIntervalSelect.append(new Option(i == 0 ? 0 : "0." + i, i == 0 ? 0 : "0." + i));
		for (let i = 1; i <= 60; i++) SingleThreadIntervalSelect.append(new Option(i, i));

		const RetrySelect = ge("#Retry", main);
		for (let i = 1; i <= 100; i++) RetrySelect.append(new Option(i, i));

		const IntervalSelect = ge("#Interval", main);
		for (let i = 1; i <= 600; i++) IntervalSelect.append(new Option(i, i));

		const LimitSelect = ge("#Limit", main);
		for (let i = 1; i <= 66; i++) LimitSelect.append(new Option(i == 66 ? "65535" : i * 1000, i));

		const ExtensionSelect = ge("#Extension", main);
		for (let v of ["zip", "cbz"]) ExtensionSelect.append(new Option(v, v));

		const ManhuaguiSelect = ge("#Manhuagui", main);
		for (let v of ["i", "eu", "eu1", "eu2", "us", "us1", "us2", "us3"]) ManhuaguiSelect.append(new Option(v, v));

		const HitomiSelect = ge("#Hitomi", main);
		for (let v of ["webp", "avif"]) HitomiSelect.append(new Option(v, v));

		const QualitySelect = ge("#Quality", main);
		for (let i = 10; i <= 100; i++) QualitySelect.append(i == 100 ? new Option(1, i) : new Option("0." + i, i));

		const cdnSelect = ge("#cdn", main);
		for (let v of ["-1", "0", "1", "2", "3", "w", "b"]) {
			if (v < 4) {
				cdnSelect.append(new Option(v < 0 ? DL.str_209 : `i${v}.wp.com`, v));
			} else if (v == "w") {
				cdnSelect.append(new Option("wsrv.nl", v));
			} else {
				cdnSelect.append(new Option("baidu", v));
			}
		};

		topDistance = () => {
			if ((isM ? 412 : 470) < _unsafeWindow.innerHeight) {
				let num = (_unsafeWindow.innerHeight - (isM ? 412 : 470)) / 2;
				main.style.top = num + "px";
			} else {
				main.style.top = "10px";
			}
		};

		ge("#language", main).value = lv;
		ge("#DownloadAPI", main).value = _GM_getValue("DownloadAPI", "default");
		ge("#icon", main).checked = options.icon == 1 ? true : false;
		ge("#AutoInsertImg", main).checked = options.autoInsert == 1 ? true : false;
		ge("#GoToFirst", main).checked = _GM_getValue("goToFirstImage", 1) == 1 ? true : false;
		ge("#noPageNav", main).checked = _GM_getValue("TurnOffImageNavigationShortcutKeys", 0) == 1 ? true : false;
		ge("#ShowFixedMenu", main).checked = _GM_getValue("ShowFullPictureLoadFixedMenu", 1) == 1 ? true : false;
		ge("#FavorNewTab", main).checked = _GM_getValue("FavorOpenInNewTab", 0) == 1 ? true : false;
		ge("#loopView", main).checked = _GM_getValue("FullPictureLoadLoopView", 1) == 1 ? true : false;
		ge("#MsgPos", main).value = _GM_getValue("FullPictureLoadMsgPos", 0);
		ge("#Threading", main).value = options.threading;
		ge("#SingleThreadInterval", main).value = options.singleThreadInterval;
		ge("#Retry", main).value = options.retry;
		ge("#Interval", main).value = options.interval;
		ge("#Limit", main).value = options.combineLimit;
		ge("#Zip", main).checked = options.zip == 1 ? true : false;
		ge("#Extension", main).value = _GM_getValue("compressed_extension", "zip");
		ge("#Manhuagui", main).value = _GM_getValue("manhuagui_img_serv", "i");
		ge("#EHentai", main).checked = _GM_getValue("E_HENTAI_LoadOriginalImage", 0) == 1 ? true : false;
		ge("#Hitomi", main).value = _GM_getValue("hitomi_img_type", "avif");
		ge("#Yinaw", main).checked = _GM_getValue("setYinawSinaOriginalURL", 0) == 1 ? true : false;
		ge("#cdn", main).value = options.cdn;
		ge("#zipFolder", main).checked = zipFolderConfig == 1 ? true : false;
		ge("#ConvertWEBP", main).checked = _GM_getValue("convertWebpToJpg", 0) == 1 ? true : false;
		ge("#ConvertAVIF", main).checked = _GM_getValue("convertAvifToJpg", 0) == 1 ? true : false;
		ge("#Quality", main).value = _GM_getValue("jpgConvertQuality", 95);
		ge("#AutoDownload", main).checked = options.autoDownload == 1 ? true : false;
		ge("#Countdown", main).value = options.autoDownloadCountdown;
		ge("#Comic", main).checked = options.comic == 1 ? true : false;
		ge("#Double", main).checked = _GM_getValue("doubleTouchNext", 1) == 1 ? true : false;
		if ((isString(siteData.srcset) || isString(siteData.imgs)) && !isArray(siteData.insertImg)) {
			ge("#ShowEyeDIV", main).style.display = "flex";
			ge("#ShowEye", main).checked = FullPictureLoadShowEye == 1 ? true : false;
		}
		const hide = (selectors) => {
			for (let s of selectors) {
				for (let e of gae(s, main)) e.classList.add("hide");
			}
		};

		if ("insertImg" in siteData) {
			const [, insertMode] = siteData.insertImg;
			if (![1, 2].some(n => n == insertMode)) {
				hide(["#AutoInsertImgDIV"]);
			}
		}
		if (!("insertImg" in siteData)) {
			hide([
				"#AutoInsertImgDIV",
				"#GoToFirstDIV",
				"#noPageNavDIV",
				"#ZoomDIV",
				"#viewModeDIV",
				"#ColumnDIV"
			]);
		}
		if (isM) {
			hide([
				"#noPageNavDIV",
				"#ShowFixedMenuDIV",
				//"#ShadowGalleryModeDIV",
				"#ShadowGalleryWheelDIV",
				"#horizontalWheelDIV",
				"#FancyboxWheelDIV",
				"#ShadowGalleryloopViewDIV"
			]);
		}
		if (isPC) {
			hide([
				"#MobileGalleryModeDIV",
				"#GalleryInIconDIV"
			]);
		}
		if (!isInfinite) {
			hide(["#InfiniteDIV"]);
		}
		if (isSimpleMode) {
			hide([
				"#MobileGalleryModeDIV",
				"#autoExportDIV"
			]);
		}
		if (isSimpleMode || siteData.aeg == 0) {
			hide(["#ShadowGalleryModeDIV"]);
		}
		if (siteData?.category?.includes("autoPager")) {
			hide([
				"#gallery_tab",
				"#lightbox_tab",
				"#download_tab",
				"#iconDIV",
				"#ShowFixedMenuDIV",
				"#autoExportDIV",
				"#CDNDIV"
			]);
		}
		if (isSimpleMode) {
			hide([
				"#iconDIV",
				"#AutoDownloadDIV",
				"#CountdownDIV"
			]);
		}
		ge("#Viewer", main).checked = (localStorage.getItem("newTabViewLightGallery") ?? 0) == 1 ? true : false;
		ge("#Fancybox", main).checked = options.fancybox == 1 ? true : false;
		ge("#FancyboxSlideshowTimeout", main).value = FancyboxSlideshowTimeout;
		ge("#FancyboxWheel", main).value = _GM_getValue("FancyboxWheel", 1);
		ge("#FancyboxIdle", main).value = _GM_getValue("FancyboxIdle", 0);
		ge("#FancyboxTransition", main).value = _GM_getValue("FancyboxSlideshowTransition", "fade");
		ge("#FancyboxShowThumbs", main).checked = _GM_getValue("FancyboxShowThumbs", 0) == 1 ? true : false;
		ge("#FancyboxThumbnails", main).value = _GM_getValue("FancyboxThumbnails", "modern");
		ge("#FancyboxAutoClose", main).checked = _GM_getValue("FancyboxAutoClose", 1) == 1 ? true : false;
		ge("#FancyboxAutoNext", main).checked = _GM_getValue("FancyboxAutoNext", 1) == 1 ? true : false;
		ge("#Zoom", main).value = options.zoom;
		siteData.category == "comic" ? ge("#Column", main).value = 2 : ge("#Column", main).value = options.column;
		//ge("#viewMode", main).checked = options.viewMode == 1 ? true : false;
		ge("#viewMode", main).checked = _GM_getValue("pageViewMode", 0) == 1 ? true : false;
		if (isInfinite) {
			ge("#InfiniteMode", main).checked = comicInfiniteScrollMode == 1 ? true : false;
		}
		ge("#ShadowGalleryMode", main).checked = options.shadowGallery == 1 ? true : false;
		ge("#MobileGalleryMode", main).checked = options.mobileGallery == 1 ? true : false;
		ge("#GalleryInIcon", main).checked = _GM_getValue("GalleryInIcon", 0) == 1 ? true : false;
		ge("#autoExport", main).checked = options.autoExport == 1 ? true : false;
		ge("#ShadowGalleryWheel", main).value = config.shadowGalleryWheel;
		ge("#horizontalWheel", main).value = config.horizontalWheel;
		if (comicSwitch) {
			ge("#ComicDIV", main).style.display = "flex";
		}
		let autoDownload = siteData.autoDownload;
		if (isM && showOptions || !autoDownload && showOptions) {
			hide([
				"#AutoDownloadDIV",
				"#CountdownDIV"
			]);
		}
		if (isSimpleMode || isPC && showOptions || (isM && showOptions && !("next" in siteData)) || isAutoPager) {
			hide(["#DoubleDIV"]);
		}
		let downloadVideo = siteData.downloadVideo;
		if (!!downloadVideo && downloadVideo === true && isPC) {
			ge("#CustomDownloadVideoDIV", main).style.display = "flex";
			ge("#CustomDownloadVideo", main).checked = FullPictureLoadCustomDownloadVideo == 1 ? true : false;
		}
		ge("#CancelBtn", main).addEventListener("click", event => {
			cancelDefault(event);
			mainElement.remove();
			_unsafeWindow.removeEventListener("resize", topDistance);
			setTimeout(() => (isOpenOptionsUI = false), 200);
		});
		ge("#ResetBtn", main).addEventListener("click", event => {
			cancelDefault(event);
			setDefault();
			location.reload();
		});
		ge("#SaveBtn", main).addEventListener("click", event => {
			cancelDefault(event);
			_GM_setValue("language", ge("#language", main).value);
			_GM_setValue("DownloadAPI", ge("#DownloadAPI", main).value);
			options.icon = ge("#icon", main).checked == true ? 1 : 0;
			options.autoInsert = ge("#AutoInsertImg", main).checked == true ? 1 : 0;
			_GM_setValue("goToFirstImage", ge("#GoToFirst", main).checked == true ? 1 : 0);
			_GM_setValue("TurnOffImageNavigationShortcutKeys", ge("#noPageNav", main).checked == true ? 1 : 0);
			_GM_setValue("ShowFullPictureLoadFixedMenu", ge("#ShowFixedMenu", main).checked == true ? 1 : 0);
			_GM_setValue("FavorOpenInNewTab", ge("#FavorNewTab", main).checked == true ? 1 : 0);
			_GM_setValue("FullPictureLoadLoopView", ge("#loopView", main).checked == true ? 1 : 0);
			_GM_setValue("FullPictureLoadMsgPos", ge("#MsgPos", main).value);
			options.threading = ge("#Threading", main).value;
			options.singleThreadInterval = ge("#SingleThreadInterval", main).value;
			options.retry = ge("#Retry", main).value;
			options.interval = ge("#Interval", main).value;
			options.combineLimit = ge("#Limit", main).value;
			options.zip = ge("#Zip", main).checked == true ? 1 : 0;
			_GM_setValue("compressed_extension", ge("#Extension", main).value);
			_GM_setValue("manhuagui_img_serv", ge("#Manhuagui", main).value);
			_GM_setValue("E_HENTAI_LoadOriginalImage", ge("#EHentai", main).checked == true ? 1 : 0);
			_GM_setValue("hitomi_img_type", ge("#Hitomi", main).value);
			_GM_setValue("setYinawSinaOriginalURL", ge("#Yinaw", main).checked == true ? 1 : 0);
			options.cdn = ge("#cdn", main).value;
			_GM_setValue("zipFolderConfig", ge("#zipFolder", main).checked == true ? 1 : 0);
			_GM_setValue("convertWebpToJpg", ge("#ConvertWEBP", main).checked == true ? 1 : 0);
			_GM_setValue("convertAvifToJpg", ge("#ConvertAVIF", main).checked == true ? 1 : 0);
			_GM_setValue("jpgConvertQuality", ge("#Quality", main).value);
			options.comic = ge("#Comic", main).checked == true ? 1 : 0;
			_GM_setValue("doubleTouchNext", ge("#Double", main).checked == true ? 1 : 0);
			options.autoDownload = ge("#AutoDownload", main).checked == true ? 1 : 0;
			options.autoDownloadCountdown = ge("#Countdown", main).value;
			options.fancybox = ge("#Fancybox", main).checked == true ? 1 : 0;
			localStorage.setItem("newTabViewLightGallery", ge("#Viewer", main).checked == true ? 1 : 0);
			_GM_setValue("FancyboxSlideshowTimeout", ge("#FancyboxSlideshowTimeout", main).value);
			_GM_setValue("FancyboxWheel", ge("#FancyboxWheel", main).value);
			_GM_setValue("FancyboxIdle", ge("#FancyboxIdle", main).value);
			_GM_setValue("FancyboxSlideshowTransition", ge("#FancyboxTransition", main).value);
			_GM_setValue("FancyboxShowThumbs", ge("#FancyboxShowThumbs", main).checked == true ? 1 : 0);
			_GM_setValue("FancyboxThumbnails", ge("#FancyboxThumbnails", main).value);
			_GM_setValue("FancyboxAutoClose", ge("#FancyboxAutoClose", main).checked == true ? 1 : 0);
			_GM_setValue("FancyboxAutoNext", ge("#FancyboxAutoNext", main).checked == true ? 1 : 0);
			options.zoom = ge("#Zoom", main).value;
			options.column = ge("#Column", main).value;
			//options.viewMode = ge("#viewMode", main).checked == true ? 1 : 0;
			_GM_setValue("pageViewMode", ge("#viewMode", main).checked == true ? 1 : 0);
			if (isInfinite) {
				localStorage.setItem("FullPictureLoadComicInfiniteScrollMode", ge("#InfiniteMode", main).checked == true ? 1 : 0);
			}
			options.shadowGallery = ge("#ShadowGalleryMode", main).checked == true ? 1 : 0;
			options.mobileGallery = ge("#MobileGalleryMode", main).checked == true ? 1 : 0;
			_GM_setValue("GalleryInIcon", ge("#GalleryInIcon", main).checked == true ? 1 : 0);
			options.autoExport = ge("#autoExport", main).checked == true ? 1 : 0;
			config.shadowGalleryWheel = ge("#ShadowGalleryWheel", main).value;
			config.horizontalWheel = ge("#horizontalWheel", main).value;
			saveConfig(config);
			if ((isString(siteData.srcset) || isString(siteData.imgs)) && !isArray(siteData.insertImg)) {
				ge("#ShowEye", main).checked == true ? localStorage.setItem("FullPictureLoadShowEye", 1) : localStorage.setItem("FullPictureLoadShowEye", 0);
			}
			if (!!downloadVideo && downloadVideo === true && isPC) {
				ge("#CustomDownloadVideo", main).checked == true ? localStorage.setItem("FullPictureLoadCustomDownloadVideo", 1) : localStorage.setItem("FullPictureLoadCustomDownloadVideo", 0);
			}
			let jsonStr = JSON.stringify(options);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
			location.reload();
		});
		topDistance();
		_unsafeWindow.addEventListener("resize", topDistance);
	};

	//腳本的CSS樣式

	const FullPictureLoadStyle = `
.fancybox-container,
.fancybox__container,
.fancybox__dialog,
html > .viewer-container {
    z-index: ${UI_zIndex} !important;
}

.fancybox-image,
.viewer-canvas > img {
    opacity: 1 !important;
}

.fancybox__container:has(.fancybox__thumbs.is-scrollable) {
    flex-direction: row;
}

.fancybox__thumbs.is-scrollable {
    --f-thumbs-cols: 1 !important;
    --f-thumbs-gap: 4px;
    --f-thumbs-padding-x: 2px;
    --f-thumbs-padding-y: 2px;
    --f-thumbs-viewport-padding-x: 2px;
    --f-thumbs-viewport-padding-y: 2px;
    --f-thumb-width: 100px;
    --f-thumb-height: 75px;
    --f-thumb-border-radius: 0;
}

@media (min-width: 768px) {
    .fancybox__thumbs.is-scrollable {
        --f-thumbs-cols: 2 !important;
    }
}

.viewer-backdrop {
    background-color: rgba(0, 0, 0, 0.96) !important;
}

.viewer-container .viewer-footer,
.viewer-container .viewer-footer .viewer-toolbar {
    text-align: center !important;
}

.viewer-toolbar > ul > li {
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
}

#FullPictureLoadButtons,
#FullPictureLoadAutoPagerButtonsRoot,
#FullPictureLoadShadowGallery,
#FullPictureLoadFilterDownload,
#FullPictureLoadFavorSites {
    overflow: clip !important;
    display: initial !important;
    position: fixed !important;
}

#FullPictureLoadOptionsShadowElement {
    z-index: ${UI_zIndex - 1} !important;
}

#FullPictureLoadFavorSites {
    z-index: ${UI_zIndex - 2} !important;
}

#FullPictureLoadShadowGallery,
#FullPictureLoadIframeGallery,
#FullPictureLoadAutoPagerButtonsRoot {
    z-index: ${UI_zIndex - 3} !important;
}

#FullPictureLoadIframe {
    z-index: ${UI_zIndex - 3} !important;
    display: block;
    visibility: visible;
    float: none;
    clear: both;
    width: 100%;
    height: 0px;
    background: initial;
    border: 0px;
    border-radius: 0px;
    margin: 0px;
    padding: 0px;
    content-visibility: auto;
    contain-intrinsic-size: auto 300px;
}

#FullPictureLoadFilterDownload {
    z-index: ${UI_zIndex - 5} !important;
}

#FullPictureLoadButtons {
    z-index: ${UI_zIndex - 6};
}

.FullPictureLoadImageReturnTop {
    position: fixed;
    right: 10px;
    bottom: 80px;
    width: 53px !important;
    height: 53px !important;
    border: unset;
    z-index: ${UI_zIndex - 6};
    opacity: 0.6;
}

#FullPictureLoad {
    display: block !important;
}

#FullPictureLoadGoToLastImage {
    transform: rotate(180deg);
    bottom: 66px !important;
}

#FullPictureLoadGoToFirstImage {
    bottom: 108px !important;
}

.FullPictureLoadFixedBtn {
    position: fixed !important;
    left: 24px;
    width: 32px !important;
    height: 32px !important;
    border: unset !important;
    border-radius: unset !important;
    margin: unset !important;
    padding: unset !important;
    z-index: ${UI_zIndex - 6} !important;
    cursor: pointer !important;
    pointer-events: auto !important;
    background: unset !important;
    min-width: unset !important;
    min-height: unset !important;
    opacity: 0.8 !important;
}

#FullPictureLoadEye {
    position: fixed !important;
    display: block !important;
    width: 32px !important;
    height: 32px !important;
    margin: 0 !important;
    border-radius: unset !important;
    z-index: ${UI_zIndex - 6} !important;
    opacity: 1 !important;
    cursor: pointer !important;
    pointer-events: auto !important;
}

#FullPictureLoadFixedMenu {
    text-align: center !important;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    color: #000000 !important;
    height: auto !important;
    padding: 5px 5px 2px 5px !important;
    position: fixed !important;
    left: 10px !important;
    bottom: 152px !important;
    border: #ccc 1px solid !important;
    border-radius: 3px !important;
    background-color: #fff !important;
    box-sizing: unset !important;
    opacity: 0.4;
    z-index: ${UI_zIndex - 6} !important;
}

#FullPictureLoadFixedMenu > div,
#FullPictureLoadFixedMenuB > div {
    display: flex;
    align-items: center !important;
    justify-content: center !important;
    height: 24px !important;
    line-height: 24px !important;
    width: auto !important;
    overflow: hidden !important;
    font-size: 14px !important;
    text-shadow: unset !important;
    text-align: center !important;
    letter-spacing: unset !important;
    border: #ccc 1px solid !important;
    background-color: #f6f6f6 !important;
    padding: 0 5px 0 5px !important;
    margin: 0 2px 3px 0 !important;
    cursor: pointer !important;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

#FullPictureLoadFixedMenu:hover,
.FullPictureLoadFixedBtn:hover {
    opacity: 1 !important;
}

#FullPictureLoadFixedMenu .itemNoShow {
    display: none !important;
}

#FullPictureLoadFixedMenuB {
    text-align: center !important;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-weight: 500 !important;
    font-size: 14px !important;
    color: #000000 !important;
    width: 112px !important;
    height: auto !important;
    min-height: 29px !important;
    padding: 5px 5px 2px 5px !important;
    position: fixed !important;
    border: #ccc 1px solid !important;
    border-radius: 3px !important;
    background-color: #fff !important;
    opacity: 1;
    z-index: ${UI_zIndex - 6} !important;
    letter-spacing: unset !important;
}

#FullPictureLoadMsg {
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-size: ${language.includes("zh") ? "24px" : "22px"};
    font-weight: 500;
    text-align: center;
    line-height: 50px;
    color: #ffffff;
    width: 360px;
    height: auto;
    padding: 0px !important;
    background-color: #000;
    border: 1px solid #303030;
    border-radius: 10px;
    position: fixed;
    z-index: ${UI_zIndex - 4};
    opacity: 0.7;
}

.FullPictureLoadImage:not(.small) {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: unset !important;
    display: block !important;
    float: unset !important;
    opacity: 1 !important;
    border: none !important;
    border-radius: unset !important;
    padding: 0 !important;
    margin: 0 auto !important;
    transition: unset !important;
    transform: unset !important;
}

.FullPictureLoadImage.small {
    width: auto;
    height: auto;
    max-width: 100% !important;
    max-height: 100% !important;
    min-height: 50x !important;
    display: block !important;
    float: unset !important;
    opacity: 1 !important;
    border: none !important;
    border-radius: unset !important;
    padding: 0 !important;
    margin: auto;
    transition: unset !important;
    transform: unset !important;
}

#FullPictureLoadImgBox {
    display: block;
    opacity: 1 !important;
    border: none !important;
    border-radius: unset !important;
    padding: 0 !important;
    margin: 0 auto 10px !important;
}

#FullPictureLoadImgBox > div {
    height: auto;
}

a[data-fancybox="FullPictureLoadImageOriginal"],
a[data-fancybox="FullPictureLoadImageSmall"] {
    position: unset !important;
    padding: 0 !important;
    margin: 0 auto !important;
    display: block !important;
    color: unset !important;
    border: unset !important;
    --local-colour1-primary: unset !important;
    --local-colour1-secondary: unset !important;
    --local-colour2-primary: unset !important;
    --local-colour2-secondary: unset !important;
    transition-property: unset !important;
    transition-duration: unset !important;
}

#FullPictureLoadEnd {
    display: block;
    font-size: 20px;
    height: 30px;
    width: 100%;
    line-height: 30px;
    text-align: center !important;
    margin: 5px auto !important;
}

#FullPictureLoadEnd
    ~ *:not(
        h3,
        ul,
        p,
        .tags,
        [id^="Full"],
        [class^="Full"],
        a[href="javascript:void(0);"],
        .post-info,
        .post-tags,
        .article-tags,
        *[class^="fancybox"],
        div[tabindex],
        .row,
        .text-center,
        .link-d,
        #myrating,
        .gallery-a,
        .pagination,
        div[class^="picnext"],
        a.zwf,
        .bo_nav
    ) {
    display: none !important;
}

.FullPictureLoadLoading {
    font-size: 20px;
    text-align: center;
    height: 30px;
    line-height: 30px;
    margin: 5px auto !important;
    border: none !important;
}

.autoPagerTitle {
    width: auto;
    height: 30px;
    font-size: 18px;
    color: black;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-weight: 500 !important;
    line-height: 29px;
    text-align: center;
    user-select: none;
    overflow: hidden;
    display: block;
    margin: 10px 5px;
    border: 1px solid #e0e0e0;
    background-color: #f0f0f0;
    background: -webkit-gradient(
        linear,
        0 0,
        0 100%,
        from(#f9f9f9),
        to(#f0f0f0)
    );
    background: -moz-linear-gradient(top, #f9f9f9, #f0f0f0);
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.6);
    border-radius: 5px;
}

.autoPagerTitle.off {
    color: white;
    border: 1px solid #0e0e0e;
    background-color: #0f0f0f;
    background: -webkit-gradient(
        linear,
        0 0,
        0 100%,
        from(#9f9f9f),
        to(#0f0f0f)
    );
    background: -moz-linear-gradient(top, #9f9f9f, #0f0f0f);
    box-shadow: 0 0 5px rgba(255, 255, 255, 0.6);
    border-radius: 5px;
}

.autoPagerTitle a:-webkit-any-link {
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-weight: 500 !important;
    color: black;
}

.autoPagerTitle.off a:-webkit-any-link {
    color: white;
}

.autoPagerLoading {
    width: auto;
    height: auto;
    max-width: 60px !important;
    max-height: 60px !important;
    display: block !important;
    opacity: 1 !important;
    border: none !important;
    border-radius: unset !important;
    padding: 0 !important;
    margin: 20px auto !important;
}

#FullPictureLoadOptionsButtonParentDiv {
    display: grid !important;
    grid-template-columns: 1fr 1fr 1fr 1fr !important;
    text-align: center !important;
    align-items: center !important;
    justify-content: center !important;
    width: calc(100% - 10px) !important;
    max-width: 100% !important;
    height: 90px !important;
    min-height: unset !important;
    margin-left: auto !important;
    margin-right: auto !important;
    margin-bottom: 10px !important;
    padding: 0 5px !important;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-size: initial !important;
    font-weight: 500 !important;
}

.FullPictureLoadPageButtonTop {
    display: flex !important;
    text-align: center !important;
    justify-content: center !important;
    align-items: center !important;
    height: 32px !important;
    line-height: 30px !important;
    min-height: unset !important;
    padding: 1px !important;
    margin: 10px 0 10px 0 !important;
    border-radius: unset !important;
    appearance: auto;
    text-rendering: auto;
    color: black !important;
    letter-spacing: normal;
    word-spacing: normal;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    box-sizing: border-box;
    background: unset !important;
    background-color: #f6f6f6 !important;
    border: 1px solid #a0a0a0 !important;
    cursor: pointer !important;
}

.FullPictureLoadPageButtonBottom {
    display: flex !important;
    text-align: center !important;
    justify-content: center !important;
    align-items: center !important;
    height: 32px !important;
    line-height: 30px !important;
    min-height: unset !important;
    padding: 1px !important;
    margin: 0px !important;
    border-radius: unset !important;
    appearance: auto;
    text-rendering: auto;
    color: black !important;
    letter-spacing: normal;
    word-spacing: normal;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    text-transform: none;
    text-indent: 0px;
    text-shadow: none;
    box-sizing: border-box;
    background: unset !important;
    background-color: #f6f6f6 !important;
    border: 1px solid #a0a0a0 !important;
    cursor: pointer !important;
}

#FullPictureLoadOptions button:hover,
.FullPictureLoadPageButtonTop:hover,
.FullPictureLoadPageButtonBottom:hover {
    color: black !important;
}

.viewer-open:not(.fancybox-active) {
    overflow: unset !important;
    padding-right: 0px !important;
}

.fancybox-infobar *,
.fancybox__infobar,
a[data-fancybox-download],
a[data-fancybox-download]:hover,
a[data-fancybox-download]:link,
a[data-fancybox-download]:visited,
a[data-fancybox-download]:active {
    color: white;
}

a[data-fancybox]:hover {
    opacity: 1 !important;
}
.viewer-toolbar > ul > li {
    line-height: unset !important;
}`;

	const goToFirstImage = _GM_getValue("goToFirstImage", 1);
	const TurnOffImageNavigationShortcutKeys = _GM_getValue("TurnOffImageNavigationShortcutKeys", 0);
	const ShowFullPictureLoadFixedMenu = _GM_getValue("ShowFullPictureLoadFixedMenu", 1);
	const autoScrollAllElement = _GM_getValue("autoScrollAllElement", 0);

	const comicInfiniteScrollMode = localStorage.getItem("FullPictureLoadComicInfiniteScrollMode") ?? 0;

	const E_HENTAI_LoadOriginalImage = _GM_getValue("E_HENTAI_LoadOriginalImage", 0);

	const setYinawSinaOriginalURL = _GM_getValue("setYinawSinaOriginalURL", 0);

	const hitomi_img_type = _GM_getValue("hitomi_img_type", "avif");

	const manhuagui_img_serv = _GM_getValue("manhuagui_img_serv", "i");

	//確認選項設置資料
	const checkOptionsData = async () => {
		const getOptionsData = localStorage.getItem("FullPictureLoadOptions");
		if (getOptionsData === null && options.autoDownload !== 1) {
			let jsonStr = JSON.stringify(defaultOptions);
			localStorage.setItem("FullPictureLoadOptions", jsonStr);
		} else if (options.autoDownload !== 1) {
			let optionsJson = JSON.parse(getOptionsData);
			options = Object.assign(defaultOptions, optionsJson);
			//debug("\nFull Picture Load Options Json\n", options);
		}
	};

	//Fancybox6的語系
	const Fancyboxl10nV6 = () => {
		if (!isFn(_unsafeWindow?.Fancybox?.getDefaults)) return;
		switch (language) {
		case "TW":
		case "zh-TW":
		case "zh-HK":
		case "zh-Hant-TW":
		case "zh-Hant-HK":
			_unsafeWindow.Fancybox.getDefaults().l10n = {
				IMAGE_ERROR: "找不到圖像",
				MOVE_UP: "上移",
				MOVE_DOWN: "下移",
				MOVE_LEFT: "左移",
				MOVE_RIGHT: "右移",
				ZOOM_IN: "放大",
				ZOOM_OUT: "縮小",
				TOGGLE_FULL: "切換縮放等級",
				TOGGLE_1TO1: "切換縮放等級",
				ITERATE_ZOOM: "切換縮放等級",
				ROTATE_CCW: "逆時針旋轉",
				ROTATE_CW: "順時針旋轉",
				FLIP_X: "水平翻轉",
				FLIP_Y: "垂直翻轉",
				RESET: "重設",
				TOGGLE_FS: "切換全螢幕",
				ERROR: "無法載入要求的內容。 <br/> 請稍後重試。",
				GOTO: "Go to page #%d",
				DOWNLOAD: "下載",
				TOGGLE_FULLSCREEN: "切換全螢幕",
				TOGGLE_EXPAND: "切換全螢幕e",
				TOGGLE_THUMBS: "切換縮圖",
				TOGGLE_AUTOPLAY: "切換幻燈片",
				CLOSE: "關閉",
				NEXT: "下一個",
				PREV: "上一個",
				MODAL: "使用 ESC 鍵關閉",
				ELEMENT_NOT_FOUND: "找不到 HTML 元素",
				IFRAME_ERROR: "頁面載入錯誤"
			};
			break;
		case "zh":
		case "zh-CN":
		case "zh-Hans-CN":
			_unsafeWindow.Fancybox.getDefaults().l10n = {
				IMAGE_ERROR: "找不到图像",
				MOVE_UP: "上移",
				MOVE_DOWN: "下移",
				MOVE_LEFT: "左移",
				MOVE_RIGHT: "右移",
				ZOOM_IN: "放大",
				ZOOM_OUT: "缩小",
				TOGGLE_FULL: "切换缩放等级",
				TOGGLE_1TO1: "切换缩放等级",
				ITERATE_ZOOM: "切换缩放等级",
				ROTATE_CCW: "逆时针旋转",
				ROTATE_CW: "顺时针旋转",
				FLIP_X: "水平翻转",
				FLIP_Y: "垂直翻转",
				RESET: "重设",
				TOGGLE_FS: "切换全萤幕",
				ERROR: "无法加载请求的内容。 <br/> 请稍后重试。",
				GOTO: "Go to page #%d",
				DOWNLOAD: "下载",
				TOGGLE_FULLSCREEN: "切换全萤幕",
				TOGGLE_EXPAND: "切换全萤幕e",
				TOGGLE_THUMBS: "切换缩图",
				TOGGLE_AUTOPLAY: "切换幻灯片",
				CLOSE: "关闭",
				NEXT: "下一个",
				PREV: "上一个",
				MODAL: "使用 ESC 键关闭",
				ELEMENT_NOT_FOUND: "找不到 HTML 元素",
				IFRAME_ERROR: "页面加载错误"
			};
			break;
		}
	};

	//Fancybox5的語系
	const Fancyboxl10nV5 = () => {
		let l10n;
		switch (language) {
		case "TW":
		case "zh-TW":
		case "zh-HK":
		case "zh-Hant-TW":
		case "zh-Hant-HK":
			l10n = {
				PANUP: "上移",
				PANDOWN: "下移",
				PANLEFT: "左移",
				PANRIGHT: "右移",
				ZOOMIN: "放大",
				ZOOMOUT: "縮小",
				TOGGLEZOOM: "切換縮放等級",
				TOGGLE1TO1: "切換縮放等級",
				ITERATEZOOM: "切換縮放等級",
				ROTATECCW: "逆時針旋轉",
				ROTATECW: "順時針旋轉",
				FLIPX: "水平翻轉",
				FLIPY: "垂直翻轉",
				FITX: "水平適應",
				FITY: "垂直適應",
				RESET: "重設",
				TOGGLEFS: "切換全螢幕",
				CLOSE: "關閉",
				NEXT: "下一個",
				PREV: "上一個",
				MODAL: "使用 ESC 鍵關閉",
				ERROR: "無法載入要求的內容。 <br/> 請稍後重試。",
				IMAGE_ERROR: "找不到圖像",
				ELEMENT_NOT_FOUND: "找不到 HTML 元素",
				AJAX_NOT_FOUND: "載入 AJAX 時出錯: 未找到",
				AJAX_FORBIDDEN: "載入 AJAX 時出錯: 被阻止",
				IFRAME_ERROR: "載入頁面出錯",
				TOGGLE_ZOOM: "切換縮放等級",
				TOGGLE_THUMBS: "切換縮圖",
				TOGGLE_SLIDESHOW: "切換幻燈片",
				TOGGLE_FULLSCREEN: "切換全螢幕",
				DOWNLOAD: "下載"
			};
			break;
		case "zh":
		case "zh-CN":
		case "zh-Hans-CN":
			l10n = {
				PANUP: "上移",
				PANDOWN: "下移",
				PANLEFT: "左移",
				PANRIGHT: "右移",
				ZOOMIN: "放大",
				ZOOMOUT: "缩小",
				TOGGLEZOOM: "切换缩放级别",
				TOGGLE1TO1: "切换缩放级别",
				ITERATEZOOM: "切换缩放级别",
				ROTATECCW: "逆时针旋转",
				ROTATECW: "顺时针旋转",
				FLIPX: "水平翻转",
				FLIPY: "垂直翻转",
				FITX: "水平适应",
				FITY: "垂直适应",
				RESET: "重置",
				TOGGLEFS: "切换全屏",
				CLOSE: "关闭",
				NEXT: "下一个",
				PREV: "上一个",
				MODAL: "使用 ESC 键关闭",
				ERROR: "无法加载请求的内容。 <br/> 请稍后重试。",
				IMAGE_ERROR: "找不到图像",
				ELEMENT_NOT_FOUND: "找不到 HTML 元素",
				AJAX_NOT_FOUND: "载入 AJAX 时出错: 未找到",
				AJAX_FORBIDDEN: "载入 AJAX 时出错: 被阻止",
				IFRAME_ERROR: "加载页面出错",
				TOGGLE_ZOOM: "切换缩放级别",
				TOGGLE_THUMBS: "切换缩略图",
				TOGGLE_SLIDESHOW: "切换幻灯片",
				TOGGLE_FULLSCREEN: "切换全屏",
				DOWNLOAD: "下载"
			};
			break;
		default:
			l10n = "EN";
		}
		return l10n;
	};

	//更改Fancybox3的預設選項
	const FancyboxOptionsV3 = () => {
		if (siteData.fancybox?.js === false) return;
		const d = _unsafeWindow.jQuery.fancybox.defaults;
		// Transition effect between slides
		//
		// Possible values:
		//   false            - disable
		//   "fade'
		//   "slide'
		//   "circular'
		//   "tube'
		//   "zoom-in-out'
		//   "rotate'
		//
		//d.transitionEffect = "circular";
		d.buttons = ["zoom", "slideShow", "fullScreen", "thumbs", "close"];
		d.animationEffect = false;
		d.loop = true;
		d.toolbar = true;
		d.thumbs.autoStart = FancyboxShowThumbs;
		d.slideShow.speed = FancyboxSlideshowTimeoutNum;
		d.idleTime = _GM_getValue("FancyboxIdle", 0) == 0 ? 3 : Number(_GM_getValue("FancyboxIdle", 0));
		d.i18n.tw = {
			"CLOSE": "關閉",
			"NEXT": "下一個",
			"PREV": "上一個",
			"ERROR": "無法載入要求的內容。 <br/> 請稍後重試。",
			"PLAY_START": "開始幻燈片",
			"PLAY_STOP": "暫停幻燈片",
			"FULL_SCREEN": "全螢幕",
			"THUMBS": "縮圖",
			"DOWNLOAD": "下載",
			"SHARE": "分享",
			"ZOOM": "縮放"
		};
		d.i18n.cn = {
			"CLOSE": "关闭",
			"NEXT": "下一个",
			"PREV": "上一个",
			"ERROR": "无法加载请求的内容。 <br/> 请稍后重试。",
			"PLAY_START": "开始幻灯片",
			"PLAY_STOP": "暂停幻灯片",
			"FULL_SCREEN": "全面屏",
			"THUMBS": "缩略图",
			"DOWNLOAD": "下载",
			"SHARE": "分享",
			"ZOOM": "缩放"
		};
		switch (language) {
		case "TW":
		case "zh-TW":
		case "zh-HK":
		case "zh-Hant-TW":
		case "zh-Hant-HK":
			d.lang = "tw";
			break;
		case "zh":
		case "zh-CN":
		case "zh-Hans-CN":
			d.lang = "cn";
			break;
		}
		//console.log("fancybox 3.5.7 選項物件", d);
	};

	//頁面容器快捷鍵
	const addKeyEvent = async event => {
		if (isOpenFilter || isOpenFancybox || isOpenGallery || ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
		if (event.ctrlKey && event.altKey && (event.code === "KeyC" || event.key === "c" || event.key === "C")) return;
		if (event.ctrlKey && (event.code === "NumpadDecimal" || event.code === "Period" || event.key === ".")) return;
		if ((event.code != "Escape" || event.key != "Escape") && isOpenOptionsUI) return;
		if (["INPUT", "TEXTAREA"].some(n => n === document.activeElement.tagName)) return;
		if (event.ctrlKey && event.altKey && (event.code === "KeyT" || event.key === "t" || event.key === "T")) {
			let str = _unsafeWindow.getSelection().toString();
			str == "" ? null : customTitle = str;
			let newTitle = await prompt("New Title", customTitle);
			newTitle == null ? null : customTitle = newTitle;
			fn.showMsg(DL.str_118);
			debug("圖集新標題", newTitle || customTitle);
		}
		if (event.ctrlKey || event.altKey || event.shiftKey) return;
		if (event.code === "KeyF" || event.key === "f" || event.key === "F") { //F鍵
			return createFilterUI();
		}
		if (!isSimpleMode && (event.code === "KeyG" || event.key === "g" || event.key === "G")) { //G鍵
			return createShadowGallery();
		}
		if (!isSimpleMode && (event.code === "KeyI" || event.key === "i" || event.key === "I")) { //I鍵
			return createIframeGallery();
		}
		if (!isSimpleMode && (event.code === "Numpad0" || event.key === "0")) { //數字鍵0
			fastDownloadSwitch = false;
			return DownloadFn();
		}
		if (!isSimpleMode && (event.code === "Numpad1" || event.key === "1")) return copyImgSrcText(); //數字鍵1
		if (!isSimpleMode && (event.code === "Numpad2" || event.key === "2")) return goToImg("first"); //數字鍵2
		if (!isSimpleMode && (event.code === "Numpad3" || event.key === "3")) { //數字鍵3
			fastDownloadSwitch = true;
			return DownloadFn();
		}
		if (!isSimpleMode && (event.code === "Numpad4" || event.key === "4")) return goToImg("last"); //數字鍵4
		if (!isSimpleMode && (event.code === "Numpad5" || event.key === "5")) return toggleImgMode(); //數字鍵5
		if (!isSimpleMode && (event.code === "Numpad6" || event.key === "6")) { //數字鍵6
			if ("fn" in siteData && isFn(siteData.fn)) {
				return siteData.fn();
			} else {
				return autoScrollEles();
			}
		}
		if (!isSimpleMode && (event.code === "Numpad7" || event.key === "7")) return exportImgSrcText(); //數字鍵7
		if (!isSimpleMode && (event.code === "Numpad8" || event.key === "8")) return newTabView(); //數字鍵8
		if (event.code === "Numpad9" || event.key === "9") return createFavorShadowElement(); //數字鍵9
		if (!isSimpleMode && (event.code === "NumpadSubtract" || event.key === "-")) { //數字鍵-
			fn.clearSetTimeout();
			return reduceZoom();
		}
		if (!isSimpleMode && (event.code === "NumpadAdd" || event.key === "+")) { //數字鍵+
			fn.clearSetTimeout();
			return increaseZoom();
		}
		if (!isSimpleMode && (event.code === "NumpadDecimal" || event.code === "Period" || event.key === ".")) { //數字鍵.
			fn.clearSetTimeout();
			return cancelZoom();
		}
		if (event.code === "NumpadMultiply" || event.key === "*") { //數字鍵*
			createPictureLoadOptionsShadowElement();
		}
		if (event.code === "Escape" || event.key === "Escape") { //Esc鍵
			if (!isStopDownload && isDownloading) {
				isStopDownload = true;
				isDownloading = false;
				fn.clearAllTimer(2);
				fn.showMsg(DL.str_149);
			}
			if (isCountdowning) {
				isCountdowning = false;
				isStopDownload = true;
				fn.clearAllTimer(2);
				fn.showMsg(DL.str_149);
			}
			isEsc = true;
			setTimeout(() => (isEsc = false), 200);
			let UI = ge("#FullPictureLoadOptionsShadowElement");
			if (UI) {
				UI.remove();
				_unsafeWindow.removeEventListener("resize", topDistance);
				setTimeout(() => (isOpenOptionsUI = false), 200);
			}
			return;
		}
		if (event.code === "NumpadDivide" || event.key === "/") { //數字鍵/
			fn.showMsg(DL.str_91);
			setDefault(); //重置用戶設定恢復為預設選項
			setTimeout(() => location.reload(), 1000);
			return;
		}
	};

	const toggleUI = async () => {
		if (!"SPA" in siteData || !isFn(siteData.SPA) || !!ge(".FullPictureLoadImage") || isOpenMenu || isFetching) return;
		isFetching = true;
		if (isOpenGallery) {
			closeGallery();
		}
		if (isOpenFilter) {
			closeFilter()
		}
		const validPage = await siteData.SPA();
		isFetching = false;
		if (!!validPage) {
			isValidPage = true;
			if (isAddFullPictureLoadButton) addFullPictureLoadButton();
			if (isAddFullPictureLoadFixedMenu) addFullPictureLoadFixedMenu();
			if (isAddNewTabViewButton) addNewTabViewButton();
			if (!isAddKeyEvent) {
				document.addEventListener("keydown", addKeyEvent);
				isAddKeyEvent = true;
			}
		} else {
			iconObserver.disconnect();
			eyeObserver.disconnect();
			fn.remove(".FullPictureLoadFixedBtn,#FullPictureLoadEye,#FullPictureLoadFixedMenu,#FullPictureLoadFixedMenuB,div.addUrl");
			EyeNumElement = null;
			document.removeEventListener("keydown", addKeyEvent);
			isAddKeyEvent = false;
			isValidPage = false;
			globalImgArray = [];
		}
		await delay(200);
	};

	const toggleUI_B = async () => {
		if (!"SPA" in siteData || !isFn(siteData.SPA) || !!ge(".FullPictureLoadImage") || isOpenMenu || isFetching) return;
		isFetching = true;
		if (isOpenGallery) {
			closeGallery();
		}
		if (isOpenFilter) {
			closeFilter()
		}
		const validPage = await siteData.SPA();
		isFetching = false;
		if (!!validPage) {
			isValidPage = true;
			if (isAddFullPictureLoadButton) addFullPictureLoadButton();
			if (isAddFullPictureLoadFixedMenu) addFullPictureLoadFixedMenu();
			if (!isAddKeyEvent) {
				document.addEventListener("keydown", addKeyEvent);
				isAddKeyEvent = true;
			}
			await setFPLF();
			if ("next" in siteData) {
				await getNextLink(siteData.next, "\nURL變換 nextLink:");
			}
			if ("prev" in siteData) {
				await getPrevLink(siteData.prev, "\nURL變換 prevLink:");
			}
			if (isAddNewTabViewButton) {
				addNewTabViewButton();
				captureSrcB();
			}
		} else {
			iconObserver.disconnect();
			eyeObserver.disconnect();
			fn.remove(".FullPictureLoadFixedBtn,#FullPictureLoadEye,#FullPictureLoadFixedMenu,#FullPictureLoadFixedMenuB,div.addUrl");
			EyeNumElement = null;
			document.removeEventListener("keydown", addKeyEvent);
			isAddKeyEvent = false;
			isValidPage = false;
			globalImgArray = [];
		}
	};

	const getNextLink = async (next, text = "\n圖片全載NEXT:") => {
		let tempLink = null;
		if (isFn(next)) {
			tempLink = await next();
		} else if (isString(next) || isObject(next)) {
			tempLink = fn.ge(next);
		}
		debug(text, tempLink);
		try {
			if (tempLink !== null && tempLink !== undefined) {
				if (isString(tempLink)) {
					nextLink = tempLink;
					return tempLink;
				}
				if (isEle(tempLink) && ["A", "LINK"].some(t => tempLink?.tagName === t) && !tempLink?.getAttribute("_href")) {
					try {
						if (/^http/.test(tempLink.href)) {
							nextLink = tempLink.href;
							if (tempLink?.tagName === "LINK") {
								return nextLink;
							}
							return tempLink;
						} else {
							nextElement = tempLink;
						}
					} catch {}
				} else if (isEle(tempLink)) {
					let attr = tempLink.getAttribute("_href");
					if (attr) {
						nextLink = attr;
						return nextLink;
					} else {
						nextElement = tempLink;
					}
				}
			}
		} catch {}
		return tempLink;
	};

	const getPrevLink = async (prev, text = "\n圖片全載PREV:") => {
		prevLink = null;
		let tempLink = null;
		if (isNumber(prev)) {
			return (prevLink = 1);
		} else if (isFn(prev)) {
			tempLink = await prev();
		} else if (isString(prev) || isObject(prev)) {
			tempLink = fn.ge(prev);
		}
		debug(text, tempLink);
		try {
			if (tempLink !== null && tempLink !== undefined) {
				if (isString(tempLink)) {
					return (prevLink = tempLink);
				}
				if (isEle(tempLink) && ["A", "LINK"].some(t => tempLink?.tagName === t) && !tempLink?.getAttribute("_href")) {
					if (tempLink?.href?.startsWith("http")) {
						return (prevLink = tempLink.href);
					}
				} else if (isEle(tempLink)) {
					let attr = tempLink.getAttribute("_href");
					if (attr) {
						return (prevLink = attr);
					}
				}
			}
		} catch {}
	};

	const getTitle = async (title, dom = document) => {
		let text;
		if (isString(title)) {
			text = fn.gt(title, 1, dom);
		}
		if (isArray(title)) {
			if (title.length == 3) {
				let [s, mi, ci] = title
				let texts = fn.gat(s, dom, dom);
				text = texts.at(mi) + " - " + texts.at(ci);
			} else {
				let titles = title;
				let texts = titles.map(s => fn.dt({
					s
				}, dom));
				let [a_text, b_text] = texts;
				if (b_text?.toLowerCase()?.includes(a_text?.toLowerCase())) {
					text = b_text;
				} else {
					text = texts.join(" - ");
				}
			}
		} else if (isFn(title)) {
			text = await title();
		}
		return text;
	};

	let showOptions = false;
	let comicSwitch = false;

	//遍歷腳本站點JSON數據
	for (let i = 0, n = customData.length; i < n; i++) {
		const data = customData[i];
		tempData = data;
		let check = false;
		try {
			if ("url" in data) {
				const url = data.url;
				if (isObject(url)) {
					check = fn.checkUrl(url);
				} else if (isFn(url)) {
					check = await url();
				}
			}
			if ("reg" in data) {
				const reg = data.reg;
				if (isRegExp(reg)) {
					check = reg.test(siteUrl);
				} else if (isArray(reg)) {
					check = reg.some(r => r.test(siteUrl));
				} else if (isFn(reg)) {
					check = await reg();
				}
			}
			if (check) {
				const category = data.category;
				if (category == "comic" && data.enable == 0) {
					showOptions = true;
					comicSwitch = true;
				}
				const delayTime = data.delay;
				if (isNumber(delayTime)) await delay(delayTime);
				checkOptionsData();
				if (data.enable == 0) {
					//checkOptionsData();
					if (options.comic == 1 && category === "comic") {
						showOptions = true;
						options.enable = 1;
						debug("\n漫畫類預設關閉的此站規則已開啟");
					} else {
						//showOptions = true;
						debug("\n此規則禁用", data);
						continue;
					}
				}
				//if (data.enable != 0) checkOptionsData();
				const include = data.include;
				if (isString(include)) {
					if (!fn.ge(include)) {
						debug("\n頁面沒有包含必須的元素", data);
						continue;
					}
				} else if (isArray(include)) {
					const checkEles = include.every(e => !!fn.ge(e));
					if (!checkEles) {
						debug("\n頁面沒有包含必須的所有元素", data);
						continue;
					}
				}
				const exclude = data.exclude;
				if (isString(exclude)) {
					if (!!fn.ge(exclude)) {
						debug("\n頁面包含必須排除的元素", data);
						continue;
					}
				} else if (isArray(exclude)) {
					const checkEles = exclude.some(s => !!fn.ge(s));
					if (checkEles) {
						debug("\n頁面包含陣列選擇器中必須排除的元素", data);
						continue;
					}
				}
				if ("autoPager" in data && isObject(data.autoPager) && category !== "comic autoPager") {
					if (!fn.checkAutoPagerEle(data.autoPager)) {
						siteData = {};
						_this = {};
						continue;
					}
				}
				siteData = data;
				_this = data;
				if (!data.category.includes("autoPager") && !["none", "ad"].some(c => c === data.category)) {
					showOptions = true;
				}
				const loadingBakBlobURL = fn.dataURLtoBlobURL(loading_bak);
				const checkBlobURL = await fn.checkImgStatus(loadingBakBlobURL, 0);
				if (checkBlobURL.ok) {
					if (["nsfw1", "nsfw2"].some(c => c === data.category)) {
						loading_bak = fn.dataURLtoBlobURL(bunny_girl_loading_bak);
					} else {
						loading_bak = loadingBakBlobURL;
					}
					autoPagerLoading_gif = fn.dataURLtoBlobURL(autoPagerLoading_gif);
				}
				break;
			}
		} catch (error) {
			console.error("圖片全載規則出錯", error);
			debug("圖片全載規則出錯", data);
			debug("出錯之前的規則", customData[i - 1]);
			return;
		}
	}

	const isComic = siteData?.category?.includes("comic");
	const isInfinite = (siteData?.category === "comic" && siteData?.infiniteScroll || siteData?.category === "comic autoPager");
	const isAutoPager = siteData?.category?.includes("autoPager");

	_GM_registerMenuCommand(DL.str_204, () => {
		let num = prompt(DL.str_205, UI_zIndex);
		if (Number(num) && Number(num) > 6 && Number(num) < 2147483648) {
			_GM_setValue("UI_zIndex", num);
			location.reload();
		}
	});

	if (showOptions) {
		_GM_registerMenuCommand(DL.str_67, () => createPictureLoadOptionsShadowElement());
		if (!ge("#FullPictureLoadMainStyle") && !["none", "ad"].some(c => c === siteData.category)) {
			fn.css(FullPictureLoadStyle, "FullPictureLoadMainStyle");
		}
	}

	let doubleTouchNext = _GM_getValue("doubleTouchNext", 1);
	let isObserveURL = false;
	let isAddFancybox = false;
	let isOutputLog = false;
	let isAddNextEvent = false;
	let isAddPrevEvent = false;
	let isAddOpenInNewTab = false;
	let isAddLoadMore = false;
	let isAddLoopClick = false;
	let isClearLoop = false;
	let isAddLoop = false;
	let isAddMutationObserver = false;

	// SPA初始化變數
	const InitializeVariables = () => {
		globalImgArray = [];
		thumbnailSrcArray = [];
		videoSrcArray = [];
		fileUrlArray = [];
		siteJson = {};
		customTitle = null;
		apiCustomTitle = null;
		nextLink = null;
		nextElement = null;
		tempNextLink = null;
		isGetAll = false;
	};

	const historyEvent = event => {
		const url = event.target.location.href;
		setTimeout(() => {
			if (currentURL !== url.replace(new URL(url).hash, "")) {
				currentURL = url;
				InitializeVariables();
				toggleUI_B();
			}
		}, 200);
	};

	const historyObserver = () => {
		_unsafeWindow.addEventListener("popstate", historyEvent);
	};

	const headUrlObserver = async () => {
		const config = {
			attributes: false,
			childList: true,
			characterData: true,
			subtree: true
		};
		const callback = (mutations, observer) => {
			if (isGoToNext || isGoToPrev) return;
			let mutation;
			for (mutation of mutations) {
				if (
					mutation.type === "childList" && mutation.target.tagName === "TITLE" ||
					mutation.type === "childList" && !!mutation.addedNodes.length && [...mutation.addedNodes].some(e => e.tagName === "TITLE") ||
					mutation.type === "characterData" && mutation.target?.parentNode?.tagName === "TITLE"
				) {
					if (currentURL !== document.URL) {
						currentURL = document.URL;
						InitializeVariables();
						toggleUI_B();
						return (mutation = null);
					}
				}
			}
		};
		const observer = new MutationObserver(callback);
		observer.observe(document.head, config);
		historyObserver();
	};

	const navUrlEvent = event => {
		if (isGoToNext || isGoToPrev) return;
		const url = event.destination.url.replace(new URL(event.destination.url).hash, "");
		const c_host = new URL(currentURL).host;
		const e_host = new URL(url).host;
		if (event.downloadRequest !== null || c_host !== e_host || url.startsWith("blob") || url.startsWith("data")) return;
		if (currentURL !== url) {
			currentURL = url;
			InitializeVariables();
			toggleUI_B();
		}
	};

	const navUrlObserver = () => {
		//Firefox、Safari尚未支持Navigation API
		_unsafeWindow.navigation.addEventListener("navigate", navUrlEvent);
		historyObserver();
	};

	const gmUrlEvent = event => {
		if (isGoToNext || isGoToPrev) return;
		const url = event.url.replace(new URL(event.url).hash, "");
		if (currentURL !== url) {
			currentURL = url;
			InitializeVariables();
			toggleUI_B();
		}
	};

	const gmUrlObserver = () => {
		window.addEventListener("urlchange", gmUrlEvent);
		historyObserver();
	};

	const loopUrlObserver = () => {
		setInterval(() => {
			if (isGoToNext || isGoToPrev) return;
			const url = document.URL.replace(new URL(document.URL).hash, "");
			if (currentURL !== url) {
				currentURL = url;
				InitializeVariables();
				toggleUI_B();
			}
		}, 500);
	};

	const setCss = () => {
		if (("category" in siteData) && !["none", "ad"].some(c => c === siteData.category)) {
			fn.css(FullPictureLoadStyle, "FullPictureLoadMainStyle");
		}
		if (("category" in siteData) && options.fancybox == 1 && !isObject(siteData.autoPager) && !["none", "ad"].some(c => c === siteData.category) && siteData.fancybox?.v == 3 && siteData.fancybox?.insertLibrarys == 1) {
			fn.css(FancyboxV3Css, "FancyboxV3Css");
		} else if (("category" in siteData) && options.fancybox == 1 && !isObject(siteData.autoPager) && !["none", "ad"].some(c => c === siteData.category) && !fancyboxBlackList()) {
			fn.css(FancyboxV6Css, "FancyboxV6Css");
		}
		if ("css" in siteData && isString(siteData.css)) {
			fn.css(siteData.css, "FullPictureLoadCustomSiteStyle");
		}
		if ("mcss" in siteData && isString(siteData.mcss) && isM) {
			fn.css(siteData.mcss, "FullPictureLoadCustomMobileSiteStyle");
		}
		if ("hide" in siteData && (isString(siteData.hide) || isArray(siteData.hide))) {
			let text = siteData.hide;
			if (isArray(text)) {
				text = text.join(",");
			}
			text += "{display:none!important;}";
			fn.css(text, "FullPictureLoadCustomHide");
		}
	};

	const setFPLF = async () => {
		try {
			if ("clearEvent" in siteData) {
				await fn.clearElementEvent();
			}
			if ("clearLoop" in siteData) {
				if ("SPA" in siteData) {
					if (!isClearLoop) {
						isClearLoop = true;
						fn.clearAllTimer(3);
					}
				} else {
					fn.clearAllTimer(3);
				}
			}
			if ("loop" in siteData) {
				let loop;
				if (!isAddLoop) {
					isAddLoop = true;
					loop = setInterval(() => siteData.loop(), 500);
				}
				if ("loopTime" in siteData) {
					setTimeout(() => clearInterval(loop), siteData.loopTime);
				}
			}
			setCss();
			if (("loopClick" in siteData) && !isAddLoopClick) {
				isAddLoopClick = true;
				let obj = siteData.loopClick;
				if (isObject(obj)) {
					let {
						s,
						t
					} = obj;
					let time_id = setInterval(() => EClick(s), 200);
					if (Number(t)) {
						setTimeout(() => clearInterval(time_id), Number(t));
					}
				}
			}
			if ("MutationObserver" in siteData) {
				if (!isAddMutationObserver) {
					isAddMutationObserver = true;
					fn.addMutationObserver(siteData.MutationObserver);
				}
			}
			if ("init" in siteData) {
				const init_code = siteData.init;
				if (isString(init_code)) {
					await new Function("siteData", "fn", '"use strict";' + init_code)(siteData, fn);
				} else if (isFn(init_code)) {
					await init_code();
				}
			}
			setCss();
			if (("category" in siteData) && options.fancybox == 1 && siteData.category !== "none" && !isObject(siteData.autoPager) && siteData.fancybox?.v == 3 && siteData.fancybox?.insertLibrarys == 1 && !isAddFancybox) {
				isAddFancybox = true;
				addLibrarysV3();
				FancyboxOptionsV3();
			} else if (("category" in siteData) && options.fancybox == 1 && !siteData.category?.includes("autoPager") && !["none", "ad"].some(c => c === siteData.category) && !fancyboxBlackList() && !isAddFancybox) {
				isAddFancybox = true;
				addLibrarysV6();
				Fancyboxl10nV6();
			}
			if ("box" in siteData && isArray(siteData.box)) {
				const para = siteData.box;
				fn.createImgBox(...para);
			}
			if (!isOutputLog) {
				isOutputLog = true;
				if (("imgs" in siteData) || ("srcset" in siteData)) {
					debug("\nCSS/Xpath/JS選擇器:" + (siteData.srcset || siteData.imgs));
				}
				if ("threading" in siteData && isNumber(siteData.threading)) {
					options.threading = siteData.threading;
					debug("\n下載線程數:" + options.threading);
				}
			}
			if ("customTitle" in siteData) {
				customTitle = await getTitle(siteData.customTitle);
				if (isString(customTitle)) {
					if (("ot" in siteData)) {
						customTitle = fn.rStr(customTitle);
					} else {
						customTitle = fn.dt({
							t: customTitle
						});
					}
				}
				debug(`\n自定義標題:${customTitle}`);
			}
			if ("observeURL" in siteData && siteData.observeURL === "head" && !isObserveURL) {
				isObserveURL = true;
				headUrlObserver();
			}
			if ("observeURL" in siteData && siteData.observeURL === "nav" && !isObserveURL) {
				isObserveURL = true;
				if ("navigation" in _unsafeWindow) {
					navUrlObserver();
				} else {
					loopUrlObserver();
				}
			}
			if ("observeURL" in siteData && siteData.observeURL === "gm" && !isObserveURL) {
				isObserveURL = true;
				gmUrlObserver();
			}
			if ("observeURL" in siteData && siteData.observeURL === "loop" && !isObserveURL) {
				isObserveURL = true;
				loopUrlObserver();
			}
			if ("next" in siteData && !isAddNextEvent) {
				isAddNextEvent = true;
				const next = siteData.next;
				const nextE = await getNextLink(next);
				const callback = (event) => {
					if (event.type === "dblclick") {
						if (event?.target?.closest(".fancybox-container,.fancybox__container,.viewer-container,#FullPictureLoadOptionsShadowElement") || isChangeSize) return;
					}
					if ("observeURL" in siteData && isString(nextLink)) {
						fn.showMsg(DL.str_34.n, 0);
						return (location.href = nextLink);
					}
					if (isFn(next)) {
						fn.showMsg(DL.str_34.n, 0);
						if (isString(nextE)) {
							location.href = nextE;
						} else if (isEle(nextE)) {
							EClick(nextE);
						} else {
							fn.showMsg(DL.str_37);
						}
					} else if (isString(next)) {
						if (isEle(nextE)) {
							EClick(nextE);
							fn.showMsg(DL.str_35);
						} else if (isString(nextE)) {
							fn.showMsg(DL.str_34.n, 0);
							location.href = nextE;
						} else {
							fn.showMsg(DL.str_37);
						}
					}
				};
				if (isM && ("next" in siteData) && doubleTouchNext == 1) {
					document.addEventListener("dblclick", (event) => callback(event));
				}
				document.addEventListener("keydown", event => {
					if (isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || isDownloading || !isValidPage || ["INPUT", "TEXTAREA"].some(n => n === document.activeElement.tagName) || ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
					if (event.code === "ArrowRight" || event.key === "ArrowRight") callback(event);
				});
			}
			if ("prev" in siteData && !isAddPrevEvent) {
				isAddPrevEvent = true;
				let prev = siteData.prev;
				await getPrevLink(prev);
				document.addEventListener("keydown", async event => {
					if (isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || isDownloading || !isValidPage || ["INPUT", "TEXTAREA"].some(n => n === document.activeElement.tagName) || ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
					if (event.code === "ArrowLeft" || event.key === "ArrowLeft") {
						event.preventDefault();
						if (prev === 1) {
							fn.showMsg(DL.str_38);
							history.back();
							return;
						} else if (isString(prev)) {
							let ele = fn.ge(prev);
							if (ele) {
								EClick(ele);
								fn.showMsg(DL.str_39);
							} else {
								fn.showMsg(DL.str_40);
							}
						} else if (isFn(prev)) {
							prev = await prev();
							if (isString(prev)) {
								fn.showMsg(DL.str_34.p);
								location.href = prev;
							} else if (isEle(prev)) {
								EClick(prev);
								fn.showMsg(DL.str_39);
							} else {
								fn.showMsg(DL.str_40);
							}
						}
					}
				});
			}
			if ("autoClick" in siteData) {
				const autoClick = siteData.autoClick;
				if (isArray(autoClick)) {
					let [selector, delay] = autoClick;
					setTimeout(() => {
						let ele = fn.ge(selector);
						if (ele) {
							EClick(ele);
							debug(`\n圖片全載autoClick("${selector}")`, ele);
						}
					}, delay ?? 1000);
				} else if (isString(autoClick)) {
					let ele = fn.ge(autoClick);
					if (!!ele) {
						EClick(ele);
						debug(`\n圖片全載autoClick("${autoClick}")`, ele);
					}
				}
			}
			if ("observerClick" in siteData) {
				const observerClick = siteData.observerClick;
				let selectors;
				if (isString(observerClick)) {
					selectors = [observerClick];
				} else {
					selectors = observerClick;
				}
				fn.wait(() => selectors.some(selector => !!fn.ge(selector)), 30).then(() => {
					for (let [i, selector] of selectors.entries()) {
						setTimeout(() => {
							let ele = fn.ge(selector);
							if (ele) {
								const observer = new IntersectionObserver((entries, observer) => {
									for (let entry of entries) {
										if (entry.isIntersecting) {
											observer.unobserve(entry.target);
											EClick(entry.target);
											debug(`\n圖片全載observerClick("${selector}")\n`, entry.target);
											setTimeout(async () => {
												if (await fn.waitEle(selector, 30)) {
													observer.observe(fn.ge(selector));
												}
											}, 1000);
										}
									}
								});
								observer.observe(ele);
							}
						}, (i + 1) * 200);
					}
				});
			}
			if ("loadMore" in siteData && isString(siteData.loadMore) && !isAddLoadMore) {
				isAddLoadMore = true;
				const selector = siteData.loadMore;
				const callback = () => {
					if (_unsafeWindow.innerHeight + _unsafeWindow.pageYOffset >= document.body.offsetHeight - 200) {
						document.removeEventListener("scroll", callback);
						const ele = fn.ge(selector);
						if (!!ele) {
							EClick(ele);
							debug(`圖片全載loadMore("${selector}")`);
						}
						setTimeout(async () => {
							if (await fn.waitEle(selector, 30)) {
								document.addEventListener("scroll", callback);
							}
						}, 1000);
					}
				};
				document.addEventListener("scroll", callback);
			}
			if ("autoPager" in siteData && isObject(siteData.autoPager)) {
				fn.createAutoPagerButtons();
				const observer = siteData.autoPager?.observer;
				if (isString(observer)) {
					let ele = fn.gae(observer).at(-1);
					if (ele) fn.nextObserver.observe(ele);
				} else {
					const callback = async () => {
						if (_unsafeWindow.innerHeight + _unsafeWindow.pageYOffset >= document.body.offsetHeight - (siteData.autoPager?.bottom ?? screen.height)) {
							if (!autoPagerSwitch) return;
							document.removeEventListener("scroll", callback);
							await fn.infiniteScroll();
							await delay(siteData.autoPager?.sleep || 1000);
							document.addEventListener("scroll", callback);
						}
					};
					document.addEventListener("scroll", callback);
				}
				document.addEventListener("dblclick", () => fn.toggleAutoPager());
				let hide = siteData.autoPager?.hide;
				if (isString(hide)) {
					hide += "{display:none!important;}";
					fn.css(hide, "autoPagerHide");
				}
				if ("preloadNextPage" in siteData.autoPager) {
					setTimeout(() => fn.preloadNextPage(), 3000);
				}
			}
			if ("insertImg" in siteData) {
				const insertImg = siteData.insertImg;
				const autoDownload = siteData.autoDownload;
				if (isArray(insertImg)) {
					let autoStart;
					if (isArray(autoDownload)) {
						[autoStart] = autoDownload;
						autoStart = (autoStart == 1 || options.autoDownload == 1);
					}
					const [, insertMode] = insertImg;
					if (insertMode == 1 && !autoStart || insertMode == 2 && !autoStart) {
						if (options.autoInsert == 1) {
							if (GalleryInIcon == 0 && options.shadowGallery == 1 && siteData.aeg != 0 || GalleryInIcon == 0 && options.mobileGallery == 1 && siteData.aeg != 0) {
								await fn.immediateInsertImg();
							} else {
								fn.immediateInsertImg();
							}
						}
					}
				}
			}
			if ("autoDownload" in siteData) {
				const autoDownload = siteData.autoDownload;
				if (isArray(autoDownload)) {
					const [autoStart] = autoDownload;
					if (autoStart == 1 || options.autoDownload == 1) {
						DownloadFn();
					}
				}
			}
			if (GalleryInIcon == 0 && options.shadowGallery == 1 && siteData.aeg != 0 && options.autoDownload != 1 && ("imgs" in siteData) && !siteData.category.includes("autoPager") && !["none", "ad"].some(c => c === siteData.category) && !(("capture" in siteData) && ("SPA" in siteData))) {
				fn.hm();
				if ("SPA" in siteData && isFn(siteData.SPA)) {
					if (!!await siteData.SPA()) {
						createShadowGallery();
					}
				} else {
					createShadowGallery();
				}
			}
			if (GalleryInIcon == 0 && isM && options.mobileGallery == 1 && siteData.aeg != 0 && options.autoDownload != 1 && ("imgs" in siteData) && !siteData.category.includes("autoPager") && !["none", "ad"].some(c => c === siteData.category)) {
				fn.hm();
				if ("SPA" in siteData && isFn(siteData.SPA)) {
					if (!!await siteData.SPA()) {
						createFilterUI();
					}
				} else {
					createFilterUI();
				}
			}
			if (options.autoExport == 1 && options.autoDownload != 1) {
				exportImgSrcText();
			}
			if ("openInNewTab" in siteData && isString(siteData.openInNewTab) && !isAddOpenInNewTab) {
				isAddOpenInNewTab = true;
				const openInNewTab = siteData.openInNewTab;
				fn.openInNewTab(openInNewTab);
				fn.addMutationObserver(() => fn.openInNewTab(openInNewTab));
			}
			if ("topButton" in siteData && isBoolean(siteData.topButton) && siteData.topButton === true) {
				addReturnTopButton();
			}
			if ("setFancybox" in siteData) {
				setTimeout(() => {
					const setFancybox = siteData.setFancybox;
					if (isBoolean(setFancybox) && options.fancybox == 1 && (isString(siteData.srcset) || isString(siteData.imgs))) {
						fn.setFancybox(siteData.srcset || siteData.imgs);
					} else if (isString(setFancybox) && options.fancybox == 1) {
						fn.setFancybox(setFancybox);
					}
				}, 1200);
			}
			if ("preloadNext" in siteData) {
				//漫畫類預讀下一話圖片
				setTimeout(async () => {
					const {
						page,
						preloadNext,
						frame,
						imgs,
						customTitle: title
					} = siteData;
					try {
						if ("page" in siteData) {
							if (!page()) return;
						}
						if (!!nextLink && !!preloadNext && !isDownloading) {
							let cors_ok = await fn.checkCors(nextLink);
							//debug("\ncors_ok", cors_ok);
							let _fetch;
							if ("frame" in siteData) {
								_fetch = fn.iframeDoc(nextLink, frame);
							} else if (!cors_ok || ("cors" in siteData)) {
								_fetch = fn.xhrDoc(nextLink);
							} else {
								_fetch = fn.fetchDoc(nextLink);
							}
							_fetch.then(async nextDoc => {
								//debug("\nnextDoc", nextDoc);
								if (isBoolean(preloadNext) && preloadNext === true && isFn(imgs) && isFn(title)) {
									fn.picPreload(await imgs(nextDoc), await title(nextDoc), "next");
								} else if (isBoolean(preloadNext) && preloadNext === true && isString(imgs) && isFn(title)) {
									let arr = fn.getImgSrcArr(imgs, nextDoc);
									fn.picPreload(arr, await title(nextDoc), "next");
								} else if (isBoolean(preloadNext) && preloadNext === true && isString(imgs) && isArray(title)) {
									let arr = fn.getImgSrcArr(imgs, nextDoc);
									fn.picPreload(arr, await getTitle(title, nextDoc), "next");
								}
								if (isFn(preloadNext)) {
									preloadNext(nextDoc);
								}
							});
						}
					} catch (error) {
						console.error("圖片全載preloadNext()出錯", error);
					}
				}, 3000);
			}
		} catch (error) {
			console.error("圖片全載規則出錯", error);
			debug("圖片全載規則出錯", siteData);
			return;
		}
	};
	await setFPLF();

	if (("reg" in siteData) || ("url" in siteData)) {
		debug("\n列出此站資料", siteData);
		debug(`\n列出規則總數(${customData.length})`);
		debug("\n列出PHOTO規則", photoData);
		debug("\n列出NSFW規則", nsfw1Data);
		debug("\n列出NSFW+規則", nsfw2Data);
		debug("\n列出COMIC規則", comicData);
		debug("\n列出HCOMIC規則", hcomicData);
		debug("\n列出自動翻頁規則", autoPagerData);
		debug("\n列出去廣告規則", AD_Data);
		debug("\n列出未分類規則", noneData);
	}

	if (isArray(siteData.scrollEle) || isFn(siteData.scrollEle)) {
		_GM_registerMenuCommand(autoScrollAllElement == 0 ? "❌ " + DL.str_116 : "✔️ " + DL.str_116, () => {
			autoScrollAllElement == 0 ? _GM_setValue("autoScrollAllElement", 1) : _GM_setValue("autoScrollAllElement", 0);
			location.reload();
		});
	}

	if (isInfinite) {
		_GM_registerMenuCommand(comicInfiniteScrollMode == 0 ? "❌ " + DL.str_122 : "✔️  " + DL.str_122, () => {
			comicInfiniteScrollMode == 0 ? localStorage.setItem("FullPictureLoadComicInfiniteScrollMode", 1) : localStorage.setItem("FullPictureLoadComicInfiniteScrollMode", 0);
			location.reload();
		});
	}

	let autoDownload = siteData.autoDownload;

	if (!!autoDownload) {
		//自動下載快捷鍵
		document.addEventListener("keydown", event => {
			if (isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
			if (event.ctrlKey && (event.code === "NumpadDecimal" || event.code === "Period" || event.key === ".")) {
				if (options.autoDownload == 0) {
					fn.showMsg(DL.str_64, 0);
					options.autoDownload = 1;
					let jsonStr = JSON.stringify(options);
					localStorage.setItem("FullPictureLoadOptions", jsonStr);
					setTimeout(() => location.reload(), 2000);
				} else {
					isStopDownload = true;
					fn.clearAllTimer(2);
					options.autoDownload = 0;
					let jsonStr = JSON.stringify(options);
					localStorage.setItem("FullPictureLoadOptions", jsonStr);
					fn.clearSetTimeout();
					fn.showMsg(DL.str_65, 0);
					location.reload();
				}
			}
		});
	}

	//移動端手動模式頁面聚圖
	if (isM && "insertImg" in siteData) {
		let timeId;
		const touchstartCB = event => {
			//console.log(event);
			if ("page" in siteData) {
				if (!siteData.page()) return;
			}
			if (isFetching || isDownloading || isOpenFilter || isOpenFancybox || isOpenGallery || ge(".fancybox-container,#FullPictureLoadFavorSites")) return;
			const check = (e) => {
				if (["SPAN", "DIV", "A"].some(t => t === e.target.tagName) && getComputedStyle(e.target).getPropertyValue("background-image") != "none") {
					return true;
				}
				if (["A", "FIGURE", "SPAN"].some(t => t === e.target.tagName)) {
					return !!e.target.querySelector("img,canvas");
				}
				if (e.target.tagName === "A" && e.target?.previousElementSibling?.nodeName === "IMG") {
					return true;
				}
				if (["IMG", "CANVAS"].some(t => t === e.target.tagName) && !["Full"].some(id => e.target?.id?.startsWith(id)) && !["fancybox", "viewer-move"].some(className => e.target?.className?.startsWith(className))) {
					return true;
				}
				return false;
			};
			if (check(event)) {
				timeId = setTimeout(() => {
					copyImgSrcText();
				}, 500);
			}
		};
		const clearCB = () => {
			if (isFetching || isDownloading) return;
			clearTimeout(timeId);
		};
		document.addEventListener("touchstart", touchstartCB);
		document.addEventListener("touchmove", clearCB);
		document.addEventListener("touchend", clearCB);
	}

	//debug("\n最終options物件\n", options);

	//捕獲圖片網址
	async function captureSrc(mutationList) {
		if (isChangeNum || isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || isDownloading || isFetching || FullPictureLoadShowEye == 0) return;
		if (mutationList) {
			for (const mutation of mutationList) {
				if (mutation.type === "childList" && mutation?.target?.id === "FullPictureLoadCaptureNum") {
					return;
				}
			}
			//console.log(mutationList);
		}
		let srcs = await getImgs(siteData.capture || siteData.srcset || siteData.imgs);
		let imagePreloadArray = [];
		for (let src of srcs) {
			if (!captureSrcArray.includes(src)) {
				captureSrcArray.push(src);
				imagePreloadArray.push(src);
			}
		}
		if (isEle(EyeNumElement) && captureTotal != captureSrcArray.length) {
			isChangeNum = true;
			captureTotal = captureSrcArray.length;
			updateEyeNum(captureTotal);
			await delay(100);
			isChangeNum = false;
			if (GalleryInIcon == 0 && options.shadowGallery == 1 && siteData.aeg != 0) {
				setTimeout(() => createShadowGallery(), 200);
			}
		}
	}

	async function captureSrcB(invalidPage = 0) {
		if (isChangeNum || isOpenOptionsUI || isOpenGallery || isOpenFancybox || isOpenFilter || isDownloading || isFetching || FullPictureLoadShowEye == 0) return;
		if (invalidPage === 1 && EyeNumElement?.innerText != 0) {
			isChangeNum = true;
			updateEyeNum(0);
			await delay(100);
			isChangeNum = false;
			return;
		}
		if (!["m2ph.xyz", "bdsmlr.com"].some(h => fn.lh.includes(h))) {
			await delay(900);
		}
		let captureSrcArray = await getImgs(siteData.capture || siteData.srcset || siteData.imgs);
		let num = captureSrcArray.length;
		if (isEle(EyeNumElement)) {
			isChangeNum = true;
			updateEyeNum(num);
			await delay(100);
			isChangeNum = false;
			lastValidPageURL = currentURL;
			if (GalleryInIcon == 0 && options.shadowGallery == 1 && siteData.aeg != 0) {
				setTimeout(() => createShadowGallery(), 200);
			}
		}
	}

	//動態捕獲圖片網址
	if ((isString(siteData.srcset) || isString(siteData.imgs)) && !isArray(siteData.insertImg) || isFn(siteData.capture)) {
		if (FullPictureLoadShowEye == 1 && siteData.eye != 0) {
			await delay(1000);
			isCaptureMode = true;
			addNewTabViewButton();
			captureSrc();
		}
	}

	const defaultFavor = `main-background-color,#333
    text-color,#fff
    background-color,#454d55
    小黄书 xChina,https://xchina.site/
    紳士会所,https://www.hentaiclub.net/
    图宅网,https://www.tuzac.com/
    丝袜客,https://siwake.cc/
    萌图社,http://www.446m.com/
    美图社,https://928r.com/
    六色美图,https://www.06se.com/
    秀色女神,https://www.xsnvshen.co/
    4KHD,https://www.4khd.com/
    Xiunice.com,https://xiunice.com/
    AVJB,https://avjb.com/albums/
    Xasiat,https://www.xasiat.com/albums/
    EVERIA.CLUB,https://everia.club/
    HotGirl World,https://hotgirl.world/
    Cup2D,https://cup2d.com/
    AHottie,https://ahottie.net/
    HotAsiaGirl,https://hotgirl.asia/photos/
    紳士漫畫,https://www.wnacg.com/albums-index-cate-3.html
    肉感美ガール,https://bi-girl.net/
    エロ画像まとめ,https://geinou-nude.com/`;

	let FavorOpenInNewTab = _GM_getValue("FavorOpenInNewTab", 0);

	// 創建收藏
	const createFavorShadowElement = () => {

		const FavorSitesShadowElement = fn.ace("bodya", "div", {
			id: "FullPictureLoadFavorSites"
		});
		const shadow = FavorSitesShadowElement.attachShadow({
			mode: "closed"
		});
		hidePageScrollbarY();

		fn.ace(shadow, "style", {
			type: "text/css",
			innerHTML: `
#FavorSitesMain {
    z-index: ${UI_zIndex - 2} !important;
}
#FavorUl {
    width: 100%;
    background-color: transparent;
    list-style-type: none;
    display: grid;
    list-style: none;
    margin: 10px 0px 0px 0px;
    padding: 0px;
    border: 0;
    font: inherit;
    vertical-align: baseline;
}

.favor-item {
    float: left;
    width: unset;
    height: unset;
    min-height: unset;
    max-height: 44px;
    margin: 0px 10px 10px 0px;
    position: unset;
    line-height: 24px !important;
    padding: 3px;
    font: unset;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    font-weight: 500;
    font-size: 16px;
    text-align: center;
    border-radius: 8px;
    white-space: nowrap;
    list-style: none;
    cursor: pointer;
}

.favor-item a {
    display: block;
    text-align: center;
    text-decoration: unset;
    font-family: ui-monospace, sans-serif, system-ui, -apple-system, Segoe UI, Arial;
    font-weight: 500;
    font-size: 16px;
    background-color: unset;
    border-color: unset;
    margin: 0;
}

#editFavorTextarea {
    display: block;
    height: 30em;
    resize: both;
    overflow: auto;
    background-color: unset;
    color: #000000;
    border-color: #000000;
    margin: 0px auto;
    padding: 5px;
    max-width: unset;
    max-height: unset;
}

#editFavorDiv {
    text-align: center;
    background-color: #fafafa;
    margin: 0;
    padding-top: 6px;
}

.editFavorButton {
    min-width: 70px;
    line-height: 25px;
    margin: 5px;
    float: none;
    padding: 0;
    color: #000000;
    border: 1px solid #a0a0a0;
    background-color: transparent;
    cursor: pointer;
}`
		});

		const FavorSitesElement = fn.ace(shadow, "div", {
			id: "FavorSitesMain"
		}, {
			inset: "0",
			width: "99%",
			height: "98%",
			margin: "auto",
			padding: "10px",
			position: "fixed",
			opacity: "1",
			backgroundColor: "#333",
			fontSize: "14px",
			overflow: "hidden auto"
		});

		const reSize_cb = () => {
			const verticalScreen = _unsafeWindow.innerHeight / _unsafeWindow.innerWidth > 1;
			let ul = ge("#FavorUl", shadow);
			if (ul) {
				ul.style.gridTemplateColumns = `${fn.arr(Math.floor(_unsafeWindow.innerWidth / 180), () => "1fr").join(" ")}`;
				if (isM) {
					if (verticalScreen) {
						ul.style.width = "calc(100% - 5px)";
					} else {
						ul.style.width = "calc(100% - 2px)";
					}
				}
			}
			let edit = ge("#editFavorDiv", shadow);
			if (edit && isM) {
				if (verticalScreen) {
					edit.style.width = "calc(100% - 18px)";
				} else {
					edit.style.width = "calc(100% - 14px)";
				}
			} else if (edit) {
				if (verticalScreen) {
					edit.style.width = "calc(100% - 2px)";
				} else {
					edit.style.width = "calc(100% - 6px)";
				}
			}
		};

		const createFavorTextarea = () => {
			FavorSitesElement.style.backgroundColor = "#fafafa";
			let favorData = _GM_getValue("favorData", defaultFavor);
			let editFavorDiv = fn.ace(FavorSitesElement, "div", {
				id: "editFavorDiv"
			}, {
				height: "calc(100% - 20px)"
			});
			if (isM) {
				const verticalScreen = _unsafeWindow.innerHeight / _unsafeWindow.innerWidth > 1;
				if (verticalScreen) {
					editFavorDiv.style.width = "calc(100% - 18px)";
				} else {
					editFavorDiv.style.width = "calc(100% - 14px)";
				}
			} else {
				editFavorDiv.style.width = "calc(100% - 6px)";
			}
			let textarea = fn.ace(editFavorDiv, "textarea", {
				id: "editFavorTextarea"
			}, {
				width: "calc(100% - 20px)",
				height: "calc(100% - 30px)"
			});
			[{
				text: DL.str_111,
				id: "editFavorExportBtn",
				cfn: event => {
					cancelDefault(event);
					const blob = new Blob([textarea.value], {
						type: "text/plain"
					});
					const date = new Date();
					const time = [
						date.getFullYear(),
						date.getMonth() + 1,
						date.getDate(),
						date.getHours(),
						date.getMinutes()
					].map(e => String(e).padStart(2, "0")).join("-");
					saveData(blob, `FullPictureLoadFavoriteSites [${time}].txt`);
				}
			}, {
				text: DL.str_212,
				id: "editFavorImportBtn",
				cfn: event => {
					cancelDefault(event);
					const input = fn.ace(FavorSitesElement, "input", {
						type: "file",
						accept: ".txt",
						acceptCharset: "utf-8",
						onchange: () => {
							if (input.value !== input.initialValue) {
								const [file] = input.files;
								if (!file) {
									return;
								}
								const reader = new FileReader();
								reader.onloadend = event => {
									input.remove();
									textarea.value = event.target.result;
								};
								reader.readAsText(file, "utf-8");
							}
						}
					}, {
						display: "none"
					});
					input.initialValue = input.value;
					input.click();
				}
			}, {
				text: DL.str_131,
				id: "editFavorSaveBtn",
				cfn: event => {
					cancelDefault(event);
					_GM_setValue("favorData", textarea.value);
					editFavorDiv.remove();
					createFavor();
				}
			}, {
				text: DL.str_132,
				id: "editFavorCloseBtn",
				cfn: event => {
					cancelDefault(event);
					editFavorDiv.remove();
					createFavor();
				}
			}].forEach(obj => fn.ace(editFavorDiv, "button", {
				id: obj.id,
				className: "editFavorButton",
				innerText: obj.text,
				onclick: obj.cfn
			}));
			textarea.value = favorData.replace(/(\n)(\s+)/g, "$1");
		};

		const createFavor = () => {
			let favorData = _GM_getValue("favorData", defaultFavor);
			FavorSitesElement.style.backgroundColor = "#333";
			let FavorUl = fn.ace(FavorSitesElement, "ul", {
				id: "FavorUl"
			}, {
				gridTemplateColumns: `${fn.arr(Math.floor(_unsafeWindow.innerWidth / 180), () => "1fr").join(" ")}`
			});
			if (isM) {
				const verticalScreen = _unsafeWindow.innerHeight / _unsafeWindow.innerWidth > 1;
				if (verticalScreen) {
					FavorUl.style.width = "calc(100% - 5px)";
				} else {
					FavorUl.style.width = "calc(100% - 2px)";
				}
			}
			let favorDataArray = favorData.split("\n").filter(Boolean);
			let color = "#fff";
			let backgroundColor = "#454d55";
			for (let favor of favorDataArray) {
				if (favor?.trim()?.startsWith("//") || favor?.trim()?.startsWith("/*")) {
					continue;
				}
				try {
					let [name, value] = favor.split(",");
					name = name.trim();
					value = value.trim();
					if (name === "main-background-color") {
						FavorSitesElement.style.backgroundColor = value;
					} else if (name === "text-color") {
						color = value;
					} else if (name === "background-color") {
						backgroundColor = value;
					} else {
						let li = fn.ace(fragment, "li", {
							className: "favor-item"
						}, {
							backgroundColor,
							color
						});
						fn.ace(li, "a", {
							innerText: name,
							href: value,
							target: (FavorOpenInNewTab == 1) ? "_blank" : ""
						}, {
							color
						});
					}
				} catch (error) {
					console.error(error);
				}
			}
			[{
				text: DL.str_130,
				cfn: event => {
					cancelDefault(event);
					createFavorTextarea();
					FavorUl.remove();
				}
			}, {
				text: DL.str_129,
				cfn: event => {
					cancelDefault(event);
					if (!isOpenFilter && !isOpenGallery) fn.remove("#overflowYHidden");
					FavorSitesShadowElement.remove();
					_unsafeWindow.removeEventListener("resize", reSize_cb);
				}
			}].forEach(obj => fn.ace(fragment, "li", {
				className: "favor-item",
				innerText: obj.text,
				onclick: obj.cfn
			}, {
				backgroundColor,
				color
			}));
			FavorUl.append(fragment);
		};
		createFavor();

		_unsafeWindow.addEventListener("resize", reSize_cb);

	};

	_GM_registerMenuCommand(DL.str_125, () => {
		const keys = [
			"newTabViewLightGallery",
			"newWindowData",
			"FullPictureLoadComicInfiniteScrollMode",
			"FullPictureLoadOptions",
			"FullPictureLoadCustomDownloadVideo",
			"FullPictureLoadShowEye",
			"FullPictureLoadBlacklist"
		];
		for (const key of keys) {
			if (key in localStorage) {
				localStorage.removeItem(key);
			}
		}
		location.reload();
	});

	_GM_registerMenuCommand(DL.str_126, () => {
		const GM_keys = _GM_listValues();
		if (GM_keys.length > 0) {
			for (let key of GM_keys) _GM_deleteValue(key);
		}
		location.reload();
	});

	_GM_registerMenuCommand(DL.str_230, () => {
		_GM_setValue("icon_top", "auto");
		_GM_setValue("icon_bottom", "24px");
		_GM_setValue("icon_left", "24px");
		_GM_setValue("icon_right", "auto");
		_GM_setValue("eye_icon_top", "auto");
		_GM_setValue("eye_icon_bottom", "24px");
		_GM_setValue("eye_icon_left", "auto");
		_GM_setValue("eye_icon_right", "24px");
		_GM_setValue("eye_menu_top", "auto");
		_GM_setValue("eye_menu_bottom", "22px");
		_GM_setValue("eye_menu_left", "auto");
		_GM_setValue("eye_menu_right", "64px");
		location.reload();
	});

	//簡易模式規則
	if (!("category" in siteData)) {
		isSimpleMode = true;
		const setFullPictureLoadSimpleMode = localStorage.getItem("setFullPictureLoadSimpleMode") ?? 0;
		_GM_registerMenuCommand(setFullPictureLoadSimpleMode == 0 ? "❌ " + DL.str_191 : "✔️  " + DL.str_191, () => {
			setFullPictureLoadSimpleMode == 0 ? localStorage.setItem("setFullPictureLoadSimpleMode", 1) : localStorage.setItem("setFullPictureLoadSimpleMode", 0);
			location.reload();
		});
		let menu_command_id_1;
		let menu_command_id_2;
		let menu_command_id_3;
		const setMode = () => {
			menu_command_id_1 = _GM_registerMenuCommand(DL.str_67, createPictureLoadOptionsShadowElement);
			checkOptionsData();
			siteData = {
				imgs: () => {
					let eles = gae("a,p,div,span,li,figure,article,picture>source,canvas,svg,img:not(.FullPictureLoadFixedBtn)");
					let shadowRootEles = eles.map(ele => {
						if (("shadowRoot" in ele) && ele?.shadowRoot?.nodeName == "#document-fragment") {
							return gae("a,p,div,span,li,figure,article,picture>source,canvas,svg,img", ele.shadowRoot);
						}
						return null;
					}).filter(Boolean).flat();
					if (shadowRootEles.length) {
						eles = [...eles, ...shadowRootEles];
					}
					return fn.getImgSrcset(eles).map(src => {
						if (src.includes(".sinaimg.")) {
							return src.replace(/\/orj\d+\/|\/mw\d+\//, "/large/");
						}
						if (src.includes("imx.to/u/t/")) {
							return src.replace("/t/", "/i/");
						}
						if (src.includes(".imgbox.")) {
							return fn.rt(src, [
								["thumbs", "images"],
								["_t.", "_o."],
								["_b.", "_o."]
							]);
						}
						return fn.rt(src, [
							[/(\.md)(\.\w+)$/i, "$2"]
						]);
					});
				},
				repeat: 1,
				SPA: true,
				category: "photo"
			};
			addFullPictureLoadButton();
			if (isPC) {
				addFullPictureLoadFixedMenu();
				document.addEventListener("keydown", addKeyEvent);
			}
			if (!ge("#FullPictureLoadMainStyle")) {
				fn.css(FullPictureLoadStyle, "FullPictureLoadMainStyle");
			}
			if (!("Fancybox" in _unsafeWindow)) {
				addLibrarysV6();
				Fancyboxl10nV6();
			}
			_GM_unregisterMenuCommand(menu_command_id_2);
			registerB();
		};
		const removeMode = () => {
			_GM_unregisterMenuCommand(menu_command_id_1);
			siteData = {};
			fn.remove(".FullPictureLoadFixedBtn,#FullPictureLoadFixedMenu");
			if (isPC) {
				document.removeEventListener("keydown", addKeyEvent);
			}
			_GM_unregisterMenuCommand(menu_command_id_3);
			registerA();
		};
		const registerA = () => {
			menu_command_id_2 = _GM_registerMenuCommand(DL.str_163, setMode);
		};
		const registerB = () => {
			menu_command_id_3 = _GM_registerMenuCommand(DL.str_164, removeMode);
		};
		registerA();
		if (setFullPictureLoadSimpleMode == 1) {
			setTimeout(() => setMode(), 500);
		}
	}

	if (!isSimpleMode && !siteData.category?.includes("autoPager") && !["none", "ad"].some(c => c === siteData.category)) {
		if (siteData.key != 0) {
			if (isPC) {
				if (ShowFullPictureLoadFixedMenu === 1) addFullPictureLoadFixedMenu();
			}
			if (!isAddKeyEvent) {
				document.addEventListener("keydown", addKeyEvent);
				isAddKeyEvent = true;
			}
		}

		if (siteData.icon == 0) {
			//return;
		} else if (options.icon == 1 || siteData.icon == 1) {
			addFullPictureLoadButton();
		}
		setTimeout(() => {
			if (!isOpenGallery && !isOpenFilter) {
				toggleUI();
			}
		}, 500);
	}

	if (fn.lh.includes(".v2ph.")) {
		_GM_registerMenuCommand("🍪 Set V2PH CF Cookie", () => {
			v2ph_cookie = prompt("Set Cookie", v2ph_cookie || "");
			if (!!v2ph_cookie) {
				_GM_setValue("v2ph_cookie", v2ph_cookie);
			}
		});
	} else if (fn.lh.includes("myreadingmanga")) {
		_GM_registerMenuCommand("🍪 Set MyReadingManga CF Cookie", () => {
			myreadingmanga_cookie = prompt("Set Cookie", myreadingmanga_cookie || "");
			if (!!myreadingmanga_cookie) {
				_GM_setValue("myreadingmanga_cookie", myreadingmanga_cookie);
			}
		});
	} else {
		_GM_registerMenuCommand(("_cf_cookie" in localStorage) ? "🍪 Update Cloudflare Clearance Cookies" : "🍪 Set Cloudflare Clearance Cookies", () => {
			let cookie = prompt("Set Cookie", localStorage.getItem("_cf_cookie") || "");
			if (!!cookie) {
				localStorage.setItem("_cf_cookie", cookie);
			}
		});
	}

})(axios);