karin-plugin-kkk 2.45.2-beta.1 → 2.45.2-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/lib/apps/admin.js +1 -1
- package/lib/apps/help.js +1 -1
- package/lib/apps/push.js +1 -1
- package/lib/apps/qrlogin.js +1 -1
- package/lib/apps/statistics.js +1 -1
- package/lib/apps/testPush.js +1 -1
- package/lib/apps/tools.js +2 -2
- package/lib/build-metadata.json +5 -5
- package/lib/core_chunk/RiskVerify.js +1 -1
- package/lib/core_chunk/amagiClient.js +1 -1
- package/lib/core_chunk/db.js +1 -1
- package/lib/core_chunk/main.js +820 -415
- package/lib/root.js +1 -1
- package/lib/style.css +15 -72
- package/lib/template-registry.js +1 -1
- package/lib/web.config.js +1 -1
- package/package.json +2 -2
package/lib/core_chunk/main.js
CHANGED
|
@@ -7,7 +7,7 @@ import fs from "node:fs";
|
|
|
7
7
|
import path, { resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import karin, { BOT_CONNECT, app, authMiddleware, checkPkgUpdate, common, config, createBadRequestResponse, createNotFoundResponse, createServerErrorResponse, createSuccessResponse, db, defineConfig, exec, ffmpeg, ffprobe, getPkgVersion, getRemotePkgVersion, hooks, isDocker, karin as karin$1, karinPathHtml, logger, logs, mkdirSync, parseChangelog, range, render, restart, segment, updatePkg, watch } from "node-karin";
|
|
10
|
-
import crypto from "node:crypto";
|
|
10
|
+
import crypto, { randomBytes } from "node:crypto";
|
|
11
11
|
import { deflateSync, inflateSync } from "node:zlib";
|
|
12
12
|
import express from "node-karin/express";
|
|
13
13
|
import axios, { AxiosError } from "node-karin/axios";
|
|
@@ -11791,6 +11791,8 @@ var DecorationCard = ({ data }) => {
|
|
|
11791
11791
|
};
|
|
11792
11792
|
//#endregion
|
|
11793
11793
|
//#region ktr/template/bilibili/bangumi/components/bangumi.tsx
|
|
11794
|
+
/** 海报每页展示的集数,和 core 的 EPISODE_SELECTION_PAGE_SIZE 保持一致 */
|
|
11795
|
+
var DEFAULT_POSTER_PAGE_SIZE$1 = 15;
|
|
11794
11796
|
/**
|
|
11795
11797
|
* 格式化数字显示
|
|
11796
11798
|
* @param num 要格式化的数字
|
|
@@ -11814,20 +11816,6 @@ var formatDateParts = (timestamp) => {
|
|
|
11814
11816
|
};
|
|
11815
11817
|
};
|
|
11816
11818
|
/**
|
|
11817
|
-
* 格式化完整日期时间
|
|
11818
|
-
* @param timestamp 时间戳
|
|
11819
|
-
* @returns 格式化的日期时间字符串
|
|
11820
|
-
*/
|
|
11821
|
-
var formatDateTime = (timestamp) => {
|
|
11822
|
-
return (/* @__PURE__ */ new Date(timestamp * 1e3)).toLocaleDateString("zh-CN", {
|
|
11823
|
-
year: "numeric",
|
|
11824
|
-
month: "short",
|
|
11825
|
-
day: "numeric",
|
|
11826
|
-
hour: "2-digit",
|
|
11827
|
-
minute: "2-digit"
|
|
11828
|
-
});
|
|
11829
|
-
};
|
|
11830
|
-
/**
|
|
11831
11819
|
* B站番剧头部组件
|
|
11832
11820
|
* @param props 头部组件属性
|
|
11833
11821
|
*/
|
|
@@ -11839,102 +11827,88 @@ var BangumiBilibiliHeader = (props) => {
|
|
|
11839
11827
|
className: "flex relative z-10 gap-25 p-25",
|
|
11840
11828
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11841
11829
|
className: "flex flex-col shrink-0 gap-20",
|
|
11842
|
-
children: [
|
|
11843
|
-
|
|
11844
|
-
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
className: "
|
|
11853
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11854
|
-
className: "relative",
|
|
11855
|
-
children: [
|
|
11856
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11857
|
-
className: "w-28 h-28 rounded-full select-text",
|
|
11858
|
-
src: `https://images.weserv.nl/?url=${encodeURIComponent(props.upInfo.avatar)}`,
|
|
11859
|
-
alt: props.upInfo.uname
|
|
11860
|
-
}),
|
|
11861
|
-
props.upInfo.avatar_subscript_url && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11862
|
-
className: "absolute -right-1 -bottom-1 w-8 h-8 select-text",
|
|
11863
|
-
src: props.upInfo.avatar_subscript_url,
|
|
11864
|
-
alt: "头像角标"
|
|
11865
|
-
}),
|
|
11866
|
-
props.upInfo.pendant?.image && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11867
|
-
className: "absolute inset-0 w-full h-full transform select-text scale-160",
|
|
11868
|
-
src: props.upInfo.pendant.image,
|
|
11869
|
-
alt: props.upInfo.pendant.name || "挂件"
|
|
11870
|
-
})
|
|
11871
|
-
]
|
|
11872
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11873
|
-
className: "flex flex-col gap-4",
|
|
11874
|
-
children: [
|
|
11875
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11876
|
-
className: "flex gap-3 items-center",
|
|
11877
|
-
children: [
|
|
11878
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
11879
|
-
className: "text-4xl font-medium select-text",
|
|
11880
|
-
style: { color: props.upInfo.vip_status === 1 ? props.upInfo.nickname_color || "#FB7299" : "#EDEDED" },
|
|
11881
|
-
children: props.upInfo.uname
|
|
11882
|
-
}),
|
|
11883
|
-
props.upInfo.verify_type > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
11884
|
-
className: "flex items-center",
|
|
11885
|
-
children: props.upInfo.verify_type === 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shield, {
|
|
11886
|
-
width: 20,
|
|
11887
|
-
className: "text-warning"
|
|
11888
|
-
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Crown, {
|
|
11889
|
-
width: 20,
|
|
11890
|
-
className: "text-accent"
|
|
11891
|
-
})
|
|
11892
|
-
}),
|
|
11893
|
-
props.upInfo.vip_status === 1 && props.upInfo.vip_label?.text && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
11894
|
-
size: "sm",
|
|
11895
|
-
className: "px-2 py-1 text-xs select-text",
|
|
11896
|
-
style: {
|
|
11897
|
-
backgroundColor: props.upInfo.vip_label.bg_color || "#FB7299",
|
|
11898
|
-
color: props.upInfo.vip_label.text_color || "#FFFFFF",
|
|
11899
|
-
borderColor: props.upInfo.vip_label.border_color || "transparent"
|
|
11900
|
-
},
|
|
11901
|
-
children: props.upInfo.vip_label.text
|
|
11902
|
-
})
|
|
11903
|
-
]
|
|
11904
|
-
}),
|
|
11905
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11906
|
-
className: "flex gap-6 items-center text-3xl select-text text-foreground",
|
|
11907
|
-
children: [
|
|
11908
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Users, { size: 30 }),
|
|
11909
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [formatNumber$2(props.upInfo.follower), "粉丝"] }),
|
|
11910
|
-
props.upInfo.is_follow === 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
11911
|
-
size: "sm",
|
|
11912
|
-
color: "accent",
|
|
11913
|
-
variant: "soft",
|
|
11914
|
-
className: "text-xs select-text",
|
|
11915
|
-
children: "已关注"
|
|
11916
|
-
})
|
|
11917
|
-
]
|
|
11918
|
-
}),
|
|
11919
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11920
|
-
className: "flex gap-2 items-center text-2xl select-text text-foreground/70",
|
|
11921
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Hash, { size: 20 }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["UID: ", props.upInfo.mid] })]
|
|
11922
|
-
})
|
|
11923
|
-
]
|
|
11924
|
-
})]
|
|
11925
|
-
}),
|
|
11926
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11927
|
-
className: "flex text-3xl select-text text-foreground",
|
|
11830
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
11831
|
+
className: "overflow-hidden rounded-4xl w-120 h-160",
|
|
11832
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11833
|
+
src: props.mainCover,
|
|
11834
|
+
alt: props.title,
|
|
11835
|
+
className: "object-cover w-full h-full select-text"
|
|
11836
|
+
})
|
|
11837
|
+
}), props.upInfo && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11838
|
+
className: "flex gap-12 items-center mt-15",
|
|
11839
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11840
|
+
className: "relative",
|
|
11928
11841
|
children: [
|
|
11929
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
11930
|
-
|
|
11931
|
-
|
|
11932
|
-
|
|
11842
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11843
|
+
className: "w-28 h-28 rounded-full select-text",
|
|
11844
|
+
src: `https://images.weserv.nl/?url=${encodeURIComponent(props.upInfo.avatar)}`,
|
|
11845
|
+
alt: props.upInfo.uname
|
|
11846
|
+
}),
|
|
11847
|
+
props.upInfo.avatar_subscript_url && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11848
|
+
className: "absolute -right-1 -bottom-1 w-8 h-8 select-text",
|
|
11849
|
+
src: props.upInfo.avatar_subscript_url,
|
|
11850
|
+
alt: "头像角标"
|
|
11933
11851
|
}),
|
|
11934
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
11852
|
+
props.upInfo.pendant?.image && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
11853
|
+
className: "absolute inset-0 w-full h-full transform select-text scale-160",
|
|
11854
|
+
src: props.upInfo.pendant.image,
|
|
11855
|
+
alt: props.upInfo.pendant.name || "挂件"
|
|
11856
|
+
})
|
|
11935
11857
|
]
|
|
11936
|
-
})
|
|
11937
|
-
|
|
11858
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11859
|
+
className: "flex flex-col gap-4",
|
|
11860
|
+
children: [
|
|
11861
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11862
|
+
className: "flex gap-3 items-center",
|
|
11863
|
+
children: [
|
|
11864
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
11865
|
+
className: "text-4xl font-medium select-text",
|
|
11866
|
+
style: { color: props.upInfo.vip_status === 1 ? props.upInfo.nickname_color || "#FB7299" : "#EDEDED" },
|
|
11867
|
+
children: props.upInfo.uname
|
|
11868
|
+
}),
|
|
11869
|
+
props.upInfo.verify_type > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
11870
|
+
className: "flex items-center",
|
|
11871
|
+
children: props.upInfo.verify_type === 1 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Shield, {
|
|
11872
|
+
width: 20,
|
|
11873
|
+
className: "text-warning"
|
|
11874
|
+
}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Crown, {
|
|
11875
|
+
width: 20,
|
|
11876
|
+
className: "text-accent"
|
|
11877
|
+
})
|
|
11878
|
+
}),
|
|
11879
|
+
props.upInfo.vip_status === 1 && props.upInfo.vip_label?.text && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
11880
|
+
size: "sm",
|
|
11881
|
+
className: "px-2 py-1 text-xs select-text",
|
|
11882
|
+
style: {
|
|
11883
|
+
backgroundColor: props.upInfo.vip_label.bg_color || "#FB7299",
|
|
11884
|
+
color: props.upInfo.vip_label.text_color || "#FFFFFF",
|
|
11885
|
+
borderColor: props.upInfo.vip_label.border_color || "transparent"
|
|
11886
|
+
},
|
|
11887
|
+
children: props.upInfo.vip_label.text
|
|
11888
|
+
})
|
|
11889
|
+
]
|
|
11890
|
+
}),
|
|
11891
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11892
|
+
className: "flex gap-6 items-center text-3xl select-text text-foreground",
|
|
11893
|
+
children: [
|
|
11894
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Users, { size: 30 }),
|
|
11895
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [formatNumber$2(props.upInfo.follower), "粉丝"] }),
|
|
11896
|
+
props.upInfo.is_follow === 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
11897
|
+
size: "sm",
|
|
11898
|
+
color: "accent",
|
|
11899
|
+
variant: "soft",
|
|
11900
|
+
className: "text-xs select-text",
|
|
11901
|
+
children: "已关注"
|
|
11902
|
+
})
|
|
11903
|
+
]
|
|
11904
|
+
}),
|
|
11905
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11906
|
+
className: "flex gap-2 items-center text-2xl select-text text-foreground/70",
|
|
11907
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Hash, { size: 20 }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["UID: ", props.upInfo.mid] })]
|
|
11908
|
+
})
|
|
11909
|
+
]
|
|
11910
|
+
})]
|
|
11911
|
+
})]
|
|
11938
11912
|
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
11939
11913
|
className: "flex flex-col flex-1 justify-between text-foreground",
|
|
11940
11914
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
@@ -12057,171 +12031,132 @@ var BangumiBilibiliHeader = (props) => {
|
|
|
12057
12031
|
})
|
|
12058
12032
|
});
|
|
12059
12033
|
};
|
|
12034
|
+
/** 文字选集提示里的命令高亮,和海报的强调色保持一致 */
|
|
12035
|
+
var CommandChip$1 = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12036
|
+
className: "inline-flex items-center rounded-xl bg-danger px-4 py-1.5 font-semibold text-danger-foreground",
|
|
12037
|
+
children
|
|
12038
|
+
});
|
|
12060
12039
|
/**
|
|
12061
|
-
* B
|
|
12040
|
+
* B站番剧剧集列表组件。
|
|
12041
|
+
* 每页最多 15 集,3 列网格展示封面 + 标题;长番剧不会再生成超长截图。
|
|
12062
12042
|
* @param props 剧集列表组件属性
|
|
12063
12043
|
*/
|
|
12064
12044
|
var BangumiBilibiliEpisodes = (props) => {
|
|
12065
|
-
const
|
|
12066
|
-
const
|
|
12067
|
-
|
|
12068
|
-
|
|
12069
|
-
|
|
12070
|
-
|
|
12071
|
-
|
|
12072
|
-
|
|
12073
|
-
const
|
|
12074
|
-
const
|
|
12075
|
-
|
|
12076
|
-
const episodesInDate = groupedEpisodes[dateIndex];
|
|
12077
|
-
episodesInDate.forEach((episode, episodeIndex) => {
|
|
12078
|
-
flattenedEpisodes.push({
|
|
12079
|
-
episode,
|
|
12080
|
-
isFirstOfDate: episodeIndex === 0,
|
|
12081
|
-
isLastOfDate: episodeIndex === episodesInDate.length - 1,
|
|
12082
|
-
isLastOfAll: false,
|
|
12083
|
-
dateKey: dateIndex,
|
|
12084
|
-
episodesInSameDate: episodesInDate.length
|
|
12085
|
-
});
|
|
12086
|
-
});
|
|
12087
|
-
});
|
|
12088
|
-
if (flattenedEpisodes.length > 0) flattenedEpisodes[flattenedEpisodes.length - 1].isLastOfAll = true;
|
|
12045
|
+
const totalEpisodes = props.length > 0 ? props.length : props.Episodes.length;
|
|
12046
|
+
const pageSize = Math.max(1, props.posterPageSize ?? DEFAULT_POSTER_PAGE_SIZE$1);
|
|
12047
|
+
const pageCount = Math.max(1, Math.ceil(totalEpisodes / pageSize));
|
|
12048
|
+
const page = Math.min(Math.max(1, props.posterPage ?? 1), pageCount);
|
|
12049
|
+
const start = (page - 1) * pageSize;
|
|
12050
|
+
const visibleEpisodes = props.Episodes.slice(start, start + pageSize);
|
|
12051
|
+
if (visibleEpisodes.length === 0) return null;
|
|
12052
|
+
const episodeNumbers = visibleEpisodes.map((episode, index) => episode.episode ?? start + index + 1);
|
|
12053
|
+
const firstEpisode = episodeNumbers[0];
|
|
12054
|
+
const lastEpisode = episodeNumbers[episodeNumbers.length - 1];
|
|
12055
|
+
const range = firstEpisode === lastEpisode ? `第 ${firstEpisode} 集` : `第 ${firstEpisode}–${lastEpisode} 集`;
|
|
12089
12056
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12090
12057
|
className: "px-10",
|
|
12091
|
-
children: [
|
|
12092
|
-
|
|
12093
|
-
|
|
12094
|
-
|
|
12095
|
-
|
|
12096
|
-
|
|
12097
|
-
|
|
12098
|
-
|
|
12099
|
-
|
|
12100
|
-
|
|
12058
|
+
children: [
|
|
12059
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12060
|
+
className: "flex flex-wrap gap-6 items-center mb-16 text-5xl font-bold select-text text-foreground",
|
|
12061
|
+
children: [
|
|
12062
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Play, { size: 46 }),
|
|
12063
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "剧集列表" }),
|
|
12064
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Chip, {
|
|
12065
|
+
size: "lg",
|
|
12066
|
+
color: "danger",
|
|
12067
|
+
variant: "soft",
|
|
12068
|
+
className: "h-18 px-4 py-2 text-4xl select-text",
|
|
12069
|
+
children: [
|
|
12070
|
+
"共",
|
|
12071
|
+
totalEpisodes,
|
|
12072
|
+
"集"
|
|
12073
|
+
]
|
|
12074
|
+
}),
|
|
12075
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12076
|
+
className: "text-3xl font-semibold select-text text-muted",
|
|
12077
|
+
children: props.selectionMode === "button" ? range : `第 ${page}/${pageCount} 页 · ${range}`
|
|
12078
|
+
})
|
|
12079
|
+
]
|
|
12080
|
+
}),
|
|
12081
|
+
props.selectionMode !== "button" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12082
|
+
className: "flex flex-col gap-4 mb-12 text-3xl select-text text-foreground/80",
|
|
12083
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12084
|
+
className: "flex flex-wrap gap-3 items-center",
|
|
12101
12085
|
children: [
|
|
12102
|
-
"
|
|
12103
|
-
|
|
12104
|
-
"
|
|
12086
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "发送" }),
|
|
12087
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip$1, { children: "第?集" }),
|
|
12088
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "选集" })
|
|
12105
12089
|
]
|
|
12106
|
-
})
|
|
12107
|
-
|
|
12108
|
-
|
|
12109
|
-
|
|
12110
|
-
|
|
12111
|
-
|
|
12112
|
-
|
|
12113
|
-
|
|
12114
|
-
className: "flex gap-15",
|
|
12115
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12116
|
-
className: "flex flex-col shrink-0 items-center w-20",
|
|
12117
|
-
children: isFirstOfDate ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
12118
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12119
|
-
className: "text-4xl select-text text-foreground",
|
|
12120
|
-
children: month
|
|
12090
|
+
}), pageCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12091
|
+
className: "flex flex-wrap gap-3 items-center",
|
|
12092
|
+
children: [
|
|
12093
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "发送" }),
|
|
12094
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip$1, { children: "上一页" }),
|
|
12095
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12096
|
+
className: "text-foreground/30",
|
|
12097
|
+
children: "/"
|
|
12121
12098
|
}),
|
|
12122
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
12123
|
-
|
|
12124
|
-
|
|
12099
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip$1, { children: "下一页" }),
|
|
12100
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12101
|
+
className: "text-foreground/30",
|
|
12102
|
+
children: "/"
|
|
12125
12103
|
}),
|
|
12126
|
-
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12104
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip$1, { children: "第?页" }),
|
|
12105
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "翻页" })
|
|
12106
|
+
]
|
|
12107
|
+
})]
|
|
12108
|
+
}),
|
|
12109
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12110
|
+
className: "grid grid-cols-3 gap-8",
|
|
12111
|
+
children: visibleEpisodes.map((episode, index) => {
|
|
12112
|
+
const episodeNumber = episodeNumbers[index];
|
|
12113
|
+
const { month, day } = formatDateParts(episode.pub_time);
|
|
12114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12115
|
+
className: "flex flex-col overflow-hidden bg-surface rounded-3xl shadow-large",
|
|
12136
12116
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12137
|
-
className: "
|
|
12138
|
-
children: [
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12117
|
+
className: "overflow-hidden relative aspect-video",
|
|
12118
|
+
children: [
|
|
12119
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
12120
|
+
src: episode.cover,
|
|
12121
|
+
alt: `第${episodeNumber}集 ${episode.long_title}`,
|
|
12122
|
+
className: "object-cover w-full h-full select-text"
|
|
12123
|
+
}),
|
|
12124
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12125
|
+
className: "absolute top-4 left-4 px-3 py-1 text-2xl font-bold text-white rounded-xl bg-black/65",
|
|
12126
|
+
children: [
|
|
12127
|
+
"第",
|
|
12128
|
+
episodeNumber,
|
|
12129
|
+
"集"
|
|
12130
|
+
]
|
|
12131
|
+
}),
|
|
12132
|
+
episode.badge && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
12133
|
+
size: "sm",
|
|
12134
|
+
className: "absolute top-4 right-4 px-2 py-1 text-lg font-medium select-text",
|
|
12135
|
+
style: {
|
|
12136
|
+
backgroundColor: episode.badge_info?.bg_color || "#FB7299",
|
|
12137
|
+
color: "#FFFFFF"
|
|
12138
|
+
},
|
|
12139
|
+
children: episode.badge_info?.text || episode.badge
|
|
12144
12140
|
})
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
})]
|
|
12154
|
-
})]
|
|
12155
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12156
|
-
className: "shrink-0 pr-20",
|
|
12157
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12158
|
-
className: "text-5xl font-semibold select-text text-foreground/70",
|
|
12141
|
+
]
|
|
12142
|
+
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12143
|
+
className: "flex flex-col flex-1 gap-3 p-5",
|
|
12144
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12145
|
+
className: "text-3xl font-semibold leading-snug select-text text-foreground line-clamp-2",
|
|
12146
|
+
children: episode.long_title || `第${episodeNumber}集`
|
|
12147
|
+
}), episode.pub_time > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12148
|
+
className: "mt-auto text-2xl select-text text-foreground/60",
|
|
12159
12149
|
children: [
|
|
12160
|
-
|
|
12161
|
-
|
|
12162
|
-
"
|
|
12150
|
+
month,
|
|
12151
|
+
day,
|
|
12152
|
+
"日"
|
|
12163
12153
|
]
|
|
12164
|
-
})
|
|
12165
|
-
})]
|
|
12166
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12167
|
-
className: "overflow-hidden shadow-large bg-surface rounded-4xl",
|
|
12168
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12169
|
-
className: "flex gap-12 p-12",
|
|
12170
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12171
|
-
className: "relative shrink-0",
|
|
12172
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12173
|
-
className: "overflow-hidden relative h-64 rounded-3xl w-md",
|
|
12174
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
12175
|
-
src: episode.cover,
|
|
12176
|
-
alt: `第${actualEpisodeNumber}集 ${episode.long_title}`,
|
|
12177
|
-
className: "object-cover w-full h-full select-text"
|
|
12178
|
-
}), episode.badge && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Chip, {
|
|
12179
|
-
size: "lg",
|
|
12180
|
-
className: "absolute top-6 right-8 rounded-2xl py-1 text-lg font-medium select-text scale-150",
|
|
12181
|
-
style: {
|
|
12182
|
-
backgroundColor: episode.badge_info?.bg_color || "#FB7299",
|
|
12183
|
-
color: "#FFFFFF"
|
|
12184
|
-
},
|
|
12185
|
-
children: episode.badge_info?.text || episode.badge
|
|
12186
|
-
})]
|
|
12187
|
-
})
|
|
12188
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12189
|
-
className: "flex flex-col flex-1 justify-center h-64",
|
|
12190
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
12191
|
-
className: "mb-8 text-5xl font-semibold select-text text-foreground line-clamp-2",
|
|
12192
|
-
children: episode.long_title
|
|
12193
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12194
|
-
className: "space-y-4 text-4xl",
|
|
12195
|
-
children: [
|
|
12196
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12197
|
-
className: "flex gap-6 items-center select-text text-foreground/70",
|
|
12198
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Hash, { size: 36 }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12199
|
-
className: "truncate",
|
|
12200
|
-
children: episode.bvid
|
|
12201
|
-
})]
|
|
12202
|
-
}),
|
|
12203
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12204
|
-
className: "flex gap-6 items-center select-text text-foreground/70",
|
|
12205
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Clock, { size: 36 }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12206
|
-
className: "whitespace-nowrap",
|
|
12207
|
-
children: formatDateTime(episode.pub_time)
|
|
12208
|
-
})]
|
|
12209
|
-
}),
|
|
12210
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
12211
|
-
className: "flex gap-6 items-center select-text text-foreground/70",
|
|
12212
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Share2, { size: 36 }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
12213
|
-
className: "truncate",
|
|
12214
|
-
children: episode.link
|
|
12215
|
-
})]
|
|
12216
|
-
})
|
|
12217
|
-
]
|
|
12218
|
-
})]
|
|
12219
12154
|
})]
|
|
12220
|
-
})
|
|
12221
|
-
})
|
|
12222
|
-
})
|
|
12223
|
-
}
|
|
12224
|
-
|
|
12155
|
+
})]
|
|
12156
|
+
}, `${episodeNumber}-${episode.bvid}`);
|
|
12157
|
+
})
|
|
12158
|
+
})
|
|
12159
|
+
]
|
|
12225
12160
|
});
|
|
12226
12161
|
};
|
|
12227
12162
|
var BangumiBilibili = import_react.memo((props) => {
|
|
@@ -18600,6 +18535,8 @@ var live_default = defineTemplate({
|
|
|
18600
18535
|
});
|
|
18601
18536
|
//#endregion
|
|
18602
18537
|
//#region ktr/template/douyin/mix/components/Mix.tsx
|
|
18538
|
+
/** 海报每页展示的集数,和 core 的 EPISODE_SELECTION_PAGE_SIZE 保持一致 */
|
|
18539
|
+
var DEFAULT_POSTER_PAGE_SIZE = 15;
|
|
18603
18540
|
/** 万/亿 计数,数值与单位分开返回:数字用大号等宽,单位用小号 */
|
|
18604
18541
|
var splitCount = (count) => {
|
|
18605
18542
|
if (count >= 1e8) return {
|
|
@@ -18872,113 +18809,114 @@ var MixSynopsis = ({ data }) => {
|
|
|
18872
18809
|
})]
|
|
18873
18810
|
});
|
|
18874
18811
|
};
|
|
18812
|
+
/** 文字选集提示里的命令高亮,和 B 站番剧模板保持一致 */
|
|
18813
|
+
var CommandChip = ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18814
|
+
className: "inline-flex items-center rounded-xl bg-danger px-4 py-1.5 font-semibold text-danger-foreground",
|
|
18815
|
+
children
|
|
18816
|
+
});
|
|
18875
18817
|
var MixEpisodes = ({ data }) => {
|
|
18876
|
-
const { kind, episodes, total_episode, updated_to_episode,
|
|
18877
|
-
const
|
|
18878
|
-
const
|
|
18879
|
-
const
|
|
18880
|
-
|
|
18881
|
-
|
|
18882
|
-
|
|
18883
|
-
const
|
|
18884
|
-
const
|
|
18885
|
-
const
|
|
18886
|
-
const unit = kind === "collection" ? "视频" : "剧集";
|
|
18818
|
+
const { kind, episodes, total_episode, updated_to_episode, selectionMode } = data;
|
|
18819
|
+
const pageSize = Math.max(1, data.posterPageSize ?? DEFAULT_POSTER_PAGE_SIZE);
|
|
18820
|
+
const pageCount = Math.max(1, Math.ceil(episodes.length / pageSize));
|
|
18821
|
+
const page = Math.min(Math.max(1, data.posterPage ?? 1), pageCount);
|
|
18822
|
+
const start = (page - 1) * pageSize;
|
|
18823
|
+
const visibleEpisodes = episodes.slice(start, start + pageSize);
|
|
18824
|
+
if (visibleEpisodes.length === 0) return null;
|
|
18825
|
+
const firstEpisode = visibleEpisodes[0].episode;
|
|
18826
|
+
const lastEpisode = visibleEpisodes[visibleEpisodes.length - 1].episode;
|
|
18827
|
+
const range = firstEpisode === lastEpisode ? `第 ${firstEpisode} 集` : `第 ${firstEpisode}–${lastEpisode} 集`;
|
|
18887
18828
|
const countUnit = kind === "collection" ? "个视频" : "集";
|
|
18829
|
+
const maxEpisode = episodes.reduce((max, item) => Math.max(max, item.episode), 0);
|
|
18830
|
+
const episodeSet = new Set(episodes.map((item) => item.episode));
|
|
18831
|
+
const missingEpisodes = [];
|
|
18832
|
+
for (let episode = 1; episode <= Math.max(maxEpisode, updated_to_episode); episode++) if (!episodeSet.has(episode)) missingEpisodes.push(episode);
|
|
18888
18833
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("section", {
|
|
18889
18834
|
className: "mt-16",
|
|
18890
18835
|
children: [
|
|
18891
18836
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionTitle$1, {
|
|
18892
|
-
extra: /* @__PURE__ */ (0, import_jsx_runtime.
|
|
18837
|
+
extra: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18893
18838
|
className: "text-[30px] font-semibold text-muted",
|
|
18894
|
-
children:
|
|
18895
|
-
"已列出 ",
|
|
18896
|
-
episodes.length,
|
|
18897
|
-
" / ",
|
|
18898
|
-
total_episode,
|
|
18899
|
-
" ",
|
|
18900
|
-
countUnit
|
|
18901
|
-
]
|
|
18839
|
+
children: selectionMode === "button" ? range : `第 ${page}/${pageCount} 页 · ${range}`
|
|
18902
18840
|
}),
|
|
18903
18841
|
children: "选集"
|
|
18904
18842
|
}),
|
|
18905
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18906
|
-
className: "
|
|
18843
|
+
selectionMode !== "button" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18844
|
+
className: "flex flex-col gap-4 mt-8 text-[32px] select-text text-foreground/80",
|
|
18907
18845
|
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18908
|
-
className: "flex
|
|
18846
|
+
className: "flex flex-wrap gap-3 items-center",
|
|
18909
18847
|
children: [
|
|
18910
18848
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "发送" }),
|
|
18911
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
18912
|
-
|
|
18913
|
-
children: "第?集"
|
|
18914
|
-
}),
|
|
18915
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: ["或直接发送集数,解析对应", unit] })
|
|
18849
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip, { children: "第?集" }),
|
|
18850
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "选集" })
|
|
18916
18851
|
]
|
|
18917
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18918
|
-
className: "
|
|
18919
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18920
|
-
className: "text-[64px] font-semibold leading-none text-foreground tabular-nums",
|
|
18921
|
-
children: [timeoutSeconds, "s"]
|
|
18922
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18923
|
-
className: "mt-2 text-[24px] font-semibold text-muted",
|
|
18924
|
-
children: "内有效"
|
|
18925
|
-
})]
|
|
18926
|
-
})]
|
|
18927
|
-
}),
|
|
18928
|
-
kind === "collection" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18929
|
-
className: "mt-8 grid grid-cols-2 gap-4",
|
|
18930
|
-
children: cells.map((cell) => cell.item === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18931
|
-
className: "flex items-center gap-6 rounded-3xl border-2 border-dashed border-foreground/20 px-7 py-6",
|
|
18932
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18933
|
-
className: "shrink-0 text-[40px] font-semibold leading-none text-foreground/25 tabular-nums",
|
|
18934
|
-
children: String(cell.episode).padStart(padLength, "0")
|
|
18935
|
-
}), /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18936
|
-
className: "text-[30px] font-semibold text-foreground/25",
|
|
18937
|
-
children: "缺失"
|
|
18938
|
-
})]
|
|
18939
|
-
}, cell.episode) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18940
|
-
className: "flex items-center gap-6 rounded-3xl border border-foreground/10 bg-foreground/6 px-7 py-6",
|
|
18852
|
+
}), pageCount > 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18853
|
+
className: "flex flex-wrap gap-3 items-center",
|
|
18941
18854
|
children: [
|
|
18855
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "发送" }),
|
|
18856
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip, { children: "上一页" }),
|
|
18942
18857
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18943
|
-
className: "
|
|
18944
|
-
children:
|
|
18858
|
+
className: "text-foreground/30",
|
|
18859
|
+
children: "/"
|
|
18945
18860
|
}),
|
|
18861
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip, { children: "下一页" }),
|
|
18946
18862
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", {
|
|
18947
|
-
className: "
|
|
18948
|
-
|
|
18949
|
-
children: cell.item.title || "无标题"
|
|
18863
|
+
className: "text-foreground/30",
|
|
18864
|
+
children: "/"
|
|
18950
18865
|
}),
|
|
18951
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("
|
|
18952
|
-
|
|
18953
|
-
children: formatDuration$4(cell.item.duration)
|
|
18954
|
-
})
|
|
18866
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CommandChip, { children: "第?页" }),
|
|
18867
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "翻页" })
|
|
18955
18868
|
]
|
|
18956
|
-
}
|
|
18957
|
-
})
|
|
18958
|
-
|
|
18959
|
-
|
|
18960
|
-
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18964
|
-
|
|
18965
|
-
|
|
18966
|
-
|
|
18967
|
-
|
|
18968
|
-
|
|
18969
|
-
|
|
18970
|
-
|
|
18971
|
-
|
|
18972
|
-
|
|
18973
|
-
|
|
18974
|
-
|
|
18975
|
-
|
|
18976
|
-
|
|
18977
|
-
|
|
18869
|
+
})]
|
|
18870
|
+
}),
|
|
18871
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18872
|
+
className: "grid grid-cols-3 gap-8 mt-8",
|
|
18873
|
+
children: visibleEpisodes.map((episode) => {
|
|
18874
|
+
const cover = kind === "collection" ? episode.cover || episode.originCover : episode.originCover || episode.cover;
|
|
18875
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18876
|
+
className: "flex flex-col overflow-hidden bg-surface rounded-3xl shadow-large",
|
|
18877
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18878
|
+
className: `relative overflow-hidden ${kind === "collection" ? "aspect-square" : "aspect-[3/4]"}`,
|
|
18879
|
+
children: [
|
|
18880
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(EnhancedImage, {
|
|
18881
|
+
src: cover || "",
|
|
18882
|
+
alt: `第${episode.episode}集 ${episode.title}`,
|
|
18883
|
+
className: "object-cover w-full h-full select-text"
|
|
18884
|
+
}),
|
|
18885
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18886
|
+
className: "absolute top-4 left-4 px-3 py-1 text-2xl font-bold text-white rounded-xl bg-black/65",
|
|
18887
|
+
children: [
|
|
18888
|
+
"第",
|
|
18889
|
+
episode.episode,
|
|
18890
|
+
"集"
|
|
18891
|
+
]
|
|
18892
|
+
}),
|
|
18893
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18894
|
+
className: "absolute right-4 bottom-4 px-3 py-1 text-xl font-semibold text-white rounded-xl bg-black/65 tabular-nums",
|
|
18895
|
+
children: formatDuration$4(episode.duration)
|
|
18896
|
+
})
|
|
18897
|
+
]
|
|
18898
|
+
}), kind === "collection" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18899
|
+
className: "flex flex-col flex-1 gap-3 p-5",
|
|
18900
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
|
|
18901
|
+
className: "text-3xl font-semibold leading-snug select-text text-foreground line-clamp-2",
|
|
18902
|
+
children: episode.title || `第${episode.episode}集`
|
|
18903
|
+
})
|
|
18904
|
+
})]
|
|
18905
|
+
}, `${episode.episode}-${episode.aweme_id}`);
|
|
18906
|
+
})
|
|
18978
18907
|
}),
|
|
18979
18908
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", {
|
|
18980
|
-
className: "
|
|
18981
|
-
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
18909
|
+
className: "flex flex-wrap items-center justify-between gap-6 mt-8 text-[26px] text-muted",
|
|
18910
|
+
children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { children: [
|
|
18911
|
+
"已列出 ",
|
|
18912
|
+
episodes.length,
|
|
18913
|
+
" / ",
|
|
18914
|
+
total_episode,
|
|
18915
|
+
" ",
|
|
18916
|
+
countUnit,
|
|
18917
|
+
missingEpisodes.length > 0 && `;接口未返回第 ${missingEpisodes.join("、")} ${countUnit},暂不能解析。`,
|
|
18918
|
+
updated_to_episode < total_episode && `;已更新至第 ${updated_to_episode} ${countUnit}。`
|
|
18919
|
+
] }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", {
|
|
18982
18920
|
className: "select-text",
|
|
18983
18921
|
children: ["图片生成于: ", format(/* @__PURE__ */ new Date(), "yyyy-MM-dd HH:mm:ss")]
|
|
18984
18922
|
})]
|
|
@@ -30617,6 +30555,268 @@ var wrapWithErrorHandler = (fn, options) => {
|
|
|
30617
30555
|
}
|
|
30618
30556
|
};
|
|
30619
30557
|
};
|
|
30558
|
+
/** 每个会话最多缓存几张海报,避免长番剧来回翻页把图片全留在内存里 */
|
|
30559
|
+
var MAX_CACHED_POSTERS = 3;
|
|
30560
|
+
/** 会话表上限,防止异常流量无限堆积 */
|
|
30561
|
+
var MAX_SESSIONS = 500;
|
|
30562
|
+
/** 句中的「第N集」,集数可以是阿拉伯数字或中文数字,数字两侧允许空格 */
|
|
30563
|
+
var EPISODE_IN_TEXT = /第\s*([0-9]+|[零一二三四五六七八九十百千]+)\s*集/;
|
|
30564
|
+
/** 整条回复只有集数:「12」「12集」「十二」 */
|
|
30565
|
+
var EPISODE_ONLY = /^([0-9]+|[零一二三四五六七八九十百千]+)\s*集?$/;
|
|
30566
|
+
/**
|
|
30567
|
+
* 支持按钮 + 上下文交互选集的适配器。
|
|
30568
|
+
* 目前只有 QQBot;后续适配器确认支持 callback 按钮和指令按钮(输入框)后再加入。
|
|
30569
|
+
*/
|
|
30570
|
+
var BUTTON_SELECTION_PROTOCOLS = /* @__PURE__ */ new Set(["qqbot"]);
|
|
30571
|
+
var sessions = /* @__PURE__ */ new Map();
|
|
30572
|
+
var parseStatSkipped = /* @__PURE__ */ new WeakSet();
|
|
30573
|
+
var bilibiliAutoSelectEvents = /* @__PURE__ */ new WeakSet();
|
|
30574
|
+
/**
|
|
30575
|
+
* 从用户输入中解析集数。
|
|
30576
|
+
* @param text 用户输入
|
|
30577
|
+
* @returns 集数(从 1 开始);没解析出来返回 null
|
|
30578
|
+
*/
|
|
30579
|
+
var parseEpisodeNumber = (text) => {
|
|
30580
|
+
const normalized = text.trim();
|
|
30581
|
+
const raw = (EPISODE_IN_TEXT.exec(normalized) ?? EPISODE_ONLY.exec(normalized))?.[1];
|
|
30582
|
+
if (!raw) return null;
|
|
30583
|
+
const episode = /^[0-9]+$/.test(raw) ? Number(raw) : Common.chineseToArabic(raw);
|
|
30584
|
+
return Number.isInteger(episode) && episode > 0 ? episode : null;
|
|
30585
|
+
};
|
|
30586
|
+
/** 解析 `#选集` 命令的第二个参数,支持页码和集数。 */
|
|
30587
|
+
var parseEpisodeSelectionAction = (action) => {
|
|
30588
|
+
const pageMatch = /^page:\s*(\d+)$/.exec(action.trim());
|
|
30589
|
+
if (pageMatch) {
|
|
30590
|
+
const page = Number(pageMatch[1]);
|
|
30591
|
+
return Number.isInteger(page) && page > 0 ? {
|
|
30592
|
+
type: "page",
|
|
30593
|
+
page
|
|
30594
|
+
} : null;
|
|
30595
|
+
}
|
|
30596
|
+
const episode = parseEpisodeNumber(action);
|
|
30597
|
+
return episode === null ? null : {
|
|
30598
|
+
type: "episode",
|
|
30599
|
+
episode
|
|
30600
|
+
};
|
|
30601
|
+
};
|
|
30602
|
+
/**
|
|
30603
|
+
* 解析文字选集的翻页命令。
|
|
30604
|
+
* 支持「上一页」「下一页」「第12页」「十二页」「12页」「page:12」;
|
|
30605
|
+
* 单独的「12」仍然表示集数,避免和选集输入冲突。
|
|
30606
|
+
*/
|
|
30607
|
+
var parseEpisodePosterPageAction = (text) => {
|
|
30608
|
+
const normalized = text.trim();
|
|
30609
|
+
if (/^(?:上一页|上页|上一頁)$/.test(normalized)) return { type: "prev" };
|
|
30610
|
+
if (/^(?:下一页|下页|下一頁)$/.test(normalized)) return { type: "next" };
|
|
30611
|
+
const rawPage = /^page:(\d+)$/.exec(normalized)?.[1] ?? /^(?:第\s*)?([0-9]+|[零一二三四五六七八九十百千]+)\s*页$/.exec(normalized)?.[1];
|
|
30612
|
+
if (!rawPage) return null;
|
|
30613
|
+
const page = /^[0-9]+$/.test(rawPage) ? Number(rawPage) : Common.chineseToArabic(rawPage);
|
|
30614
|
+
return Number.isInteger(page) && page > 0 ? {
|
|
30615
|
+
type: "page",
|
|
30616
|
+
page
|
|
30617
|
+
} : null;
|
|
30618
|
+
};
|
|
30619
|
+
/** 生成会话作用域;群聊内所有人共用,私聊只绑定当前用户。 */
|
|
30620
|
+
var getEpisodeSelectionScope = (event) => {
|
|
30621
|
+
const subPeer = event.contact.subPeer || "";
|
|
30622
|
+
return `${event.selfId}:${event.contact.peer}:${subPeer}`;
|
|
30623
|
+
};
|
|
30624
|
+
/** 当前适配器是否支持按钮 + 上下文交互选集(目前为 QQBot 群聊/单聊)。 */
|
|
30625
|
+
var isButtonSelectionScene = (event) => {
|
|
30626
|
+
return BUTTON_SELECTION_PROTOCOLS.has(event.bot.adapter.protocol) && (event.isGroup || event.isFriend);
|
|
30627
|
+
};
|
|
30628
|
+
/** 标记本次解析只负责发选集,不计入解析统计。 */
|
|
30629
|
+
var markParseStatSkipped = (event) => {
|
|
30630
|
+
parseStatSkipped.add(event);
|
|
30631
|
+
};
|
|
30632
|
+
/** 消费一次性统计跳过标记。 */
|
|
30633
|
+
var consumeParseStatSkip = (event) => {
|
|
30634
|
+
return parseStatSkipped.delete(event);
|
|
30635
|
+
};
|
|
30636
|
+
/** 标记本次 B 站 ep 解析来自选集按钮,需要直接选中对应集。 */
|
|
30637
|
+
var markBilibiliEpisodeAutoSelect = (event) => {
|
|
30638
|
+
bilibiliAutoSelectEvents.add(event);
|
|
30639
|
+
};
|
|
30640
|
+
/** 消费一次 B 站自动选集标记,用户分享的 ep 链接不会命中。 */
|
|
30641
|
+
var consumeBilibiliEpisodeAutoSelect = (event) => {
|
|
30642
|
+
return bilibiliAutoSelectEvents.delete(event);
|
|
30643
|
+
};
|
|
30644
|
+
var cleanupExpiredSessions = () => {
|
|
30645
|
+
const now = Date.now();
|
|
30646
|
+
for (const [token, session] of sessions) if (session.expiresAt <= now) sessions.delete(token);
|
|
30647
|
+
};
|
|
30648
|
+
var createToken = () => {
|
|
30649
|
+
for (;;) {
|
|
30650
|
+
const token = randomBytes(6).toString("base64url");
|
|
30651
|
+
if (!sessions.has(token)) return token;
|
|
30652
|
+
}
|
|
30653
|
+
};
|
|
30654
|
+
/**
|
|
30655
|
+
* 创建一次选集会话。
|
|
30656
|
+
* @param scope 由 {@link getEpisodeSelectionScope} 生成
|
|
30657
|
+
* @param options 海报、剧集和平台信息
|
|
30658
|
+
* @returns 可放进按钮 data 的短 token 会话
|
|
30659
|
+
*/
|
|
30660
|
+
var createEpisodeSelection = (scope, options) => {
|
|
30661
|
+
cleanupExpiredSessions();
|
|
30662
|
+
if (sessions.size >= MAX_SESSIONS) {
|
|
30663
|
+
const oldest = sessions.keys().next().value;
|
|
30664
|
+
if (oldest) sessions.delete(oldest);
|
|
30665
|
+
}
|
|
30666
|
+
const session = {
|
|
30667
|
+
token: createToken(),
|
|
30668
|
+
scope,
|
|
30669
|
+
title: options.title,
|
|
30670
|
+
platform: options.platform,
|
|
30671
|
+
scene: options.scene,
|
|
30672
|
+
pageSize: Math.max(1, options.pageSize ?? 15),
|
|
30673
|
+
poster: options.poster,
|
|
30674
|
+
posterPages: /* @__PURE__ */ new Map([[options.posterPage ?? 1, options.poster]]),
|
|
30675
|
+
renderPoster: options.renderPoster,
|
|
30676
|
+
episodes: options.episodes,
|
|
30677
|
+
forceBurnDanmaku: options.forceBurnDanmaku ?? false,
|
|
30678
|
+
expiresAt: Date.now() + 12e4,
|
|
30679
|
+
currentMessageId: "",
|
|
30680
|
+
currentMessageSentAt: 0
|
|
30681
|
+
};
|
|
30682
|
+
sessions.set(session.token, session);
|
|
30683
|
+
return session;
|
|
30684
|
+
};
|
|
30685
|
+
/** 任务结束后立即关闭会话,旧按钮再次点击时只提示不再解析。 */
|
|
30686
|
+
var endEpisodeSelection = (token, scope) => {
|
|
30687
|
+
const session = sessions.get(token);
|
|
30688
|
+
if (!session || session.scope !== scope) return false;
|
|
30689
|
+
return sessions.delete(token);
|
|
30690
|
+
};
|
|
30691
|
+
/** 读取有效会话;token 不存在、scope 不匹配或已过期时返回 null。 */
|
|
30692
|
+
var getEpisodeSelection = (token, scope) => {
|
|
30693
|
+
const session = sessions.get(token);
|
|
30694
|
+
if (!session) return null;
|
|
30695
|
+
if (session.scope !== scope) return null;
|
|
30696
|
+
if (session.expiresAt <= Date.now()) {
|
|
30697
|
+
sessions.delete(token);
|
|
30698
|
+
return null;
|
|
30699
|
+
}
|
|
30700
|
+
return session;
|
|
30701
|
+
};
|
|
30702
|
+
/** 翻页成功后重新计算 120 秒有效期。 */
|
|
30703
|
+
var touchEpisodeSelection = (token, scope) => {
|
|
30704
|
+
const session = getEpisodeSelection(token, scope);
|
|
30705
|
+
if (!session) return false;
|
|
30706
|
+
session.expiresAt = Date.now() + 12e4;
|
|
30707
|
+
return true;
|
|
30708
|
+
};
|
|
30709
|
+
/** 记录当前选集消息,供下一次翻页撤回。 */
|
|
30710
|
+
var setEpisodeSelectionMessage = (session, messageId, sentAt = Date.now()) => {
|
|
30711
|
+
session.currentMessageId = messageId;
|
|
30712
|
+
session.currentMessageSentAt = messageId ? sentAt : 0;
|
|
30713
|
+
};
|
|
30714
|
+
/** 只有距离发送不超过 110 秒时才尝试撤回,避免顶格撞平台 120 秒窗口。 */
|
|
30715
|
+
var canRecallEpisodeMessage = (messageId, sentAt, now = Date.now()) => {
|
|
30716
|
+
if (!messageId || !sentAt) return false;
|
|
30717
|
+
const age = now - sentAt;
|
|
30718
|
+
return age >= 0 && age <= 11e4;
|
|
30719
|
+
};
|
|
30720
|
+
/** 会话里记录的当前消息是否还能撤回。 */
|
|
30721
|
+
var canRecallEpisodeSelectionMessage = (session, now = Date.now()) => {
|
|
30722
|
+
return canRecallEpisodeMessage(session.currentMessageId, session.currentMessageSentAt, now);
|
|
30723
|
+
};
|
|
30724
|
+
/** 总页数;海报和按钮共用。空选集返回 0。 */
|
|
30725
|
+
var getEpisodePageCount = (session) => {
|
|
30726
|
+
return Math.ceil(session.episodes.length / session.pageSize);
|
|
30727
|
+
};
|
|
30728
|
+
/** 取指定页;页码越界返回 null。 */
|
|
30729
|
+
var getEpisodePage = (session, page) => {
|
|
30730
|
+
if (!Number.isInteger(page) || page < 1) return null;
|
|
30731
|
+
const pageCount = getEpisodePageCount(session);
|
|
30732
|
+
if (page > pageCount) return null;
|
|
30733
|
+
const start = (page - 1) * session.pageSize;
|
|
30734
|
+
const items = session.episodes.slice(start, start + session.pageSize);
|
|
30735
|
+
if (!items.length) return null;
|
|
30736
|
+
return {
|
|
30737
|
+
page,
|
|
30738
|
+
pageCount,
|
|
30739
|
+
items,
|
|
30740
|
+
firstEpisode: items[0].episode,
|
|
30741
|
+
lastEpisode: items[items.length - 1].episode
|
|
30742
|
+
};
|
|
30743
|
+
};
|
|
30744
|
+
/** 取海报页(按需渲染并缓存);没有分页渲染器时始终返回初始海报。 */
|
|
30745
|
+
var getEpisodeSelectionPoster = async (session, posterPage) => {
|
|
30746
|
+
const cached = session.posterPages.get(posterPage);
|
|
30747
|
+
if (cached) return cached;
|
|
30748
|
+
if (!session.renderPoster) return session.poster;
|
|
30749
|
+
const poster = await session.renderPoster(posterPage);
|
|
30750
|
+
session.posterPages.set(posterPage, poster);
|
|
30751
|
+
while (session.posterPages.size > MAX_CACHED_POSTERS) {
|
|
30752
|
+
const oldest = session.posterPages.keys().next().value;
|
|
30753
|
+
if (oldest === void 0) break;
|
|
30754
|
+
session.posterPages.delete(oldest);
|
|
30755
|
+
}
|
|
30756
|
+
return poster;
|
|
30757
|
+
};
|
|
30758
|
+
/**
|
|
30759
|
+
* 生成 QQBot keyboard 行。
|
|
30760
|
+
* 跳转输入行在最上面,集数按钮每行 5 个,翻页按钮单独一行;
|
|
30761
|
+
* 15 集一页时正好 1 + 3 + 1 = 5 行,不会超过 QQBot 的上限。
|
|
30762
|
+
*/
|
|
30763
|
+
var buildEpisodeKeyboardRows = (session, page) => {
|
|
30764
|
+
const data = getEpisodePage(session, page);
|
|
30765
|
+
if (!data) return [];
|
|
30766
|
+
const rows = [];
|
|
30767
|
+
if (data.pageCount > 1) rows.push([{
|
|
30768
|
+
text: "跳转到第x页",
|
|
30769
|
+
data: `#选集 ${session.token} page:`,
|
|
30770
|
+
enter: false,
|
|
30771
|
+
style: 1
|
|
30772
|
+
}]);
|
|
30773
|
+
for (let index = 0; index < data.items.length; index += 5) rows.push(data.items.slice(index, index + 5).map((item) => ({
|
|
30774
|
+
text: String(item.episode),
|
|
30775
|
+
show: String(item.episode),
|
|
30776
|
+
callback: true,
|
|
30777
|
+
data: `#选集 ${session.token} ${item.episode}`,
|
|
30778
|
+
style: 1
|
|
30779
|
+
})));
|
|
30780
|
+
const navigation = [];
|
|
30781
|
+
if (data.page > 1) navigation.push({
|
|
30782
|
+
text: "上一页",
|
|
30783
|
+
callback: true,
|
|
30784
|
+
data: `#选集 ${session.token} page:${data.page - 1}`
|
|
30785
|
+
});
|
|
30786
|
+
if (data.page < data.pageCount) navigation.push({
|
|
30787
|
+
text: "下一页",
|
|
30788
|
+
callback: true,
|
|
30789
|
+
data: `#选集 ${session.token} page:${data.page + 1}`
|
|
30790
|
+
});
|
|
30791
|
+
if (navigation.length) rows.push(navigation);
|
|
30792
|
+
return rows;
|
|
30793
|
+
};
|
|
30794
|
+
/** 生成选集提示文本。 */
|
|
30795
|
+
var buildEpisodeSelectionText = (session, page) => {
|
|
30796
|
+
const data = getEpisodePage(session, page);
|
|
30797
|
+
if (!data) return "";
|
|
30798
|
+
const range = data.firstEpisode === data.lastEpisode ? `第 ${data.firstEpisode} 集` : `第 ${data.firstEpisode}–${data.lastEpisode} 集`;
|
|
30799
|
+
return `《${session.title}》\n${range} · 第 ${data.page}/${data.pageCount} 页\n点击下方按钮选集(120 秒内有效)。`;
|
|
30800
|
+
};
|
|
30801
|
+
/** 按实际集号查找目标。 */
|
|
30802
|
+
var resolveEpisodeTarget = (session, episode) => {
|
|
30803
|
+
return session.episodes.find((item) => item.episode === episode)?.target ?? null;
|
|
30804
|
+
};
|
|
30805
|
+
/** 生成现有解析命令能识别的目标链接。 */
|
|
30806
|
+
var buildEpisodeTargetUrl = (target) => {
|
|
30807
|
+
return target.platform === "douyin" ? `https://www.douyin.com/video/${target.awemeId}` : `https://www.bilibili.com/bangumi/play/ep${target.epId}`;
|
|
30808
|
+
};
|
|
30809
|
+
/**
|
|
30810
|
+
* 组装 QQBot 选集消息:复用已渲染海报,并附当前页文本和 keyboard。
|
|
30811
|
+
* 海报按需传入(翻页跨 15 集区块时由调用方重新渲染),默认复用初始海报。
|
|
30812
|
+
*/
|
|
30813
|
+
var buildEpisodeSelectionReply = (session, page, poster = session.poster) => {
|
|
30814
|
+
const text = buildEpisodeSelectionText(session, page);
|
|
30815
|
+
const rows = buildEpisodeKeyboardRows(session, page);
|
|
30816
|
+
const elements = [...poster, segment.text(text)];
|
|
30817
|
+
if (rows.length) elements.push(segment.keyboard(rows));
|
|
30818
|
+
return elements;
|
|
30819
|
+
};
|
|
30620
30820
|
//#endregion
|
|
30621
30821
|
//#region src/platform/bilibili/danmaku.ts
|
|
30622
30822
|
/**
|
|
@@ -31901,8 +32101,13 @@ var Bilibili = class extends Base {
|
|
|
31901
32101
|
const videoInfo = await this.amagi.bilibili.fetcher.fetchBangumiInfo({ [iddata.isEpid ? "ep_id" : "season_id"]: iddata.realid });
|
|
31902
32102
|
this.islogin = (await checkCk()).Status === "isLogin";
|
|
31903
32103
|
this.isVIP = (await checkCk()).isVIP;
|
|
31904
|
-
const
|
|
31905
|
-
|
|
32104
|
+
const sourceEpisodes = videoInfo.data.result.episodes ?? [];
|
|
32105
|
+
if (!sourceEpisodes.length) {
|
|
32106
|
+
await this.e.reply("未获取到可解析的剧集,请稍后重试");
|
|
32107
|
+
return true;
|
|
32108
|
+
}
|
|
32109
|
+
const displayEpisodes = sourceEpisodes.map((item, index) => ({
|
|
32110
|
+
episode: index + 1,
|
|
31906
32111
|
cover: item.cover,
|
|
31907
32112
|
bvid: item.bvid,
|
|
31908
32113
|
link: item.short_link,
|
|
@@ -31910,8 +32115,23 @@ var Bilibili = class extends Base {
|
|
|
31910
32115
|
pub_time: item.pub_time,
|
|
31911
32116
|
badge: item.badge === "" ? "限免" : item.badge,
|
|
31912
32117
|
badge_info: item.badge_info
|
|
31913
|
-
});
|
|
31914
|
-
|
|
32118
|
+
})).reverse();
|
|
32119
|
+
const episodeTargets = sourceEpisodes.map((item, index) => ({
|
|
32120
|
+
episode: index + 1,
|
|
32121
|
+
target: {
|
|
32122
|
+
platform: "bilibili",
|
|
32123
|
+
epId: String(item.ep_id)
|
|
32124
|
+
}
|
|
32125
|
+
})).reverse();
|
|
32126
|
+
const autoSelectEpisode = consumeBilibiliEpisodeAutoSelect(this.e);
|
|
32127
|
+
const linkedEpId = iddata.isEpid ? String(iddata.realid).replace(/^ep/i, "") : "";
|
|
32128
|
+
const linkedSourceIndex = linkedEpId ? sourceEpisodes.findIndex((item) => String(item.ep_id) === linkedEpId) : -1;
|
|
32129
|
+
const linkedDisplayIndex = linkedSourceIndex >= 0 ? sourceEpisodes.length - 1 - linkedSourceIndex : -1;
|
|
32130
|
+
let selectedIndex = autoSelectEpisode ? linkedSourceIndex : -1;
|
|
32131
|
+
const buttonSelection = isButtonSelectionScene(this.e);
|
|
32132
|
+
const selectionMode = buttonSelection ? "button" : "text";
|
|
32133
|
+
/** 按海报页码渲染:15 集一页,长番剧不会撑爆单张 PNG */
|
|
32134
|
+
const renderPoster = (posterPage) => Render(this.e, "bilibili/bangumi", {
|
|
31915
32135
|
mainCover: videoInfo.data.result.cover,
|
|
31916
32136
|
Actors: videoInfo.data.result.actors,
|
|
31917
32137
|
Evaluate: videoInfo.data.result.evaluate,
|
|
@@ -31924,38 +32144,104 @@ var Bilibili = class extends Base {
|
|
|
31924
32144
|
UPInfo: videoInfo.data.result.up_info,
|
|
31925
32145
|
Copyright: videoInfo.data.result.rights.copyright,
|
|
31926
32146
|
Stat: videoInfo.data.result.stat,
|
|
31927
|
-
Episodes,
|
|
31928
|
-
length:
|
|
32147
|
+
Episodes: displayEpisodes,
|
|
32148
|
+
length: sourceEpisodes.length,
|
|
32149
|
+
selectionMode,
|
|
32150
|
+
posterPage,
|
|
32151
|
+
posterPageSize: 15
|
|
31929
32152
|
});
|
|
31930
|
-
|
|
31931
|
-
|
|
31932
|
-
|
|
31933
|
-
|
|
31934
|
-
|
|
31935
|
-
if (
|
|
31936
|
-
|
|
31937
|
-
|
|
31938
|
-
|
|
31939
|
-
|
|
31940
|
-
|
|
31941
|
-
|
|
31942
|
-
|
|
32153
|
+
if (autoSelectEpisode) {
|
|
32154
|
+
if (linkedSourceIndex < 0) {
|
|
32155
|
+
await this.e.reply("未找到该集,请重新发送番剧链接");
|
|
32156
|
+
return true;
|
|
32157
|
+
}
|
|
32158
|
+
} else if (buttonSelection) {
|
|
32159
|
+
const initialPage = linkedDisplayIndex >= 0 ? Math.floor(linkedDisplayIndex / 15) + 1 : 1;
|
|
32160
|
+
const poster = await renderPoster(initialPage);
|
|
32161
|
+
const session = createEpisodeSelection(getEpisodeSelectionScope(this.e), {
|
|
32162
|
+
title: videoInfo.data.result.title,
|
|
32163
|
+
platform: "bilibili",
|
|
32164
|
+
scene: this.e.isFriend ? "friend" : "group",
|
|
32165
|
+
poster,
|
|
32166
|
+
posterPage: initialPage,
|
|
32167
|
+
renderPoster,
|
|
32168
|
+
episodes: episodeTargets,
|
|
32169
|
+
forceBurnDanmaku: this.forceBurnDanmaku
|
|
32170
|
+
});
|
|
32171
|
+
markParseStatSkipped(this.e);
|
|
32172
|
+
const sentAt = Date.now();
|
|
32173
|
+
setEpisodeSelectionMessage(session, (await this.e.reply(buildEpisodeSelectionReply(session, initialPage, poster))).messageId, sentAt);
|
|
32174
|
+
return true;
|
|
31943
32175
|
} else {
|
|
31944
|
-
|
|
31945
|
-
|
|
32176
|
+
const posterPageCount = Math.ceil(displayEpisodes.length / 15);
|
|
32177
|
+
let posterPage = linkedDisplayIndex >= 0 ? Math.floor(linkedDisplayIndex / 15) + 1 : 1;
|
|
32178
|
+
/** 上一页海报消息,翻页发送成功后撤回,避免聊天里堆一串过期海报 */
|
|
32179
|
+
let posterMessageId = "";
|
|
32180
|
+
let posterMessageSentAt = 0;
|
|
32181
|
+
for (;;) {
|
|
32182
|
+
const poster = await renderPoster(posterPage);
|
|
32183
|
+
const start = (posterPage - 1) * 15;
|
|
32184
|
+
const pageEpisodes = displayEpisodes.slice(start, start + 15);
|
|
32185
|
+
const firstEpisode = pageEpisodes[0]?.episode ?? 0;
|
|
32186
|
+
const lastEpisode = pageEpisodes[pageEpisodes.length - 1]?.episode ?? 0;
|
|
32187
|
+
const range = firstEpisode === lastEpisode ? `第 ${firstEpisode} 集` : `第 ${firstEpisode}–${lastEpisode} 集`;
|
|
32188
|
+
const sentAt = Date.now();
|
|
32189
|
+
const result = await this.e.reply([...poster, segment.text(`《${videoInfo.data.result.title}》\n${range}(共 ${displayEpisodes.length} 集)\n第 ${posterPage}/${posterPageCount} 页\n发送 第?集 选集${posterPageCount > 1 ? ",发送 上一页 / 下一页 / 第?页 翻页" : ""}(120 秒内有效)`)]);
|
|
32190
|
+
const previousMessageId = posterMessageId;
|
|
32191
|
+
const previousMessageSentAt = posterMessageSentAt;
|
|
32192
|
+
posterMessageId = result.messageId;
|
|
32193
|
+
posterMessageSentAt = result.messageId ? sentAt : 0;
|
|
32194
|
+
if (previousMessageId && canRecallEpisodeMessage(previousMessageId, previousMessageSentAt)) try {
|
|
32195
|
+
await this.e.bot.recallMsg(this.e.contact, previousMessageId);
|
|
32196
|
+
} catch (error) {
|
|
32197
|
+
logger$1.debug("[选集] 撤回上一页失败:", error);
|
|
32198
|
+
}
|
|
32199
|
+
const context = await karin.ctx(this.e, {
|
|
32200
|
+
reply: true,
|
|
32201
|
+
throwOnTimeout: false,
|
|
32202
|
+
time: 120
|
|
32203
|
+
});
|
|
32204
|
+
if (!context) return true;
|
|
32205
|
+
const replyText = context.msg.trim();
|
|
32206
|
+
if (/^[#/]/.test(replyText) || /(https?:\/\/|b23\.tv|bilibili\.com|douyin\.com|iesdouyin\.com)/i.test(replyText)) return true;
|
|
32207
|
+
const pageAction = parseEpisodePosterPageAction(context.msg);
|
|
32208
|
+
if (pageAction) {
|
|
32209
|
+
const nextPage = pageAction.type === "prev" ? posterPage - 1 : pageAction.type === "next" ? posterPage + 1 : pageAction.page;
|
|
32210
|
+
if (nextPage < 1 || nextPage > posterPageCount) {
|
|
32211
|
+
await this.e.reply(`页码超出范围,请发送 1-${posterPageCount} 之间的页码`);
|
|
32212
|
+
continue;
|
|
32213
|
+
}
|
|
32214
|
+
posterPage = nextPage;
|
|
32215
|
+
continue;
|
|
32216
|
+
}
|
|
32217
|
+
const parsedEpisode = parseEpisodeNumber(context.msg);
|
|
32218
|
+
if (parsedEpisode === null || parsedEpisode > sourceEpisodes.length) {
|
|
32219
|
+
await this.e.reply(parsedEpisode === null ? "匹配内容失败,请发送 第?集 选择集数,或发送 上一页 / 下一页 / 第?页 翻页" : `第${parsedEpisode}集不在可解析的剧集里,请重新选择`);
|
|
32220
|
+
continue;
|
|
32221
|
+
}
|
|
32222
|
+
selectedIndex = parsedEpisode - 1;
|
|
32223
|
+
break;
|
|
32224
|
+
}
|
|
32225
|
+
}
|
|
32226
|
+
const episodeInfo = sourceEpisodes[selectedIndex];
|
|
32227
|
+
if (!episodeInfo) {
|
|
32228
|
+
await this.e.reply("未找到该集,请重新发送番剧链接");
|
|
31946
32229
|
return true;
|
|
31947
32230
|
}
|
|
32231
|
+
const displayEpisode = selectedIndex + 1;
|
|
32232
|
+
this.downloadfilename = episodeInfo.share_copy.substring(0, 50).replace(/[\\/:*?"<>|\r\n\s]/g, " ");
|
|
32233
|
+
await this.e.reply(`收到请求,第${displayEpisode}集\n${this.downloadfilename}\n正在下载中`);
|
|
31948
32234
|
const bangumidataBASEURL = bilibiliApiUrls.getBangumiStream({
|
|
31949
|
-
cid:
|
|
31950
|
-
ep_id:
|
|
32235
|
+
cid: episodeInfo.cid,
|
|
32236
|
+
ep_id: episodeInfo.ep_id.toString()
|
|
31951
32237
|
});
|
|
31952
32238
|
const Params = await genParams(bangumidataBASEURL);
|
|
31953
|
-
if (!this.islogin) this.e.reply("B站ck未配置或已失效,无法获取视频流,可尝试【#B站登录】以配置新ck");
|
|
32239
|
+
if (!this.islogin) await this.e.reply("B站ck未配置或已失效,无法获取视频流,可尝试【#B站登录】以配置新ck");
|
|
31954
32240
|
const playUrlData = await new Network({
|
|
31955
32241
|
url: bangumidataBASEURL + Params,
|
|
31956
32242
|
headers: this.headers
|
|
31957
32243
|
}).getData();
|
|
31958
|
-
if (
|
|
32244
|
+
if (episodeInfo.badge === "会员" && !this.isVIP) {
|
|
31959
32245
|
logger$1.warn("该CK不是大会员,无法获取视频流");
|
|
31960
32246
|
return true;
|
|
31961
32247
|
}
|
|
@@ -35942,24 +36228,6 @@ async function burnDouyinDanmaku(videoPath, danmakuList, outputPath, options = {
|
|
|
35942
36228
|
return result.status;
|
|
35943
36229
|
}
|
|
35944
36230
|
//#endregion
|
|
35945
|
-
//#region src/platform/douyin/mix.ts
|
|
35946
|
-
/** 句中的「第N集」,集数可以是阿拉伯数字或中文数字,数字两侧允许空格(模板里写的就是「第 N 集」) */
|
|
35947
|
-
var EPISODE_IN_TEXT = /第\s*([0-9]+|[零一二三四五六七八九十百千]+)\s*集/;
|
|
35948
|
-
/** 整条回复只有集数:「12」「12集」「十二」 */
|
|
35949
|
-
var EPISODE_ONLY = /^([0-9]+|[零一二三四五六七八九十百千]+)\s*集?$/;
|
|
35950
|
-
/**
|
|
35951
|
-
* 从用户回复里解析要看的集数。
|
|
35952
|
-
* @param msg 用户回复的文本
|
|
35953
|
-
* @returns 集数(从 1 开始);没解析出来返回 null
|
|
35954
|
-
*/
|
|
35955
|
-
var parseMixEpisode = (msg) => {
|
|
35956
|
-
const text = msg.trim();
|
|
35957
|
-
const raw = (EPISODE_IN_TEXT.exec(text) ?? EPISODE_ONLY.exec(text))?.[1];
|
|
35958
|
-
if (!raw) return null;
|
|
35959
|
-
const episode = /^[0-9]+$/.test(raw) ? Number(raw) : Common.chineseToArabic(raw);
|
|
35960
|
-
return Number.isInteger(episode) && episode > 0 ? episode : null;
|
|
35961
|
-
};
|
|
35962
|
-
//#endregion
|
|
35963
36231
|
//#region src/platform/douyin/videoQuality.ts
|
|
35964
36232
|
/** 档位优先级,从高到低 */
|
|
35965
36233
|
var QUALITY_PRIORITY = [
|
|
@@ -37463,18 +37731,24 @@ var DouYin = class DouYin extends Base {
|
|
|
37463
37731
|
const mixInfo = first.mix_info;
|
|
37464
37732
|
const author = first.author;
|
|
37465
37733
|
const isPlaylet = typeof mixInfo.statis.total_episode === "number";
|
|
37466
|
-
const
|
|
37734
|
+
const totalEpisode = isPlaylet ? mixInfo.statis.total_episode : mixInfo.statis.updated_to_episode;
|
|
37735
|
+
const displayEpisodes = [...awemeList.map((aweme) => ({
|
|
37467
37736
|
episode: aweme.mix_info.statis.current_episode,
|
|
37468
37737
|
aweme_id: aweme.aweme_id,
|
|
37469
37738
|
title: aweme.desc.replace(/#\S+/g, "").trim(),
|
|
37470
|
-
duration: aweme.video.duration
|
|
37471
|
-
|
|
37472
|
-
|
|
37739
|
+
duration: aweme.video.duration,
|
|
37740
|
+
cover: aweme.video.cover?.url_list?.[0] ?? "",
|
|
37741
|
+
originCover: aweme.video.origin_cover?.url_list?.[0] ?? ""
|
|
37742
|
+
}))].sort((a, b) => b.episode - a.episode);
|
|
37743
|
+
const buttonSelection = isButtonSelectionScene(this.e);
|
|
37744
|
+
const selectionMode = buttonSelection ? "button" : "text";
|
|
37745
|
+
/** 按海报页码渲染:15 集一页,长合集不会撑爆单张 PNG */
|
|
37746
|
+
const renderPoster = (posterPage) => Render(this.e, "douyin/mix", {
|
|
37473
37747
|
kind: isPlaylet ? "playlet" : "collection",
|
|
37474
37748
|
mix_name: mixInfo.mix_name,
|
|
37475
37749
|
image_url: mixInfo.cover_url.url_list[0],
|
|
37476
|
-
desc: isPlaylet ?
|
|
37477
|
-
total_episode:
|
|
37750
|
+
desc: isPlaylet ? displayEpisodes[0]?.title ?? "" : "",
|
|
37751
|
+
total_episode: totalEpisode,
|
|
37478
37752
|
updated_to_episode: mixInfo.statis.updated_to_episode,
|
|
37479
37753
|
author: {
|
|
37480
37754
|
nickname: author.nickname,
|
|
@@ -37488,29 +37762,91 @@ var DouYin = class DouYin extends Base {
|
|
|
37488
37762
|
digg_count: awemeList.reduce((sum, aweme) => sum + aweme.statistics.digg_count, 0),
|
|
37489
37763
|
collect_count: awemeList.reduce((sum, aweme) => sum + aweme.statistics.collect_count, 0)
|
|
37490
37764
|
},
|
|
37491
|
-
episodes,
|
|
37492
|
-
timeoutSeconds
|
|
37493
|
-
|
|
37494
|
-
|
|
37495
|
-
|
|
37496
|
-
reply: true,
|
|
37497
|
-
throwOnTimeout: false,
|
|
37498
|
-
time: timeoutSeconds
|
|
37765
|
+
episodes: displayEpisodes,
|
|
37766
|
+
timeoutSeconds,
|
|
37767
|
+
selectionMode,
|
|
37768
|
+
posterPage,
|
|
37769
|
+
posterPageSize: 15
|
|
37499
37770
|
});
|
|
37500
|
-
if (
|
|
37501
|
-
|
|
37502
|
-
|
|
37503
|
-
|
|
37504
|
-
|
|
37771
|
+
if (buttonSelection) {
|
|
37772
|
+
const initialPage = 1;
|
|
37773
|
+
const poster = await renderPoster(initialPage);
|
|
37774
|
+
const session = createEpisodeSelection(getEpisodeSelectionScope(this.e), {
|
|
37775
|
+
title: mixInfo.mix_name,
|
|
37776
|
+
platform: "douyin",
|
|
37777
|
+
scene: this.e.isFriend ? "friend" : "group",
|
|
37778
|
+
poster,
|
|
37779
|
+
posterPage: initialPage,
|
|
37780
|
+
renderPoster,
|
|
37781
|
+
episodes: displayEpisodes.map((item) => ({
|
|
37782
|
+
episode: item.episode,
|
|
37783
|
+
target: {
|
|
37784
|
+
platform: "douyin",
|
|
37785
|
+
awemeId: String(item.aweme_id)
|
|
37786
|
+
}
|
|
37787
|
+
})),
|
|
37788
|
+
forceBurnDanmaku: this.forceBurnDanmaku
|
|
37789
|
+
});
|
|
37790
|
+
markParseStatSkipped(this.e);
|
|
37791
|
+
const sentAt = Date.now();
|
|
37792
|
+
setEpisodeSelectionMessage(session, (await this.e.reply(buildEpisodeSelectionReply(session, initialPage, poster))).messageId, sentAt);
|
|
37793
|
+
return true;
|
|
37794
|
+
}
|
|
37795
|
+
const posterPageCount = Math.ceil(displayEpisodes.length / 15);
|
|
37796
|
+
let posterPage = 1;
|
|
37797
|
+
/** 上一页海报消息,翻页发送成功后撤回,避免聊天里堆一串过期海报 */
|
|
37798
|
+
let posterMessageId = "";
|
|
37799
|
+
let posterMessageSentAt = 0;
|
|
37800
|
+
for (;;) {
|
|
37801
|
+
const poster = await renderPoster(posterPage);
|
|
37802
|
+
const start = (posterPage - 1) * 15;
|
|
37803
|
+
const pageEpisodes = displayEpisodes.slice(start, start + 15);
|
|
37804
|
+
const firstEpisode = pageEpisodes[0]?.episode ?? 0;
|
|
37805
|
+
const lastEpisode = pageEpisodes[pageEpisodes.length - 1]?.episode ?? 0;
|
|
37806
|
+
const range = firstEpisode === lastEpisode ? `第 ${firstEpisode} 集` : `第 ${firstEpisode}–${lastEpisode} 集`;
|
|
37807
|
+
const sentAt = Date.now();
|
|
37808
|
+
const result = await this.e.reply([...poster, segment.text(`《${mixInfo.mix_name}》\n${range}(共 ${totalEpisode} 集,已列出 ${displayEpisodes.length} 集)\n第 ${posterPage}/${posterPageCount} 页\n发送 第?集 选集${posterPageCount > 1 ? ",发送 上一页 / 下一页 / 第?页 翻页" : ""}(${timeoutSeconds} 秒内有效)`)]);
|
|
37809
|
+
const previousMessageId = posterMessageId;
|
|
37810
|
+
const previousMessageSentAt = posterMessageSentAt;
|
|
37811
|
+
posterMessageId = result.messageId;
|
|
37812
|
+
posterMessageSentAt = result.messageId ? sentAt : 0;
|
|
37813
|
+
if (previousMessageId && canRecallEpisodeMessage(previousMessageId, previousMessageSentAt)) try {
|
|
37814
|
+
await this.e.bot.recallMsg(this.e.contact, previousMessageId);
|
|
37815
|
+
} catch (error) {
|
|
37816
|
+
logger.debug("[选集] 撤回上一页失败:", error);
|
|
37817
|
+
}
|
|
37818
|
+
const context = await karin.ctx(this.e, {
|
|
37819
|
+
reply: true,
|
|
37820
|
+
throwOnTimeout: false,
|
|
37821
|
+
time: timeoutSeconds
|
|
37822
|
+
});
|
|
37823
|
+
if (!context) return true;
|
|
37824
|
+
const replyText = context.msg.trim();
|
|
37825
|
+
if (/^[#/]/.test(replyText) || /(https?:\/\/|b23\.tv|bilibili\.com|douyin\.com|iesdouyin\.com)/i.test(replyText)) return true;
|
|
37826
|
+
const pageAction = parseEpisodePosterPageAction(context.msg);
|
|
37827
|
+
if (pageAction) {
|
|
37828
|
+
const nextPage = pageAction.type === "prev" ? posterPage - 1 : pageAction.type === "next" ? posterPage + 1 : pageAction.page;
|
|
37829
|
+
if (nextPage < 1 || nextPage > posterPageCount) {
|
|
37830
|
+
await this.e.reply(`页码超出范围,请发送 1-${posterPageCount} 之间的页码`);
|
|
37831
|
+
continue;
|
|
37832
|
+
}
|
|
37833
|
+
posterPage = nextPage;
|
|
37834
|
+
continue;
|
|
37835
|
+
}
|
|
37836
|
+
const episode = parseEpisodeNumber(context.msg);
|
|
37837
|
+
const target = episode === null ? void 0 : displayEpisodes.find((item) => item.episode === episode);
|
|
37838
|
+
if (!target) {
|
|
37839
|
+
await this.e.reply(episode === null ? "匹配内容失败,请发送 第?集 选择集数,或发送 上一页 / 下一页 / 第?页 翻页" : `第${episode}集不在可解析的剧集里,请重新选择`);
|
|
37840
|
+
continue;
|
|
37841
|
+
}
|
|
37842
|
+
await this.e.reply(`收到请求,第${episode}集\n${mixInfo.mix_name}\n正在解析中`);
|
|
37843
|
+
const targetData = {
|
|
37844
|
+
type: "one_work",
|
|
37845
|
+
aweme_id: target.aweme_id
|
|
37846
|
+
};
|
|
37847
|
+
await new DouYin(context, targetData, { forceBurnDanmaku: this.forceBurnDanmaku }).DouyinHandler(targetData);
|
|
37505
37848
|
return true;
|
|
37506
37849
|
}
|
|
37507
|
-
await this.e.reply(`收到请求,第${episode}集\n${mixInfo.mix_name}\n正在解析中`);
|
|
37508
|
-
const targetData = {
|
|
37509
|
-
type: "one_work",
|
|
37510
|
-
aweme_id: target.aweme_id
|
|
37511
|
-
};
|
|
37512
|
-
await new DouYin(context, targetData, { forceBurnDanmaku: this.forceBurnDanmaku }).DouyinHandler(targetData);
|
|
37513
|
-
return true;
|
|
37514
37850
|
}
|
|
37515
37851
|
case "music_work": {
|
|
37516
37852
|
this.workType = "music";
|
|
@@ -42024,7 +42360,7 @@ var handleDouyin = wrapWithErrorHandler(async (e, next) => {
|
|
|
42024
42360
|
const iddata = await getDouyinID(e, url);
|
|
42025
42361
|
const douyin = new DouYin(e, iddata, { forceBurnDanmaku });
|
|
42026
42362
|
await douyin.DouyinHandler(iddata);
|
|
42027
|
-
await recordParseStat(e, "douyin", {
|
|
42363
|
+
if (!consumeParseStatSkip(e)) await recordParseStat(e, "douyin", {
|
|
42028
42364
|
workType: douyin.workType,
|
|
42029
42365
|
durationMs: Date.now() - startedAt
|
|
42030
42366
|
});
|
|
@@ -42049,7 +42385,7 @@ var handleBilibili = wrapWithErrorHandler(async (e, next) => {
|
|
|
42049
42385
|
const iddata = await getBilibiliID(url);
|
|
42050
42386
|
const bilibili = new Bilibili(e, iddata, { forceBurnDanmaku });
|
|
42051
42387
|
await bilibili.BilibiliHandler(iddata);
|
|
42052
|
-
await recordParseStat(e, "bilibili", {
|
|
42388
|
+
if (!consumeParseStatSkip(e)) await recordParseStat(e, "bilibili", {
|
|
42053
42389
|
workType: bilibili.workType,
|
|
42054
42390
|
durationMs: Date.now() - startedAt
|
|
42055
42391
|
});
|
|
@@ -42120,6 +42456,75 @@ var xiaohongshu = karin.command(reg.xiaohongshu, handleXiaohongshu, {
|
|
|
42120
42456
|
priority: Config.app.videoTool ? -Infinity : 800
|
|
42121
42457
|
});
|
|
42122
42458
|
var prefix = karin.command(/^#?(解析|kkk解析|弹幕解析)/, handlePrefix, { name: "kkk-视频功能-引用解析" });
|
|
42459
|
+
var handleEpisodeSelection = wrapWithErrorHandler(async (e, next) => {
|
|
42460
|
+
if (!isButtonSelectionScene(e)) return next();
|
|
42461
|
+
const match = /^#选集\s+([A-Za-z0-9_-]+)(?:\s+(.+?))?\s*$/.exec(e.msg);
|
|
42462
|
+
if (!match) return next();
|
|
42463
|
+
const [, token, actionText] = match;
|
|
42464
|
+
const session = getEpisodeSelection(token, getEpisodeSelectionScope(e));
|
|
42465
|
+
if (!session) {
|
|
42466
|
+
await e.reply("本次选集已结束,请重新发送原链接", { at: true });
|
|
42467
|
+
return true;
|
|
42468
|
+
}
|
|
42469
|
+
if (!actionText) {
|
|
42470
|
+
await e.reply("请点击下方按钮,或点击「跳转到第x页」输入页码");
|
|
42471
|
+
return true;
|
|
42472
|
+
}
|
|
42473
|
+
const action = parseEpisodeSelectionAction(actionText);
|
|
42474
|
+
if (!action) {
|
|
42475
|
+
await e.reply("集数或页码格式不正确,请重新选择");
|
|
42476
|
+
return true;
|
|
42477
|
+
}
|
|
42478
|
+
if (action.type === "page") {
|
|
42479
|
+
if (!getEpisodePage(session, action.page)) {
|
|
42480
|
+
await e.reply("页码超出范围,请重新选择");
|
|
42481
|
+
return true;
|
|
42482
|
+
}
|
|
42483
|
+
const poster = await getEpisodeSelectionPoster(session, action.page);
|
|
42484
|
+
const previousMessageId = session.currentMessageId;
|
|
42485
|
+
const sentAt = Date.now();
|
|
42486
|
+
const result = await e.reply(buildEpisodeSelectionReply(session, action.page, poster));
|
|
42487
|
+
const shouldRecall = canRecallEpisodeSelectionMessage(session);
|
|
42488
|
+
setEpisodeSelectionMessage(session, result.messageId, sentAt);
|
|
42489
|
+
if (previousMessageId && shouldRecall) await e.bot.recallMsg(e.contact, previousMessageId).catch((error) => {
|
|
42490
|
+
logger$1.debug("[选集] 撤回上一页失败:", error);
|
|
42491
|
+
});
|
|
42492
|
+
touchEpisodeSelection(token, session.scope);
|
|
42493
|
+
return true;
|
|
42494
|
+
}
|
|
42495
|
+
const target = resolveEpisodeTarget(session, action.episode);
|
|
42496
|
+
if (!target) {
|
|
42497
|
+
await e.reply(`第${action.episode}集不在可解析的剧集里,请重新选择`);
|
|
42498
|
+
return true;
|
|
42499
|
+
}
|
|
42500
|
+
if (target.platform === "douyin" && !Config.douyin.switch) {
|
|
42501
|
+
endEpisodeSelection(token, session.scope);
|
|
42502
|
+
await e.reply("抖音解析未开启");
|
|
42503
|
+
return true;
|
|
42504
|
+
}
|
|
42505
|
+
if (target.platform === "bilibili" && !Config.bilibili.switch) {
|
|
42506
|
+
endEpisodeSelection(token, session.scope);
|
|
42507
|
+
await e.reply("B站解析未开启");
|
|
42508
|
+
return true;
|
|
42509
|
+
}
|
|
42510
|
+
if (!endEpisodeSelection(token, session.scope)) {
|
|
42511
|
+
await e.reply("本次选集已结束,请重新发送原链接");
|
|
42512
|
+
return true;
|
|
42513
|
+
}
|
|
42514
|
+
const originalMsg = e.msg;
|
|
42515
|
+
e.msg = `${session.forceBurnDanmaku ? "#弹幕解析 " : "#解析"}${buildEpisodeTargetUrl(target)}`;
|
|
42516
|
+
try {
|
|
42517
|
+
if (target.platform === "douyin") await handleDouyin(e, () => {});
|
|
42518
|
+
else {
|
|
42519
|
+
markBilibiliEpisodeAutoSelect(e);
|
|
42520
|
+
await handleBilibili(e, () => {});
|
|
42521
|
+
}
|
|
42522
|
+
} finally {
|
|
42523
|
+
e.msg = originalMsg;
|
|
42524
|
+
}
|
|
42525
|
+
return true;
|
|
42526
|
+
}, { businessName: "KKK选集" });
|
|
42527
|
+
var episodeSelection = karin.command(/^#选集\s+/, handleEpisodeSelection, { name: "kkk-视频功能-选集" });
|
|
42123
42528
|
var douyinAPP = Config.douyin.switch && douyin;
|
|
42124
42529
|
var bilibiliAPP = Config.bilibili.switch && bilibili;
|
|
42125
42530
|
var kuaishouAPP = Config.kuaishou.switch && kuaishou;
|
|
@@ -43658,4 +44063,4 @@ mkdirSync(`${karinPathBase}/${Root.pluginName}/data`);
|
|
|
43658
44063
|
mkdirSync(Common.tempDri.images);
|
|
43659
44064
|
mkdirSync(Common.tempDri.video);
|
|
43660
44065
|
//#endregion
|
|
43661
|
-
export {
|
|
44066
|
+
export { bilibiliFetcher as $, removeOldFiles as A, douyinDBInstance as B, changelog as C, biRefreshLogin as D, biLogin as E, runWithVerifyContext as F, METRIC_BUCKETS as G, getDouyinDB as H, templates as I, DouyinDBBase as J, StatisticsDBBase as K, webConfig as L, testWrapWithErrorHandler as M, xhsLogin as N, dylogin as O, handleRiskChallenge as P, SOFT_ERROR_CODES as Q, bilibiliDBInstance as R, setdyPush as S, version as T, getStatisticsDB as U, getBilibiliDB as V, initAllDatabases as W, AmagiBase as X, BilibiliDBBase as Y, AmagiError as Z, douyinPush as _, bilibiliAPP as a, reloadAmagiConfig as at, globalIgnore as b, kuaishouAPP as c, Root as ct, testPush as d, douyinFetcher as et, globalStatistics as f, bilibiliPushList as g, bilibiliPush as h, update as i, registerAmagiReloadListener as it, task as j, ksLogin as k, prefix as l, qrLogin as m, kkkUpdateCommand as n, isSoftFailure as nt, douyinAPP as o, softFetch as ot, groupStatistics as p, resolveMetricBucket as q, kkkUpdateTest as r, kuaishouFetcher as rt, episodeSelection as s, xiaohongshuFetcher as st, kkkUpdate as t, getAmagiClient as tt, xiaohongshuAPP as u, douyinPushList as v, help as w, setbiliPush as x, forcePush as y, cleanOldDynamicCache as z };
|