您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
bilibili 视频合集标题搜索, 分 P 搜索
// ==UserScript== // @name bilibili 视频合集标题搜索 // @namespace https://github.com/LesslsMore/bili-part-video-search // @version 0.1.1 // @author lesslsmore // @description bilibili 视频合集标题搜索, 分 P 搜索 // @license MIT // @icon https://i0.hdslb.com/bfs/static/jinkela/long/images/favicon.ico // @match https://space.bilibili.com/* // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.global.prod.js // @require data:application/javascript,%3Bwindow.Vue%3DVue%3B // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/index.full.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/axios.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/dexie.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/exceljs.min.js // @require https://cdn.jsdelivr.net/npm/@element-plus/[email protected]/dist/index.iife.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/dexie-export-import.min.js // @require https://cdn.jsdelivr.net/npm/[email protected]/dist/FileSaver.min.js // @resource element-plus/dist/index.css https://cdn.jsdelivr.net/npm/[email protected]/dist/index.css // @connect https://lesslsmore-api.vercel.app/* // @grant GM_addStyle // @grant GM_getResourceText // @grant unsafeWindow // ==/UserScript== (t=>{if(typeof GM_addStyle=="function"){GM_addStyle(t);return}const a=document.createElement("style");a.textContent=t,document.head.append(a)})(" .search-fab-wrapper[data-v-ac2e5c92]{position:fixed;left:10px;bottom:50px;z-index:9999;width:40px;height:40px;display:flex;align-items:center;justify-content:center;padding:10px}.search-fab[data-v-ac2e5c92]{transform:translate(-25px);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1)}.search-fab-wrapper:hover .search-fab[data-v-ac2e5c92]{transform:translate(0);opacity:1}.storage-container[data-v-a8697122]{display:flex;flex-direction:column;gap:10px;width:240px}.storage-row[data-v-a8697122]{display:flex;align-items:center;justify-content:center;margin-bottom:0}.upload-row[data-v-a8697122]{justify-content:flex-start;gap:5px}.setting-fab-wrapper[data-v-0bb163f6]{position:fixed;left:10px;bottom:10px;z-index:9999;width:40px;height:40px;display:flex;align-items:center;justify-content:center;padding:10px}.setting-fab[data-v-0bb163f6]{transform:translate(-25px);transition:transform .3s cubic-bezier(.4,0,.2,1),opacity .3s cubic-bezier(.4,0,.2,1)}.setting-fab-wrapper:hover .setting-fab[data-v-0bb163f6]{transform:translate(0);opacity:1} "); (function (vue, ElementPlusIconsVue, Dexie, dexieExportImport, fileSaver, axios, ExcelJS, ElementPlus) { 'use strict'; function _interopNamespaceDefault(e) { const n = Object.create(null, { [Symbol.toStringTag]: { value: 'Module' } }); if (e) { for (const k in e) { if (k !== 'default') { const d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: () => e[k] }); } } } n.default = e; return Object.freeze(n); } const ElementPlusIconsVue__namespace = /*#__PURE__*/_interopNamespaceDefault(ElementPlusIconsVue); const db_name_bili = "bili"; const db_name_json = "json"; const db_schema_bili = { vlist: "&bvid, mid", cids: "&cid, bvid, mid, view" // 主键 索引 // bvids: '&bvid', }; const mids = [37974444, 302417610]; const db_schema_json = { bvids: "&bvid" }; mids.forEach((mid) => { let schema = `pages[${mid}]`; db_schema_json[schema] = "&pn"; }); const db_bili = get_db(db_name_bili, db_schema_bili); const db_json = get_db(db_name_json, db_schema_json); function get_db(db_name, db_schema, db_ver = 1) { let db2 = new Dexie(db_name); db2.version(db_ver).stores(db_schema); return db2; } async function export_db(_, databaseName) { console.log("export_db:"); console.log(/* @__PURE__ */ new Date()); let databases = await Dexie.getDatabaseNames(); console.log(databases); if (!databases.includes(databaseName)) { throw new Error(`数据库 ${databaseName} 不存在`); } const dbInstance = new Dexie(databaseName); await dbInstance.open(); const blob = await dexieExportImport.exportDB(dbInstance); fileSaver.saveAs(blob, `IndexedDB_${databaseName}.json`); console.log(/* @__PURE__ */ new Date()); } async function import_db(file) { console.log("import_db:"); console.log(/* @__PURE__ */ new Date()); console.log(file); const blob = new Blob([file.raw], { type: file.raw.type }); await dexieExportImport.importDB(blob); console.log(/* @__PURE__ */ new Date()); } async function get_cids_items$1(word, page, limit) { console.log(word); const collection = db_bili.cids.orderBy("view").filter((item) => { try { return item.part.text.includes(word); } catch (e) { console.log(e); console.log(item.part); } }); const res = await collection.toArray(); const result = await collection.reverse().offset((page - 1) * limit).limit(limit).toArray(); console.log(result); return { data: result, total: res.length }; } const db = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, db_bili, db_json, export_db, get_cids_items: get_cids_items$1, get_db, import_db, mids }, Symbol.toStringTag, { value: "Module" })); const service = axios.create({ baseURL: "https://lesslsmore-api.vercel.app/", timeout: 15e3 // 请求超时时间 }); function get_cids_items(part, page, limit) { return service({ url: `/cids`, method: "post", data: { part, page, limit } }); } const _hoisted_1$4 = { style: { "display": "flex", "justify-content": "center" } }; const _hoisted_2$1 = { style: { "display": "flex", "justify-content": "center" } }; const _sfc_main$5 = { __name: "Indexed", setup(__props) { const searchObjRef = vue.ref(); let total = vue.ref(); let tableData = vue.ref([]); let currentPage4 = vue.ref(1); let pageSize4 = vue.ref(10); let searchObj = vue.ref({ name: "", mid: "", bvid: "", part: "" }); const dataSource = vue.ref("index"); let keys = vue.ref( { "name": 10, "title.text": 45, "part.text": 45, "page": 8, "view": 8, "duration": 10, "mid": 10, "bvid": 12, "cid": 11, "url": 38 } ); function sort_data({ prop, order }) { console.log(prop, order); } async function fetchData() { if (dataSource.value === "mongo") { const res = await get_cids_items(searchObj.value.name, currentPage4.value, pageSize4.value); tableData.value = res.data.data; total.value = res.data.total; } else if (dataSource.value === "index") { let res = await get_cids_items$1(searchObj.value.name, currentPage4.value, pageSize4.value); tableData.value = res.data; total.value = res.total; } } const small = vue.ref(false); const background = vue.ref(false); const disabled = vue.ref(false); const handleSizeChange = (val) => { console.log(`${val} items per page`); fetchData(); }; const handleCurrentChange = (val) => { console.log(`current page: ${val}`); fetchData(); }; return (_ctx, _cache) => { const _component_el_option = vue.resolveComponent("el-option"); const _component_el_select = vue.resolveComponent("el-select"); const _component_el_form_item = vue.resolveComponent("el-form-item"); const _component_el_input = vue.resolveComponent("el-input"); const _component_el_button = vue.resolveComponent("el-button"); const _component_el_form = vue.resolveComponent("el-form"); const _component_el_table_column = vue.resolveComponent("el-table-column"); const _component_el_table = vue.resolveComponent("el-table"); const _component_el_pagination = vue.resolveComponent("el-pagination"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createElementVNode("div", _hoisted_1$4, [ vue.createVNode(_component_el_form, { ref_key: "searchObjRef", ref: searchObjRef, style: { "max-width": "100%" }, model: vue.unref(searchObj), "status-icon": "", rules: _ctx.rules, "label-width": "auto", class: "demo-ruleForm", inline: "" }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_form_item, { label: "数据来源" }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_select, { modelValue: dataSource.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => dataSource.value = $event), placeholder: "请选择", style: { "width": "100px" } }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_option, { label: "index", value: "index" }), vue.createVNode(_component_el_option, { label: "mongo", value: "mongo" }) ]), _: 1 }, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_form_item, { label: "分段视频名称" }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_input, { modelValue: vue.unref(searchObj).name, "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => vue.unref(searchObj).name = $event), onKeyup: vue.withKeys(fetchData, ["enter"]) }, null, 8, ["modelValue"]) ]), _: 1 }), vue.createVNode(_component_el_form_item, null, { default: vue.withCtx(() => [ vue.createVNode(_component_el_button, { type: "primary", icon: vue.unref(ElementPlusIconsVue.Search), size: "mini", onClick: _cache[2] || (_cache[2] = ($event) => fetchData()) }, { default: vue.withCtx(() => _cache[5] || (_cache[5] = [ vue.createTextVNode("搜索") ])), _: 1 }, 8, ["icon"]), vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Refresh), size: "mini", onClick: _ctx.resetData }, { default: vue.withCtx(() => _cache[6] || (_cache[6] = [ vue.createTextVNode("重置") ])), _: 1 }, 8, ["icon", "onClick"]) ]), _: 1 }) ]), _: 1 }, 8, ["model", "rules"]) ]), vue.createVNode(_component_el_table, { data: vue.unref(tableData), border: "", style: { "width": "100%" }, onSortChange: sort_data }, { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(Object.entries(vue.unref(keys)), ([head, width], index) => { return vue.openBlock(), vue.createBlock(_component_el_table_column, { sortable: "custom", key: index, prop: head, label: head, width: width * 10 }, null, 8, ["prop", "label", "width"]); }), 128)) ]), _: 1 }, 8, ["data"]), vue.createElementVNode("div", _hoisted_2$1, [ vue.createVNode(_component_el_pagination, { "current-page": vue.unref(currentPage4), "onUpdate:currentPage": _cache[3] || (_cache[3] = ($event) => vue.isRef(currentPage4) ? currentPage4.value = $event : currentPage4 = $event), "page-size": vue.unref(pageSize4), "onUpdate:pageSize": _cache[4] || (_cache[4] = ($event) => vue.isRef(pageSize4) ? pageSize4.value = $event : pageSize4 = $event), "page-sizes": [10, 20, 50, 100, 200, 500, 1e3], small: small.value, disabled: disabled.value, background: background.value, layout: "total, sizes, prev, pager, next, jumper", total: vue.unref(total), onSizeChange: handleSizeChange, onCurrentChange: handleCurrentChange }, null, 8, ["current-page", "page-size", "small", "disabled", "background", "total"]) ]) ], 64); }; } }; const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _hoisted_1$3 = { class: "search-fab-wrapper" }; const _sfc_main$4 = { __name: "Search", setup(__props) { const dialogVisible = vue.ref(false); const openDialog = () => { dialogVisible.value = true; }; return (_ctx, _cache) => { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_dialog = vue.resolveComponent("el-dialog"); return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createElementVNode("div", _hoisted_1$3, [ !dialogVisible.value ? (vue.openBlock(), vue.createBlock(_component_el_button, { key: 0, type: "primary", onClick: openDialog, icon: vue.unref(ElementPlusIconsVue.Search), circle: "", plain: "", class: "search-fab" }, null, 8, ["icon"])) : vue.createCommentVNode("", true) ]), vue.createVNode(_component_el_dialog, { modelValue: dialogVisible.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => dialogVisible.value = $event), fullscreen: "", top: "40vh", width: "70%", draggable: "" }, { default: vue.withCtx(() => [ vue.createVNode(_sfc_main$5) ]), _: 1 }, 8, ["modelValue"]) ], 64); }; } }; const Search = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["__scopeId", "data-v-ac2e5c92"]]); const _hoisted_1$2 = { class: "storage-row upload-row" }; const _sfc_main$3 = { __name: "indexeddb", setup(__props) { let dbNames = vue.ref([]); let selectedDb = vue.ref(""); const dbWhiteList = ["bili", "json"]; vue.onMounted(async () => { let databases = await Dexie.getDatabaseNames(); console.log(databases); dbNames.value = databases.filter((db2) => dbWhiteList.includes(db2)); if (dbNames.value.length > 0) selectedDb.value = dbNames.value[0]; }); function handleExportDb() { if (!selectedDb.value) { ElMessage.error("请选择数据库名称"); return; } export_db(null, selectedDb.value); } return (_ctx, _cache) => { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_upload = vue.resolveComponent("el-upload"); const _component_el_option = vue.resolveComponent("el-option"); const _component_el_select = vue.resolveComponent("el-select"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$2, [ vue.createVNode(_component_el_upload, { multiple: "", "auto-upload": false, accept: ".json", "on-change": vue.unref(import_db), "show-file-list": false }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Upload), style: { "width": "70px" }, type: "primary" }, { default: vue.withCtx(() => _cache[1] || (_cache[1] = [ vue.createTextVNode(" db") ])), _: 1 }, 8, ["icon"]) ]), _: 1 }, 8, ["on-change"]), vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Download), type: "primary", plain: "", style: { "width": "70px" }, onClick: handleExportDb }, { default: vue.withCtx(() => _cache[2] || (_cache[2] = [ vue.createTextVNode("db") ])), _: 1 }, 8, ["icon"]), vue.createVNode(_component_el_select, { modelValue: vue.unref(selectedDb), "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => vue.isRef(selectedDb) ? selectedDb.value = $event : selectedDb = $event), placeholder: "选择数据库名称", style: { "width": "70px" }, "popper-append-to-body": "", "popper-class": "monkey-el-select-popper" }, { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(dbNames), (db2) => { return vue.openBlock(), vue.createBlock(_component_el_option, { key: db2, label: db2, value: db2 }, null, 8, ["label", "value"]); }), 128)) ]), _: 1 }, 8, ["modelValue"]) ]); }; } }; async function export_excel() { let tb_name = "cids"; console.log("export_excel..."); console.log(/* @__PURE__ */ new Date()); const res = await db_bili[tb_name].toArray(); res.sort((a, b) => { if (a.view != b.view) { return b.view - a.view; } else { return a.page - b.page; } }); console.log(res.length); const keys = { "name": 10, "title": 45, "part": 45, "page": 4, "view": 8, "duration": 8, "mid": 10, "bvid": 12, "cid": 10, "url": 45 }; const columns = []; for (const [header, width] of Object.entries(keys)) { columns.push({ header, key: header, width: width * 1.2 }); } await exportToExcel(res, tb_name, columns); console.log(/* @__PURE__ */ new Date()); } async function exportToExcel(jsonData, tb_name, columns) { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet(tb_name); worksheet.columns = columns; jsonData.forEach((record) => { worksheet.addRow(record); }); const buffer = await workbook.xlsx.writeBuffer(); const blob = new Blob([buffer], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); saveAs(blob, `${db_bili.name}.xlsx`); } async function import_excel(_, file) { console.log("import_excel:"); console.log(/* @__PURE__ */ new Date()); console.log(file); console.log(/* @__PURE__ */ new Date()); } function bvid2cids(obj) { const bvid = obj.data.bvid; let item_info = []; obj.data.pages.forEach((el) => { let url = `https://www.bilibili.com/video/${bvid}?p=${el.page}`; let hyperlink = `https://www.bilibili.com/video/${bvid}`; let title = { text: obj.data.title, hyperlink }; let mid = obj.data.owner.mid; let name = obj.data.owner.name; let view = obj.data.stat.view; let page = el.page; let cid = el.cid; let part = { text: el.part, hyperlink: url }; let duration = new Date(el.duration * 1e3).toISOString().substr(11, 8); item_info.push({ name, title, part, page, view, duration, mid, bvid, cid, url }); }); return item_info; } const import_json_bvids = async (_, file) => { console.log("import_json_bvids..."); console.log(/* @__PURE__ */ new Date()); let json_str = await file.raw.text(); let json_obj = JSON.parse(json_str); let bvid = json_obj.data.bvid; db_json.bvids.put({ bvid, json_obj }); console.log(/* @__PURE__ */ new Date()); }; async function vlist2bvids() { console.log("vlist2bvids..."); console.log(/* @__PURE__ */ new Date()); const new_bvids = await db_bili.vlist.orderBy("bvid").primaryKeys(); const old_bvids = await db_json.bvids.orderBy("bvid").primaryKeys(); const bvids = new_bvids.filter((item) => !old_bvids.includes(item)); console.log(bvids.length); for (const bvid of bvids) { try { const response = await fetch(`https://api.bilibili.com/x/web-interface/view?bvid=${bvid}`); if (!response.ok) { console.error(`请求失败: ${bvid}`, response.status); continue; } const json_obj = await response.json(); console.log("fetch 成功:", bvid); console.log(json_obj); await db_json.bvids.put({ bvid, json_obj }); } catch (e) { console.error("fetch 异常:", bvid, e); } } console.log(/* @__PURE__ */ new Date()); } async function bvids2cids() { console.log("bvids2cids..."); console.log(/* @__PURE__ */ new Date()); const old_bvids = await db_bili.cids.orderBy("bvid").uniqueKeys(); let bvids = await db_json.bvids.toArray(); for (let { bvid, json_obj } of bvids) { if (old_bvids.includes(bvid)) continue; let cids = bvid2cids(json_obj); console.log(`每 bvid 下 cid 数: ${cids.length}`); await db_bili.cids.bulkPut(cids); } console.log(/* @__PURE__ */ new Date()); } const import_json_pages = async (_, file) => { console.log("import_json_pages..."); console.log(/* @__PURE__ */ new Date()); let json_str = await file.raw.text(); let json_obj = JSON.parse(json_str); let vlist = json_obj.data.list.vlist; let mid = vlist[0].mid; let pn = json_obj.data.page.pn; await db_json[`pages[${mid}]`].put({ pn, json_obj }); console.log(/* @__PURE__ */ new Date()); }; const _hoisted_1$1 = { class: "storage-container" }; const _hoisted_2 = { class: "storage-row upload-row" }; const _hoisted_3 = { class: "storage-row upload-row" }; const _hoisted_4 = { class: "storage-row upload-row" }; const _hoisted_5 = { class: "storage-row upload-row", style: { "display": "none" } }; const _hoisted_6 = { class: "storage-row upload-row" }; const _sfc_main$2 = { __name: "Storage", setup(__props) { const midsInput = vue.ref(JSON.stringify(mids)); const midsArr = vue.ref(Array.isArray(mids) ? [...mids] : []); vue.watch(midsArr, (arr) => { midsInput.value = JSON.stringify(arr); }, { deep: true }); vue.watch(midsInput, (val) => { try { midsArr.value = JSON.parse(val); } catch (e) { midsArr.value = []; } try { window.monkeyMids = JSON.parse(val); } catch (e) { window.monkeyMids = []; } }, { immediate: true }); function addCurrentMid() { const url = window.location.href; const match = url.match(/space\.bilibili\.com\/(\d+)/); if (match) { let arr; try { arr = JSON.parse(midsInput.value); if (!Array.isArray(arr)) arr = []; } catch (e) { arr = []; } const mid = Number(match[1]); if (!arr.includes(mid)) { arr.push(mid); midsInput.value = JSON.stringify(arr); } } else { window.ElMessage && window.ElMessage.warning("未检测到mid"); } } vue.watch(midsInput, (val) => { try { window.monkeyMids = JSON.parse(val); } catch (e) { window.monkeyMids = []; } }, { immediate: true }); return (_ctx, _cache) => { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_option = vue.resolveComponent("el-option"); const _component_el_select = vue.resolveComponent("el-select"); const _component_el_upload = vue.resolveComponent("el-upload"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1$1, [ vue.createElementVNode("div", _hoisted_2, [ vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Plus), plain: "", style: { "width": "70px" }, type: "primary", onClick: addCurrentMid }, { default: vue.withCtx(() => _cache[2] || (_cache[2] = [ vue.createTextVNode("mids") ])), _: 1 }, 8, ["icon"]), vue.createVNode(_component_el_select, { modelValue: midsArr.value, "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => midsArr.value = $event), multiple: "", "default-first-option": "", placeholder: "请选择或输入mid", style: { "width": "140px" } }, { default: vue.withCtx(() => [ (vue.openBlock(true), vue.createElementBlock(vue.Fragment, null, vue.renderList(vue.unref(mids), (mid) => { return vue.openBlock(), vue.createBlock(_component_el_option, { key: mid, label: mid, value: mid }, null, 8, ["label", "value"]); }), 128)) ]), _: 1 }, 8, ["modelValue"]) ]), vue.createElementVNode("div", _hoisted_3, [ vue.createVNode(_sfc_main$3) ]), vue.createElementVNode("div", _hoisted_4, [ vue.createVNode(_component_el_upload, { "auto-upload": false, accept: ".xlsx, .xls", "on-change": vue.unref(import_excel), "show-file-list": false }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Upload), style: { "width": "80px" }, type: "primary" }, { default: vue.withCtx(() => _cache[3] || (_cache[3] = [ vue.createTextVNode("excel") ])), _: 1 }, 8, ["icon"]) ]), _: 1 }, 8, ["on-change"]), vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Download), plain: "", type: "primary", style: { "width": "80px" }, onClick: _cache[1] || (_cache[1] = ($event) => vue.unref(export_excel)()) }, { default: vue.withCtx(() => _cache[4] || (_cache[4] = [ vue.createTextVNode("excel") ])), _: 1 }, 8, ["icon"]) ]), vue.createElementVNode("div", _hoisted_5, [ vue.createVNode(_component_el_upload, { multiple: "", "auto-upload": false, accept: ".json", "on-change": vue.unref(import_json_bvids), "show-file-list": false }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Upload), style: { "width": "80px" }, type: "primary" }, { default: vue.withCtx(() => _cache[5] || (_cache[5] = [ vue.createTextVNode("bvids") ])), _: 1 }, 8, ["icon"]) ]), _: 1 }, 8, ["on-change"]), vue.createVNode(_component_el_upload, { multiple: "", "auto-upload": false, accept: ".json", "on-change": vue.unref(import_json_pages), "show-file-list": false }, { default: vue.withCtx(() => [ vue.createVNode(_component_el_button, { icon: vue.unref(ElementPlusIconsVue.Upload), style: { "width": "80px" }, type: "primary" }, { default: vue.withCtx(() => _cache[6] || (_cache[6] = [ vue.createTextVNode("pages") ])), _: 1 }, 8, ["icon"]) ]), _: 1 }, 8, ["on-change"]) ]), vue.createElementVNode("div", _hoisted_6, [ vue.createVNode(_component_el_button, { style: { "width": "80px" }, plain: "", type: "primary", onClick: vue.unref(vlist2bvids) }, { default: vue.withCtx(() => _cache[7] || (_cache[7] = [ vue.createTextVNode("vlist2bvids") ])), _: 1 }, 8, ["onClick"]), vue.createVNode(_component_el_button, { style: { "width": "80px", "margin": "0px" }, plain: "", type: "primary", onClick: vue.unref(bvids2cids) }, { default: vue.withCtx(() => _cache[8] || (_cache[8] = [ vue.createTextVNode("bvids2cids") ])), _: 1 }, 8, ["onClick"]) ]) ]); }; } }; const Storage = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["__scopeId", "data-v-a8697122"]]); const _hoisted_1 = { class: "setting-fab-wrapper" }; const _sfc_main$1 = { __name: "Setting", setup(__props) { return (_ctx, _cache) => { const _component_el_button = vue.resolveComponent("el-button"); const _component_el_popover = vue.resolveComponent("el-popover"); return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createVNode(_component_el_popover, { placement: "bottom", width: 250, trigger: "click" }, { reference: vue.withCtx(() => [ vue.createVNode(_component_el_button, { class: "setting-fab", icon: vue.unref(ElementPlusIconsVue.Setting), plain: "", type: "primary", circle: "" }, null, 8, ["icon"]) ]), default: vue.withCtx(() => [ vue.createVNode(Storage) ]), _: 1 }) ]); }; } }; const Setting = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["__scopeId", "data-v-0bb163f6"]]); const _sfc_main = { __name: "App", setup(__props) { return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock(vue.Fragment, null, [ vue.createVNode(Search), vue.createVNode(Setting) ], 64); }; } }; const cssLoader = (e) => { const t = GM_getResourceText(e); return GM_addStyle(t), t; }; cssLoader("element-plus/dist/index.css"); const scriptRel = /* @__PURE__ */ function detectScriptRel() { const relList = typeof document !== "undefined" && document.createElement("link").relList; return relList && relList.supports && relList.supports("modulepreload") ? "modulepreload" : "preload"; }(); const assetsURL = function(dep) { return "/" + dep; }; const seen = {}; const __vitePreload = function preload(baseModule, deps, importerUrl) { let promise = Promise.resolve(); if (deps && deps.length > 0) { let allSettled2 = function(promises) { return Promise.all( promises.map( (p) => Promise.resolve(p).then( (value) => ({ status: "fulfilled", value }), (reason) => ({ status: "rejected", reason }) ) ) ); }; document.getElementsByTagName("link"); const cspNonceMeta = document.querySelector( "meta[property=csp-nonce]" ); const cspNonce = (cspNonceMeta == null ? void 0 : cspNonceMeta.nonce) || (cspNonceMeta == null ? void 0 : cspNonceMeta.getAttribute("nonce")); promise = allSettled2( deps.map((dep) => { dep = assetsURL(dep); if (dep in seen) return; seen[dep] = true; const isCss = dep.endsWith(".css"); const cssSelector = isCss ? '[rel="stylesheet"]' : ""; if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) { return; } const link = document.createElement("link"); link.rel = isCss ? "stylesheet" : scriptRel; if (!isCss) { link.as = "script"; } link.crossOrigin = ""; link.href = dep; if (cspNonce) { link.setAttribute("nonce", cspNonce); } document.head.appendChild(link); if (isCss) { return new Promise((res, rej) => { link.addEventListener("load", res); link.addEventListener( "error", () => rej(new Error(`Unable to preload CSS for ${dep}`)) ); }); } }) ); } function handlePreloadError(err) { const e = new Event("vite:preloadError", { cancelable: true }); e.payload = err; window.dispatchEvent(e); if (!e.defaultPrevented) { throw err; } } return promise.then((res) => { for (const item of res || []) { if (item.status !== "rejected") continue; handlePreloadError(item.reason); } return baseModule().catch(handlePreloadError); }); }; var _unsafeWindow = /* @__PURE__ */ (() => typeof unsafeWindow != "undefined" ? unsafeWindow : void 0)(); function interceptor() { const originalFetch = _unsafeWindow.fetch; _unsafeWindow.fetch = async function(input, init) { const response = await originalFetch(input, init); const url = typeof input === "string" ? input : input.url; if (url.includes("api.bilibili.com/x/space/wbi/arc/search")) { const urlParams = new URLSearchParams(url.split("?")[1]); const mid = urlParams.get("mid"); const pn = urlParams.get("pn"); const ps = urlParams.get("ps"); console.log("提取参数:", { mid, pn, ps }); let mids2 = []; try { if (window.monkeyMids) { if (typeof window.monkeyMids === "string") { mids2 = JSON.parse(window.monkeyMids); } else if (Array.isArray(window.monkeyMids)) { mids2 = window.monkeyMids; } } } catch (e) { console.warn("解析 monkeyMids 失败", e); } if (mids2.includes(Number(mid)) || mids2.includes(mid)) { const cloned = response.clone(); cloned.json().then(async (data) => { console.log("Fetch响应内容:", data); if (data && data.data && data.data.list && data.data.list.vlist) { const db_bili2 = window.db_bili || (await __vitePreload(async () => { const { db_bili: db_bili3 } = await Promise.resolve().then(() => db); return { db_bili: db_bili3 }; }, void 0 )).db_bili; await db_bili2.vlist.bulkPut(data.data.list.vlist); console.log("已同步 vlist 到 IndexedDB"); } }); } } return response; }; } interceptor(); const app = vue.createApp(_sfc_main); for (const [key, component] of Object.entries(ElementPlusIconsVue__namespace)) { app.component(key, component); } app.use(ElementPlus); app.mount( (() => { const app2 = document.createElement("div"); document.body.append(app2); return app2; })() ); })(Vue, ElementPlusIconsVue, Dexie, DexieExportImport, saveAs, axios, ExcelJS, ElementPlus);