@haklex/rich-renderer-linkcard 0.0.79 → 0.0.81
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/dist/LinkCardRenderer-C-luOWVc.js +1331 -0
- package/dist/index.mjs +262 -292
- package/dist/rich-renderer-linkcard.css +2 -1
- package/dist/static.mjs +2 -29
- package/package.json +4 -4
- package/dist/LinkCardRenderer-CJB5CmHP.js +0 -1314
|
@@ -0,0 +1,1331 @@
|
|
|
1
|
+
import { Globe, Star } from "lucide-react";
|
|
2
|
+
import { createContext, use, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import { vars } from "@haklex/rich-style-token";
|
|
4
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { useInView } from "react-intersection-observer";
|
|
6
|
+
//#region src/plugins/academic/arxiv.tsx
|
|
7
|
+
var arxivPlugin = {
|
|
8
|
+
name: "arxiv",
|
|
9
|
+
displayName: "arXiv Paper",
|
|
10
|
+
priority: 80,
|
|
11
|
+
typeClass: "academic",
|
|
12
|
+
matchUrl(url) {
|
|
13
|
+
if (url.hostname !== "arxiv.org") return null;
|
|
14
|
+
const match = url.pathname.match(/\/(abs|pdf)\/(\d{4}\.\d+(?:v\d+)?)/i);
|
|
15
|
+
if (!match) return null;
|
|
16
|
+
return {
|
|
17
|
+
id: match[2].toLowerCase(),
|
|
18
|
+
fullUrl: url.toString()
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
isValidId(id) {
|
|
22
|
+
return /^\d{4}\.\d+(?:v\d+)?$/.test(id);
|
|
23
|
+
},
|
|
24
|
+
async fetch(id) {
|
|
25
|
+
const text = await (await fetch(`https://export.arxiv.org/api/query?id_list=${id}`)).text();
|
|
26
|
+
const entry = new DOMParser().parseFromString(text, "application/xml").getElementsByTagName("entry")[0];
|
|
27
|
+
const title = entry.getElementsByTagName("title")[0].textContent;
|
|
28
|
+
const authors = entry.getElementsByTagName("author");
|
|
29
|
+
const authorNames = Array.from(authors).map((author) => author.getElementsByTagName("name")[0].textContent);
|
|
30
|
+
return {
|
|
31
|
+
title: /* @__PURE__ */ jsxs("span", {
|
|
32
|
+
style: {
|
|
33
|
+
display: "flex",
|
|
34
|
+
alignItems: "center",
|
|
35
|
+
gap: "8px"
|
|
36
|
+
},
|
|
37
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
38
|
+
style: { flex: 1 },
|
|
39
|
+
children: title
|
|
40
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
41
|
+
style: { flexShrink: 0 },
|
|
42
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
43
|
+
style: {
|
|
44
|
+
display: "inline-flex",
|
|
45
|
+
alignItems: "center",
|
|
46
|
+
gap: "4px",
|
|
47
|
+
fontSize: vars.typography.fontSizeMd,
|
|
48
|
+
color: "#fb923c"
|
|
49
|
+
},
|
|
50
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
51
|
+
style: {
|
|
52
|
+
fontFamily: "sans-serif",
|
|
53
|
+
fontWeight: 500
|
|
54
|
+
},
|
|
55
|
+
children: id
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
})]
|
|
59
|
+
}),
|
|
60
|
+
desc: authorNames.length > 1 ? `${authorNames[0]} et al.` : authorNames[0]
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/utils.ts
|
|
66
|
+
function toCamelCase(str) {
|
|
67
|
+
return str.replaceAll(/_([a-z])/g, (_, c) => c.toUpperCase());
|
|
68
|
+
}
|
|
69
|
+
function camelcaseKeys(obj) {
|
|
70
|
+
if (Array.isArray(obj)) return obj.map(camelcaseKeys);
|
|
71
|
+
if (obj !== null && typeof obj === "object") return Object.fromEntries(Object.entries(obj).map(([k, v]) => [toCamelCase(k), camelcaseKeys(v)]));
|
|
72
|
+
return obj;
|
|
73
|
+
}
|
|
74
|
+
async function fetchJsonWithContext(url, context, provider, init) {
|
|
75
|
+
const providerAdapter = provider && context?.adapters ? context.adapters[provider] : void 0;
|
|
76
|
+
if (providerAdapter) return providerAdapter.request(url, init);
|
|
77
|
+
if (context?.fetchJson) return context.fetchJson(url, init);
|
|
78
|
+
const response = await fetch(url, init);
|
|
79
|
+
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
|
|
80
|
+
return response.json();
|
|
81
|
+
}
|
|
82
|
+
async function fetchGitHubApi(url, context) {
|
|
83
|
+
return fetchJsonWithContext(`https://api.github.com${url.replace("https://api.github.com", "")}`, context, "github");
|
|
84
|
+
}
|
|
85
|
+
var LanguageToColorMap = {
|
|
86
|
+
"typescript": "#2b7489",
|
|
87
|
+
"javascript": "#f1e05a",
|
|
88
|
+
"html": "#e34c26",
|
|
89
|
+
"java": "#b07219",
|
|
90
|
+
"go": "#00add8",
|
|
91
|
+
"vue": "#2c3e50",
|
|
92
|
+
"css": "#563d7c",
|
|
93
|
+
"yaml": "#cb171e",
|
|
94
|
+
"json": "#292929",
|
|
95
|
+
"markdown": "#083fa1",
|
|
96
|
+
"csharp": "#178600",
|
|
97
|
+
"c#": "#178600",
|
|
98
|
+
"c": "#555555",
|
|
99
|
+
"cpp": "#f34b7d",
|
|
100
|
+
"c++": "#f34b7d",
|
|
101
|
+
"python": "#3572a5",
|
|
102
|
+
"lua": "#000080",
|
|
103
|
+
"vimscript": "#199f4b",
|
|
104
|
+
"shell": "#89e051",
|
|
105
|
+
"dockerfile": "#384d54",
|
|
106
|
+
"ruby": "#701516",
|
|
107
|
+
"php": "#4f5d95",
|
|
108
|
+
"lisp": "#3fb68b",
|
|
109
|
+
"kotlin": "#F18E33",
|
|
110
|
+
"rust": "#dea584",
|
|
111
|
+
"dart": "#00B4AB",
|
|
112
|
+
"swift": "#ffac45",
|
|
113
|
+
"objective-c": "#438eff",
|
|
114
|
+
"objective-c++": "#6866fb",
|
|
115
|
+
"r": "#198ce7",
|
|
116
|
+
"matlab": "#e16737",
|
|
117
|
+
"scala": "#c22d40",
|
|
118
|
+
"sql": "#e38c00",
|
|
119
|
+
"perl": "#0298c3"
|
|
120
|
+
};
|
|
121
|
+
var bangumiTypeMap = {
|
|
122
|
+
subject: "subjects",
|
|
123
|
+
character: "characters",
|
|
124
|
+
person: "persons"
|
|
125
|
+
};
|
|
126
|
+
var allowedBangumiTypes = Object.keys(bangumiTypeMap);
|
|
127
|
+
function hslToHex(h, s, l) {
|
|
128
|
+
s /= 100;
|
|
129
|
+
l /= 100;
|
|
130
|
+
const a = s * Math.min(l, 1 - l);
|
|
131
|
+
const f = (n) => {
|
|
132
|
+
const k = (n + h / 30) % 12;
|
|
133
|
+
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
|
134
|
+
return Math.round(255 * color).toString(16).padStart(2, "0");
|
|
135
|
+
};
|
|
136
|
+
return `#${f(0)}${f(8)}${f(4)}`;
|
|
137
|
+
}
|
|
138
|
+
function generateColor(str, saturation = [30, 35], lightness = [60, 70]) {
|
|
139
|
+
let hash = 0;
|
|
140
|
+
for (let i = 0; i < str.length; i++) hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
|
141
|
+
const sRange = saturation[1] - saturation[0] + 1;
|
|
142
|
+
const lRange = lightness[1] - lightness[0] + 1;
|
|
143
|
+
return hslToHex(Math.abs(hash) % 360, saturation[0] + Math.abs(hash >> 8) % sRange, lightness[0] + Math.abs(hash >> 16) % lRange);
|
|
144
|
+
}
|
|
145
|
+
function stripMarkdown(text) {
|
|
146
|
+
return text.replaceAll(/!\[[^\]]*\]\([^)]*\)/g, "").replaceAll(/\[([^\]]*)\]\([^)]*\)/g, "$1").replaceAll(/[#*>_`~]/g, "").replaceAll(/\n+/g, " ").trim();
|
|
147
|
+
}
|
|
148
|
+
//#endregion
|
|
149
|
+
//#region src/plugins/code/leetcode.tsx
|
|
150
|
+
function getDifficultyColor(difficulty) {
|
|
151
|
+
switch (difficulty) {
|
|
152
|
+
case "Easy": return "#00BFA5";
|
|
153
|
+
case "Medium": return "#FFA726";
|
|
154
|
+
case "Hard": return "#F44336";
|
|
155
|
+
default: return "#757575";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
var leetcodePlugin = {
|
|
159
|
+
name: "leetcode",
|
|
160
|
+
displayName: "LeetCode",
|
|
161
|
+
priority: 65,
|
|
162
|
+
typeClass: "wide",
|
|
163
|
+
provider: "leetcode",
|
|
164
|
+
matchUrl(url) {
|
|
165
|
+
if (url.hostname !== "leetcode.cn" && url.hostname !== "leetcode.com") return null;
|
|
166
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
167
|
+
if (parts[0] !== "problems" || !parts[1]) return null;
|
|
168
|
+
return {
|
|
169
|
+
id: parts[1],
|
|
170
|
+
fullUrl: url.toString()
|
|
171
|
+
};
|
|
172
|
+
},
|
|
173
|
+
isValidId(id) {
|
|
174
|
+
return typeof id === "string" && id.length > 0;
|
|
175
|
+
},
|
|
176
|
+
async fetch(id, _meta, context) {
|
|
177
|
+
const body = {
|
|
178
|
+
query: `query questionData($titleSlug: String!) {\n question(titleSlug: $titleSlug) {translatedTitle\n difficulty\n likes\n topicTags { translatedName\n }\n stats\n }\n}\n`,
|
|
179
|
+
variables: { titleSlug: id }
|
|
180
|
+
};
|
|
181
|
+
const questionTitleData = camelcaseKeys((await fetchJsonWithContext("https://leetcode.cn/graphql/", context, "leetcode", {
|
|
182
|
+
method: "POST",
|
|
183
|
+
headers: { "Content-Type": "application/json" },
|
|
184
|
+
body: JSON.stringify(body)
|
|
185
|
+
})).data.question);
|
|
186
|
+
const stats = JSON.parse(questionTitleData.stats);
|
|
187
|
+
return {
|
|
188
|
+
title: /* @__PURE__ */ jsxs("span", {
|
|
189
|
+
style: {
|
|
190
|
+
display: "flex",
|
|
191
|
+
alignItems: "center",
|
|
192
|
+
gap: "8px"
|
|
193
|
+
},
|
|
194
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
195
|
+
style: { flex: 1 },
|
|
196
|
+
children: questionTitleData.translatedTitle
|
|
197
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
198
|
+
style: { flexShrink: 0 },
|
|
199
|
+
children: questionTitleData.likes > 0 && /* @__PURE__ */ jsxs("span", {
|
|
200
|
+
style: {
|
|
201
|
+
display: "inline-flex",
|
|
202
|
+
alignItems: "center",
|
|
203
|
+
gap: "4px",
|
|
204
|
+
fontSize: vars.typography.fontSizeMd,
|
|
205
|
+
color: "#fb923c"
|
|
206
|
+
},
|
|
207
|
+
children: ["👍", /* @__PURE__ */ jsx("span", {
|
|
208
|
+
style: {
|
|
209
|
+
fontFamily: "sans-serif",
|
|
210
|
+
fontWeight: 500
|
|
211
|
+
},
|
|
212
|
+
children: questionTitleData.likes
|
|
213
|
+
})]
|
|
214
|
+
})
|
|
215
|
+
})]
|
|
216
|
+
}),
|
|
217
|
+
desc: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
218
|
+
/* @__PURE__ */ jsx("span", {
|
|
219
|
+
style: {
|
|
220
|
+
marginRight: "16px",
|
|
221
|
+
fontWeight: "bold",
|
|
222
|
+
color: getDifficultyColor(questionTitleData.difficulty)
|
|
223
|
+
},
|
|
224
|
+
children: questionTitleData.difficulty
|
|
225
|
+
}),
|
|
226
|
+
/* @__PURE__ */ jsx("span", {
|
|
227
|
+
style: { overflow: "hidden" },
|
|
228
|
+
children: questionTitleData.topicTags.map((tag) => tag.translatedName).join(" / ")
|
|
229
|
+
}),
|
|
230
|
+
/* @__PURE__ */ jsxs("span", {
|
|
231
|
+
style: {
|
|
232
|
+
float: "right",
|
|
233
|
+
overflow: "hidden"
|
|
234
|
+
},
|
|
235
|
+
children: ["AR: ", stats.acRate]
|
|
236
|
+
})
|
|
237
|
+
] }),
|
|
238
|
+
image: "https://upload.wikimedia.org/wikipedia/commons/1/19/LeetCode_logo_black.png",
|
|
239
|
+
color: getDifficultyColor(questionTitleData.difficulty)
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
//#endregion
|
|
244
|
+
//#region src/plugins/github/commit.tsx
|
|
245
|
+
var githubCommitPlugin = {
|
|
246
|
+
name: "gh-commit",
|
|
247
|
+
displayName: "GitHub Commit",
|
|
248
|
+
priority: 95,
|
|
249
|
+
typeClass: "github",
|
|
250
|
+
provider: "github",
|
|
251
|
+
matchUrl(url) {
|
|
252
|
+
if (url.hostname !== "github.com") return null;
|
|
253
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
254
|
+
if (parts.length < 4 || parts[2] !== "commit") return null;
|
|
255
|
+
const [owner, repo, , commitId] = parts;
|
|
256
|
+
return {
|
|
257
|
+
id: `${owner}/${repo}/commit/${commitId}`,
|
|
258
|
+
fullUrl: url.toString()
|
|
259
|
+
};
|
|
260
|
+
},
|
|
261
|
+
isValidId(id) {
|
|
262
|
+
const parts = id.split("/");
|
|
263
|
+
return parts.length === 4 && parts.every((p) => p.length > 0) && parts[2] === "commit";
|
|
264
|
+
},
|
|
265
|
+
async fetch(id, _meta, context) {
|
|
266
|
+
const [owner, repo, , commitId] = id.split("/");
|
|
267
|
+
const data = camelcaseKeys(await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}/commits/${commitId}`, context));
|
|
268
|
+
return {
|
|
269
|
+
title: /* @__PURE__ */ jsx("span", {
|
|
270
|
+
style: { fontWeight: "normal" },
|
|
271
|
+
children: data.commit.message.replace(/Signed-off-by:.+/s, "").trim()
|
|
272
|
+
}),
|
|
273
|
+
desc: /* @__PURE__ */ jsxs("span", {
|
|
274
|
+
style: {
|
|
275
|
+
display: "flex",
|
|
276
|
+
flexWrap: "wrap",
|
|
277
|
+
alignItems: "center",
|
|
278
|
+
gap: "4px 12px",
|
|
279
|
+
fontFamily: vars.typography.fontMono
|
|
280
|
+
},
|
|
281
|
+
children: [
|
|
282
|
+
/* @__PURE__ */ jsxs("span", {
|
|
283
|
+
style: {
|
|
284
|
+
display: "inline-flex",
|
|
285
|
+
alignItems: "center",
|
|
286
|
+
gap: "8px"
|
|
287
|
+
},
|
|
288
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
289
|
+
style: { color: "#238636" },
|
|
290
|
+
children: ["+", data.stats.additions]
|
|
291
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
292
|
+
style: { color: "#f85149" },
|
|
293
|
+
children: ["-", data.stats.deletions]
|
|
294
|
+
})]
|
|
295
|
+
}),
|
|
296
|
+
/* @__PURE__ */ jsx("span", {
|
|
297
|
+
style: { fontSize: vars.typography.fontSizeMd },
|
|
298
|
+
children: data.sha.slice(0, 7)
|
|
299
|
+
}),
|
|
300
|
+
/* @__PURE__ */ jsxs("span", {
|
|
301
|
+
style: {
|
|
302
|
+
fontSize: vars.typography.fontSizeMd,
|
|
303
|
+
opacity: .8
|
|
304
|
+
},
|
|
305
|
+
children: [
|
|
306
|
+
owner,
|
|
307
|
+
"/",
|
|
308
|
+
repo
|
|
309
|
+
]
|
|
310
|
+
})
|
|
311
|
+
]
|
|
312
|
+
}),
|
|
313
|
+
image: data.author?.avatarUrl
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/plugins/github/discussion.tsx
|
|
319
|
+
var githubDiscussionPlugin = {
|
|
320
|
+
name: "gh-discussion",
|
|
321
|
+
displayName: "GitHub Discussion",
|
|
322
|
+
priority: 95,
|
|
323
|
+
typeClass: "github",
|
|
324
|
+
provider: "github",
|
|
325
|
+
matchUrl(url) {
|
|
326
|
+
if (url.hostname !== "github.com") return null;
|
|
327
|
+
if (!url.pathname.includes("/discussions/")) return null;
|
|
328
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
329
|
+
if (parts.length < 4 || parts[2] !== "discussions") return null;
|
|
330
|
+
const discussionNumber = parts[3];
|
|
331
|
+
if (!/^\d+$/.test(discussionNumber)) return null;
|
|
332
|
+
const [owner, repo] = parts;
|
|
333
|
+
return {
|
|
334
|
+
id: `${owner}/${repo}/${discussionNumber}`,
|
|
335
|
+
fullUrl: url.toString()
|
|
336
|
+
};
|
|
337
|
+
},
|
|
338
|
+
isValidId(id) {
|
|
339
|
+
const parts = id.split("/");
|
|
340
|
+
return parts.length === 3 && parts.every((p) => p.length > 0) && /^\d+$/.test(parts[2]);
|
|
341
|
+
},
|
|
342
|
+
async fetch(id, _meta, context) {
|
|
343
|
+
const [owner, repo, discussionNumber] = id.split("/");
|
|
344
|
+
const data = camelcaseKeys(await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}/discussions/${discussionNumber}`, context));
|
|
345
|
+
const categoryName = data.category?.name || "Discussion";
|
|
346
|
+
return {
|
|
347
|
+
title: `Discussion: ${data.title}`,
|
|
348
|
+
desc: /* @__PURE__ */ jsxs("span", {
|
|
349
|
+
style: {
|
|
350
|
+
display: "flex",
|
|
351
|
+
flexWrap: "wrap",
|
|
352
|
+
alignItems: "center",
|
|
353
|
+
gap: "4px 12px",
|
|
354
|
+
fontFamily: vars.typography.fontMono
|
|
355
|
+
},
|
|
356
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
357
|
+
style: {
|
|
358
|
+
borderRadius: "4px",
|
|
359
|
+
backgroundColor: "rgba(128,128,128,0.15)",
|
|
360
|
+
padding: "2px 6px",
|
|
361
|
+
fontSize: vars.typography.fontSizeXs
|
|
362
|
+
},
|
|
363
|
+
children: categoryName
|
|
364
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
365
|
+
style: {
|
|
366
|
+
fontSize: vars.typography.fontSizeMd,
|
|
367
|
+
opacity: .8
|
|
368
|
+
},
|
|
369
|
+
children: [
|
|
370
|
+
"#",
|
|
371
|
+
discussionNumber,
|
|
372
|
+
" · ",
|
|
373
|
+
owner,
|
|
374
|
+
"/",
|
|
375
|
+
repo
|
|
376
|
+
]
|
|
377
|
+
})]
|
|
378
|
+
}),
|
|
379
|
+
image: data.user?.avatarUrl
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
};
|
|
383
|
+
//#endregion
|
|
384
|
+
//#region src/plugins/github/issue.tsx
|
|
385
|
+
var stateColors = {
|
|
386
|
+
open: "#238636",
|
|
387
|
+
closed: "#f85149"
|
|
388
|
+
};
|
|
389
|
+
var stateTextMap$1 = {
|
|
390
|
+
open: "Open",
|
|
391
|
+
closed: "Closed"
|
|
392
|
+
};
|
|
393
|
+
var githubIssuePlugin = {
|
|
394
|
+
name: "gh-issue",
|
|
395
|
+
displayName: "GitHub Issue",
|
|
396
|
+
priority: 95,
|
|
397
|
+
typeClass: "github",
|
|
398
|
+
provider: "github",
|
|
399
|
+
matchUrl(url) {
|
|
400
|
+
if (url.hostname !== "github.com") return null;
|
|
401
|
+
if (!url.pathname.includes("/issues/")) return null;
|
|
402
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
403
|
+
if (parts.length < 4 || parts[2] !== "issues") return null;
|
|
404
|
+
const issueNumber = parts[3];
|
|
405
|
+
if (!/^\d+$/.test(issueNumber)) return null;
|
|
406
|
+
const [owner, repo] = parts;
|
|
407
|
+
return {
|
|
408
|
+
id: `${owner}/${repo}/${issueNumber}`,
|
|
409
|
+
fullUrl: url.toString()
|
|
410
|
+
};
|
|
411
|
+
},
|
|
412
|
+
isValidId(id) {
|
|
413
|
+
const parts = id.split("/");
|
|
414
|
+
return parts.length === 3 && parts.every((p) => p.length > 0) && /^\d+$/.test(parts[2]);
|
|
415
|
+
},
|
|
416
|
+
async fetch(id, _meta, context) {
|
|
417
|
+
const [owner, repo, issueNumber] = id.split("/");
|
|
418
|
+
const data = camelcaseKeys(await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}/issues/${issueNumber}`, context));
|
|
419
|
+
const color = stateColors[data.state] || "#6b7280";
|
|
420
|
+
const stateText = stateTextMap$1[data.state] || data.state;
|
|
421
|
+
return {
|
|
422
|
+
title: `Issue: ${data.title}`,
|
|
423
|
+
color,
|
|
424
|
+
desc: /* @__PURE__ */ jsxs("span", {
|
|
425
|
+
style: {
|
|
426
|
+
display: "flex",
|
|
427
|
+
flexWrap: "wrap",
|
|
428
|
+
alignItems: "center",
|
|
429
|
+
gap: "4px 12px",
|
|
430
|
+
fontFamily: vars.typography.fontMono
|
|
431
|
+
},
|
|
432
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
433
|
+
style: { color },
|
|
434
|
+
children: stateText
|
|
435
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
436
|
+
style: {
|
|
437
|
+
fontSize: vars.typography.fontSizeMd,
|
|
438
|
+
opacity: .8
|
|
439
|
+
},
|
|
440
|
+
children: [
|
|
441
|
+
"#",
|
|
442
|
+
issueNumber,
|
|
443
|
+
" · ",
|
|
444
|
+
owner,
|
|
445
|
+
"/",
|
|
446
|
+
repo
|
|
447
|
+
]
|
|
448
|
+
})]
|
|
449
|
+
}),
|
|
450
|
+
image: data.user?.avatarUrl
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
//#endregion
|
|
455
|
+
//#region src/plugins/github/pr.tsx
|
|
456
|
+
var getPrState = (data) => {
|
|
457
|
+
if (data.merged) return "merged";
|
|
458
|
+
return data.state;
|
|
459
|
+
};
|
|
460
|
+
var stateColorMap = {
|
|
461
|
+
open: "#238636",
|
|
462
|
+
merged: "#8957e5",
|
|
463
|
+
closed: "#f85149"
|
|
464
|
+
};
|
|
465
|
+
var stateTextMap = {
|
|
466
|
+
open: "Open",
|
|
467
|
+
merged: "Merged",
|
|
468
|
+
closed: "Closed"
|
|
469
|
+
};
|
|
470
|
+
var githubPrPlugin = {
|
|
471
|
+
name: "gh-pr",
|
|
472
|
+
displayName: "GitHub Pull Request",
|
|
473
|
+
priority: 95,
|
|
474
|
+
typeClass: "github",
|
|
475
|
+
provider: "github",
|
|
476
|
+
matchUrl(url) {
|
|
477
|
+
if (url.hostname !== "github.com") return null;
|
|
478
|
+
if (!url.pathname.includes("/pull/")) return null;
|
|
479
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
480
|
+
if (parts.length < 4 || parts[2] !== "pull") return null;
|
|
481
|
+
const [owner, repo, , prNumber] = parts;
|
|
482
|
+
return {
|
|
483
|
+
id: `${owner}/${repo}/${prNumber}`,
|
|
484
|
+
fullUrl: url.toString()
|
|
485
|
+
};
|
|
486
|
+
},
|
|
487
|
+
isValidId(id) {
|
|
488
|
+
const parts = id.split("/");
|
|
489
|
+
return parts.length === 3 && parts.every((p) => p.length > 0);
|
|
490
|
+
},
|
|
491
|
+
async fetch(id, _meta, context) {
|
|
492
|
+
const [owner, repo, prNumber] = id.split("/");
|
|
493
|
+
const data = camelcaseKeys(await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`, context));
|
|
494
|
+
const state = getPrState(data);
|
|
495
|
+
const color = stateColorMap[state];
|
|
496
|
+
const stateText = stateTextMap[state];
|
|
497
|
+
return {
|
|
498
|
+
title: `PR: ${data.title}`,
|
|
499
|
+
color,
|
|
500
|
+
desc: /* @__PURE__ */ jsxs("span", {
|
|
501
|
+
style: {
|
|
502
|
+
display: "flex",
|
|
503
|
+
flexWrap: "wrap",
|
|
504
|
+
alignItems: "center",
|
|
505
|
+
gap: "4px 12px",
|
|
506
|
+
fontFamily: vars.typography.fontMono
|
|
507
|
+
},
|
|
508
|
+
children: [
|
|
509
|
+
/* @__PURE__ */ jsx("span", {
|
|
510
|
+
style: { color },
|
|
511
|
+
children: stateText
|
|
512
|
+
}),
|
|
513
|
+
/* @__PURE__ */ jsxs("span", {
|
|
514
|
+
style: {
|
|
515
|
+
display: "inline-flex",
|
|
516
|
+
alignItems: "center",
|
|
517
|
+
gap: "8px",
|
|
518
|
+
whiteSpace: "nowrap"
|
|
519
|
+
},
|
|
520
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
521
|
+
style: { color: "#238636" },
|
|
522
|
+
children: ["+", data.additions]
|
|
523
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
524
|
+
style: { color: "#f85149" },
|
|
525
|
+
children: ["-", data.deletions]
|
|
526
|
+
})]
|
|
527
|
+
}),
|
|
528
|
+
/* @__PURE__ */ jsxs("span", {
|
|
529
|
+
style: {
|
|
530
|
+
fontSize: vars.typography.fontSizeMd,
|
|
531
|
+
opacity: .8
|
|
532
|
+
},
|
|
533
|
+
children: [
|
|
534
|
+
owner,
|
|
535
|
+
"/",
|
|
536
|
+
repo
|
|
537
|
+
]
|
|
538
|
+
})
|
|
539
|
+
]
|
|
540
|
+
}),
|
|
541
|
+
image: data.user.avatarUrl
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/plugins/github/repo.tsx
|
|
547
|
+
function formatStargazers(n) {
|
|
548
|
+
return n.toLocaleString("en-US");
|
|
549
|
+
}
|
|
550
|
+
var githubRepoPlugin = {
|
|
551
|
+
name: "gh-repo",
|
|
552
|
+
displayName: "GitHub Repository",
|
|
553
|
+
priority: 100,
|
|
554
|
+
typeClass: "github",
|
|
555
|
+
provider: "github",
|
|
556
|
+
matchUrl(url) {
|
|
557
|
+
if (url.hostname !== "github.com") return null;
|
|
558
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
559
|
+
if (parts.length !== 2) return null;
|
|
560
|
+
const [owner, repo] = parts;
|
|
561
|
+
if (!owner || !repo) return null;
|
|
562
|
+
return {
|
|
563
|
+
id: `${owner}/${repo}`,
|
|
564
|
+
fullUrl: url.toString()
|
|
565
|
+
};
|
|
566
|
+
},
|
|
567
|
+
isValidId(id) {
|
|
568
|
+
const parts = id.split("/");
|
|
569
|
+
return parts.length === 2 && parts[0].length > 0 && parts[1].length > 0;
|
|
570
|
+
},
|
|
571
|
+
async fetch(id, _meta, context) {
|
|
572
|
+
const [owner, repo] = id.split("/");
|
|
573
|
+
const data = camelcaseKeys(await fetchGitHubApi(`https://api.github.com/repos/${owner}/${repo}`, context));
|
|
574
|
+
return {
|
|
575
|
+
title: /* @__PURE__ */ jsxs("span", {
|
|
576
|
+
style: {
|
|
577
|
+
display: "flex",
|
|
578
|
+
alignItems: "center",
|
|
579
|
+
gap: "8px"
|
|
580
|
+
},
|
|
581
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
582
|
+
style: { flex: 1 },
|
|
583
|
+
children: data.name
|
|
584
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
585
|
+
style: { flexShrink: 0 },
|
|
586
|
+
children: data.stargazersCount > 0 && /* @__PURE__ */ jsxs("span", {
|
|
587
|
+
style: {
|
|
588
|
+
display: "inline-flex",
|
|
589
|
+
alignItems: "center",
|
|
590
|
+
gap: "4px",
|
|
591
|
+
fontSize: vars.typography.fontSizeMd,
|
|
592
|
+
color: "#fb923c"
|
|
593
|
+
},
|
|
594
|
+
children: [/* @__PURE__ */ jsx(Star, {
|
|
595
|
+
"aria-hidden": true,
|
|
596
|
+
size: 14,
|
|
597
|
+
strokeWidth: 2
|
|
598
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
599
|
+
style: {
|
|
600
|
+
fontFamily: "sans-serif",
|
|
601
|
+
fontWeight: 500
|
|
602
|
+
},
|
|
603
|
+
children: formatStargazers(data.stargazersCount)
|
|
604
|
+
})]
|
|
605
|
+
})
|
|
606
|
+
})]
|
|
607
|
+
}),
|
|
608
|
+
desc: data.description,
|
|
609
|
+
image: data.owner.avatarUrl,
|
|
610
|
+
color: LanguageToColorMap[data.language?.toLowerCase()]
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
//#endregion
|
|
615
|
+
//#region src/plugins/media/bangumi.tsx
|
|
616
|
+
var bangumiPlugin = {
|
|
617
|
+
name: "bangumi",
|
|
618
|
+
displayName: "Bangumi",
|
|
619
|
+
priority: 70,
|
|
620
|
+
typeClass: "media",
|
|
621
|
+
provider: "bangumi",
|
|
622
|
+
matchUrl(url) {
|
|
623
|
+
if (url.hostname !== "bgm.tv" && url.hostname !== "bangumi.tv") return null;
|
|
624
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
625
|
+
if (parts.length < 2) return null;
|
|
626
|
+
const [type, realId] = parts;
|
|
627
|
+
if (!allowedBangumiTypes.includes(type)) return null;
|
|
628
|
+
return {
|
|
629
|
+
id: `${type}/${realId}`,
|
|
630
|
+
fullUrl: url.toString(),
|
|
631
|
+
meta: { type }
|
|
632
|
+
};
|
|
633
|
+
},
|
|
634
|
+
isValidId(id) {
|
|
635
|
+
const [type, realId] = id.split("/");
|
|
636
|
+
return allowedBangumiTypes.includes(type) && realId?.length > 0;
|
|
637
|
+
},
|
|
638
|
+
async fetch(id, _meta, context) {
|
|
639
|
+
const [type, realId] = id.split("/");
|
|
640
|
+
const json = await fetchJsonWithContext(`https://api.bgm.tv/v0/${bangumiTypeMap[type]}/${realId}`, context, "bangumi");
|
|
641
|
+
let title = "";
|
|
642
|
+
let originalTitle = "";
|
|
643
|
+
if (type === "subject") if (json.name_cn && json.name_cn !== json.name && json.name_cn !== "") {
|
|
644
|
+
title = json.name_cn;
|
|
645
|
+
originalTitle = json.name;
|
|
646
|
+
} else {
|
|
647
|
+
title = json.name;
|
|
648
|
+
originalTitle = json.name;
|
|
649
|
+
}
|
|
650
|
+
else if (type === "character" || type === "person") {
|
|
651
|
+
const { infobox } = json;
|
|
652
|
+
infobox.forEach((item) => {
|
|
653
|
+
if (item.key === "简体中文名") title = typeof item.value === "string" ? item.value : item.value[0].v;
|
|
654
|
+
else if (item.key === "别名") {
|
|
655
|
+
item.value.forEach((alias) => {
|
|
656
|
+
originalTitle += `${alias.v} / `;
|
|
657
|
+
});
|
|
658
|
+
originalTitle = originalTitle.slice(0, -3);
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
const starStyle = {
|
|
663
|
+
display: "inline-flex",
|
|
664
|
+
flexShrink: 0,
|
|
665
|
+
alignItems: "center",
|
|
666
|
+
gap: "4px",
|
|
667
|
+
alignSelf: "center",
|
|
668
|
+
fontSize: vars.typography.fontSizeXs,
|
|
669
|
+
color: "#fb923c"
|
|
670
|
+
};
|
|
671
|
+
return {
|
|
672
|
+
title: /* @__PURE__ */ jsxs("span", {
|
|
673
|
+
style: {
|
|
674
|
+
display: "flex",
|
|
675
|
+
flexWrap: "wrap",
|
|
676
|
+
alignItems: "flex-end",
|
|
677
|
+
gap: "8px"
|
|
678
|
+
},
|
|
679
|
+
children: [
|
|
680
|
+
/* @__PURE__ */ jsx("span", { children: title }),
|
|
681
|
+
title !== originalTitle && /* @__PURE__ */ jsxs("span", {
|
|
682
|
+
style: {
|
|
683
|
+
fontSize: vars.typography.fontSizeMd,
|
|
684
|
+
opacity: .7
|
|
685
|
+
},
|
|
686
|
+
children: [
|
|
687
|
+
"(",
|
|
688
|
+
originalTitle,
|
|
689
|
+
")"
|
|
690
|
+
]
|
|
691
|
+
}),
|
|
692
|
+
type === "subject" && /* @__PURE__ */ jsxs("span", {
|
|
693
|
+
style: {
|
|
694
|
+
display: "inline-flex",
|
|
695
|
+
flexShrink: 0,
|
|
696
|
+
alignItems: "center",
|
|
697
|
+
gap: "12px",
|
|
698
|
+
alignSelf: "center"
|
|
699
|
+
},
|
|
700
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
701
|
+
style: starStyle,
|
|
702
|
+
children: ["★", /* @__PURE__ */ jsx("span", {
|
|
703
|
+
style: {
|
|
704
|
+
fontFamily: "sans-serif",
|
|
705
|
+
fontWeight: 500
|
|
706
|
+
},
|
|
707
|
+
children: json.rating.score > 0 && json.rating.score.toFixed(1)
|
|
708
|
+
})]
|
|
709
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
710
|
+
style: starStyle,
|
|
711
|
+
children: ["☆", /* @__PURE__ */ jsx("span", {
|
|
712
|
+
style: {
|
|
713
|
+
fontFamily: "sans-serif",
|
|
714
|
+
fontWeight: 500
|
|
715
|
+
},
|
|
716
|
+
children: json.collection && json.collection.on_hold + json.collection.dropped + json.collection.wish + json.collection.collect + json.collection.doing
|
|
717
|
+
})]
|
|
718
|
+
})]
|
|
719
|
+
}),
|
|
720
|
+
(type === "character" || type === "person") && /* @__PURE__ */ jsxs("span", {
|
|
721
|
+
style: starStyle,
|
|
722
|
+
children: ["☆", /* @__PURE__ */ jsx("span", {
|
|
723
|
+
style: {
|
|
724
|
+
fontFamily: "sans-serif",
|
|
725
|
+
fontWeight: 500
|
|
726
|
+
},
|
|
727
|
+
children: json.stat.collects > 0 && json.stat.collects
|
|
728
|
+
})]
|
|
729
|
+
})
|
|
730
|
+
]
|
|
731
|
+
}),
|
|
732
|
+
desc: /* @__PURE__ */ jsx("span", {
|
|
733
|
+
style: {
|
|
734
|
+
overflow: "visible",
|
|
735
|
+
whiteSpace: "pre-wrap"
|
|
736
|
+
},
|
|
737
|
+
children: json.summary
|
|
738
|
+
}),
|
|
739
|
+
image: json.images.grid,
|
|
740
|
+
color: generateColor(title),
|
|
741
|
+
classNames: {
|
|
742
|
+
image: "link-card__image--poster",
|
|
743
|
+
cardRoot: "link-card--poster"
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
};
|
|
748
|
+
//#endregion
|
|
749
|
+
//#region src/plugins/media/netease-music.tsx
|
|
750
|
+
var neteaseMusicPlugin = {
|
|
751
|
+
name: "netease-music-song",
|
|
752
|
+
displayName: "Netease Music Song",
|
|
753
|
+
priority: 60,
|
|
754
|
+
typeClass: "wide",
|
|
755
|
+
provider: "netease-music",
|
|
756
|
+
matchUrl(url) {
|
|
757
|
+
if (url.hostname !== "music.163.com") return null;
|
|
758
|
+
if (!url.pathname.includes("/song") && !url.hash.includes("/song")) return null;
|
|
759
|
+
const urlString = url.toString().replaceAll("/#/", "/");
|
|
760
|
+
const id = new URL(urlString).searchParams.get("id");
|
|
761
|
+
if (!id) return null;
|
|
762
|
+
return {
|
|
763
|
+
id,
|
|
764
|
+
fullUrl: url.toString()
|
|
765
|
+
};
|
|
766
|
+
},
|
|
767
|
+
isValidId(id) {
|
|
768
|
+
return id.length > 0;
|
|
769
|
+
},
|
|
770
|
+
async fetch(id, _meta, context) {
|
|
771
|
+
const songInfo = (await fetchJsonWithContext(`https://music.163.com/song/${id}`, context, "netease-music")).songs[0];
|
|
772
|
+
const albumInfo = songInfo.al;
|
|
773
|
+
const singerInfo = songInfo.ar;
|
|
774
|
+
return {
|
|
775
|
+
title: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { children: songInfo.name }), songInfo.tns && /* @__PURE__ */ jsx("span", {
|
|
776
|
+
style: {
|
|
777
|
+
marginLeft: "8px",
|
|
778
|
+
fontSize: vars.typography.fontSizeMd,
|
|
779
|
+
color: "#a1a1aa"
|
|
780
|
+
},
|
|
781
|
+
children: songInfo.tns[0]
|
|
782
|
+
})] }),
|
|
783
|
+
desc: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
|
|
784
|
+
style: { display: "block" },
|
|
785
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
786
|
+
style: { fontWeight: "bold" },
|
|
787
|
+
children: "歌手:"
|
|
788
|
+
}), /* @__PURE__ */ jsx("span", { children: singerInfo.map((p) => p.name).join(" / ") })]
|
|
789
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
790
|
+
style: { display: "block" },
|
|
791
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
792
|
+
style: { fontWeight: "bold" },
|
|
793
|
+
children: "专辑:"
|
|
794
|
+
}), /* @__PURE__ */ jsx("span", { children: albumInfo.name })]
|
|
795
|
+
})] }),
|
|
796
|
+
image: albumInfo.picUrl,
|
|
797
|
+
color: "#e72d2c"
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
};
|
|
801
|
+
//#endregion
|
|
802
|
+
//#region src/plugins/media/qq-music.tsx
|
|
803
|
+
var qqMusicPlugin = {
|
|
804
|
+
name: "qq-music-song",
|
|
805
|
+
displayName: "QQ Music Song",
|
|
806
|
+
priority: 60,
|
|
807
|
+
typeClass: "wide",
|
|
808
|
+
provider: "qq-music",
|
|
809
|
+
matchUrl(url) {
|
|
810
|
+
if (url.hostname !== "y.qq.com") return null;
|
|
811
|
+
if (!url.pathname.includes("/songDetail/")) return null;
|
|
812
|
+
const parts = url.pathname.split("/");
|
|
813
|
+
const songDetailIndex = parts.indexOf("songDetail");
|
|
814
|
+
if (songDetailIndex === -1 || !parts[songDetailIndex + 1]) return null;
|
|
815
|
+
return {
|
|
816
|
+
id: parts[songDetailIndex + 1],
|
|
817
|
+
fullUrl: url.toString()
|
|
818
|
+
};
|
|
819
|
+
},
|
|
820
|
+
isValidId(id) {
|
|
821
|
+
return typeof id === "string" && id.length > 0;
|
|
822
|
+
},
|
|
823
|
+
async fetch(id, _meta, context) {
|
|
824
|
+
const songInfo = (await fetchJsonWithContext(`https://y.qq.com/song/${id}`, context, "qq-music")).data[0];
|
|
825
|
+
const albumId = songInfo.album.mid;
|
|
826
|
+
return {
|
|
827
|
+
title: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", { children: songInfo.title }), songInfo.subtitle && /* @__PURE__ */ jsx("span", {
|
|
828
|
+
style: {
|
|
829
|
+
marginLeft: "8px",
|
|
830
|
+
fontSize: vars.typography.fontSizeMd,
|
|
831
|
+
color: "#a1a1aa"
|
|
832
|
+
},
|
|
833
|
+
children: songInfo.subtitle
|
|
834
|
+
})] }),
|
|
835
|
+
desc: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("span", {
|
|
836
|
+
style: { display: "block" },
|
|
837
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
838
|
+
style: { fontWeight: "bold" },
|
|
839
|
+
children: "歌手:"
|
|
840
|
+
}), /* @__PURE__ */ jsx("span", { children: songInfo.singer.map((p) => p.name).join(" / ") })]
|
|
841
|
+
}), /* @__PURE__ */ jsxs("span", {
|
|
842
|
+
style: { display: "block" },
|
|
843
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
844
|
+
style: { fontWeight: "bold" },
|
|
845
|
+
children: "专辑:"
|
|
846
|
+
}), /* @__PURE__ */ jsx("span", { children: songInfo.album.name })]
|
|
847
|
+
})] }),
|
|
848
|
+
image: `https://y.gtimg.cn/music/photo_new/T002R300x300M000${albumId}.jpg?max_age=2592000`,
|
|
849
|
+
color: "#31c27c"
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
//#endregion
|
|
854
|
+
//#region src/plugins/media/tmdb.tsx
|
|
855
|
+
var TMDB_LANGUAGE_BY_LOCALE = {
|
|
856
|
+
zh: "zh-CN",
|
|
857
|
+
en: "en-US",
|
|
858
|
+
ja: "ja-JP"
|
|
859
|
+
};
|
|
860
|
+
var getCurrentLocale = () => {
|
|
861
|
+
if (typeof document !== "undefined") {
|
|
862
|
+
const lang = document.documentElement?.lang?.trim();
|
|
863
|
+
if (lang) return lang;
|
|
864
|
+
}
|
|
865
|
+
if (typeof window !== "undefined") {
|
|
866
|
+
const firstSegment = window.location.pathname.split("/").find((s) => s.length > 0);
|
|
867
|
+
if (firstSegment) return firstSegment;
|
|
868
|
+
}
|
|
869
|
+
return "en";
|
|
870
|
+
};
|
|
871
|
+
var tmdbPlugin = {
|
|
872
|
+
name: "tmdb",
|
|
873
|
+
displayName: "The Movie Database",
|
|
874
|
+
priority: 70,
|
|
875
|
+
typeClass: "media",
|
|
876
|
+
provider: "tmdb",
|
|
877
|
+
matchUrl(url) {
|
|
878
|
+
if (!url.hostname.includes("themoviedb.org")) return null;
|
|
879
|
+
const parts = url.pathname.split("/").filter(Boolean);
|
|
880
|
+
if (parts.length < 2) return null;
|
|
881
|
+
const [type, realId] = parts;
|
|
882
|
+
if (!["tv", "movie"].includes(type) || !realId) return null;
|
|
883
|
+
return {
|
|
884
|
+
id: `${type}/${realId}`,
|
|
885
|
+
fullUrl: url.toString(),
|
|
886
|
+
meta: { type }
|
|
887
|
+
};
|
|
888
|
+
},
|
|
889
|
+
isValidId(id) {
|
|
890
|
+
const [type, realId] = id.split("/");
|
|
891
|
+
return ["tv", "movie"].includes(type) && realId?.length > 0;
|
|
892
|
+
},
|
|
893
|
+
async fetch(id, _meta, context) {
|
|
894
|
+
const [type, realId] = id.split("/");
|
|
895
|
+
const json = await fetchJsonWithContext(`https://api.themoviedb.org/3/${type}/${realId}?language=${TMDB_LANGUAGE_BY_LOCALE[getCurrentLocale()] || (typeof navigator !== "undefined" ? navigator.language : "en-US") || "en-US"}`, context, "tmdb");
|
|
896
|
+
const title = type === "tv" ? json.name : json.title;
|
|
897
|
+
const originalTitle = type === "tv" ? json.original_name : json.original_title;
|
|
898
|
+
return {
|
|
899
|
+
title: /* @__PURE__ */ jsxs("span", {
|
|
900
|
+
style: {
|
|
901
|
+
display: "flex",
|
|
902
|
+
flexWrap: "wrap",
|
|
903
|
+
alignItems: "flex-end",
|
|
904
|
+
gap: "8px"
|
|
905
|
+
},
|
|
906
|
+
children: [
|
|
907
|
+
/* @__PURE__ */ jsx("span", { children: title }),
|
|
908
|
+
title !== originalTitle && /* @__PURE__ */ jsxs("span", {
|
|
909
|
+
style: {
|
|
910
|
+
fontSize: vars.typography.fontSizeMd,
|
|
911
|
+
opacity: .7
|
|
912
|
+
},
|
|
913
|
+
children: [
|
|
914
|
+
"(",
|
|
915
|
+
originalTitle,
|
|
916
|
+
")"
|
|
917
|
+
]
|
|
918
|
+
}),
|
|
919
|
+
/* @__PURE__ */ jsxs("span", {
|
|
920
|
+
style: {
|
|
921
|
+
display: "inline-flex",
|
|
922
|
+
flexShrink: 0,
|
|
923
|
+
alignItems: "center",
|
|
924
|
+
gap: "4px",
|
|
925
|
+
alignSelf: "center",
|
|
926
|
+
fontSize: vars.typography.fontSizeXs,
|
|
927
|
+
color: "#fb923c"
|
|
928
|
+
},
|
|
929
|
+
children: ["★", /* @__PURE__ */ jsx("span", {
|
|
930
|
+
style: {
|
|
931
|
+
fontFamily: "sans-serif",
|
|
932
|
+
fontWeight: 500
|
|
933
|
+
},
|
|
934
|
+
children: json.vote_average > 0 && json.vote_average.toFixed(1)
|
|
935
|
+
})]
|
|
936
|
+
})
|
|
937
|
+
]
|
|
938
|
+
}),
|
|
939
|
+
desc: /* @__PURE__ */ jsx("span", {
|
|
940
|
+
style: {
|
|
941
|
+
overflow: "visible",
|
|
942
|
+
whiteSpace: "pre-wrap"
|
|
943
|
+
},
|
|
944
|
+
children: json.overview
|
|
945
|
+
}),
|
|
946
|
+
image: `https://image.tmdb.org/t/p/w500${json.poster_path}`,
|
|
947
|
+
color: generateColor(title || originalTitle || id),
|
|
948
|
+
classNames: {
|
|
949
|
+
image: "link-card__image--poster",
|
|
950
|
+
cardRoot: "link-card--poster"
|
|
951
|
+
}
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
};
|
|
955
|
+
//#endregion
|
|
956
|
+
//#region src/plugins/self/mx-space.tsx
|
|
957
|
+
function createMxSpacePlugin(config) {
|
|
958
|
+
const webHost = new URL(config.webUrl).hostname;
|
|
959
|
+
return {
|
|
960
|
+
name: "self",
|
|
961
|
+
displayName: "MxSpace Article",
|
|
962
|
+
priority: 10,
|
|
963
|
+
provider: "mx-space",
|
|
964
|
+
matchUrl(url) {
|
|
965
|
+
if (webHost !== url.hostname) return null;
|
|
966
|
+
if (!url.pathname.startsWith("/posts/") && !url.pathname.startsWith("/notes/")) return null;
|
|
967
|
+
return {
|
|
968
|
+
id: url.pathname.slice(1),
|
|
969
|
+
fullUrl: url.toString()
|
|
970
|
+
};
|
|
971
|
+
},
|
|
972
|
+
isValidId(id) {
|
|
973
|
+
const [type, ...rest] = id.split("/");
|
|
974
|
+
if (type !== "posts" && type !== "notes") return false;
|
|
975
|
+
if (type === "posts") return rest.length === 2;
|
|
976
|
+
return rest.length === 1;
|
|
977
|
+
},
|
|
978
|
+
async fetch(id, _meta, context) {
|
|
979
|
+
const [type, ...rest] = id.split("/");
|
|
980
|
+
let data = {
|
|
981
|
+
title: "",
|
|
982
|
+
text: ""
|
|
983
|
+
};
|
|
984
|
+
if (type === "posts") {
|
|
985
|
+
const [cate, slug] = rest;
|
|
986
|
+
data = await fetchJsonWithContext(`posts/${cate}/${slug}`, context, "mx-space");
|
|
987
|
+
} else if (type === "notes") {
|
|
988
|
+
const [nid] = rest;
|
|
989
|
+
const response = await fetchJsonWithContext(`notes/${nid}`, context, "mx-space");
|
|
990
|
+
data = response.data || response;
|
|
991
|
+
}
|
|
992
|
+
const coverImage = data.cover || data.meta?.cover;
|
|
993
|
+
const spotlightColor = generateColor(data.title);
|
|
994
|
+
return {
|
|
995
|
+
title: data.title,
|
|
996
|
+
desc: data.summary || `${stripMarkdown(data.text).slice(0, 50)}...`,
|
|
997
|
+
image: coverImage || data.images?.[0]?.src,
|
|
998
|
+
color: spotlightColor
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
//#endregion
|
|
1004
|
+
//#region src/plugins/index.ts
|
|
1005
|
+
var plugins = [
|
|
1006
|
+
githubRepoPlugin,
|
|
1007
|
+
githubCommitPlugin,
|
|
1008
|
+
githubPrPlugin,
|
|
1009
|
+
githubIssuePlugin,
|
|
1010
|
+
githubDiscussionPlugin,
|
|
1011
|
+
arxivPlugin,
|
|
1012
|
+
tmdbPlugin,
|
|
1013
|
+
bangumiPlugin,
|
|
1014
|
+
qqMusicPlugin,
|
|
1015
|
+
neteaseMusicPlugin,
|
|
1016
|
+
leetcodePlugin
|
|
1017
|
+
].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
1018
|
+
function getPluginByName(name) {
|
|
1019
|
+
return plugins.find((p) => p.name === name);
|
|
1020
|
+
}
|
|
1021
|
+
var pluginMap = new Map(plugins.map((p) => [p.name, p]));
|
|
1022
|
+
//#endregion
|
|
1023
|
+
//#region src/hooks/useUrlMatcher.ts
|
|
1024
|
+
function matchUrl(url, pluginRegistry = plugins) {
|
|
1025
|
+
try {
|
|
1026
|
+
const parsed = new URL(url);
|
|
1027
|
+
for (const plugin of pluginRegistry) {
|
|
1028
|
+
const match = plugin.matchUrl(parsed);
|
|
1029
|
+
if (match) return {
|
|
1030
|
+
plugin,
|
|
1031
|
+
match
|
|
1032
|
+
};
|
|
1033
|
+
}
|
|
1034
|
+
} catch {}
|
|
1035
|
+
return null;
|
|
1036
|
+
}
|
|
1037
|
+
function useUrlMatcher(url, pluginRegistry = plugins) {
|
|
1038
|
+
return useMemo(() => {
|
|
1039
|
+
if (!url) return null;
|
|
1040
|
+
return matchUrl(url, pluginRegistry);
|
|
1041
|
+
}, [url, pluginRegistry]);
|
|
1042
|
+
}
|
|
1043
|
+
//#endregion
|
|
1044
|
+
//#region src/styles.css.ts
|
|
1045
|
+
var semanticClassNames = {
|
|
1046
|
+
card: "link-card",
|
|
1047
|
+
cardShortDesc: "link-card--short-desc",
|
|
1048
|
+
cardSkeleton: "link-card--skeleton",
|
|
1049
|
+
cardError: "link-card--error",
|
|
1050
|
+
cardPoster: "link-card--poster",
|
|
1051
|
+
cardWide: "link-card--wide",
|
|
1052
|
+
cardMedia: "link-card--media",
|
|
1053
|
+
cardGithub: "link-card--github",
|
|
1054
|
+
cardAcademic: "link-card--academic",
|
|
1055
|
+
bg: "link-card__bg",
|
|
1056
|
+
image: "link-card__image",
|
|
1057
|
+
imagePoster: "link-card__image--poster",
|
|
1058
|
+
icon: "link-card__icon",
|
|
1059
|
+
content: "link-card__content",
|
|
1060
|
+
title: "link-card__title",
|
|
1061
|
+
titleText: "link-card__title-text",
|
|
1062
|
+
desc: "link-card__desc",
|
|
1063
|
+
desc2: "link-card__desc-2",
|
|
1064
|
+
editWrapper: "rich-link-card-edit-wrapper",
|
|
1065
|
+
editPanel: "rich-link-card-edit-panel",
|
|
1066
|
+
editUrlRow: "rich-link-card-edit-url-row",
|
|
1067
|
+
editLinkIcon: "rich-link-card-edit-link-icon",
|
|
1068
|
+
editInput: "rich-link-card-edit-input"
|
|
1069
|
+
};
|
|
1070
|
+
var card = "_13weebv0";
|
|
1071
|
+
var image = "_13weebv3";
|
|
1072
|
+
var icon = "_13weebv5";
|
|
1073
|
+
var content = "_13weebv6";
|
|
1074
|
+
var title = "_13weebv7";
|
|
1075
|
+
var titleText = "_13weebv8";
|
|
1076
|
+
var desc = "_13weebv9";
|
|
1077
|
+
var desc2 = "_13weebva";
|
|
1078
|
+
var cardSkeleton = "_13weebvg";
|
|
1079
|
+
var editWrapper = "_13weebvj";
|
|
1080
|
+
var editPanel = "_13weebvk";
|
|
1081
|
+
var editUrlRow = "_13weebvl";
|
|
1082
|
+
var editLinkIcon = "_13weebvm";
|
|
1083
|
+
var editInput = "_13weebvn";
|
|
1084
|
+
var typeCardModifier = {
|
|
1085
|
+
media: "_13weebvd",
|
|
1086
|
+
github: "_13weebve",
|
|
1087
|
+
academic: "_13weebvf",
|
|
1088
|
+
wide: "_13weebvc"
|
|
1089
|
+
};
|
|
1090
|
+
var semanticTypeClassNames = {
|
|
1091
|
+
media: "link-card--media",
|
|
1092
|
+
github: "link-card--github",
|
|
1093
|
+
academic: "link-card--academic",
|
|
1094
|
+
wide: "link-card--wide"
|
|
1095
|
+
};
|
|
1096
|
+
var semanticClassToStyle = {
|
|
1097
|
+
"link-card--short-desc": "_13weebv1",
|
|
1098
|
+
"link-card--skeleton": "_13weebvg",
|
|
1099
|
+
"link-card--error": "_13weebvi",
|
|
1100
|
+
"link-card--poster": "_13weebvb",
|
|
1101
|
+
"link-card--wide": "_13weebvc",
|
|
1102
|
+
"link-card--media": "_13weebvd",
|
|
1103
|
+
"link-card--github": "_13weebve",
|
|
1104
|
+
"link-card--academic": "_13weebvf",
|
|
1105
|
+
"link-card__image--poster": "_13weebv4"
|
|
1106
|
+
};
|
|
1107
|
+
//#endregion
|
|
1108
|
+
//#region src/FetchContext.tsx
|
|
1109
|
+
var ctx = createContext(void 0);
|
|
1110
|
+
var LinkCardFetchProvider = ctx.Provider;
|
|
1111
|
+
function useLinkCardFetchContext() {
|
|
1112
|
+
return use(ctx);
|
|
1113
|
+
}
|
|
1114
|
+
//#endregion
|
|
1115
|
+
//#region src/hooks/useCardFetcher.ts
|
|
1116
|
+
function useCardFetcher(options) {
|
|
1117
|
+
const { source, plugin, id, fallbackUrl, enabled = true, context } = options;
|
|
1118
|
+
const [loading, setLoading] = useState(true);
|
|
1119
|
+
const [isError, setIsError] = useState(false);
|
|
1120
|
+
const [fullUrl] = useState(fallbackUrl || "javascript:;");
|
|
1121
|
+
const [cardInfo, setCardInfo] = useState();
|
|
1122
|
+
const isValid = useMemo(() => {
|
|
1123
|
+
if (!enabled || !plugin) return false;
|
|
1124
|
+
return plugin.isValidId(id);
|
|
1125
|
+
}, [
|
|
1126
|
+
plugin,
|
|
1127
|
+
enabled,
|
|
1128
|
+
id
|
|
1129
|
+
]);
|
|
1130
|
+
const fetchInfo = useCallback(async () => {
|
|
1131
|
+
if (!plugin || !isValid) return;
|
|
1132
|
+
setLoading(true);
|
|
1133
|
+
setIsError(false);
|
|
1134
|
+
try {
|
|
1135
|
+
setCardInfo(await plugin.fetch(id, void 0, context));
|
|
1136
|
+
} catch (err) {
|
|
1137
|
+
console.error(`[LinkCard] Error fetching ${source || plugin.name} data:`, err);
|
|
1138
|
+
setIsError(true);
|
|
1139
|
+
} finally {
|
|
1140
|
+
setLoading(false);
|
|
1141
|
+
}
|
|
1142
|
+
}, [
|
|
1143
|
+
context,
|
|
1144
|
+
plugin,
|
|
1145
|
+
isValid,
|
|
1146
|
+
id,
|
|
1147
|
+
source
|
|
1148
|
+
]);
|
|
1149
|
+
const { ref } = useInView({
|
|
1150
|
+
triggerOnce: true,
|
|
1151
|
+
onChange(inView) {
|
|
1152
|
+
if (!inView || !enabled) return;
|
|
1153
|
+
fetchInfo();
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
return {
|
|
1157
|
+
loading,
|
|
1158
|
+
isError,
|
|
1159
|
+
cardInfo,
|
|
1160
|
+
fullUrl,
|
|
1161
|
+
isValid,
|
|
1162
|
+
ref
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
//#endregion
|
|
1166
|
+
//#region src/LinkCardSkeleton.tsx
|
|
1167
|
+
function LinkCardSkeleton({ source, className }) {
|
|
1168
|
+
const typeClass = (source ? pluginMap.get(source) : void 0)?.typeClass;
|
|
1169
|
+
const typeStyleClass = typeClass ? typeCardModifier[typeClass] : "";
|
|
1170
|
+
const typeSemanticClass = typeClass ? semanticTypeClassNames[typeClass] : "";
|
|
1171
|
+
return /* @__PURE__ */ jsxs("span", {
|
|
1172
|
+
"data-hide-print": true,
|
|
1173
|
+
"data-source": source || void 0,
|
|
1174
|
+
className: [
|
|
1175
|
+
card,
|
|
1176
|
+
semanticClassNames.card,
|
|
1177
|
+
cardSkeleton,
|
|
1178
|
+
semanticClassNames.cardSkeleton,
|
|
1179
|
+
typeStyleClass,
|
|
1180
|
+
typeSemanticClass,
|
|
1181
|
+
className
|
|
1182
|
+
].filter(Boolean).join(" "),
|
|
1183
|
+
children: [/* @__PURE__ */ jsx("span", { className: `${image} ${semanticClassNames.image}` }), /* @__PURE__ */ jsxs("span", {
|
|
1184
|
+
className: `${content} ${semanticClassNames.content}`,
|
|
1185
|
+
children: [
|
|
1186
|
+
/* @__PURE__ */ jsx("span", {
|
|
1187
|
+
className: `${title} ${semanticClassNames.title}`,
|
|
1188
|
+
children: /* @__PURE__ */ jsx("span", { className: `${titleText} ${semanticClassNames.titleText}` })
|
|
1189
|
+
}),
|
|
1190
|
+
/* @__PURE__ */ jsx("span", { className: `${desc} ${semanticClassNames.desc}` }),
|
|
1191
|
+
/* @__PURE__ */ jsx("span", { className: `${desc} ${semanticClassNames.desc} ${desc2} ${semanticClassNames.desc2}` })
|
|
1192
|
+
]
|
|
1193
|
+
})]
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
//#endregion
|
|
1197
|
+
//#region src/LinkCardRenderer.tsx
|
|
1198
|
+
function FallbackIcon({ favicon }) {
|
|
1199
|
+
const [faviconFailed, setFaviconFailed] = useState(false);
|
|
1200
|
+
return /* @__PURE__ */ jsx("span", {
|
|
1201
|
+
className: `${icon} ${semanticClassNames.icon}`,
|
|
1202
|
+
children: favicon && !faviconFailed ? /* @__PURE__ */ jsx("img", {
|
|
1203
|
+
alt: "",
|
|
1204
|
+
src: favicon,
|
|
1205
|
+
onError: () => setFaviconFailed(true)
|
|
1206
|
+
}) : /* @__PURE__ */ jsx(Globe, { "aria-hidden": "true" })
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
function mapSemanticClasses(classNames) {
|
|
1210
|
+
if (!classNames) return "";
|
|
1211
|
+
return classNames.split(/\s+/).filter(Boolean).map((cls) => semanticClassToStyle[cls] ? `${semanticClassToStyle[cls]} ${cls}` : cls).join(" ");
|
|
1212
|
+
}
|
|
1213
|
+
var LinkCardRenderer = (props) => {
|
|
1214
|
+
const { url, title: title$1, description, favicon, image: image$1, source: explicitSource, id: explicitId, className, plugins: extraPlugins, fetchContext: fetchContextProp } = props;
|
|
1215
|
+
const contextValue = useLinkCardFetchContext();
|
|
1216
|
+
const fetchContext = fetchContextProp ?? contextValue;
|
|
1217
|
+
const mergedPlugins = useMemo(() => {
|
|
1218
|
+
if (!extraPlugins || extraPlugins.length === 0) return plugins;
|
|
1219
|
+
const map = new Map(plugins.map((p) => [p.name, p]));
|
|
1220
|
+
for (const plugin of extraPlugins) map.set(plugin.name, plugin);
|
|
1221
|
+
return [...map.values()].sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
1222
|
+
}, [extraPlugins]);
|
|
1223
|
+
const pluginMap = useMemo(() => new Map(mergedPlugins.map((plugin) => [plugin.name, plugin])), [mergedPlugins]);
|
|
1224
|
+
const urlMatch = useUrlMatcher(!explicitSource || !explicitId ? url : void 0, mergedPlugins);
|
|
1225
|
+
const source = explicitSource || urlMatch?.plugin.name;
|
|
1226
|
+
const id = explicitId || urlMatch?.match.id;
|
|
1227
|
+
const matchedFullUrl = urlMatch?.match.fullUrl;
|
|
1228
|
+
const useDynamicFetch = !!source && !!id;
|
|
1229
|
+
const selectedPlugin = source ? pluginMap.get(source) : void 0;
|
|
1230
|
+
const { loading, isError, cardInfo, fullUrl, isValid, ref } = useCardFetcher({
|
|
1231
|
+
source,
|
|
1232
|
+
plugin: selectedPlugin,
|
|
1233
|
+
id: id || "",
|
|
1234
|
+
fallbackUrl: matchedFullUrl || url,
|
|
1235
|
+
enabled: useDynamicFetch,
|
|
1236
|
+
context: fetchContext
|
|
1237
|
+
});
|
|
1238
|
+
const typeClass = selectedPlugin?.typeClass;
|
|
1239
|
+
const typeStyleClass = typeClass ? typeCardModifier[typeClass] : "";
|
|
1240
|
+
const typeSemanticClass = typeClass ? semanticTypeClassNames[typeClass] : "";
|
|
1241
|
+
const isErrorState = useDynamicFetch && isError;
|
|
1242
|
+
const finalTitle = cardInfo?.title || title$1 || (isErrorState ? "" : url);
|
|
1243
|
+
const finalDesc = cardInfo?.desc || description;
|
|
1244
|
+
const finalImage = cardInfo?.image || image$1;
|
|
1245
|
+
const finalColor = cardInfo?.color;
|
|
1246
|
+
const classNames = cardInfo?.classNames || {};
|
|
1247
|
+
const mappedCardRootClass = mapSemanticClasses(classNames.cardRoot);
|
|
1248
|
+
const mappedImageClass = mapSemanticClasses(classNames.image);
|
|
1249
|
+
const [shortDesc, setShortDesc] = useState(false);
|
|
1250
|
+
const descRef = useRef(null);
|
|
1251
|
+
useEffect(() => {
|
|
1252
|
+
const el = descRef.current;
|
|
1253
|
+
if (!el || !finalDesc) {
|
|
1254
|
+
setShortDesc(false);
|
|
1255
|
+
return;
|
|
1256
|
+
}
|
|
1257
|
+
const style = getComputedStyle(el);
|
|
1258
|
+
const maxTwoLines = (Number.parseFloat(style.lineHeight) || 1.5 * 14) * 2;
|
|
1259
|
+
setShortDesc(el.scrollHeight <= maxTwoLines + 1);
|
|
1260
|
+
}, [finalDesc, finalTitle]);
|
|
1261
|
+
if (useDynamicFetch && !isValid) return null;
|
|
1262
|
+
if (useDynamicFetch && loading) return /* @__PURE__ */ jsx("a", {
|
|
1263
|
+
"data-hide-print": true,
|
|
1264
|
+
href: fullUrl,
|
|
1265
|
+
ref,
|
|
1266
|
+
rel: "noopener noreferrer",
|
|
1267
|
+
target: "_blank",
|
|
1268
|
+
children: /* @__PURE__ */ jsx(LinkCardSkeleton, { source })
|
|
1269
|
+
});
|
|
1270
|
+
const hasImage = !!finalImage;
|
|
1271
|
+
const showImagePlaceholder = isErrorState && !hasImage;
|
|
1272
|
+
const shouldCenterContent = !finalDesc || shortDesc;
|
|
1273
|
+
return /* @__PURE__ */ jsxs("a", {
|
|
1274
|
+
"data-hide-print": true,
|
|
1275
|
+
"data-source": source || void 0,
|
|
1276
|
+
href: useDynamicFetch ? fullUrl : url,
|
|
1277
|
+
ref: useDynamicFetch ? ref : void 0,
|
|
1278
|
+
rel: "noopener noreferrer",
|
|
1279
|
+
target: "_blank",
|
|
1280
|
+
className: [
|
|
1281
|
+
card,
|
|
1282
|
+
semanticClassNames.card,
|
|
1283
|
+
typeStyleClass,
|
|
1284
|
+
typeSemanticClass,
|
|
1285
|
+
shouldCenterContent && "_13weebv1",
|
|
1286
|
+
shouldCenterContent && semanticClassNames.cardShortDesc,
|
|
1287
|
+
useDynamicFetch && (loading || isError) && "_13weebvg",
|
|
1288
|
+
useDynamicFetch && (loading || isError) && semanticClassNames.cardSkeleton,
|
|
1289
|
+
useDynamicFetch && isError && "_13weebvi",
|
|
1290
|
+
useDynamicFetch && isError && semanticClassNames.cardError,
|
|
1291
|
+
"not-prose",
|
|
1292
|
+
className,
|
|
1293
|
+
mappedCardRootClass
|
|
1294
|
+
].filter(Boolean).join(" "),
|
|
1295
|
+
style: { borderColor: finalColor ? `${finalColor}30` : void 0 },
|
|
1296
|
+
children: [
|
|
1297
|
+
finalColor && /* @__PURE__ */ jsx("div", {
|
|
1298
|
+
className: `_13weebv2 ${semanticClassNames.bg}`,
|
|
1299
|
+
style: {
|
|
1300
|
+
backgroundColor: finalColor,
|
|
1301
|
+
opacity: .04
|
|
1302
|
+
}
|
|
1303
|
+
}),
|
|
1304
|
+
hasImage || showImagePlaceholder ? /* @__PURE__ */ jsx("span", {
|
|
1305
|
+
"data-image": finalImage || "",
|
|
1306
|
+
className: [
|
|
1307
|
+
image,
|
|
1308
|
+
semanticClassNames.image,
|
|
1309
|
+
mappedImageClass
|
|
1310
|
+
].filter(Boolean).join(" "),
|
|
1311
|
+
style: { backgroundImage: finalImage ? `url(${finalImage})` : void 0 }
|
|
1312
|
+
}) : /* @__PURE__ */ jsx(FallbackIcon, { favicon }),
|
|
1313
|
+
/* @__PURE__ */ jsxs("span", {
|
|
1314
|
+
className: `${content} ${semanticClassNames.content}`,
|
|
1315
|
+
children: [/* @__PURE__ */ jsx("span", {
|
|
1316
|
+
className: `${title} ${semanticClassNames.title}`,
|
|
1317
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
1318
|
+
className: `${titleText} ${semanticClassNames.titleText}`,
|
|
1319
|
+
children: finalTitle
|
|
1320
|
+
})
|
|
1321
|
+
}), finalDesc && /* @__PURE__ */ jsx("span", {
|
|
1322
|
+
className: `_13weebv9 ${semanticClassNames.desc}`,
|
|
1323
|
+
ref: descRef,
|
|
1324
|
+
children: finalDesc
|
|
1325
|
+
})]
|
|
1326
|
+
})
|
|
1327
|
+
]
|
|
1328
|
+
});
|
|
1329
|
+
};
|
|
1330
|
+
//#endregion
|
|
1331
|
+
export { fetchJsonWithContext as A, githubIssuePlugin as C, LanguageToColorMap as D, leetcodePlugin as E, arxivPlugin as M, camelcaseKeys as O, githubPrPlugin as S, githubCommitPlugin as T, tmdbPlugin as _, editInput as a, bangumiPlugin as b, editUrlRow as c, matchUrl as d, useUrlMatcher as f, createMxSpacePlugin as g, plugins as h, useLinkCardFetchContext as i, generateColor as j, fetchGitHubApi as k, editWrapper as l, pluginMap as m, LinkCardSkeleton as n, editLinkIcon as o, getPluginByName as p, LinkCardFetchProvider as r, editPanel as s, LinkCardRenderer as t, semanticClassNames as u, qqMusicPlugin as v, githubDiscussionPlugin as w, githubRepoPlugin as x, neteaseMusicPlugin as y };
|