diff --git a/bilibili-evolved.offline.user.js b/bilibili-evolved.offline.user.js
index d09fd32df..96c1097eb 100644
--- a/bilibili-evolved.offline.user.js
+++ b/bilibili-evolved.offline.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved (Offline)
-// @version 173.34
+// @version 173.87
// @description 增强哔哩哔哩Web端体验(离线版): 修复界面瑕疵, 删除广告, 使用夜间模式浏览; 下载视频,封面,弹幕, 以及增加对触屏设备的支持等.
// @author Grant Howard, Coulomb-G
// @copyright 2018, Grant Howrad (https://github.com/the1812)
@@ -1091,7 +1091,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/blur-video-control.min.js"] = (()=>{return(r,e)=>{(Observer.childListSubtree||Observer.subtree)("#bofqi",()=>{SpinQuery.count(()=>$(".bui-slider .bui-track.bui-track-video-progress,.bilibili-player-video-control-bottom"),2,r=>{if(!r.hasClass("video-control-blur-container")){r.addClass("video-control-blur-container");r.prepend(`
`)}})});e.applyStyle("blurVideoControlStyle")}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-schedule.min.js"] = (()=>{return(e,t)=>{class s{constructor(...e){if(e.length===0){const e=new Date;this.hour=e.getHours();this.minute=e.getMinutes()}else if(e.length===1){const[t]=e;[this.hour,this.minute]=t.split(":").slice(0,2).map(e=>this.validatePart(e));this.normalize()}else if(v.length===2){[this.hour,this.minute]=e}}validatePart(e){const t=parseInt(e);if(!isNaN(t)&&0<=t&&t<=59){return t}else{return null}}normalize(){while(this.minute<0){this.minute+=60;this.hour-=1}while(this.minute>=60){this.minute-=60;this.hour+=1}while(this.hour<0){this.hour+=24}while(this.hour>=24){this.hour-=24}}lessThan(e){if(this.houre.hour||this.hour===e.hour&&this.minute>e.minute){return true}return false}equals(e){return this.hour===e.hour&&this.minute===e.minute}isInRange(e,t){if(e.equals(t)){return false}let s=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){s=this.greaterThan(e)||this.lessThan(t)}const i=s||this.equals(e);return i}static millisecondsBefore(e){const t=new s;const i=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+i);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&i!==0){h+=24*3600*1e3}return h}}function i(){if(e.darkSchedule){const t=new s(e.darkScheduleStart);const r=new s(e.darkScheduleEnd);const n=new s;const h=n.isInRange(t,r);if(e.useDarkStyle!==h){e.useDarkStyle=h;saveSettings(e)}let u=0;if(h){u=s.millisecondsBefore(r)}else{u=s.millisecondsBefore(t)}if(u!==0){setTimeout(()=>i(),u)}}}i();return{export:s}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(n,c)=>{return{widget:{content:`\n `,condition:()=>typeof offlineData==="undefined",success:()=>{$("#clear-cache").on("click",()=>{n.cache={};saveSettings(n);Toast.success("已删除全部缓存.","清除缓存",5e3)})}}}}})();
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class a{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const r=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new a(o.pop(),r.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class r{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const a=o.durl;this.fragments=a.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await a.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const a=`下载完成. 再次保存`;Toast.success(a,"下载视频");n.entity.resetMenuClass()}async function r(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",r);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];SpinQuery.unsafeJquery().then(()=>{unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}})});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class r{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const a=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new r(o.pop(),a.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class a{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const r=o.durl;this.fragments=r.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await r.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const r=`下载完成. 再次保存`;Toast.success(r,"下载视频");n.entity.resetMenuClass()}async function a(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",a);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(n,t)=>{const e=t.attributes.videoInfo.export.DanmakuInfo;async function a(n){const t=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");const a=new e((unsafeWindow||window).cid);await a.fetchInfo();const o=new Blob([a.rawXML],{type:"text/plain"});const i=URL.createObjectURL(o);const c=$("#danmaku-link");const d=c.attr("href");if(d){URL.revokeObjectURL(d)}clearTimeout(n);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";c.attr("download",`${t}.xml`).attr("href",i).get(0).click()}return{widget:{content:`\n `,condition:async()=>{let n=await SpinQuery.condition(()=>(unsafeWindow||window).cid,n=>n!==undefined);return n!==undefined},success:()=>{const n=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",t=>{if(t.target!==n){const n=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(n)}})}}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{constructor(t){this.aid=t}async fetchInfo(){const t=JSON.parse(await downloadText(`https://api.bilibili.com/x/web-interface/view?aid=${this.aid}`));if(t.code!==0){throw new Error(t.message)}const i=t.data;this.cid=i.cid;this.pageCount=i.videos;this.coverUrl=i.pic;this.tagId=i.tid;this.tagName=i.tname;this.title=i.title;this.description=i.desc;this.up={uid:i.owner.mid,name:i.owner.name,faceUrl:i.owner.face};this.pages=i.pages.map(t=>{return{cid:t.cid,title:t.part,pageNumber:t.page}});return this}async fetchDanmaku(){this.danmaku=new e(this.cid);return this.danmaku.fetchInfo()}}class i{constructor(t,i){this.text=t;this.p=i}}class e{constructor(t){this.cid=t}async fetchInfo(){const t=await downloadText(`https://api.bilibili.com/x/v1/dm/list.so?oid=${this.cid}`);this.rawXML=t;const e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = ``;
diff --git a/bilibili-evolved.preview-offline.user.js b/bilibili-evolved.preview-offline.user.js
index a5d7f045a..9cc75e893 100644
--- a/bilibili-evolved.preview-offline.user.js
+++ b/bilibili-evolved.preview-offline.user.js
@@ -1,6 +1,6 @@
// ==UserScript==
// @name Bilibili Evolved (Preview Offline)
-// @version 173.34
+// @version 173.87
// @description 增强哔哩哔哩Web端体验(预览离线版): 修复界面瑕疵, 删除广告, 使用夜间模式浏览; 下载视频,封面,弹幕, 以及增加对触屏设备的支持等.
// @author Grant Howard, Coulomb-G
// @copyright 2018, Grant Howrad (https://github.com/the1812)
@@ -1091,7 +1091,7 @@ offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/m
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/blur-video-control.min.js"] = (()=>{return(r,e)=>{(Observer.childListSubtree||Observer.subtree)("#bofqi",()=>{SpinQuery.count(()=>$(".bui-slider .bui-track.bui-track-video-progress,.bilibili-player-video-control-bottom"),2,r=>{if(!r.hasClass("video-control-blur-container")){r.addClass("video-control-blur-container");r.prepend(``)}})});e.applyStyle("blurVideoControlStyle")}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/dark-schedule.min.js"] = (()=>{return(e,t)=>{class s{constructor(...e){if(e.length===0){const e=new Date;this.hour=e.getHours();this.minute=e.getMinutes()}else if(e.length===1){const[t]=e;[this.hour,this.minute]=t.split(":").slice(0,2).map(e=>this.validatePart(e));this.normalize()}else if(v.length===2){[this.hour,this.minute]=e}}validatePart(e){const t=parseInt(e);if(!isNaN(t)&&0<=t&&t<=59){return t}else{return null}}normalize(){while(this.minute<0){this.minute+=60;this.hour-=1}while(this.minute>=60){this.minute-=60;this.hour+=1}while(this.hour<0){this.hour+=24}while(this.hour>=24){this.hour-=24}}lessThan(e){if(this.houre.hour||this.hour===e.hour&&this.minute>e.minute){return true}return false}equals(e){return this.hour===e.hour&&this.minute===e.minute}isInRange(e,t){if(e.equals(t)){return false}let s=this.greaterThan(e)&&this.lessThan(t);if(e.greaterThan(t)){s=this.greaterThan(e)||this.lessThan(t)}const i=s||this.equals(e);return i}static millisecondsBefore(e){const t=new s;const i=(new Date).getSeconds();const r=1e3*(t.hour*3600+t.minute*60+i);const n=1e3*(e.hour*3600+e.minute*60);let h=n-r;if(t.greaterThan(e)||t.equals(e)&&i!==0){h+=24*3600*1e3}return h}}function i(){if(e.darkSchedule){const t=new s(e.darkScheduleStart);const r=new s(e.darkScheduleEnd);const n=new s;const h=n.isInRange(t,r);if(e.useDarkStyle!==h){e.useDarkStyle=h;saveSettings(e)}let u=0;if(h){u=s.millisecondsBefore(r)}else{u=s.millisecondsBefore(t)}if(u!==0){setTimeout(()=>i(),u)}}}i();return{export:s}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/clear-cache.min.js"] = (()=>{return(n,c)=>{return{widget:{content:`\n `,condition:()=>typeof offlineData==="undefined",success:()=>{$("#clear-cache").on("click",()=>{n.cache={};saveSettings(n);Toast.success("已删除全部缓存.","清除缓存",5e3)})}}}}})();
-offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class a{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const r=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new a(o.pop(),r.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class r{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const a=o.durl;this.fragments=a.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await a.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const a=`下载完成. 再次保存`;Toast.success(a,"下载视频");n.entity.resetMenuClass()}async function r(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",r);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
+offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-video.min.js"] = (()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];SpinQuery.unsafeJquery().then(()=>{unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}})});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class r{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const a=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new r(o.pop(),a.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class a{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const r=o.durl;this.fragments=r.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await r.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const r=`下载完成. 再次保存`;Toast.success(r,"下载视频");n.entity.resetMenuClass()}async function a(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",a);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/download-danmaku.min.js"] = (()=>{return(n,t)=>{const e=t.attributes.videoInfo.export.DanmakuInfo;async function a(n){const t=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");const a=new e((unsafeWindow||window).cid);await a.fetchInfo();const o=new Blob([a.rawXML],{type:"text/plain"});const i=URL.createObjectURL(o);const c=$("#danmaku-link");const d=c.attr("href");if(d){URL.revokeObjectURL(d)}clearTimeout(n);document.querySelector("#download-danmaku>span").innerHTML="下载弹幕";c.attr("download",`${t}.xml`).attr("href",i).get(0).click()}return{widget:{content:`\n `,condition:async()=>{let n=await SpinQuery.condition(()=>(unsafeWindow||window).cid,n=>n!==undefined);return n!==undefined},success:()=>{const n=document.querySelector("#danmaku-link");$("#download-danmaku").on("click",t=>{if(t.target!==n){const n=setTimeout(()=>document.querySelector("#download-danmaku>span").innerHTML="请稍侯...",200);a(n)}})}}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/video-info.min.js"] = (()=>{return()=>{class t{constructor(t){this.aid=t}async fetchInfo(){const t=JSON.parse(await downloadText(`https://api.bilibili.com/x/web-interface/view?aid=${this.aid}`));if(t.code!==0){throw new Error(t.message)}const i=t.data;this.cid=i.cid;this.pageCount=i.videos;this.coverUrl=i.pic;this.tagId=i.tid;this.tagName=i.tname;this.title=i.title;this.description=i.desc;this.up={uid:i.owner.mid,name:i.owner.name,faceUrl:i.owner.face};this.pages=i.pages.map(t=>{return{cid:t.cid,title:t.part,pageNumber:t.page}});return this}async fetchDanmaku(){this.danmaku=new e(this.cid);return this.danmaku.fetchInfo()}}class i{constructor(t,i){this.text=t;this.p=i}}class e{constructor(t){this.cid=t}async fetchInfo(){const t=await downloadText(`https://api.bilibili.com/x/v1/dm/list.so?oid=${this.cid}`);this.rawXML=t;const e=(new DOMParser).parseFromString(t,"application/xml").documentElement;this.xml=e;this.danmakus=[].map.call(e.querySelectorAll("d[p]"),t=>{return new i(t.innerHTML,t.getAttribute("p"))})}}class a{constructor(t){this.ep=t;this.videos=[]}async fetchInfo(){const i=await downloadText(`https://www.bilibili.com/bangumi/play/ep${this.ep}/`);const e=JSON.parse(i.match(/window\.__INITIAL_STATE__=(.*);\(function\(\){/)[1]);this.title=e.mediaInfo.title;this.cover=e.mediaInfo.cover;this.squareCover=e.mediaInfo.square_cover;this.aid=e.epInfo.aid;this.cid=e.epInfo.cid;this.videos=e.epList.map(async i=>{return{title:i.index_title,aid:i.aid,cid:i.cid,info:await new t(i.aid).fetchInfo()}});return this}}return{export:{VideoInfo:t,BangumiInfo:a,Danmaku:i,DanmakuInfo:e}}}})();
offlineData["https://raw.githubusercontent.com/the1812/Bilibili-Evolved/master/min/about.min.html"] = ``;
diff --git a/min/download-video.min.js b/min/download-video.min.js
index e9233c3dd..791accf0b 100644
--- a/min/download-video.min.js
+++ b/min/download-video.min.js
@@ -1 +1 @@
-(()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class a{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const r=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new a(o.pop(),r.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class r{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const a=o.durl;this.fragments=a.map(e=>new r(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await a.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const a=`下载完成. 再次保存`;Toast.success(a,"下载视频");n.entity.resetMenuClass()}async function r(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",r);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
\ No newline at end of file
+(()=>{return(e,t)=>{const n={entity:null,aid:undefined,cid:undefined,isBangumi:false};const s=[];SpinQuery.unsafeJquery().then(()=>{unsafeWindow.$(unsafeWindow.document).ajaxSend((e,t,n)=>{if(n.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl")!==-1){s.unshift(n.url)}})});class i{constructor(){this.menuPanel=document.querySelector(".download-video-panel");this.menuClasses=["quality","action","progress"];this.currentMenuClass="quality"}addMenuClass(){this.menuPanel.classList.remove(...this.menuClasses);this.menuPanel.classList.add(this.currentMenuClass);return this.currentMenuClass}resetMenuClass(){[this.currentMenuClass]=this.menuClasses;this.addMenuClass()}nextMenuClass(){const e=this.menuClasses.indexOf(this.currentMenuClass)+1;const t=this.menuClasses[e>=this.menuClasses.length?0:e];this.currentMenuClass=t;this.addMenuClass();return t}addError(){this.menuPanel.classList.add("error")}removeError(){this.menuPanel.classList.remove("error");this.resetMenuClass()}async getUrl(e){if(e){return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&qn=${e}&otype=json`}else{return`https://api.bilibili.com/x/player/playurl?avid=${n.aid}&cid=${n.cid}&otype=json`}}}class o extends i{constructor(e){super(e);this.menuClasses=["action","progress"];this.currentMenuClass="action"}async getUrl(){const e=await SpinQuery.select(()=>s[0]).catch(()=>logError("获取番剧下载链接失败."));return e}}class r{constructor(e,t,n){this.quality=e;this.internalName=t;this.displayName=n}async downloadInfo(){const e=new l(this);await e.fetchVideoInfo();return e}static get availableFormats(){return new Promise((e,t)=>{n.entity.getUrl().then(n=>{const s=new XMLHttpRequest;s.addEventListener("load",()=>{const n=JSON.parse(s.responseText);if(n.code!==0){t("获取清晰度信息失败.")}const i=n.data||n;const o=i.accept_quality;const a=i.accept_format.split(",");const l=i.accept_description;const c=[];while(o.length>0){const e=new r(o.pop(),a.pop(),l.pop());c.push(e)}e(c)});s.addEventListener("error",()=>t(`获取清晰度信息失败.`));s.withCredentials=true;s.open("GET",n);s.send()})})}}class a{constructor(e,t,n,s){this.length=e;this.size=t;this.url=n;this.backupUrls=s}}class l{constructor(e,t){this.format=e;this.fragments=t||[];this.progress=null;this.loaded=0;this.totalSize=null;this.workingXhr=null;this.fragmentSplitFactor=6*5}fetchVideoInfo(){return new Promise((e,t)=>{n.entity.getUrl(this.format.quality).then(s=>{const i=new XMLHttpRequest;i.addEventListener("load",()=>{const s=JSON.parse(i.responseText.replace(/http:/g,"https:"));const o=s.data||s;if(!n.isBangumi&&o.quality!==this.format.quality){t("获取下载链接失败, 请确认当前账号有下载权限后重试.")}const r=o.durl;this.fragments=r.map(e=>new a(e.length,e.size,e.url,e.backup_url));e(this.fragments)});i.withCredentials=true;i.open("GET",s);i.send()})})}cancelDownload(){if("forEach"in this.workingXhr){this.workingXhr.forEach(e=>e.abort())}else{logError("Cancel Download Failed: forEach in this.workingXhr not found.")}}downloadFragment(e){const t=[];this.workingXhr=[];const n=Math.round(e.size/this.fragmentSplitFactor);let s=0;while(s{let s=0;const o=new XMLHttpRequest;o.open("GET",e.url);o.responseType="arraybuffer";o.withCredentials=false;o.addEventListener("progress",e=>{this.loaded+=e.loaded-s;s=e.loaded;this.progress&&this.progress(this.loaded/this.totalSize)});o.addEventListener("load",()=>{if((""+o.status)[0]==="2"){t(o.response)}else{n(`请求失败.`)}});o.addEventListener("abort",()=>n("下载已取消."));o.addEventListener("error",()=>n(`下载失败.`));o.setRequestHeader("Range",i);o.send();this.workingXhr.push(o)}));s=Math.round(s+n)}return Promise.all(t)}copyUrl(){const e=this.fragments.map(e=>e.url).reduce((e,t)=>e+"\r\n"+t);GM_setClipboard(e,"text")}extension(e){return(e||this.fragments[0]).url.indexOf(".flv")!==-1?".flv":".mp4"}makeBlob(e,t=null){return new Blob(Array.isArray(e)?e:[e],{type:this.extension(t)===".flv"?"video/x-flv":"video/mp4"})}cleanUpOldBlobUrl(){const e=$("a#video-complete").attr("href");if(e&&$(`.link[href=${e}]`).length===0){URL.revokeObjectURL(e)}}downloadSingle(e){const[t]=e;const n=this.makeBlob(t);const s=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","")+this.extension();return[n,s]}async downloadMultiple(e){const t=new JSZip;const n=document.title.replace("_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili","").replace("_番剧_bilibili_哔哩哔哩","");if(e.length>1){e.forEach((e,s)=>{const i=this.fragments[s];t.file(`${n} - ${s+1}${this.extension(i)}`,this.makeBlob(e,i))})}else{const[s]=e;t.file(`${n}${this.extension()}`,this.makeBlob(s))}const s=await t.generateAsync({type:"blob"});const i=n+".zip";return[s,i]}async download(){const e=[];this.loaded=0;this.totalSize=this.fragments.map(e=>e.size).reduce((e,t)=>e+t);for(const t of this.fragments){const n=await this.downloadFragment(t);e.push(n)}if(e.length<1){throw new Error("下载失败.")}let t=null;let n=null;if(e.length===1){[t,n]=this.downloadSingle(e)}else{[t,n]=await this.downloadMultiple(e)}const s=URL.createObjectURL(t);this.cleanUpOldBlobUrl();this.progress&&this.progress(0);return{url:s,filename:n}}}async function c(){const e=await SpinQuery.select(()=>(unsafeWindow||window).aid);const t=await SpinQuery.select(()=>(unsafeWindow||window).cid);n.aid=e;n.cid=t;if(document.URL.indexOf("bangumi")!==-1){n.isBangumi=true;n.entity=new o}else{n.entity=new i}return e!==undefined&&t!==undefined}async function d(){await c();const e=await r.availableFormats;let[s]=e;const i=()=>s.downloadInfo().catch(e=>{n.entity.addError();$(".video-error").text(e)});async function o(){if(!s){return}n.entity.nextMenuClass();const e=await i();e.progress=(e=>{$(".download-progress-value").text(`${fixed(e*100)}`);$(".download-progress-foreground").css("transform",`scaleX(${e})`)});document.querySelector(".download-progress-cancel>span").onclick=(()=>e.cancelDownload());const t=await e.download().catch(e=>{n.entity.addError();$(".video-error").text(e)});if(!t){return}const o=document.getElementById("video-complete");o.setAttribute("href",t.url);o.setAttribute("download",t.filename);o.click();const r=`下载完成. 再次保存`;Toast.success(r,"下载视频");n.entity.resetMenuClass()}async function a(){if(!s){return}const e=await i();e.copyUrl();Toast.success("已复制链接到剪贴板.","复制链接",3e3);n.entity.resetMenuClass()}$(".video-action>#video-action-download").on("click",o);$(".video-action>#video-action-copy").on("click",a);e.forEach(e=>{$(`${e.displayName}`).on("click",()=>{s=e;n.entity.nextMenuClass()}).prependTo("ol.video-quality")});t.applyStyle("downloadVideoStyle");const l=document.querySelector(".download-video-panel");const d=()=>$(".download-video-panel").toggleClass("opened");$("#download-video").on("click",e=>{if(!l.contains(e.target)){d()}});$(".video-error").on("click",()=>{$(".video-error").text("");n.entity.removeError()});n.entity.addMenuClass()}return{widget:{content:t.data.downloadVideoDom.text,condition:c,success:d}}}})();
\ No newline at end of file
diff --git a/video/download-video/download-video.js b/video/download-video/download-video.js
index fc3c45a64..15335f5da 100644
--- a/video/download-video/download-video.js
+++ b/video/download-video/download-video.js
@@ -12,12 +12,15 @@
};
const bangumiUrls = [];
- unsafeWindow.$(unsafeWindow.document).ajaxSend((event, request, params) =>
+ SpinQuery.unsafeJquery().then(() =>
{
- if (params.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl") !== -1)
+ unsafeWindow.$(unsafeWindow.document).ajaxSend((event, request, params) =>
{
- bangumiUrls.unshift(params.url);
- }
+ if (params.url.indexOf("https://bangumi.bilibili.com/player/web_api/v2/playurl") !== -1)
+ {
+ bangumiUrls.unshift(params.url);
+ }
+ });
});
class Video
{