Use types in node_modules

This commit is contained in:
the1812 2020-11-11 15:32:31 +08:00
parent dfb5a2c654
commit 421819381f
16 changed files with 665 additions and 19 deletions

2
min/dark.min.css vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
min/keymap.min.js vendored
View File

@ -1 +1 @@
(()=>(e,i)=>{const t=["https://www.bilibili.com/bangumi/","https://www.bilibili.com/video/","https://www.bilibili.com/watchlater/","https://www.bilibili.com/medialist/play/"];let n=true;if(t.some((e=>document.URL.startsWith(e)))){const t={f:".bilibili-player-video-fullscreen",w:".bilibili-player-video-web-fullscreen",t:".bilibili-player-video-btn-widescreen",m:".bilibili-player-video-btn-volume .bilibili-player-iconfont-volume",p:".bilibili-player-video-btn-pip",c:".video-toolbar .coin,.tool-bar .coin-info, .video-toolbar-module .coin-box, .play-options-ul > li:nth-child(2)",s:".video-toolbar .collect, .video-toolbar-module .fav-box, .play-options-ul > li:nth-child(3)"," ":".bilibili-player-video-btn-start"};let a=true;let l=false;const o=document.URL.startsWith("https://www.bilibili.com/watchlater/");const s=document.URL.startsWith("https://www.bilibili.com/medialist/play/");if(o){Observer.videoChange((()=>{Ajax.getJsonWithCredentials(`https://api.bilibili.com/x/web-interface/archive/has/like?aid=${unsafeWindow.aid}`).then((e=>{l=Boolean(e.data)}))}))}let c;const r=e=>{let t=dq(".keymap-playback-tip");if(!t){const e=dq(".bilibili-player-video-wrap");if(!e){return}e.insertAdjacentHTML("afterbegin",`\n<div class="keymap-playback-tip-container">\n<i class="mdi mdi-fast-forward"></i>\n<div class="keymap-playback-tip"></div>x\n</div>\n`);i.applyStyleFromText(`\n .keymap-playback-tip-container {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n padding: 8px 16px;\n background-color: #000A;\n color: white;\n pointer-events: none;\n opacity: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n font-size: 14pt;\n border-radius: 4px;\n transition: .2s ease-out;\n }\n .keymap-playback-tip-container.show {\n opacity: 1;\n }\n .keymap-playback-tip-container i {\n line-height: 1;\n margin-right: 8px;\n font-size: 18pt;\n }\n`,"keymapStyle");t=dq(".keymap-playback-tip")}t.innerHTML=e.toString();if(c){clearTimeout(c)}dq(".keymap-playback-tip-container").classList.add("show");c=setTimeout((()=>{dq(".keymap-playback-tip-container").classList.remove("show")}),2e3)};document.body.addEventListener("keydown",(i=>{if(!n){return}if(o&&document.URL.endsWith("list")){return}if(document.activeElement&&["input","textarea"].includes(document.activeElement.nodeName.toLowerCase())){return}const c=i.key.toLowerCase();const p=dq(".bilibili-player-sphere-control");if(p!==null&&p.style.display!=="none"&&["w","a","s","d"].includes(c)){return}const d=!i.shiftKey&&!i.altKey&&!i.ctrlKey&&!i.metaKey;if(c in t&&d){const e=dq(t[c]);if(!e){return}i.stopPropagation();i.preventDefault();e.click()}else if(c==="d"&&d){const e=dq(".bilibili-player-video-danmaku-switch input");if(!e){return}i.stopPropagation();i.preventDefault();e.checked=!e.checked;raiseEvent(e,"change")}else if(c==="j"&&d){const t=dq(".bilibili-player-video video");t.currentTime+=e.keymapJumpSeconds;i.stopPropagation();i.preventDefault()}else if(c==="l"&&d){if(o){const e={aid:unsafeWindow.aid,like:l?2:1,csrf:getCsrf()};Ajax.postTextWithCredentials(`https://api.bilibili.com/x/web-interface/archive/like`,Object.entries(e).map((([e,i])=>`${e}=${i}`)).join("&")).then((()=>{l=!l;if(l){Toast.success(`已点赞`,`快捷键扩展`,1e3)}else{Toast.success(`已取消点赞`,`快捷键扩展`,1e3)}}))}else if(s){const e=dq(".play-options-ul > li:first-child");if(e){e.click()}}else{const e=dq(".video-toolbar .like");i.preventDefault();const t=(i,t)=>{const n=new CustomEvent(i,t);e.dispatchEvent(n)};a=true;setTimeout((()=>a=false),200);t("mousedown",i);document.body.addEventListener("keyup",(e=>{e.preventDefault();t("mouseup",e);if(a){t("click",e)}}),{once:true})}}else if(c==="`"&&d){const e=dq(".bilibili-player-video-wrap");const i=e.getBoundingClientRect();e.dispatchEvent(new MouseEvent("contextmenu",{bubbles:true,cancelable:false,view:unsafeWindow,button:2,buttons:0,clientX:i.x+i.width/2-176.65/2,clientY:i.y+i.height/2-194/2}))}else if(i.shiftKey){const t=dq(".bilibili-player-video video");if(t===null){return}const n=[.5,.75,1,1.25,1.5,2,2.5,3];let a=true;if(c===">"||c==="ArrowUp".toLowerCase()){t.playbackRate=n.find((e=>e>t.playbackRate))||n[n.length-1];r(t.playbackRate)}else if(c==="<"||c==="ArrowDown".toLowerCase()){t.playbackRate=[...n].reverse().find((e=>e<t.playbackRate))||n[0];r(t.playbackRate)}else if(c==="?"){t.playbackRate=1;r(t.playbackRate)}else if(c==="w"){const e=dq(".video-toolbar .ops .watchlater, .more-ops-list .ops-watch-later, .video-toolbar-module .see-later-box");if(e!==null){e.click()}}else if(c==="j"){t.currentTime-=e.keymapJumpSeconds}else if(c==="s"){const e=dq(".quick-favorite");if(e){e.click()}}else{a=false}if(a){i.stopPropagation();i.preventDefault()}}}))}return{reload:()=>n=true,unload:()=>n=false}})();
(()=>(e,i)=>{const t=["https://www.bilibili.com/bangumi/","https://www.bilibili.com/video/","https://www.bilibili.com/watchlater/","https://www.bilibili.com/medialist/play/"];let n=true;if(t.some((e=>document.URL.startsWith(e)))){const t={f:".bilibili-player-video-fullscreen",w:".bilibili-player-video-web-fullscreen",t:".bilibili-player-video-btn-widescreen",m:".bilibili-player-video-btn-volume .bilibili-player-iconfont-volume",p:".bilibili-player-video-btn-pip",c:".video-toolbar .coin,.tool-bar .coin-info, .video-toolbar-module .coin-box, .play-options-ul > li:nth-child(2)",s:".video-toolbar .collect, .video-toolbar-module .fav-box, .play-options-ul > li:nth-child(3)"," ":".bilibili-player-video-btn-start"};let a=true;let l=false;const o=document.URL.startsWith("https://www.bilibili.com/watchlater/");const s=document.URL.startsWith("https://www.bilibili.com/medialist/play/");if(o){Observer.videoChange((()=>{Ajax.getJsonWithCredentials(`https://api.bilibili.com/x/web-interface/archive/has/like?aid=${unsafeWindow.aid}`).then((e=>{l=Boolean(e.data)}))}))}let c;const r=e=>{let t=dq(".keymap-playback-tip");if(!t){const e=dq(".bilibili-player-video-wrap");if(!e){return}e.insertAdjacentHTML("afterbegin",`\n<div class="keymap-playback-tip-container">\n<i class="mdi mdi-fast-forward"></i>\n<div class="keymap-playback-tip"></div>x\n</div>\n`);i.applyStyleFromText(`\n .keymap-playback-tip-container {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n padding: 8px 16px;\n background-color: #000A;\n color: white;\n pointer-events: none;\n opacity: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n font-size: 14pt;\n border-radius: 4px;\n transition: .2s ease-out;\n }\n .keymap-playback-tip-container.show {\n opacity: 1;\n }\n .keymap-playback-tip-container i {\n line-height: 1;\n margin-right: 8px;\n font-size: 18pt;\n }\n`,"keymapStyle");t=dq(".keymap-playback-tip")}t.innerHTML=e.toString();if(c){clearTimeout(c)}dq(".keymap-playback-tip-container").classList.add("show");c=window.setTimeout((()=>{dq(".keymap-playback-tip-container").classList.remove("show")}),2e3)};document.body.addEventListener("keydown",(i=>{if(!n){return}if(o&&document.URL.endsWith("list")){return}if(document.activeElement&&["input","textarea"].includes(document.activeElement.nodeName.toLowerCase())){return}const c=i.key.toLowerCase();const p=dq(".bilibili-player-sphere-control");if(p!==null&&p.style.display!=="none"&&["w","a","s","d"].includes(c)){return}const d=!i.shiftKey&&!i.altKey&&!i.ctrlKey&&!i.metaKey;if(c in t&&d){const e=dq(t[c]);if(!e){return}i.stopPropagation();i.preventDefault();e.click()}else if(c==="d"&&d){const e=dq(".bilibili-player-video-danmaku-switch input");if(!e){return}i.stopPropagation();i.preventDefault();e.checked=!e.checked;raiseEvent(e,"change")}else if(c==="j"&&d){const t=dq(".bilibili-player-video video");t.currentTime+=e.keymapJumpSeconds;i.stopPropagation();i.preventDefault()}else if(c==="l"&&d){if(o){const e={aid:unsafeWindow.aid,like:l?2:1,csrf:getCsrf()};Ajax.postTextWithCredentials(`https://api.bilibili.com/x/web-interface/archive/like`,Object.entries(e).map((([e,i])=>`${e}=${i}`)).join("&")).then((()=>{l=!l;if(l){Toast.success(`已点赞`,`快捷键扩展`,1e3)}else{Toast.success(`已取消点赞`,`快捷键扩展`,1e3)}}))}else if(s){const e=dq(".play-options-ul > li:first-child");if(e){e.click()}}else{const e=dq(".video-toolbar .like");i.preventDefault();const t=(i,t)=>{const n=new CustomEvent(i,t);e.dispatchEvent(n)};a=true;setTimeout((()=>a=false),200);t("mousedown",i);document.body.addEventListener("keyup",(e=>{e.preventDefault();t("mouseup",e);if(a){t("click",e)}}),{once:true})}}else if(c==="`"&&d){const e=dq(".bilibili-player-video-wrap");const i=e.getBoundingClientRect();e.dispatchEvent(new MouseEvent("contextmenu",{bubbles:true,cancelable:false,view:unsafeWindow,button:2,buttons:0,clientX:i.x+i.width/2-176.65/2,clientY:i.y+i.height/2-194/2}))}else if(i.shiftKey){const t=dq(".bilibili-player-video video");if(t===null){return}const n=[.5,.75,1,1.25,1.5,2,2.5,3];let a=true;if(c===">"||c==="ArrowUp".toLowerCase()){t.playbackRate=n.find((e=>e>t.playbackRate))||n[n.length-1];r(t.playbackRate)}else if(c==="<"||c==="ArrowDown".toLowerCase()){t.playbackRate=[...n].reverse().find((e=>e<t.playbackRate))||n[0];r(t.playbackRate)}else if(c==="?"){t.playbackRate=1;r(t.playbackRate)}else if(c==="w"){const e=dq(".video-toolbar .ops .watchlater, .more-ops-list .ops-watch-later, .video-toolbar-module .see-later-box");if(e!==null){e.click()}}else if(c==="j"){t.currentTime-=e.keymapJumpSeconds}else if(c==="s"){const e=dq(".quick-favorite");if(e){e.click()}}else{a=false}if(a){i.stopPropagation();i.preventDefault()}}}))}return{reload:()=>n=true,unload:()=>n=false}})();

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
(()=>(e,t)=>{const n=new Map;const i=e=>{console.log("create new context");const t=new AudioContext;const i=t.createMediaElementSource(e);const o=t.createGain();i.connect(o);o.connect(t.destination);n.set(e,o.gain);return o.gain};const o=e=>{if(n.has(e)){const t=n.get(e);t.value=1}};const r=(e,t)=>{if(n.has(e)){const i=n.get(e);let o=i.value+t;if(o<0){o=0}i.value=o;return o}else{const n=i(e);const o=n.value+t;n.value=o;return o}};const s=async()=>{const e=["https://www.bilibili.com/bangumi/","https://www.bilibili.com/video/","https://www.bilibili.com/watchlater/","https://www.bilibili.com/medialist/play/"];if(e.every((e=>!document.URL.startsWith(e)))){return}let i;const o=e=>{let n=dq(".volume-overdrive-tip");if(!n){const e=dq(".bilibili-player-video-wrap");if(!e){return}e.insertAdjacentHTML("afterbegin",`\n<div class="volume-overdrive-tip-container">\n<i class="mdi mdi-volume-high"></i>\n<div class="volume-overdrive-tip"></div>\n</div>\n`);t.applyStyleFromText(`\n .volume-overdrive-tip-container {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n padding: 8px 16px;\n background-color: #000A;\n color: white;\n pointer-events: none;\n opacity: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n font-size: 14pt;\n border-radius: 4px;\n transition: .2s ease-out;\n }\n .volume-overdrive-tip-container.show {\n opacity: 1;\n }\n .volume-overdrive-tip-container i {\n line-height: 1;\n margin-right: 8px;\n font-size: 18pt;\n }\n`,"volumeOverdriveStyle");n=dq(".volume-overdrive-tip")}const o=dq("video");n.innerHTML=`音量${Math.round(o.volume*100)}% x 增幅${Math.round(e*100)}% = ${Math.round(o.volume*e*100)}%`;if(i){clearTimeout(i)}dq(".volume-overdrive-tip-container").classList.add("show");i=setTimeout((()=>{dq(".volume-overdrive-tip-container").classList.remove("show")}),2e3)};Observer.videoChange((async()=>{n.clear();document.body.addEventListener("keydown",(e=>{const t=!e.shiftKey&&e.ctrlKey&&!e.altKey&&!e.metaKey;if(t&&(e.key==="ArrowDown"||e.key==="ArrowUp")){const t=dq("video");if(!t){return}const n=e.key==="ArrowDown"?-.1:.1;const i=r(t,n);o(i);e.preventDefault();e.stopImmediatePropagation()}}),{capture:true})}))};s();return{export:{setVolume:r}}})();
(()=>(e,t)=>{const n=new Map;const i=e=>{console.log("create new context");const t=new AudioContext;const i=t.createMediaElementSource(e);const o=t.createGain();i.connect(o);o.connect(t.destination);n.set(e,o.gain);return o.gain};const o=e=>{if(n.has(e)){const t=n.get(e);t.value=1}};const r=(e,t)=>{if(n.has(e)){const i=n.get(e);let o=i.value+t;if(o<0){o=0}i.value=o;return o}else{const n=i(e);const o=n.value+t;n.value=o;return o}};const s=async()=>{const e=["https://www.bilibili.com/bangumi/","https://www.bilibili.com/video/","https://www.bilibili.com/watchlater/","https://www.bilibili.com/medialist/play/"];if(e.every((e=>!document.URL.startsWith(e)))){return}let i;const o=e=>{let n=dq(".volume-overdrive-tip");if(!n){const e=dq(".bilibili-player-video-wrap");if(!e){return}e.insertAdjacentHTML("afterbegin",`\n<div class="volume-overdrive-tip-container">\n<i class="mdi mdi-volume-high"></i>\n<div class="volume-overdrive-tip"></div>\n</div>\n`);t.applyStyleFromText(`\n .volume-overdrive-tip-container {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n padding: 8px 16px;\n background-color: #000A;\n color: white;\n pointer-events: none;\n opacity: 0;\n z-index: 100;\n display: flex;\n align-items: center;\n font-size: 14pt;\n border-radius: 4px;\n transition: .2s ease-out;\n }\n .volume-overdrive-tip-container.show {\n opacity: 1;\n }\n .volume-overdrive-tip-container i {\n line-height: 1;\n margin-right: 8px;\n font-size: 18pt;\n }\n`,"volumeOverdriveStyle");n=dq(".volume-overdrive-tip")}const o=dq("video");n.innerHTML=`音量${Math.round(o.volume*100)}% x 增幅${Math.round(e*100)}% = ${Math.round(o.volume*e*100)}%`;if(i){clearTimeout(i)}dq(".volume-overdrive-tip-container").classList.add("show");i=window.setTimeout((()=>{dq(".volume-overdrive-tip-container").classList.remove("show")}),2e3)};Observer.videoChange((async()=>{n.clear();document.body.addEventListener("keydown",(e=>{const t=!e.shiftKey&&e.ctrlKey&&!e.altKey&&!e.metaKey;if(t&&(e.key==="ArrowDown"||e.key==="ArrowUp")){const t=dq("video");if(!t){return}const n=e.key==="ArrowDown"?-.1:.1;const i=r(t,n);o(i);e.preventDefault();e.stopImmediatePropagation()}}),{capture:true})}))};s();return{export:{setVolume:r}}})();

View File

@ -10,15 +10,20 @@
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
"@babel/plugin-proposal-optional-chaining": "^7.12.1",
"@babel/preset-typescript": "^7.12.1",
"@types/jquery": "^3.5.4",
"@types/lodash": "^4.14.165",
"@types/node": "^14.14.7",
"clean-css-cli": "^4.3.0",
"html-minifier": "^4.0.0",
"jszip": "^3.5.0",
"sass": "^1.22.10",
"terser": "^5.3.8",
"typescript": "^4.0.5",
"vue": "^2.6.10",
"vuex": "^3.1.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"postinstall": "node postinstall.js"
},
"repository": {
"type": "git",

5
postinstall.js Normal file
View File

@ -0,0 +1,5 @@
const fs = require('fs')
const path = './node_modules/vue/types/umd.d.ts'
if (fs.existsSync(path)) {
fs.unlinkSync(path)
}

579
src/global.d.ts vendored Normal file
View File

@ -0,0 +1,579 @@
import { LoDashStatic } from 'lodash'
import { VueConstructor } from 'vue'
import { Store } from 'vuex'
declare global {
const _: LoDashStatic
const Vue: VueConstructor
const Vuex: typeof import('vuex')
const JSZip: typeof import('jszip')
const store: Store<{
watchlaterList: number[]
watchlaterListCached: boolean
}>
interface MonkeyXhrResponse {
finalUrl: string
readyState: number
status: number
statusText: string
responseHeaders: any
response: any
responseXML: Document
responseText: string
}
interface MonkeyXhrBasicDetails {
method: 'GET' | 'POST' | 'HEAD'
url: string
headers?: { [name: string]: string },
data?: string
binary?: boolean
timeout?: number
context?: any
responseType?: 'arraybuffer' | 'blob' | 'json'
overrideMimeType?: string
anonymous?: boolean
fetch?: boolean
username?: string
password?: string
}
interface MonkeyXhrDetails extends MonkeyXhrBasicDetails {
onabort?: (response: MonkeyXhrResponse) => void
onerror?: (response: MonkeyXhrResponse) => void
onloadstart?: (response: MonkeyXhrResponse) => void
onprogress?: (response: MonkeyXhrResponse) => void
onreadystatechange?: (response: MonkeyXhrResponse) => void
ontimeout?: (response: MonkeyXhrResponse) => void
onload?: (response: MonkeyXhrResponse) => void
}
type RunAtOptions = "document-start" | "document-end" | "document-idle" | "document-body" | "context-menu"
type DanmakuOption = '无' | 'XML' | 'JSON' | 'ASS'
type SubtitleOption = '无' | 'JSON' | 'ASS'
type DashCodec = 'AVC/H.264' | 'HEVC/H.265'
type Pattern = string
type Dropdown = { key: string; items: string[] }
interface RpcOption {
secretKey: string
baseDir: string
dir: string
host: string
port: string
method: 'get' | 'post'
skipByDefault: boolean
maxDownloadLimit: string
[key: string]: any
}
interface RpcOptionProfile extends RpcOption {
name: string
}
interface SearchHistoryItem {
keyword: string
count: number
date: string
}
interface CustomStyle {
style: string
name: string
displayName: string
enabled: boolean
mode?: 'default' | 'instant' | 'important'
}
interface MonkeyInfo {
script: {
author: string
copyright: string
description: string
excludes: string[]
homepage: string
icon: string
icon64: string
includes: string[]
lastUpdated: number
matches: string[]
downloadMode: string
name: string
namespace: string
options: {
awareOfChrome: boolean
compat_arrayleft: boolean
compat_foreach: boolean
compat_forvarin: boolean
compat_metadata: boolean
compat_prototypes: boolean
compat_uW_gmonkey: boolean
noframes: boolean
override: {
excludes: false
includes: false
orig_excludes: string[]
orig_includes: string[]
use_excludes: string[]
use_includes: string[]
}
run_at: RunAtOptions
}
position: number
resources: string[]
"run-at": RunAtOptions
system: boolean
unwrap: boolean
version: string
}
scriptMetaStr: string
scriptSource: string
scriptUpdateURL: string
scriptWillUpdate: boolean
scriptHandler: string
isIncognito: boolean
version: string
}
interface CustomNavbarComponents {
blank1: number
logo: number
category: number
rankingLink: number
drawingLink: number
musicLink: number
gamesIframe: number
livesIframe: number
shopLink: number
mangaLink: number
blank2: number
search: number
userInfo: number
messages: number
activities: number
bangumi: number
watchlaterList: number
favoritesList: number
historyList: number
upload: number
blank3: number
darkMode: number
}
type CustomNavbarOrders = { [key in keyof CustomNavbarComponents]: number }
interface SimpleHomeCategoryOrders {
anime: number
bangumi: number
china: number
manga: number
music: number
dance: number
game: number
tech: number
digital: number
life: number
kichiku: number
fashion: number
// ads: number
information: number
entertainment: number
column: number
movie: number
tv: number
film: number
documentary: number
[key: string]: number
}
interface UserImage {
url: string
name: string
}
const unsafeWindow: Window
const UserAgent: string
const EmptyImageUrl: string
interface Window {
aid: string | undefined
cid: string | undefined
bvid: string | undefined
pageno: string | number | undefined
$: JQueryStatic
[key: string]: any
}
interface Document {
pictureInPictureElement: HTMLElement | null
exitPictureInPicture: () => void
}
interface HTMLVideoElement {
requestPictureInPicture: () => void
}
class SpinQuery {
static condition<T>(query: () => T, condition: (queryResult: T) => boolean, success: (queryResult: T) => void, failed?: () => void): void
static condition<T>(query: () => T, condition: (queryResult: T) => boolean): Promise<T>
static select<T>(query: () => T, action: (queryResult: T) => void, failed?: () => void): void
static select<T>(query: () => T): Promise<T>
static select(query: string): Promise<HTMLElement | null>
static select(query: string, action: (queryResult: HTMLElement) => void, failed?: () => void): void
static any<T>(query: () => T, action: (queryResult: T) => void, failed?: () => void): void
static any<T>(query: () => T): Promise<T>
static any(query: string): Promise<JQuery>
static any(query: string, action: (queryResult: JQuery) => void, failed?: () => void): void
static count<T>(query: () => T, count: number, success: (queryResult: T) => void, failed?: () => void): void
static count<T>(query: () => T, count: number): Promise<T>
static count(query: string, count: number): Promise<NodeListOf<Element>>
static count(query: string, count: number, success: (queryResult: NodeListOf<Element>) => void, failed?: () => void): Promise<void>
static unsafeJquery(action: () => void, failed?: () => void): void
static unsafeJquery(): Promise<void>
}
class Toast {
show(): void
dismiss(): void
element: HTMLElement
key: string
static show(message: string, title: string, duration?: number): Toast
static info(message: string, title: string, duration?: number): Toast
static success(message: string, title: string, duration?: number): Toast
static error(message: string, title: string, duration?: number): Toast
}
class Resource {
text: string
key: string
dependencies: Array<Resource>
styles: Array<Resource>
displayName: string
dropdown: Dropdown | Dropdown[]
downloaded: boolean
constructor(url: string, styles?: Resource[])
download(): Promise<string>
getStyle(id: string): string
getPriorStyle(): any
applyStyle(id: string, important: boolean): void
static all: { [key: string]: Resource }
static displayNames: object
static manifest: object
static root: string
static cdnRoot: string
}
class ResourceManager {
import(componentName: string): any
getDefaultStyleId(key: string): string
applyStyle(key: string, id?: string): void
removeStyle(key: string): void
applyImportantStyle(key: string, id?: string): void
applyStyleFromText(text: string, id: string): void
applyImportantStyleFromText(text: string, id: string): void
getStyle(key: string, id?: string): void
toggleStyle(content: string, id: string, urlPattern?: {
include?: (string | RegExp)[]
exclude?: (string | RegExp)[]
}): void
toggleStyle(key: string): void
applyDropdownOptions(): Promise<void>
}
const resources: ResourceManager
class DoubleClickEvent {
constructor(handler: (e: MouseEvent) => void, singleClickHandler: (e: MouseEvent) => void)
bind(element: Element): void
unbind(element: Element): void
}
class Ajax {
static send(xhr: XMLHttpRequest, body: string | Document | Blob | ArrayBufferView | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>): Promise<string>
static getText(url: string): Promise<string>
static getTextWithCredentials(url: string): Promise<string>
static getJson(url: string): Promise<any>
static getJsonWithCredentials(url: string): Promise<any>
static getBlob(url: string): Promise<Blob>
static getBlobWithCredentials(url: string): Promise<Blob>
static postText(url: string, body: string | Document | Blob | ArrayBufferView | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>): Promise<string>
static postTextWithCredentials(url: string, body: string | Document | Blob | ArrayBufferView | ArrayBuffer | FormData | URLSearchParams | ReadableStream<Uint8Array>): Promise<string>
static postJson(url: string, json: any): Promise<any>
static postJsonWithCredentials(url: string, json: any): Promise<any>
static monkey(details: MonkeyXhrBasicDetails): Promise<any>
static getPages<T = any>(config: {
api: (page: number) => Promise<any>
getList: (json: any) => T[]
getTotal: (json: any) => number
}): Promise<T[]>
}
type Observable = string | Node | Node[] | NodeList
class Observer {
constructor(element: Element, callback: MutationCallback)
start(): Observer
stop(): Observer
forEach(callback: (observer: Observer) => void): void
add(element: Element): Observer
options: MutationObserverInit
static observe(observable: Observable, callback: MutationCallback, options: MutationObserverInit): Observer
static childList(observable: Observable, callback: MutationCallback): Observer
static childListSubtree(observable: Observable, callback: MutationCallback): Observer
static attributes(observable: Observable, callback: MutationCallback): Observer
static attributesSubtree(observable: Observable, callback: MutationCallback): Observer
static all(observable: Observable, callback: MutationCallback): Observer
static videoChange(callback: MutationCallback): Promise<void>
}
interface BilibiliEvolvedSettings {
[key: string]: any,
useDarkStyle: boolean,
useNewStyle: boolean,
compactLayout: boolean,
hideBanner: boolean,
overrideNavBar: boolean,
expandDanmakuList: boolean,
expandDescription: boolean,
watchLaterRedirect: boolean,
touchNavBar: boolean,
touchVideoPlayer: boolean,
customControlBackgroundOpacity: number,
customControlBackground: boolean,
darkScheduleStart: string,
darkScheduleEnd: string,
darkSchedule: boolean,
blurVideoControl: boolean,
toast: boolean,
fullTweetsTitle: boolean,
fullPageTitle: boolean,
removeVideoTopMask: boolean,
removeLiveWatermark: boolean,
harunaScale: boolean,
removeAds: boolean,
showBlockedAdsTip: boolean,
hideTopSearch: boolean,
touchVideoPlayerDoubleTapControl: boolean,
touchVideoPlayerAnimation: boolean,
customStyleColor: string,
preserveRank: boolean,
blurBackgroundOpacity: number,
useDefaultPlayerMode: boolean,
applyPlayerModeOnPlay: boolean,
defaultPlayerMode: string,
useDefaultVideoQuality: boolean,
defaultVideoQuality: string,
useDefaultDanmakuSettings: boolean,
enableDanmaku: boolean,
rememberDanmakuSettings: boolean,
danmakuSettings: {
subtitlesPreserve: boolean,
smartMask: boolean,
},
defaultPlayerLayout: string,
defaultBangumiLayout: string,
useDefaultPlayerLayout: boolean,
skipChargeList: boolean,
comboLike: boolean,
autoLightOff: boolean,
useCache: boolean,
autoContinue: boolean,
allowJumpContinue: boolean,
autoPlay: boolean,
airborne: boolean,
showDeadVideoTitle: boolean,
deadVideoTitleProvider: '稍后再看' | 'BiliPlus',
useBiliplusRedirect: boolean,
biliplusRedirect: boolean,
framePlayback: boolean,
useCommentStyle: boolean,
imageResolution: boolean,
imageResolutionScale: string,
toastInternalError: boolean,
i18n: boolean,
i18nLanguage: string,
playerFocus: boolean,
playerFocusOffset: number,
oldTweets: boolean,
simplifyLiveroom: boolean,
simplifyLiveroomSettings: {
vip: boolean,
fansMedal: boolean,
title: boolean,
userLevel: boolean,
guard: boolean,
systemMessage: boolean,
welcomeMessage: boolean,
giftMessage: boolean,
guardPurchase: boolean,
giftPanel: boolean,
userEffect: boolean,
kanban: boolean,
eventsBanner: boolean,
rankList: boolean,
popup: boolean,
skin: boolean,
[key: string]: boolean,
},
customNavbar: boolean,
customNavbarFill: boolean,
customNavbarTransparent: boolean,
customNavbarShadow: boolean,
customNavbarCompact: boolean,
customNavbarBlur: boolean,
customNavbarBlurOpacity: number,
customNavbarOrder: CustomNavbarOrders,
customNavbarHidden: Array<keyof CustomNavbarComponents>,
customNavbarBoundsPadding: number,
playerShadow: boolean,
narrowDanmaku: boolean,
favoritesRedirect: boolean,
outerWatchlater: boolean,
hideOldEntry: boolean,
hideBangumiReviews: boolean,
videoScreenshot: boolean,
cache: {} | { version: string } | undefined,
filenameFormat: string,
batchFilenameFormat: string,
sideBarOffset: number,
noLiveAutoplay: boolean,
hideHomeLive: boolean,
noMiniVideoAutoplay: boolean,
useDefaultVideoSpeed: boolean,
defaultVideoSpeed: string,
hideCategory: boolean,
foldComment: boolean,
downloadVideoDefaultDanmaku: DanmakuOption,
downloadVideoDefaultSubtitle: SubtitleOption,
aria2RpcOption: RpcOption,
aria2RpcOptionSelectedProfile: string,
aria2RpcOptionProfiles: RpcOptionProfile[],
searchHistory: SearchHistoryItem[],
seedsToCoins: boolean,
autoSeedsToCoins: boolean,
lastSeedsToCoinsDate: number,
autoDraw: boolean,
keymap: boolean,
doubleClickFullscreen: boolean,
doubleClickFullscreenPreventSingleClick: boolean
simplifyHome: boolean,
simplifyHomeStyle: '清爽' | '极简',
minimalHomeSettings: {
showSearch: boolean,
backgroundImage: string,
},
ajaxHook: boolean,
scriptLoadingMode: '同时' | '延后' | '同时(自动)' | '延后(自动)' | '自动',
scriptDownloadMode: 'bundle' | 'legacy'
guiSettingsDockSide: '左侧' | '右侧'
fullActivityContent: boolean,
feedsFilter: boolean,
feedsFilterPatterns: Pattern[],
feedsFilterTypes: number[],
feedsSpecialFilterTypes: number[],
feedsFilterSideCards: number[],
activityImageSaver: boolean,
scriptBlockPatterns: Pattern[],
customNavbarSeasonLogo: boolean,
selectableColumnText: boolean,
downloadVideoFormat: 'flv' | 'dash',
downloadVideoDashCodec: DashCodec,
enableDashDownload: boolean,
watchlaterExpireWarnings: boolean,
watchlaterExpireWarningDays: number,
superchatTranslate: boolean,
miniPlayerTouchMove: boolean,
hideBangumiSponsors: boolean,
hideRecommendLive: boolean,
hideRelatedVideos: boolean,
defaultMedalID: number,
autoMatchMedal: boolean,
customStyles: CustomStyle[],
simpleHomeCategoryOrders: SimpleHomeCategoryOrders,
simpleHomeBangumiLayout: '时间表' | '动态',
simpleHomeWheelScroll: boolean,
keymapJumpSeconds: number,
urlParamsClean: boolean,
collapseLiveSideBar: boolean,
downloadVideoQuality: number,
downloadSubtitle: boolean,
removeGameMatchModule: boolean,
noDarkOnMember: boolean,
feedsTranslate: boolean,
feedsTranslateProvider: 'Bing' | 'Google' | 'Baidu' | 'GoogleCN',
feedsTranslateLanguage: string,
downloadLiveRecords: boolean
defaultLiveQuality: '原画' | '4K' | '蓝光' | '超清' | '高清' | '流畅'
useDefaultLiveQuality: boolean,
recordLiveDanmaku: boolean,
foregroundColorMode: '自动' | '白色' | '黑色'
preserveEventBanner: boolean
bvidConvert: boolean
fixedSidebars: boolean
updateCdn: 'jsDelivr' | 'GitHub',
lastNewVersionCheck: number,
newVersionCheckInterval: number,
useDarkStyleAsUserStyle: boolean,
darkColorScheme: boolean,
livePip: boolean,
extendFeedsLive: boolean,
userImages: UserImage[],
playerOnTop: boolean,
restoreFloors: boolean,
quickFavorite: boolean,
quickFavoriteID: number,
bilibiliSimpleNewHomeCompatible: boolean,
preferAvUrl: boolean,
elegantScrollbar: boolean,
danmakuSendBar: boolean,
watchLaterRedirectNavbar: boolean,
watchLaterRedirectPage: boolean,
showCoverBeforePlay: boolean,
customNavbarGlobalFixed: boolean,
volumeOverdrive: boolean,
seoJump: boolean,
commentsTranslate: boolean,
copyFeedsLink: boolean,
copyCommentLink: boolean,
unfoldFeeds: boolean,
feedsImageExporter: boolean,
columnImageExporter: boolean,
downloadPackageEmitMode: '打包下载' | '分别下载',
latestVersionLink: string,
currentVersion: string,
favoritesListCurrentSelect: string,
}
const GM_info: MonkeyInfo
function GM_xmlhttpRequest(details: MonkeyXhrDetails): { abort: () => void }
function GM_setClipboard(data: any, info: string | { type?: string, mimetype?: string }): void
function GM_setValue(name: keyof BilibiliEvolvedSettings, value: any): void
function GM_getValue<T>(name: keyof BilibiliEvolvedSettings, defaultValue?: T): T
const GM: {
info: MonkeyInfo
xmlHttpRequest: typeof GM_xmlhttpRequest
setClipboard: typeof GM_setClipboard
setValue: (name: keyof BilibiliEvolvedSettings, value: any) => Promise<void>
getValue: <T>(name: keyof BilibiliEvolvedSettings, defaultValue?: T) => Promise<T>
}
const settings: BilibiliEvolvedSettings
const customNavbarDefaultOrders: CustomNavbarOrders
const simpleHomeCategoryDefaultOrders: SimpleHomeCategoryOrders
const aria2RpcDefaultOption: RpcOption
const languageNameToCode: { [key: string]: string }
const languageCodeToName: { [key: string]: string }
function logError(message: Error | string): void
function loadSettings(): void
function addSettingsListener(key: keyof BilibiliEvolvedSettings, handler: (newValue: any, oldValue: any) => void, initCall?: boolean): void
function removeSettingsListener(key: keyof BilibiliEvolvedSettings, handler: (newValue: any, oldValue: any) => void): void
function raiseEvent(element: Element, eventName: string): void
function loadLazyPanel(selector: string): Promise<HTMLElement>
function loadLazyPlayerSettingsPanel(buttonSelector: string, panelSelector: string): Promise<HTMLElement>
function loadDanmakuSettingsPanel(): Promise<HTMLElement>
function loadSubtitleSettingsPanel(): Promise<HTMLElement>
function contentLoaded(callback: () => void): void
function fullyLoaded(callback: () => void): void
function fixed(number: number, precision?: number): string
function isEmbeddedPlayer(): boolean
function isIframe(): boolean
function getI18nKey(): string
function dq(selector: string): Element | null
function dq(element: Element, selector: string): Element | null
function dqa(selector: string): Element[]
function dqa(element: Element, selector: string): Element[]
function html(strings: TemplateStringsArray, ...values: unknown[]): string
const formatFileSize: (bytes: number, fixed?: number) => string
const formatDuration: (time: number, fixed?: number) => string
const ascendingSort: <T>(itemProp: (item: T) => number) => (a: T, b: T) => number
const descendingSort: <T>(itemProp: (item: T) => number) => (a: T, b: T) => number
const getDpiSourceSet: (src: string, baseSize: number | string | { width?: number | string, height?: number | string }, extension?: string) => string
const isOffline: () => boolean
const getUID: () => string
const getCsrf: () => string
const formatCount: (count: number | string) => string
const escapeFilename: (filename: string, replacement?: string) => string
const dashExtensions: string[]
const dashFragmentExtension: string
const videoCondition: () => Promise<boolean>
const matchPattern: (str: string, pattern: string | RegExp) => boolean
type ScriptVersion = 'Stable' | 'Preview' | 'Offline' | 'Preview Offline' | 'Local' | 'Local preview' | 'Local stable' | 'Local offline' | 'Local preview offline'
const getScriptVersion: () => ScriptVersion
const playerReady: () => Promise<void>
const formData: (obj: any) => string
const retrieveImageUrl: (element: Element) => { url: string; extension: string } | null
}
export { }

View File

@ -216,7 +216,7 @@ export class LiveSocket extends EventTarget {
if (this.heartBeatTimer) {
clearInterval(this.heartBeatTimer)
}
this.heartBeatTimer = setInterval(() => {
this.heartBeatTimer = window.setInterval(() => {
this.heartBeat()
}, 30 * 1000)
break

View File

@ -1,4 +1,4 @@
import { JSZipFileOptions } from '../../@types/jszip/index'
import { JSZipFileOptions } from 'jszip'
type PackageEntry = { name: string; data: Blob | string, options: JSZipFileOptions }
export class DownloadPackage {

View File

@ -563,7 +563,7 @@ class VideoSpeed {
this.workingDownloader = downloader
}
startMeasure() {
this.intervalTimer = setInterval(() => {
this.intervalTimer = window.setInterval(() => {
const progress = this.workingDownloader.progressMap
? [...this.workingDownloader.progressMap.values()].reduce((a, b) => a + b, 0) : 0
const loadedBytes = progress - this.lastProgress
@ -1182,7 +1182,7 @@ async function loadPanel() {
this.episodeList = []
return
}
const { BatchExtractor } = await import('batch-download')
const { BatchExtractor } = await import('./batch-download')
const { MaxBatchSize } = await import('./batch-warning')
if (await BatchExtractor.test() !== true) {
this.batch = false

View File

@ -84,7 +84,7 @@ if (supportedUrls.some(url => document.URL.startsWith(url))) {
clearTimeout(showPlaybackTipOldTimeout)
}
(dq('.keymap-playback-tip-container') as HTMLDivElement).classList.add('show')
showPlaybackTipOldTimeout = setTimeout(() => {
showPlaybackTipOldTimeout = window.setTimeout(() => {
(dq('.keymap-playback-tip-container') as HTMLDivElement).classList.remove('show')
}, 2000)
}

View File

@ -96,7 +96,7 @@ const entry = async () => {
clearTimeout(showVolumeTipOldTimeout)
}
(dq('.volume-overdrive-tip-container') as HTMLDivElement).classList.add('show')
showVolumeTipOldTimeout = setTimeout(() => {
showVolumeTipOldTimeout = window.setTimeout(() => {
(dq('.volume-overdrive-tip-container') as HTMLDivElement).classList.remove('show')
}, 2000)
}

View File

@ -2,13 +2,11 @@
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"strictNullChecks": true,
"sourceMap": false,
"typeRoots": [
"./@types",
"./node_modules/vue/types"
],
"outDir": ".ts-output/"
},
"include": [

View File

@ -287,6 +287,28 @@
dependencies:
chokidar "2.1.8"
"@types/jquery@^3.5.4":
version "3.5.4"
resolved "https://registry.npm.taobao.org/@types/jquery/download/@types/jquery-3.5.4.tgz#e923f7d05ca790530f17f80a3b89bc28853fa17f"
integrity sha1-6SP30FynkFMPF/gKO4m8KIU/oX8=
dependencies:
"@types/sizzle" "*"
"@types/lodash@^4.14.165":
version "4.14.165"
resolved "https://registry.npm.taobao.org/@types/lodash/download/@types/lodash-4.14.165.tgz?cache=0&sync_timestamp=1604602584734&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Flodash%2Fdownload%2F%40types%2Flodash-4.14.165.tgz#74d55d947452e2de0742bad65270433b63a8c30f"
integrity sha1-dNVdlHRS4t4HQrrWUnBDO2Ooww8=
"@types/node@^14.14.7":
version "14.14.7"
resolved "https://registry.npm.taobao.org/@types/node/download/@types/node-14.14.7.tgz?cache=0&sync_timestamp=1604951305221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Fnode%2Fdownload%2F%40types%2Fnode-14.14.7.tgz#8ea1e8f8eae2430cf440564b98c6dfce1ec5945d"
integrity sha1-jqHo+OriQwz0QFZLmMbfzh7FlF0=
"@types/sizzle@*":
version "2.3.2"
resolved "https://registry.npm.taobao.org/@types/sizzle/download/@types/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
integrity sha1-qBG4wY4rq6t9VCszZYh64uTZ3kc=
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.npm.taobao.org/ansi-styles/download/ansi-styles-3.2.1.tgz?cache=0&sync_timestamp=1601839226460&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fansi-styles%2Fdownload%2Fansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@ -838,6 +860,11 @@ html-minifier@^4.0.0:
relateurl "^0.2.7"
uglify-js "^3.5.1"
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.npm.taobao.org/immediate/download/immediate-3.0.6.tgz?cache=0&sync_timestamp=1591712459989&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fimmediate%2Fdownload%2Fimmediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
@ -1012,6 +1039,16 @@ json5@^2.1.2:
dependencies:
minimist "^1.2.5"
jszip@^3.5.0:
version "3.5.0"
resolved "https://registry.npm.taobao.org/jszip/download/jszip-3.5.0.tgz?cache=0&sync_timestamp=1592170816975&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fjszip%2Fdownload%2Fjszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6"
integrity sha1-tP0fNoJFNGZY54H+yWdYAkieFfY=
dependencies:
lie "~3.3.0"
pako "~1.0.2"
readable-stream "~2.3.6"
set-immediate-shim "~1.0.1"
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
version "3.2.2"
resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
@ -1036,6 +1073,13 @@ kind-of@^6.0.0, kind-of@^6.0.2:
resolved "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=
lie@~3.3.0:
version "3.3.0"
resolved "https://registry.npm.taobao.org/lie/download/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
integrity sha1-3Pgt7lRfRgdNryAMfBxaCOD0D2o=
dependencies:
immediate "~3.0.5"
lodash@^4.17.19:
version "4.17.20"
resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.20.tgz?cache=0&sync_timestamp=1597336053864&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flodash%2Fdownload%2Flodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
@ -1186,6 +1230,11 @@ once@^1.3.0:
dependencies:
wrappy "1"
pako@~1.0.2:
version "1.0.11"
resolved "https://registry.npm.taobao.org/pako/download/pako-1.0.11.tgz?cache=0&sync_timestamp=1580284264887&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fpako%2Fdownload%2Fpako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha1-bJWZ00DVTf05RjgCUqNXBaa5kr8=
param-case@^2.1.1:
version "2.1.1"
resolved "https://registry.npm.taobao.org/param-case/download/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247"
@ -1233,7 +1282,7 @@ process-nextick-args@~2.0.0:
resolved "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha1-eCDZsWEgzFXKmud5JoCufbptf+I=
readable-stream@^2.0.2:
readable-stream@^2.0.2, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.npm.taobao.org/readable-stream/download/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
integrity sha1-Hsoc9xGu+BTAT2IlKjamL2yyO1c=
@ -1339,6 +1388,11 @@ semver@^5.4.1, semver@^5.6.0:
resolved "https://registry.npm.taobao.org/semver/download/semver-5.7.1.tgz?cache=0&sync_timestamp=1586886267748&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsemver%2Fdownload%2Fsemver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha1-qVT5Ma66UI0we78Gnv8MAclhFvc=
set-immediate-shim@~1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/set-immediate-shim/download/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61"
integrity sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=
set-value@^2.0.0, set-value@^2.0.1:
version "2.0.1"
resolved "https://registry.npm.taobao.org/set-value/download/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
@ -1498,6 +1552,11 @@ to-regex@^3.0.1, to-regex@^3.0.2:
regex-not "^1.0.2"
safe-regex "^1.1.0"
typescript@^4.0.5:
version "4.0.5"
resolved "https://registry.npm.taobao.org/typescript/download/typescript-4.0.5.tgz#ae9dddfd1069f1cb5beb3ef3b2170dd7c1332389"
integrity sha1-rp3d/RBp8ctb6z7zshcN18EzI4k=
uglify-js@^3.5.1:
version "3.9.4"
resolved "https://registry.npm.taobao.org/uglify-js/download/uglify-js-3.9.4.tgz?cache=0&sync_timestamp=1590575862599&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fuglify-js%2Fdownload%2Fuglify-js-3.9.4.tgz#867402377e043c1fc7b102253a22b64e5862401b"