/* jshint esversion: 9 */
// ==UserScript==
// @name         Fantia downloader
// @name:en      Fantia downloader
// @name:ja      Fantia downloader
// @namespace    http://tampermonkey.net/
// @version      3.1.9
// @description  Download your Fantia rewards more easily!
// @description:en  Download your Fantia rewards more easily!
// @description:ja  Download your Fantia rewards more easily!
// @author       suzumiyahifumi
// @include        https://fantia.jp/posts/*
// @include        https://fantia.jp/fanclubs/*/backnumbers*
// @icon         https://www.google.com/s2/favicons?domain=fantia.jp
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js
// @grant        none
// @downloadURL https://update.greasyfork.icu/scripts/423306/Fantia%20downloader.user.js
// @updateURL https://update.greasyfork.icu/scripts/423306/Fantia%20downloader.meta.js
// ==/UserScript==
//log: 3.1.5 remove jQuery inject
(function () {
	'use strict';
	Date.prototype.Format = function (fmt) {
		let o = {
			"M+": this.getMonth() + 1,
			"d+": this.getDate(),
			"h+": this.getHours(),
			"m+": this.getMinutes(),
			"s+": this.getSeconds(),
			"q+": Math.floor((this.getMonth() + 3) / 3),
			"S": this.getMilliseconds()
		};
		if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
		for (let k in o)
			if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
		return fmt;
	};
	$('head').append(``);
	$('nav.scroll-tabs>div').append(`擷取下載`);
	let init = setInterval(() => {
		let pageType = (window.location.href.match(/https:\/\/fantia\.jp\/posts\/*/g) != null) ? `post` : `backnumber`;
		let post = (pageType == "backnumber") ? 1 : $(`.the-post`).length;
		if (window.setting) {
			var postContent = (window.setting.metaData.content == undefined || window.setting.metaData.content.length == 0) ? true : false;
		} else {
			window.setting = new Setting();
		}
		if (($(`div[id^='post-content-id-']`).length != 0 || postContent) && post != 0) {
			// for nonImgbox
			$(`div.image-thumbnails`).each((i, div) => {
				let b = $(div).closest('div.content-block').find(`div.text-center > div.btn-group-tabs`);
				if (b.length == 0) $(div).before(`
`);
			});
			// for single image
			$(`a.fantiaImage`).each((i, div) => {
				$(div).before(``);
			});
			// for post
			$(`.the-post .post-thumbnail .img-default`).closest(`div.post-thumbnail`).before(``);
			
			// make sure the button has been inserted before stopping interval.
			if ($(`div[role="group"]`).length) {
				window.getDownLoadButton();
				clearInterval(init);
			}
		}
	}, 500);
	class Setting {
		constructor() {
			this.pageType = (window.location.href.match(/https:\/\/fantia\.jp\/posts\/*/g) != null) ? `post` : `backnumber`;
			let qs = new URLSearchParams((this.pageType == `post`) ? `` : (window.location.search == ``) ? $(`div.text-center>a.active`).attr("href").split("?")[1] : window.location.search);
			this.jsonUrl = `https://fantia.jp/api/v1/${(this.pageType == `post`) ? `posts/${window.location.href.split("/").pop()}` : `fanclub/backnumbers/monthly_contents/plan/${qs.get("plan")}/month/${qs.get("month")}`}`;
			let authorId = $("h1.fanclub-name>a").attr(`href`).split("/").pop();
			const keyArr = [`cookieSave`, `lang`, `authorId_${authorId}`, `generalSaveZIP`, `generalSaveFile`, `authorSaveZIP_${authorId}`, `authorSaveFile_${authorId}`, `dateFormat`];
			this.cookieOri = document.cookie;
			this.cookie = this.cookieParser(keyArr);
			this.cookieSave = this.cookie.cookieSave || this.defaultCookie(`cookieSave`);
			this.setCookie({
				cookieSave: this.cookieSave,
				lang: (this.cookieSave == `On`) ? this.cookie.lang : this.getOriLang(),
				generalSave: this.defaultCookie(`generalSave`),
				authorSave: this.defaultCookie(`authorSave`),
				authorSaveCheck: this.cookie[`authorId_${authorId}`] || this.defaultCookie(`authorSaveCheck`),
				authorId: authorId,
				dateFormat: (this.cookieSave == `On`) ? this.cookie.dateFormat : this.defaultCookie(`dateFormat`)
			});
			if (this.cookieSave == `On`) {
				let g = this.cookieParser([`generalSaveZIP`, `generalSaveFile`]);
				this.setCookie({
					generalSave: {
						zipName: g.generalSaveZIP,
						fileName: g.generalSaveFile
					}
				});
				if (this.cookie[`authorId_${authorId}`] || this.cookie[`authorId_${authorId}`] == `On`) {
					let a = this.cookieParser([`authorSaveZIP_${authorId}`, `authorSaveFile_${authorId}`]);
					this[`authorId_${authorId}`] = `On`;
					this.setCookie({
						authorSaveCheck: `On`,
						authorSave: {
							zipName: a[`authorSaveZIP_${authorId}`],
							fileName: a[`authorSaveFile_${authorId}`]
						}
					});
				}
			}
			this.saveCookie(false);
			this.metaJson = {};
			this.metaData = {};
			if (window.csrfToken) {
				$.ajaxSetup({
					headers: {
						"x-csrf-token": window.csrfToken
					}
				});
			}
			let self = this;
			$.get(this.jsonUrl, (json) => {
				self.metaJson = json;
				let data = json[self.pageType];
				self.metaData = {
					user: data.fanclub.creator_name,
					uid: data.fanclub.id,
					content: data[`${self.pageType}_contents`]
				};
			});
			return this;
		}
		saveCookie(check) {
			if (this.cookie.cookieSave == 'On') {
				let date = new Date();
				date.setDate(date.getDate() + 75);
				let cookie = {
					cookieSave: this.cookie.cookieSave,
					lang: this.cookie.lang,
					dateFormat: this.cookie.dateFormat,
					Expires: date.toUTCString()
				};
				cookie.generalSaveZIP = this.cookie.generalSave.zipName;
				cookie.generalSaveFile = this.cookie.generalSave.fileName;
				if (this[`authorId_${this.authorId}`] == 'On') {
					cookie[`authorId_${this.authorId}`] = 'On';
					cookie[`authorSaveZIP_${this.authorId}`] = this.cookie.authorSave.zipName;
					cookie[`authorSaveFile_${this.authorId}`] = this.cookie.authorSave.fileName;
				}
				this.updateCookie(cookie);
			} else {
				let date = new Date();
				date.setDate(date.getTime() - 1);
				let cookie = {
					cookieSave: 'Off',
					Expires: date.toUTCString()
				};
				cookie[`authorId_${this.authorId}`] = 'Off';
				this.updateCookie(cookie);
			}
			return (check != false) ? alert(this.getDefault(`saveMessage`, this.lang)) : true;
		}
		updateCookie(cookie = undefined) {
			let Expires = cookie.Expires;
			delete cookie.Expires;
			for (let [key, value] of Object.entries(cookie)) {
				document.cookie = `${key}=${value}; Expires=${Expires}; Path=/`;
			}
			this.cookieOri = document.cookie;
			return this.cookieOri;
		}
		cookieParser(keyArr) {
			return (typeof keyArr == `string`) ? document.cookie.split('; ').map(row => row.split('=')).filter(row => keyArr == row[0])[1] || undefined : Object.fromEntries(document.cookie.split('; ').map(row => row.split('=')).filter(row => keyArr.includes(row[0])));
		}
		setCookie(settingObj) {
			for (let [key, value] of Object.entries(settingObj)) {
				this.cookie[key] = value;
				this[key] = value;
			}
			return this.cookie;
		}
		setLang(Lang) {
			let lang = Lang || this.getOriLang().toLowerCase();
			if (/^ja\b/.test(lang)) this.lang = `ja`;
			if (/^zh\b/.test(lang)) this.lang = `zh`;
			return this.lang;
		}
		getOriLang() {
			let res = `en`;
			let lang = (navigator.language || navigator.browserLanguage).toLowerCase();
			if (/^ja\b/.test(lang)) res = `ja`;
			if (/^zh\b/.test(lang)) res = `zh`;
			return res;
		}
		defaultCookie(key) {
			let defaultSetting = {
				cookieSave: "Off",
				lang: this.getOriLang(),
				generalSave: {
					zipName: `{postTitle}_{boxTitle}`,
					fileName: `{imgIndex:0}`
				},
				authorSave: {
					zipName: `[{user}]{postTitle}_{boxTitle}`,
					fileName: `{boxTitle}_{imgIndex:0}`
				},
				authorSaveCheck: `Off`,
				dateFormat: `yyyyMMdd`
			};
			return (key) ? defaultSetting[key] : defaultSetting;
		}
		getDefault(key, lang = undefined) {
			let defaultSetting = {
				en: {
					downloadImg: `Download Images`,
					downloadImgZip: `Download ZIP`,
					retrieving: `Retrieving Link`,
					zipping: `Zipping`,
					processing: `Processing`,
					done: `Done`,
					// 按紐
					settingCenter: `Setting`,
					cookieButton: `Cookie`,
					languageButton: `言語設定/Language/界面語言`,
					generalSave: `Global Save`,
					authorSave: `Author Save`,
					zipName: `ZIP file name`,
					fileName: `image file name`,
					dateFormat: `Date Format`,
					saveSetting: `Apply Setting`,
					closeSetting: `Close`,
					tableParams: `Parameter`,
					tableMean: `Mean`,
					saveMessage: `Setting has save!`,
					// 參數
					user: `Creator Name`,
					uid: `Creator ID`,
					postTitle: `Post Title`,
					postId: `Post ID`,
					boxTitle: `Image Box Title`,
					"imgIndex:0": `Index for image, Number is first index number.`,
					plan: `Name of Plan`,
					fee: `fee of Plan`,
					postDate: `Post Date`,
					taskDate: `Download Date`,
					ext: `Filename Extension`
				},
				ja: {
					downloadImg: `ダウンロード`,
					downloadImgZip: `ZIPダウンロード`,
					retrieving: `取得中`,
					zipping: `zip圧縮`,
					processing: `圧縮`,
					done: `ダウンロード完了`,
					// 按紐
					settingCenter: `設定`,
					cookieButton: `Cookie`,
					languageButton: `Language/言語設定/界面語言`,
					generalSave: `保存の設定`,
					authorSave: `クリエイターに保存`,
					zipName: `ZIPフォルダ`,
					fileName: `ファイル`,
					dateFormat: `日時の設定`,
					saveSetting: `設定を保存する`,
					closeSetting: `閉じる`,
					tableParams: `パラメータ`,
					tableMean: `効果`,
					saveMessage: `設定を保存しました!`,
					// 參數
					user: `クリエイターの名前`,
					uid: `クリエイターのID`,
					postTitle: `投稿のタイトル`,
					postId: `投稿のID`,
					boxTitle: `イラストボックスのタイトル`,
					"imgIndex:0": `画像のインデックス、番号は最初のインデックス番号です`,
					plan: `プラン名`,
					fee: `プランの月額料金`,
					postDate: `公開日時`,
					taskDate: `ダウンロード日時`,
					ext: `拡張子`
				},
				zh: {
					downloadImg: `全圖片下載`,
					downloadImgZip: `ZIP 下載`,
					retrieving: `擷取連結中`,
					zipping: `壓縮檔案中`,
					processing: `壓縮`,
					done: `下載已完成`,
					// 按紐
					settingCenter: `設定`,
					cookieButton: `Cookie`,
					languageButton: `Language/界面語言/言語設定`,
					generalSave: `全域設定`,
					authorSave: `作者特訂`,
					zipName: `壓縮檔檔名`,
					fileName: `圖片檔檔名`,
					dateFormat: `日期時間格式`,
					saveSetting: `儲存設定`,
					closeSetting: `關閉`,
					tableParams: `參數`,
					tableMean: `效果`,
					saveMessage: `設定已儲存!`,
					// 參數
					user: `創作者名稱`,
					uid: `創作者 ID`,
					postTitle: `投稿標題`,
					postId: `投稿 ID`,
					boxTitle: `圖片區標題`,
					"imgIndex:0": `檔案排序號,數字決定起始數字`,
					plan: `訂閱方案名`,
					fee: `瀏覽月費`,
					postDate: `投稿日期`,
					taskDate: `下載日期`,
					ext: `檔案副檔名`
				}
			};
			return (key) ? defaultSetting[lang || this.lang][key] : defaultSetting[lang || this.lang];
		}
		renderSettingParams() {
			$(`#cookie${this.cookieSave}`).attr("checked", true);
			$(`#${(this.authorSaveCheck == `On`) ? `authorSave` : `generalSave`}`).attr("checked", true);
			$(`#selectSetting option[value='${this.lang}']`).attr("selected", true);
			$(`#zipNameInput`).val(this[(this.authorSaveCheck == `On`) ? `authorSave` : `generalSave`].zipName);
			$(`#fileNameInput`).val(this[(this.authorSaveCheck == `On`) ? `authorSave` : `generalSave`].fileName);
			$(`#dateFormatInput`).val(this.dateFormat);
			$(`#paramsTable`).html(this.paramsTemplate(this.lang));
			return this;
		}
		changeStyle(mode) {
			let blur = CSS.supports(`backdrop-filter`, `blur(15px)`);
			switch (mode) {
				case `Blur`:
					return;
				case `unBlur`:
					return;
				default:
					return;
			}
		}
		changeLang(Lang) {
			let lang = Lang || $("#selectSetting option:selected").val();
			this.setCookie({
				lang: lang
			});
			$("#titleSetting").text(this.getDefault(`settingCenter`, lang));
			$("#cookieSetting").text(this.getDefault(`cookieButton`, lang));
			$("#langSetting").text(this.getDefault(`languageButton`, lang));
			$("#generalSaveSetting").text(this.getDefault(`generalSave`, lang));
			$("#authorSaveSetting").text(this.getDefault(`authorSave`, lang));
			$("#zipNameSetting").text(this.getDefault(`zipName`, lang));
			$("#fileNameSetting").text(this.getDefault(`fileName`, lang));
			$("#dateFormatSetting").text(this.getDefault(`dateFormat`, lang));
			$("#saveSetting").text(this.getDefault(`saveSetting`, lang));
			$("#closeSetting").text(this.getDefault(`closeSetting`, lang));
			$(".downloadSpan").text(this.getDefault('downloadImg', lang));
			$(".downloadSpanZip").text(this.getDefault('downloadImgZip', lang));
			$("#paramsTable").html(this.paramsTemplate(this.lang));
			return;
		}
		changeName(type) {
			let name = $(`#${type}NameInput`).val();
			let setting = $(`input[name='saveCheck']:checked`).attr("id");
			if (name == ``) {
				this.changeSaveSetting(setting);
			} else {
				this[setting][`${type}Name`] = name;
			}
			return;
		}
		changeSaveSetting(id) {
			let setting = this[id];
			$(`#zipNameInput`).val(setting.zipName);
			$(`#zipNameInput`).attr("placeholder", setting.zipName);
			$(`#fileNameInput`).val(setting.fileName);
			$(`#fileNameInput`).attr("placeholder", setting.fileName);
			return;
		}
		paramsTemplate(lang = this.lang) {
			let table = `
							| ${setting.getDefault(`tableParams`, lang)} | ${setting.getDefault(`tableMean`, lang)} | 
`;
			let a = [`user`, `uid`, `postTitle`, `postId`, `boxTitle`, `imgIndex:0`, `plan`, `fee`, `postDate`, `taskDate`, `ext`].forEach((p, i) => {
				table += `
							| {${p}} | ${setting.getDefault(p, lang)} | 
`;
			});
			table += `
`;
			return table;
		}
		settingCenterTemplate(lang) {
			return `
	
		${this.getDefault(`settingCenter`, lang)}
	 
	
	
		
			${this.getDefault(`cookieButton`, lang)}
		 
		
	 
	
		
			${this.getDefault(`languageButton`, lang)}
		 
		
			
	 
	
	
 `;
		}
	}
	class downloader {
		constructor(event) {
			this.pageType = setting.pageType;
			this.metaData = setting.metaData;
			this.button = ($(event.target).is("button")) ? $(event.target) : $(event.target).closest("button");
			this.boxType = this.button.attr("box-type");
			this.postContent = $(event.target).closest(".boxIndex");
			this.type = (this.button.hasClass(`zip`)) ? `zip` : `file`;
			this.boxIndex = this.postContent.attr("boxIndex");
			if (this.boxType == "box") {
				let content = this.metaData.content[this.boxIndex];
				let p = (content.plan == null) ? `一般公開` : undefined;
				this.metaData.category = content.category;
				this.metaData.indextype = (content.category == "blog") ? this.button.closest(".blogBox").attr("blog-img-index") : "photo_gallery";
				this.metaData.srcArr = (content.category == "blog") ? [JSON.parse(content.comment).ops.filter(i => {
					return (i.insert.fantiaImage && i.insert.fantiaImage.id == this.metaData.indextype) ? true : false
				})[0].insert.fantiaImage.original_url] : content.post_content_photos.map(img => img.url.original);
				this.metaData.fee = p || content.plan.price;
				this.metaData.plan = p || content.plan.name;
				this.metaData.postDate = content.parent_post.date;
				this.metaData.postId = content.parent_post.url.split("/").pop();
				this.metaData.postTitle = content.parent_post.title;
				this.metaData.title = content.title;
				this.metaData.d = (content.category == "photo_gallery") ? downloader.getDigits(Number(content.post_content_photos.length)) : 1;
			} else if (this.boxType == "post") {
				let p = `一般公開`;
				this.metaData.category = "post";
				this.metaData.indextype = "post";
				this.metaData.srcArr = [setting.metaJson.post.thumb.original];
				this.metaData.fee = p;
				this.metaData.plan = p;
				this.metaData.postDate = setting.metaJson.post.posted_at;
				this.metaData.postId = setting.metaJson.post.uri.show.split("/").pop();
				this.metaData.postTitle = setting.metaJson.post.title;
				this.metaData.title = setting.metaJson.post.title;
				this.metaData.d = 1;
			}
			this.zipName = `${setting[`${(setting.authorSaveCheck == 'On') ? `author` : `general`}Save`].zipName}.zip`;
			this.fileName = `${setting[`${(setting.authorSaveCheck == 'On') ? `author` : `general`}Save`].fileName}.{ext}`;
			this.dateFormat = setting.dateFormat;
			this.zipfmt = ``;
			this.zipImgIndex0 = 0;
			this.filefmt = ``;
			this.fileImgIndex0 = 0;
			this.d = this.metaData.d;
			this.zip = (this.type == `zip`) ? new JSZip() : undefined;
			return this.downloadImg();
		}
		changeButton(mode, input = false) {
			let button = this.button;
			switch (mode) {
				case `start`:
					button.addClass(['active', 'hdr']);
					if (this.type == `file`) {
						button.find('i').removeClass('fa-download');
						button.find('i').addClass('fa-spinner');
						button.find('i').addClass('fa-pulse');
					} else {
						button.find('i').removeClass('fa-file-archive-o');
						button.find('i').addClass('fa-spinner');
						button.find('i').addClass('fa-pulse');
					}
					break;
				case `catchLink`:
					button.find('span').text(setting.getDefault(`retrieving`));
					break;
				case `countTask`:
					button.find('span').text(`${this.finCount} / ${this.imgSrc.length}`);
					break;
				case `pickUp`:
					button.find('span').text(setting.getDefault(`zipping`));
					break;
				case `end`:
					if (this.type == `file`) {
						button.find('i').removeClass('fa-pulse').removeClass('fa-spinner').addClass('fa-download');
					} else {
						button.find('i').removeClass('fa-pulse').removeClass('fa-spinner').addClass('fa-file-archive-o');
					}
					button.removeClass(['active', 'hdr']);
					button.find('span').text(setting.getDefault(`done`));
					break;
				case `log`:
					button.find('span').text(input);
					break;
				default:
					return this;
			}
			return this;
		}
		paramsParser(type, fmt) {
			let o = {
				user: () => {
					return this.metaData.user || $("h1.fanclub-name>a").text();
				},
				uid: () => {
					return this.metaData.uid || this.authorId;
				},
				postTitle: () => {
					return this.metaData.postTitle || $("h1.post-title").text();
				},
				postId: () => {
					return this.metaData.postId || window.location.href.split("/").pop();
				},
				boxTitle: () => {
					return this.metaData.boxTitle || this.button.closest("div.post-content-inner").find('h2').text();
				},
				plan: () => {
					let feeStr = this.metaData.plan || this.button.closest("div.post-content-inner").find(`div.post-content-for strong.ng-binding`).text();
					let match = this.metaData.plan || feeStr.match(new RegExp(/(\d+円)以上限定$/g));
					if (match != null) return this.metaData.plan || feeStr.replace(match[0], ``);
					return this.metaData.plan || `一般公開`;
				},
				fee: () => {
					let feeStr = this.metaData.fee || this.button.closest("div.post-content-inner").find(`div.post-content-for strong.ng-binding`).text();
					let match = this.metaData.fee || feeStr.match(new RegExp(/((\d+)円)以上限定$/g));
					if (match != null) return this.metaData.fee || RegExp.$1;
					return this.metaData.fee || `一般公開`;
				},
				postDate: () => {
					return new Date(this.metaData.postDate || $(`small.post-date>span`).text()).Format(this.dateFormat);
				},
				taskDate: () => {
					return new Date().Format(this.dateFormat);
				}
			};
			for (let k in o) {
				if (new RegExp('(\\{' + k + '\\})', 'g').test(fmt)) fmt = fmt.replace(RegExp.$1, o[k]());
			}
			let s = (/\{imgIndex(\:(\d+))?\}/g.test(fmt)) ? RegExp.$2 : 0;
			if (/\{imgIndex(\:(\d+))?\}/g.test(fmt)) fmt = fmt.replace(RegExp.$1, ``);
			this[`${type}fmt`] = fmt;
			this[`${type}ImgIndex0`] = s;
			return this;
		}
		nextName(type, index, mimeType) {
			if (this.metaData.indextype != "photo_gallery") return this[`${type}fmt`].replace(`{imgIndex}`, (this.metaData.indextype).toString().padStart(this.d, 0)).replace(`{ext}`, mimeType.toString().split(`/`)[1]);
			return this[`${type}fmt`].replace(`{imgIndex}`, (Number(index) + Number(this[`${type}ImgIndex0`])).toString().padStart(this.d, 0)).replace(`{ext}`, mimeType.toString().split(`/`)[1]);
		}
		downloadImg() {
			let dataCont = 0;
			this.paramsParser(`zip`, this.zipName);
			this.paramsParser(`file`, this.fileName);
			this.changeButton(`start`);
			this.changeButton(`catchLink`);
			this.changeButton(`log`, `${dataCont} / ${this.metaData.srcArr.length}`);
			let self = this;
			this.metaData.srcArr.forEach((url, i) => {
				downloader.loadAsArrayBuffer(url, function (imgData, mimeType, lastModified) {
					dataCont += 1;
					self.changeButton(`log`, `${dataCont} / ${self.metaData.srcArr.length}`);
					self.mimeType = mimeType;
					if (self.zip == undefined) {
						if (dataCont == self.metaData.srcArr.length) self.changeButton('end');
						let content = new Blob([imgData], {
							type: mimeType
						});
						downloader.download(content, self.nextName('file', i, mimeType));
						return;
					} else {
						const sDate = lastModified && lastModified !== '' ? new Date(lastModified) : null
						const date = sDate ? new Date(sDate.getTime() - sDate.getTimezoneOffset() * 60000) : new Date()
						self.zip.file(self.nextName('file', i, mimeType), imgData, {
							date
						});
						if (dataCont == self.metaData.srcArr.length) {
							self.changeButton(`pickUp`);
							self.zip.generateAsync({
								type: "blob"
							},
								function updateCallback(metadata) {
									self.changeButton(`log`, `${setting.getDefault(`processing`)}:${metadata.percent.toFixed(2)} %`);
								}).then(function (content) {
									self.changeButton('end');
									downloader.download(content, self.nextName('zip', 0, mimeType));
									return;
								});
						}
					}
				});
			});
		}
		static download(content, name) {
			let tag = document.createElement('a');
			tag.href = (URL || webkitURL).createObjectURL(content);
			tag.download = name;
			document.body.appendChild(tag);
			tag.click();
			document.body.removeChild(tag);
			return;
		}
		static getDigits(i) {
			let L = 0;
			while (i >= 1) {
				i = i / 10;
				L += 1;
			}
			return `${L}`;
		}
		static loadAsArrayBuffer(url, callback) {
			let xhr = new XMLHttpRequest();
			xhr.open("GET", url);
			xhr.responseType = "arraybuffer";
			xhr.onerror = function (error) {
				return new Error(`ERROR`);
			};
			xhr.onload = function () {
				if (xhr.status === 200) {
					callback(xhr.response, xhr.getResponseHeader("Content-Type"), xhr.getResponseHeader("Last-Modified"));
				} else {
					return new Error(`ERROR`);
				}
			};
			xhr.send();
		}
	}
	window.getDownLoadButton = () => {
		$("div.post-content-inner").each((i, div) => {
			$(div).addClass("boxIndex").attr("boxIndex", i);
			$(div).find("div.btn-group-tabs").append(``);
		});
		$(`.the-post`).find("div.btn-group-tabs").append(``);
		$('.set-FD').remove();
		$("div#page").append(``);
		$("div#page").append(setting.settingCenterTemplate());
		setting.renderSettingParams().paramsTemplate();
		return;
	};
	window.openSettingCenter = () => {
		if ($(`#settingCenterDiv`).hasClass(`close`)) {
			$(`#settingCenterDiv`).removeClass(`close`);
		}
		return;
	};
	window.getImg = (event) => {
		return checkBrowser(event, (event) => {
			return new downloader(event);
		});
	};
	window.checkBrowser = (event, callBack) => {
		try {
			let excludes = [];
			let ex = excludes.map(b => navigator.userAgent.indexOf(b)).filter(b => (b != -1) ? true : false);
			if (ex.length >= 1) {
				alert(`請使用 Firefox 下載圖片!\nPlease run this script on Firefox!\n
				Also you can check the new script version!`);
				return;
			} else {
				return callBack(event);
			}
		} catch (err) {
			console.log(err);
			alert(`出了些問題!你可以嘗試使用 Firefox 下載圖片!\nThere are some ERROR, You can try this script on Firefox!\n
				Also you can check the new script version!`);
			return;
		}
	};
})();