-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
933 lines (818 loc) · 67.9 KB
/
Copy pathindex.html
File metadata and controls
933 lines (818 loc) · 67.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
<!DOCTYPE html><html lang="zh-CN" data-theme="light"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0,viewport-fit=cover"><title>CeRu - 我的个人博客</title><meta name="author" content="CeRu"><meta name="copyright" content="CeRu"><meta name="format-detection" content="telephone=no"><meta name="theme-color" content="#ffffff"><meta name="description" content="记录学习 Hexo 和编程的日常">
<meta property="og:type" content="website">
<meta property="og:title" content="CeRu">
<meta property="og:url" content="https://ceru-007.github.io/index.html">
<meta property="og:site_name" content="CeRu">
<meta property="og:description" content="记录学习 Hexo 和编程的日常">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://ceru-007.github.io/img/butterfly-icon.jpg">
<meta property="article:author" content="CeRu">
<meta property="article:tag" content="Docker,应用,编程">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://ceru-007.github.io/img/butterfly-icon.jpg"><script type="application/ld+json">{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "CeRu",
"alternateName": [
"我的个人博客",
"ceru-007.github.io"
],
"url": "https://ceru-007.github.io/"
}</script><link rel="shortcut icon" href="/img/favicon.ico"><link rel="canonical" href="https://ceru-007.github.io/index.html"><link rel="preconnect" href="//cdn.jsdelivr.net"/><link rel="stylesheet" href="/css/index.css?v=5.5.5"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@7.2.0/css/all.min.css"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/node-snackbar@0.1.16/dist/snackbar.min.css" media="print" onload="this.media='all'"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1.14/dist/fancybox/fancybox.min.css" media="print" onload="this.media='all'"><script>
(() => {
const saveToLocal = {
set: (key, value, ttl) => {
if (!ttl) return
const expiry = Date.now() + ttl * 86400000
localStorage.setItem(key, JSON.stringify({ value, expiry }))
},
get: key => {
const itemStr = localStorage.getItem(key)
if (!itemStr) return undefined
const { value, expiry } = JSON.parse(itemStr)
if (Date.now() > expiry) {
localStorage.removeItem(key)
return undefined
}
return value
}
}
window.btf = {
saveToLocal,
getScript: (url, attr = {}) => new Promise((resolve, reject) => {
const script = document.createElement('script')
script.src = url
script.async = true
Object.entries(attr).forEach(([key, val]) => script.setAttribute(key, val))
script.onload = script.onreadystatechange = () => {
if (!script.readyState || /loaded|complete/.test(script.readyState)) resolve()
}
script.onerror = reject
document.head.appendChild(script)
}),
getCSS: (url, id) => new Promise((resolve, reject) => {
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = url
if (id) link.id = id
link.onload = link.onreadystatechange = () => {
if (!link.readyState || /loaded|complete/.test(link.readyState)) resolve()
}
link.onerror = reject
document.head.appendChild(link)
}),
addGlobalFn: (key, fn, name = false, parent = window) => {
if (!true && key.startsWith('pjax')) return
const globalFn = parent.globalFn || {}
globalFn[key] = globalFn[key] || {}
globalFn[key][name || Object.keys(globalFn[key]).length] = fn
parent.globalFn = globalFn
}
}
const activateDarkMode = () => {
document.documentElement.setAttribute('data-theme', 'dark')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#0d0d0d')
}
}
const activateLightMode = () => {
document.documentElement.setAttribute('data-theme', 'light')
if (document.querySelector('meta[name="theme-color"]') !== null) {
document.querySelector('meta[name="theme-color"]').setAttribute('content', '#ffffff')
}
}
btf.activateDarkMode = activateDarkMode
btf.activateLightMode = activateLightMode
const theme = saveToLocal.get('theme')
theme === 'dark' ? activateDarkMode() : theme === 'light' ? activateLightMode() : null
const asideStatus = saveToLocal.get('aside-status')
if (asideStatus !== undefined) {
document.documentElement.classList.toggle('hide-aside', asideStatus === 'hide')
}
const detectApple = () => {
if (/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)) {
document.documentElement.classList.add('apple')
}
}
detectApple()
})()
</script><script>const GLOBAL_CONFIG = {
root: '/',
algolia: undefined,
localSearch: {"path":"/search.json","preload":true,"top_n_per_article":1,"unescape":false,"pagination":{"enable":true,"hitsPerPage":8},"languages":{"hits_empty":"未找到符合您查询的内容:${query}","hits_stats":"共找到 ${hits} 篇文章"}},
translate: {"defaultEncoding":2,"translateDelay":0,"msgToTraditionalChinese":"繁","msgToSimplifiedChinese":"簡"},
highlight: {"plugin":"highlight.js","highlightCopy":true,"highlightLang":true,"highlightHeightLimit":false,"highlightFullpage":false,"highlightMacStyle":true},
copy: {
success: '复制成功',
error: '复制失败',
noSupport: '浏览器不支持'
},
relativeDate: {
homepage: false,
post: false
},
runtime: '天',
dateSuffix: {
just: '刚刚',
min: '分钟前',
hour: '小时前',
day: '天前',
month: '个月前'
},
copyright: {"limitCount":150,"languages":{"author":"作者: CeRu","link":"链接: ","source":"来源: CeRu","info":"著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。"}},
lightbox: 'fancybox',
Snackbar: {"chs_to_cht":"已切换为繁体中文","cht_to_chs":"已切换为简体中文","day_to_night":"已切换为深色模式","night_to_day":"已切换为浅色模式","bgLight":"#49b1f5","bgDark":"#1f1f1f","position":"bottom-right"},
infinitegrid: {
js: 'https://cdn.jsdelivr.net/npm/@egjs/infinitegrid@4.13.0/dist/infinitegrid.min.js',
buttonText: '加载更多'
},
isPhotoFigcaption: false,
islazyloadPlugin: true,
isAnchor: false,
percent: {
toc: true,
rightside: true,
},
autoDarkmode: false
}</script><script id="config-diff">var GLOBAL_CONFIG_SITE = {
title: 'CeRu',
isHighlightShrink: false,
isToc: false,
pageType: 'home'
}</script><style>
.social-icon .fa-vimeo {
display: inline-block;
width: 1.3em;
height: 1.3em;
background-image: url('/img/TMDB.svg');
background-size: contain;
background-repeat: no-repeat;
background-position: center;
vertical-align: -0.125em;
color: transparent !important;
}
.social-icon .fa-vimeo:before {
display: none;
}
/* 侧边栏社交图标黑白样式 */
.card-info-social-icons .social-icon .fa-github,
.card-info-social-icons .social-icon .fa-envelope,
.card-info-social-icons .social-icon .fa-rss {
color: var(--font-color) !important;
transition: color 0.3s ease;
}
/* 暗色模式下的图标颜色 */
[data-theme='dark'] .card-info-social-icons .social-icon .fa-github,
[data-theme='dark'] .card-info-social-icons .social-icon .fa-envelope,
[data-theme='dark'] .card-info-social-icons .social-icon .fa-rss {
color: #ffffff !important;
}
</style>
<meta name="generator" content="Hexo 8.1.2"><link rel="alternate" href="/atom.xml" title="CeRu" type="application/atom+xml">
</head><body><div id="loading-box"><div class="loading-left-bg"></div><div class="loading-right-bg"></div><div class="spinner-box"><div class="configure-border-1"><div class="configure-core"></div></div><div class="configure-border-2"><div class="configure-core"></div></div><div class="loading-word">加载中...</div></div></div><script>(()=>{
const $loadingBox = document.getElementById('loading-box')
const $body = document.body
const preloader = {
endLoading: () => {
if ($loadingBox.classList.contains('loaded')) return
$body.style.overflow = ''
$loadingBox.classList.add('loaded')
},
initLoading: () => {
$body.style.overflow = 'hidden'
$loadingBox.classList.remove('loaded')
}
}
preloader.initLoading()
if (document.readyState === 'complete') {
preloader.endLoading()
} else {
window.addEventListener('load', preloader.endLoading)
document.addEventListener('DOMContentLoaded', preloader.endLoading)
// Add timeout protection: force end after 7 seconds
setTimeout(preloader.endLoading, 7000)
}
if (true) {
btf.addGlobalFn('pjaxSend', preloader.initLoading, 'preloader_init')
btf.addGlobalFn('pjaxComplete', preloader.endLoading, 'preloader_end')
}
})()</script><div class="bg-animation" id="web_bg" style="background: linear-gradient(135deg,;"></div><div id="sidebar"><div id="menu-mask"></div><div id="sidebar-menus"><div class="avatar-img text-center"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/butterfly-icon.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="site-data text-center"><a href="/archives/"><div class="headline">文章</div><div class="length-num">7</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">12</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">1</div></a></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fas fa-compass"></i><span> 导航</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></li><li><a class="site-page child" href="/shuoshuo/"><i class="fa-fw fas fa-comment-dots"></i><span> 说说</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa fa-heartbeat"></i><span> 清单</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/message/"><i class="fa-fw fas fa-comments"></i><span> 留言</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div></div></div><div class="page" id="body-wrap"><header class="full_page fixed" id="page-header" style="background-image: url(/img/2.jpg);"><nav id="nav"><span id="blog-info"><a class="nav-site-title" href="/"><span class="site-name">CeRu</span></a></span><div id="menus"><div id="search-button"><span class="site-page social-icon search"><i class="fas fa-search fa-fw"></i><span> 搜索</span></span></div><div class="menus_items"><div class="menus_item"><a class="site-page" href="/"><i class="fa-fw fas fa-home"></i><span> 首页</span></a></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fas fa-compass"></i><span> 导航</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/archives/"><i class="fa-fw fas fa-archive"></i><span> 时间轴</span></a></li><li><a class="site-page child" href="/tags/"><i class="fa-fw fas fa-tags"></i><span> 标签</span></a></li><li><a class="site-page child" href="/categories/"><i class="fa-fw fas fa-folder-open"></i><span> 分类</span></a></li><li><a class="site-page child" href="/shuoshuo/"><i class="fa-fw fas fa-comment-dots"></i><span> 说说</span></a></li></ul></div><div class="menus_item"><span class="site-page group"><i class="fa-fw fa fa-heartbeat"></i><span> 清单</span><i class="fas fa-chevron-down"></i></span><ul class="menus_item_child"><li><a class="site-page child" href="/music/"><i class="fa-fw fas fa-music"></i><span> 音乐</span></a></li><li><a class="site-page child" href="/Gallery/"><i class="fa-fw fas fa-images"></i><span> 照片</span></a></li><li><a class="site-page child" href="/movies/"><i class="fa-fw fas fa-video"></i><span> 电影</span></a></li></ul></div><div class="menus_item"><a class="site-page" href="/message/"><i class="fa-fw fas fa-comments"></i><span> 留言</span></a></div><div class="menus_item"><a class="site-page" href="/link/"><i class="fa-fw fas fa-link"></i><span> 友链</span></a></div><div class="menus_item"><a class="site-page" href="/about/"><i class="fa-fw fas fa-heart"></i><span> 关于</span></a></div></div><div id="toggle-menu"><span class="site-page"><i class="fas fa-bars fa-fw"></i></span></div></div></nav><div id="site-info"><h1 id="site-title">CeRu</h1><div id="site-subtitle"><span id="subtitle"></span></div><div id="site_social_icons"><a class="social-icon" href="https://github.com/ceru-007" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:your-email@example.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a><a class="social-icon" href="https://www.themoviedb.org/u/CeRu" target="_blank" title="TMDB"><i class="fab fa-vimeo" style="color: #01d277;"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="fas fa-rss" style="color: #f26522;"></i></a></div></div><div id="scroll-down"><i class="fas fa-angle-down scroll-down-effects"></i></div></header><main class="layout" id="content-inner"><div class="recent-posts nc" id="recent-posts"><div class="recent-post-items"><div class="recent-post-item"><div class="post_cover left"><a href="/2026/07/05/%EF%BC%88%E4%B8%89%EF%BC%89TMDB%E4%BA%BA%E7%89%A9%E7%BB%B4%E6%8A%A4%E4%B8%8E%E7%BF%BB%E8%AF%91%E8%A7%84%E8%8C%83/" title="(三)TMDB人物维护与翻译规范"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/4.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(三)TMDB人物维护与翻译规范"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/07/05/%EF%BC%88%E4%B8%89%EF%BC%89TMDB%E4%BA%BA%E7%89%A9%E7%BB%B4%E6%8A%A4%E4%B8%8E%E7%BF%BB%E8%AF%91%E8%A7%84%E8%8C%83/" title="(三)TMDB人物维护与翻译规范">(三)TMDB人物维护与翻译规范</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-07-05T14:35:00.000Z" title="发表于 2026-07-05 22:35:00 22:35:00">2026-07-05 22:35:00</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">前两篇介绍了电影和电视剧的数据编辑,这一篇聚焦人物信息维护和翻译相关的官方规范。 人物信息编辑人物条目无法直接创建,只能在编辑电影/电视剧的演职员表时,点击 Add a New Cast/Crew Member 创建。 姓名(Name) 填写该人物的主要艺名 如果艺名发生过线性变更(如改名),使用当前使用的名字 如果同时使用多个名字,选择最常用、官方网站/社交账号使用的名字 已故人物使用最广为人知的名字 姓名不需要唯一,不要添加罗马数字后缀(如 John Doe (IV)) 译名(Translated Name)中文人物的译名示例: 12中文名 → 王一博 → 姓 [王] + 名 [一博] → Wang Yibo(东方顺序)中文名 → 甄子丹 → 姓 [甄] 英文名 [Donnie] → Donnie Yen(西方顺序) 东亚人名规则: 语言 顺序 示例 中文(大陆/韩国) 东方顺序(姓在前) Wang Yibo、Song Kang-ho 中文(有英文名) 西方顺序(名在前) Donnie Yen 日文 西方顺序(名...</div></div></div><div class="recent-post-item"><div class="post_cover right"><a href="/2026/07/05/%EF%BC%88%E4%BA%8C%EF%BC%89TMDB%E5%BD%B1%E8%A7%86%E6%95%B0%E6%8D%AE%E7%BC%96%E8%BE%91%E5%AE%9E%E6%88%98/" title="(二)TMDB影视数据编辑实战"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/3.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(二)TMDB影视数据编辑实战"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/07/05/%EF%BC%88%E4%BA%8C%EF%BC%89TMDB%E5%BD%B1%E8%A7%86%E6%95%B0%E6%8D%AE%E7%BC%96%E8%BE%91%E5%AE%9E%E6%88%98/" title="(二)TMDB影视数据编辑实战">(二)TMDB影视数据编辑实战</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-07-05T14:34:00.000Z" title="发表于 2026-07-05 22:34:00 22:34:00">2026-07-05 22:34:00</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">注册好账号后就可以直接上手编辑了,这一篇按照 TMDB 官方贡献指南(Contribution Bible)来介绍具体的操作规范。 找到编辑入口在任意电影、电视剧、人物的页面,点击底部的 编辑 按钮进入编辑界面。 编辑界面按模块划分,每个模块都可以独立修改和保存。 电影核心字段编辑规范原标题(Original Title) 必须使用原始语言的原生文字,不要罗马化(例如写 Левиафан 而非 Leviathan) 不要添加年份、国家等额外信息(不要写成 Coco (2017)) 大写规则遵循语言惯例,英文标题遵循 Wikipedia/IMDb 的大写规则 罗马化的原标题应填入 译名(Alternative Titles) 字段 译名(Translated Title) 使用首次官方发行的译名 如果译名与原名相同,留空并锁定(例如英文电影的英译名字段必须留空) 中文分四个区域:大陆 (zh-CN)、香港 (zh-HK)、台湾 (zh-TW)、新加坡 (zh-SG),各填各的译名,不要混用 没有官方译名的留空,不要添加非官方翻译 简介(Overview)TMDB 对简...</div></div></div><div class="recent-post-item"><div class="post_cover left"><a href="/2026/07/05/%EF%BC%88%E4%B8%80%EF%BC%89%E8%AE%A4%E8%AF%86TMDB%E4%B8%8E%E8%B4%A1%E7%8C%AE%E8%80%85%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/" title="(一)认识TMDB与贡献者入门指南"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/8.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(一)认识TMDB与贡献者入门指南"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/07/05/%EF%BC%88%E4%B8%80%EF%BC%89%E8%AE%A4%E8%AF%86TMDB%E4%B8%8E%E8%B4%A1%E7%8C%AE%E8%80%85%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/" title="(一)认识TMDB与贡献者入门指南">(一)认识TMDB与贡献者入门指南</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-07-05T14:33:50.000Z" title="发表于 2026-07-05 22:33:50 22:33:50">2026-07-05 22:33:50</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">什么是 TMDB?TMDB(The Movie Database,全称 themoviedb.org)是一个由社区驱动的开放影视数据库。它包含了电影、电视剧、演员、幕后人员等全方位的元数据信息。 简单来说,TMDB 就是影视界的维基百科——任何人都可以注册、查看数据,符合条件的贡献者可以直接编辑和维护数据。 TMDB 的应用场景你大概率已经在使用 TMDB 的数据了: Jellyfin / Plex / Emby 等媒体服务器通过 TMDB 获取影视海报、简介、演员信息 Kodi / Infuse 等播放器通过 TMDB 刮削媒体库 各式各样的影评 App、公众号、机器人都依赖 TMDB 的 API 这也是为什么维护 TMDB 数据质量如此重要——它影响着无数的下游服务。 为什么值得参与维护? 不只是利他,对自己也有好处: 你媒体库的海报和简介会更准确 冷门电影不再显示”找不到数据” 可以给自己喜欢的作品添加中文翻译 在 TMDB 贡献者榜单中留下你的名字 注册账号首先,访问 TMDB 官网,点击右上角的”加入 TMDB”。 填写用户名、邮...</div></div></div><div class="recent-post-item"><div class="post_cover right"><a href="/2026/01/02/%EF%BC%88%E4%BA%8C%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/" title="(二)Hexo博客主题配置教程"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/10.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(二)Hexo博客主题配置教程"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/01/02/%EF%BC%88%E4%BA%8C%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/" title="(二)Hexo博客主题配置教程">(二)Hexo博客主题配置教程</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-01-02T13:12:45.000Z" title="发表于 2026-01-02 21:12:45 21:12:45">2026-01-02 21:12:45</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">前言Hexo 默认的主题比较简单,不够美观。Butterfly 是一个功能强大、设计精美的 Hexo 主题,拥有丰富的功能和良好的用户体验。 本教程将介绍如何安装和配置 Butterfly 主题。 安装 Butterfly 主题1. 下载主题在博客根目录下执行: 1git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/butterfly 2. 安装依赖Butterfly 主题需要安装渲染器插件: 1npm install hexo-renderer-pug hexo-renderer-stylus --save 3. 启用主题修改博客根目录下的 _config.yml 文件: 1theme: butterfly 4. 复制主题配置文件在博客根目录下执行: 1cp themes/butterfly/_config.yml _config.butterfly.yml 这样可以在不修改主题源码的情况下自定义配置。 基础配置1. 网站信息编辑 _config.yml: 12...</div></div></div><div class="recent-post-item"><div class="post_cover left"><a href="/2026/01/02/%EF%BC%88%E4%B8%80%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="(一)Hexo博客搭建教程"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/1.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(一)Hexo博客搭建教程"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/01/02/%EF%BC%88%E4%B8%80%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="(一)Hexo博客搭建教程">(一)Hexo博客搭建教程</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-01-02T13:12:41.000Z" title="发表于 2026-01-02 21:12:41 21:12:41">2026-01-02 21:12:41</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">前言Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。 本教程将带你从零开始搭建一个 Hexo 博客。 准备工作1. 安装 Node.jsHexo 基于 Node.js,所以首先需要安装 Node.js。 Windows 用户: 访问 Node.js 官网 下载 LTS 版本(长期支持版) 运行安装程序,一路”下一步”即可 验证安装:打开命令行(CMD 或 PowerShell),输入: 12node -vnpm -v 如果显示版本号,说明安装成功。 2. 安装 GitHexo 需要使用 Git 进行版本控制和部署。 Windows 用户: 访问 Git 官网 下载 Windows 版本 运行安装程序,使用默认配置即可 验证安装: 1git --version 安装 Hexo1. 全局安装 Hexo在命令行中执行: 1npm install -g hexo-cli 2. 初始化博客选择一个目录,执行以下命令: 123hexo init myblogcd myblognpm ...</div></div></div><div class="recent-post-item"><div class="post_cover right"><a href="/2026/01/02/%EF%BC%88%E4%B8%89%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2GitHub-Actions%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/" title="(三)Hexo博客GitHub Actions自动部署教程"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/3.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(三)Hexo博客GitHub Actions自动部署教程"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/01/02/%EF%BC%88%E4%B8%89%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2GitHub-Actions%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2%E6%95%99%E7%A8%8B/" title="(三)Hexo博客GitHub Actions自动部署教程">(三)Hexo博客GitHub Actions自动部署教程</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-01-02T12:33:58.000Z" title="发表于 2026-01-02 20:33:58 20:33:58">2026-01-02 20:33:58</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">前言之前部署 Hexo 博客都是本地构建静态文件,然后手动推送到 GitHub Pages。这种方式有几个问题: 源码只在本地,存在丢失风险 换电脑需要重新配置环境 每次更新都需要手动执行部署命令 本文介绍如何使用 GitHub Actions 实现自动部署,解决这些问题。 准备工作1. 两个仓库我们将使用两个 GitHub 仓库: 源码仓库:存放 Hexo 源码(可以私有) Pages 仓库:存放生成的静态文件(必须公开) 例如: 源码:https://github.com/CeRu-007/hexo-cerublog Pages:https://github.com/CeRu-007/CeRu-007.github.io 2. 创建源码仓库在 GitHub 上创建新仓库,用于存放 Hexo 源码。 配置源码仓库1. 初始化 Git 并推送在博客根目录执行: 123456git initgit add .git commit -m "Initial commit: Hexo blog source code"git branch -M maing...</div></div></div><div class="recent-post-item"><div class="post_cover left"><a href="/2026/01/02/115bot%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="115bot搭建教程"><img class="post-bg" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/8.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="115bot搭建教程"></a></div><div class="recent-post-info"><a class="article-title" href="/2026/01/02/115bot%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="115bot搭建教程">115bot搭建教程</a><div class="article-meta-wrap"><span class="post-meta-date"><i class="far fa-calendar-alt"></i><span class="article-meta-label">发表于</span><time datetime="2026-01-02T02:30:00.000Z" title="发表于 2026-01-02 10:30:00 10:30:00">2026-01-02 10:30:00</time></span><span class="article-meta"><span class="article-meta-separator">|</span><i class="fas fa-inbox"></i><a class="article-meta__categories" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/">技术教程</a></span></div><div class="content">115-Bot搭建部署教程 原文链接: https://xix.lol/archives/1717259753539本文为搬运文章,并在原文基础上根据自己折腾时进行了部分内容优化调整。 有时候挺羡慕PikPak得官方Bot,可以绑定自己得TG账号和PP账号使用,因为转入了115大家庭,所以我找了一下,发现有一个115Bot得项目,基本功能如下: 批量解压 视频转存115( 新版本镜像已经增加了文件,图片等类型的转存,推荐搭配浏览器插件一起使用) 创建strm文件 订阅女优每日更新 许愿树自动许愿、助愿、采纳 添加磁力链、ed2k单条或多条到115,支持转发消息到机器人自动提取消息中的磁力链 离线任务监控:任务下载完成后移动到指定文件夹,删除指定广告文件,去除指定字符串重命名 因为个人需求不一样,本博文只演示部分功能,首先准备一下东西: 一台Ubuntu/Debian系统的服务器(最好是无限流量,硬盘比较大得,预留10G硬盘空间给bot使用,因为转存tg视频,是需要通过你得服务器下载再上传) 重要提示:服务器选择建议 最好是使用国外服务器,否则无法正常使用。如果是...</div></div></div></div></div><div class="aside-content" id="aside-content"><div class="card-widget card-info text-center"><div class="avatar-img"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/butterfly-icon.jpg" onerror="this.onerror=null;this.src='/img/friend_404.gif'" alt="avatar"/></div><div class="author-info-name">CeRu</div><div class="author-info-description">喜欢折腾新技术、新事物的普通人</div><div class="site-data"><a href="/archives/"><div class="headline">文章</div><div class="length-num">7</div></a><a href="/tags/"><div class="headline">标签</div><div class="length-num">12</div></a><a href="/categories/"><div class="headline">分类</div><div class="length-num">1</div></a></div><a id="card-info-btn" target="_blank" rel="noopener" href="https://github.com/ceru-007"><i class="fab fa-github"></i><span>Follow Me</span></a><div class="card-info-social-icons"><a class="social-icon" href="https://github.com/ceru-007" target="_blank" title="Github"><i class="fab fa-github" style="color: #24292e;"></i></a><a class="social-icon" href="mailto:your-email@example.com" target="_blank" title="Email"><i class="fas fa-envelope" style="color: #4a7dbe;"></i></a><a class="social-icon" href="https://www.themoviedb.org/u/CeRu" target="_blank" title="TMDB"><i class="fab fa-vimeo" style="color: #01d277;"></i></a><a class="social-icon" href="/atom.xml" target="_blank" title="RSS"><i class="fas fa-rss" style="color: #f26522;"></i></a></div></div><div class="card-widget card-announcement"><div class="item-headline"><i class="fas fa-bullhorn fa-shake"></i><span>公告</span></div><div class="announcement_content">欢迎来到我的个人博客!希望你能喜欢这里的内容,并找到有趣的东西。如果有任何建议或想法,欢迎随时与我联系。</div></div><div class="sticky_layout"><div class="card-widget card-recent-post"><div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span></div><div class="aside-list"><div class="aside-list-item"><a class="thumbnail" href="/2026/07/05/%EF%BC%88%E4%B8%89%EF%BC%89TMDB%E4%BA%BA%E7%89%A9%E7%BB%B4%E6%8A%A4%E4%B8%8E%E7%BF%BB%E8%AF%91%E8%A7%84%E8%8C%83/" title="(三)TMDB人物维护与翻译规范"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/4.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(三)TMDB人物维护与翻译规范"/></a><div class="content"><a class="title" href="/2026/07/05/%EF%BC%88%E4%B8%89%EF%BC%89TMDB%E4%BA%BA%E7%89%A9%E7%BB%B4%E6%8A%A4%E4%B8%8E%E7%BF%BB%E8%AF%91%E8%A7%84%E8%8C%83/" title="(三)TMDB人物维护与翻译规范">(三)TMDB人物维护与翻译规范</a><time datetime="2026-07-05T14:35:00.000Z" title="发表于 2026-07-05 22:35:00 22:35:00">2026-07-05 22:35:00</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/07/05/%EF%BC%88%E4%BA%8C%EF%BC%89TMDB%E5%BD%B1%E8%A7%86%E6%95%B0%E6%8D%AE%E7%BC%96%E8%BE%91%E5%AE%9E%E6%88%98/" title="(二)TMDB影视数据编辑实战"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/3.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(二)TMDB影视数据编辑实战"/></a><div class="content"><a class="title" href="/2026/07/05/%EF%BC%88%E4%BA%8C%EF%BC%89TMDB%E5%BD%B1%E8%A7%86%E6%95%B0%E6%8D%AE%E7%BC%96%E8%BE%91%E5%AE%9E%E6%88%98/" title="(二)TMDB影视数据编辑实战">(二)TMDB影视数据编辑实战</a><time datetime="2026-07-05T14:34:00.000Z" title="发表于 2026-07-05 22:34:00 22:34:00">2026-07-05 22:34:00</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/07/05/%EF%BC%88%E4%B8%80%EF%BC%89%E8%AE%A4%E8%AF%86TMDB%E4%B8%8E%E8%B4%A1%E7%8C%AE%E8%80%85%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/" title="(一)认识TMDB与贡献者入门指南"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/8.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(一)认识TMDB与贡献者入门指南"/></a><div class="content"><a class="title" href="/2026/07/05/%EF%BC%88%E4%B8%80%EF%BC%89%E8%AE%A4%E8%AF%86TMDB%E4%B8%8E%E8%B4%A1%E7%8C%AE%E8%80%85%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97/" title="(一)认识TMDB与贡献者入门指南">(一)认识TMDB与贡献者入门指南</a><time datetime="2026-07-05T14:33:50.000Z" title="发表于 2026-07-05 22:33:50 22:33:50">2026-07-05 22:33:50</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/01/02/%EF%BC%88%E4%BA%8C%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/" title="(二)Hexo博客主题配置教程"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/10.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(二)Hexo博客主题配置教程"/></a><div class="content"><a class="title" href="/2026/01/02/%EF%BC%88%E4%BA%8C%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B/" title="(二)Hexo博客主题配置教程">(二)Hexo博客主题配置教程</a><time datetime="2026-01-02T13:12:45.000Z" title="发表于 2026-01-02 21:12:45 21:12:45">2026-01-02 21:12:45</time></div></div><div class="aside-list-item"><a class="thumbnail" href="/2026/01/02/%EF%BC%88%E4%B8%80%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="(一)Hexo博客搭建教程"><img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-lazy-src="/img/1.jpg" onerror="this.onerror=null;this.src='/img/404.jpg'" alt="(一)Hexo博客搭建教程"/></a><div class="content"><a class="title" href="/2026/01/02/%EF%BC%88%E4%B8%80%EF%BC%89Hexo%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA%E6%95%99%E7%A8%8B/" title="(一)Hexo博客搭建教程">(一)Hexo博客搭建教程</a><time datetime="2026-01-02T13:12:41.000Z" title="发表于 2026-01-02 21:12:41 21:12:41">2026-01-02 21:12:41</time></div></div></div></div><div class="card-widget" id="card-newest-comments"><div class="item-headline"><i class="fas fa-comment-dots"></i><span>最新评论</span></div><div class="aside-list"><span>加载中...</span></div></div><div class="card-widget card-categories"><div class="item-headline">
<i class="fas fa-folder-open"></i>
<span>分类</span>
</div>
<ul class="card-category-list" id="aside-cat-list">
<li class="card-category-list-item "><a class="card-category-list-link" href="/categories/%E6%8A%80%E6%9C%AF%E6%95%99%E7%A8%8B/"><span class="card-category-list-name">技术教程</span><span class="card-category-list-count">7</span></a></li>
</ul></div><div class="card-widget card-tags"><div class="item-headline"><i class="fas fa-tags"></i><span>标签</span></div><div class="card-tag-cloud"><a href="/tags/%E8%87%AA%E5%8A%A8%E9%83%A8%E7%BD%B2/" style="font-size: 1.1em; color: #999">自动部署</a> <a href="/tags/115%E7%BD%91%E7%9B%98/" style="font-size: 1.1em; color: #999">115网盘</a> <a href="/tags/Telegram/" style="font-size: 1.1em; color: #999">Telegram</a> <a href="/tags/TMDB/" style="font-size: 1.3em; color: #99a1ac">TMDB</a> <a href="/tags/%E6%95%99%E7%A8%8B/" style="font-size: 1.5em; color: #99a9bf">教程</a> <a href="/tags/GitHub-Actions/" style="font-size: 1.1em; color: #999">GitHub Actions</a> <a href="/tags/Butterfly/" style="font-size: 1.1em; color: #999">Butterfly</a> <a href="/tags/Hexo/" style="font-size: 1.3em; color: #99a1ac">Hexo</a> <a href="/tags/%E5%8D%9A%E5%AE%A2%E6%90%AD%E5%BB%BA/" style="font-size: 1.1em; color: #999">博客搭建</a> <a href="/tags/%E5%88%AE%E5%89%8A/" style="font-size: 1.3em; color: #99a1ac">刮削</a> <a href="/tags/Docker/" style="font-size: 1.1em; color: #999">Docker</a> <a href="/tags/%E4%B8%BB%E9%A2%98%E9%85%8D%E7%BD%AE/" style="font-size: 1.1em; color: #999">主题配置</a></div></div><div class="card-widget card-archives">
<div class="item-headline">
<i class="fas fa-archive"></i>
<span>归档</span>
</div>
<ul class="card-archive-list">
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/07/">
<span class="card-archive-list-date">
七月 2026
</span>
<span class="card-archive-list-count">3</span>
</a>
</li>
<li class="card-archive-list-item">
<a class="card-archive-list-link" href="/archives/2026/01/">
<span class="card-archive-list-date">
一月 2026
</span>
<span class="card-archive-list-count">4</span>
</a>
</li>
</ul>
</div><div class="card-widget card-webinfo"><div class="item-headline"><i class="fas fa-chart-line"></i><span>网站信息</span></div><div class="webinfo"><div class="webinfo-item"><div class="item-name">文章数目 :</div><div class="item-count">7</div></div><div class="webinfo-item"><div class="item-name">运行时间 :</div><div class="item-count" id="runtimeshow" data-publishDate="2026-01-02T00:00:00.000Z"><i class="fa-solid fa-spinner fa-spin"></i></div></div><div class="webinfo-item"><div class="item-name">本站总字数 :</div><div class="item-count">7.8k</div></div><div class="webinfo-item"><div class="item-name">本站访客数 :</div><div class="item-count" id="busuanzi_value_site_uv"><i class="fa-solid fa-spinner fa-spin"></i></div></div><div class="webinfo-item"><div class="item-name">本站总浏览量 :</div><div class="item-count" id="busuanzi_value_site_pv"><i class="fa-solid fa-spinner fa-spin"></i></div></div><div class="webinfo-item"><div class="item-name">最后更新时间 :</div><div class="item-count" id="last-push-date" data-lastPushDate="2026-07-05T15:00:08.987Z"><i class="fa-solid fa-spinner fa-spin"></i></div></div></div></div></div></div></main><footer id="footer" style="background-image: url(/img/6.jpg);"><div class="footer-flex"><div class="footer-flex-items"><div class="footer-flex-item"><div class="footer-flex-title">导航</div><div class="footer-flex-content"><a href="/" target="_blank" title="首页">首页</a><a href="/archives/" target="_blank" title="时间轴">时间轴</a><a href="/tags/" target="_blank" title="标签">标签</a><a href="/categories/" target="_blank" title="分类">分类</a><a href="/about/" target="_blank" title="关于">关于</a></div></div></div></div><div class="footer-other"><div class="footer-copyright"><span class="copyright">© 2025 - 2026 By CeRu</span><span class="framework-info"><span class="footer-separator">|</span><span>框架 </span><a target="_blank" rel="noopener" href="https://hexo.io">Hexo 8.1.2</a><span class="footer-separator">|</span><span>主题 </span><a target="_blank" rel="noopener" href="https://github.com/jerryc127/hexo-theme-butterfly">Butterfly 5.5.5</a></span></div><div class="footer_custom_text"><a href="https://ceru-007.github.io">CeRu 的博客</a> | 记录学习 Hexo 和编程的日常</div></div></footer></div><div id="rightside"><div id="rightside-config-hide"><button id="translateLink" type="button" title="简繁转换">繁</button><button id="darkmode" type="button" title="日间和夜间模式切换"><i class="fas fa-adjust"></i></button><button id="hide-aside-btn" type="button" title="单栏和双栏切换"><i class="fas fa-arrows-alt-h"></i></button></div><div id="rightside-config-show"><button id="rightside-config" type="button" title="设置"><i class="fas fa-cog fa-spin"></i></button><button id="chat-btn" type="button" title="聊天" style="display:none"><i class="fas fa-message"></i></button><button id="go-up" type="button" title="回到顶部"><span class="scroll-percent"></span><i class="fas fa-arrow-up"></i></button></div></div><div><script src="/js/utils.js?v=5.5.5"></script><script src="/js/main.js?v=5.5.5"></script><script src="/js/tw_cn.js?v=5.5.5"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/ui@6.1.14/dist/fancybox/fancybox.umd.min.js"></script><script src="https://cdn.jsdelivr.net/npm/instant.page@5.2.0/instantpage.min.js" type="module"></script><script src="https://cdn.jsdelivr.net/npm/vanilla-lazyload@19.1.3/dist/lazyload.iife.min.js"></script><script src="https://cdn.jsdelivr.net/npm/node-snackbar@0.1.16/dist/snackbar.min.js"></script><div class="js-pjax"><script>window.typedJSFn = {
init: str => {
window.typed = new Typed('#subtitle', Object.assign({
strings: str,
startDelay: 300,
typeSpeed: 150,
loop: true,
backSpeed: 50,
}, null))
},
run: subtitleType => {
if (true) {
if (typeof Typed === 'function') {
subtitleType()
} else {
btf.getScript('https://cdn.jsdelivr.net/npm/typed.js@3.0.0/dist/typed.umd.min.js').then(subtitleType)
}
} else {
subtitleType()
}
},
processSubtitle: (content, extraContents = []) => {
if (true) {
const sub = ["我一路走来,是为了心中的坚守","明月策!一刀出,刀光凝结成河,久久不散 —— 我看,就叫他刀河王!","我有一刀,可斩宇宙","不知天高地厚的异族们,就拿你们立威了!","刀光如长河,一刀裂苍穹,一刀破汪洋,一刀斩封王!"].slice()
if (extraContents.length > 0) {
sub.unshift(...extraContents)
}
if (typeof content === 'string') {
sub.unshift(content)
} else if (Array.isArray(content)) {
sub.unshift(...content)
}
sub.length > 0 && typedJSFn.init(sub)
} else {
document.getElementById('subtitle').textContent = typeof content === 'string' ? content :
(Array.isArray(content) && content.length > 0 ? content[0] : '')
}
}
}
btf.addGlobalFn('pjaxSendOnce', () => { typed.destroy() }, 'typedDestroy')
</script><script>function subtitleType () {
typedJSFn.processSubtitle(["我一路走来,是为了心中的坚守","明月策!一刀出,刀光凝结成河,久久不散 —— 我看,就叫他刀河王!","我有一刀,可斩宇宙","不知天高地厚的异族们,就拿你们立威了!","刀光如长河,一刀裂苍穹,一刀破汪洋,一刀斩封王!"])
}
typedJSFn.run(subtitleType)</script><script>(() => {
const parseViewBox = viewBox => {
if (!viewBox) return null
const parts = viewBox.trim().split(/[\s,]+/).map(n => Number(n))
if (parts.length !== 4 || parts.some(n => Number.isNaN(n))) return null
return parts
}
const getSvgViewBox = svg => {
const attr = parseViewBox(svg.getAttribute('viewBox'))
if (attr) return attr
// Fallback: use bbox to build a viewBox
try {
const bbox = svg.getBBox()
if (bbox && bbox.width && bbox.height) return [bbox.x, bbox.y, bbox.width, bbox.height]
} catch (e) {
// getBBox may fail on some edge cases; ignore
}
const w = Number(svg.getAttribute('width')) || 0
const h = Number(svg.getAttribute('height')) || 0
if (w > 0 && h > 0) return [0, 0, w, h]
return [0, 0, 100, 100]
}
const setSvgViewBox = (svg, vb) => {
svg.setAttribute('viewBox', `${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}`)
}
const clamp = (v, min, max) => Math.max(min, Math.min(max, v))
const openSvgInNewTab = ({ source, initViewBox }) => {
const getClonedSvg = () => {
if (typeof source === 'string') {
const template = document.createElement('template')
template.innerHTML = source.trim()
const svg = template.content.querySelector('svg')
return svg ? svg.cloneNode(true) : null
}
if (source && typeof source.cloneNode === 'function') {
return source.cloneNode(true)
}
return null
}
const clone = getClonedSvg()
if (!clone) return
if (initViewBox && initViewBox.length === 4) {
clone.setAttribute('viewBox', initViewBox.join(' '))
}
if (!clone.getAttribute('xmlns')) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
if (!clone.getAttribute('xmlns:xlink') && clone.outerHTML.includes('xlink:')) {
clone.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink')
}
// inject background to match current theme
const isDark = document.documentElement.getAttribute('data-theme') === 'dark'
const bg = getComputedStyle(document.body).backgroundColor || (isDark ? '#1e1e1e' : '#ffffff')
if (!clone.style.background) clone.style.background = bg
const serializer = new XMLSerializer()
const svgSource = serializer.serializeToString(clone)
const htmlSource = `<!doctype html><html><head><meta charset="utf-8" />
<style>
html, body { width: 100%; height: 100%; margin: 0; display: flex; align-items: center; justify-content: center; background: ${bg}; }
svg { max-width: 100%; max-height: 100%; height: auto; width: auto; }
</style>
</head><body>${svgSource}</body></html>`
const blob = new Blob([htmlSource], { type: 'text/html;charset=utf-8' })
const url = URL.createObjectURL(blob)
window.open(url, '_blank', 'noopener')
setTimeout(() => URL.revokeObjectURL(url), 30000)
}
const attachMermaidViewerButton = wrap => {
let btn = wrap.querySelector('.mermaid-open-btn')
if (!btn) {
btn = document.createElement('button')
btn.type = 'button'
btn.className = 'mermaid-open-btn'
wrap.appendChild(btn)
}
btn.innerHTML = '<i class="fa fa-search fa-fw" aria-hidden="true"></i>'
if (!btn.__mermaidViewerBound) {
btn.addEventListener('click', e => {
e.preventDefault()
e.stopPropagation()
const svg = wrap.__mermaidOriginalSvg || wrap.querySelector('svg')
if (!svg) return
const initViewBox = wrap.__mermaidInitViewBox
if (typeof svg === 'string') {
openSvgInNewTab({ source: svg, initViewBox })
return
}
openSvgInNewTab({ source: svg, initViewBox })
})
btn.__mermaidViewerBound = true
}
}
// Zoom around a point (px, py) in the SVG viewport (in viewBox coordinates)
const zoomAtPoint = (vb, factor, px, py) => {
const w = vb[2] * factor
const h = vb[3] * factor
const nx = px - (px - vb[0]) * factor
const ny = py - (py - vb[1]) * factor
return [nx, ny, w, h]
}
const initMermaidGestures = wrap => {
const svg = wrap.querySelector('svg')
if (!svg) return
// Ensure viewBox exists so gestures always work
const initVb = getSvgViewBox(svg)
wrap.__mermaidInitViewBox = initVb
wrap.__mermaidCurViewBox = initVb.slice()
setSvgViewBox(svg, initVb)
// Avoid binding multiple times on themeChange/pjax
if (wrap.__mermaidGestureBound) return
wrap.__mermaidGestureBound = true
// Helper: map client (viewport) coordinate -> viewBox coordinate
const clientToViewBox = (clientX, clientY) => {
const rect = svg.getBoundingClientRect()
const vb = wrap.__mermaidCurViewBox || getSvgViewBox(svg)
const x = vb[0] + (clientX - rect.left) * (vb[2] / rect.width)
const y = vb[1] + (clientY - rect.top) * (vb[3] / rect.height)
return { x, y, rect, vb }
}
const state = {
pointers: new Map(),
startVb: null,
startDist: 0,
startCenter: null
}
const clampVb = vb => {
const init = wrap.__mermaidInitViewBox || vb
const minW = init[2] * 0.1
const maxW = init[2] * 10
const minH = init[3] * 0.1
const maxH = init[3] * 10
vb[2] = clamp(vb[2], minW, maxW)
vb[3] = clamp(vb[3], minH, maxH)
return vb
}
const setCurVb = vb => {
vb = clampVb(vb)
wrap.__mermaidCurViewBox = vb
setSvgViewBox(svg, vb)
}
const onPointerDown = e => {
// Allow only primary button for mouse
if (e.pointerType === 'mouse' && e.button !== 0) return
svg.setPointerCapture(e.pointerId)
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
if (state.pointers.size === 1) {
state.startVb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
} else if (state.pointers.size === 2) {
const pts = [...state.pointers.values()]
const dx = pts[0].x - pts[1].x
const dy = pts[0].y - pts[1].y
state.startDist = Math.hypot(dx, dy)
state.startVb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
state.startCenter = { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
}
}
const onPointerMove = e => {
if (!state.pointers.has(e.pointerId)) return
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
// Pan with 1 pointer
if (state.pointers.size === 1 && state.startVb) {
const p = [...state.pointers.values()][0]
const prev = { x: e.clientX - e.movementX, y: e.clientY - e.movementY }
// movementX/Y unreliable on touch, compute from stored last position
const last = wrap.__mermaidLastSinglePointer || p
const dxClient = p.x - last.x
const dyClient = p.y - last.y
wrap.__mermaidLastSinglePointer = p
const { rect } = clientToViewBox(p.x, p.y)
const vb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
const dx = dxClient * (vb[2] / rect.width)
const dy = dyClient * (vb[3] / rect.height)
setCurVb([vb[0] - dx, vb[1] - dy, vb[2], vb[3]])
return
}
// Pinch zoom with 2 pointers
if (state.pointers.size === 2 && state.startVb && state.startDist > 0) {
const pts = [...state.pointers.values()]
const dx = pts[0].x - pts[1].x
const dy = pts[0].y - pts[1].y
const dist = Math.hypot(dx, dy)
if (!dist) return
const factor = state.startDist / dist // dist bigger => zoom in (viewBox smaller)
const cx = (pts[0].x + pts[1].x) / 2
const cy = (pts[0].y + pts[1].y) / 2
const centerClient = { x: cx, y: cy }
const pxy = clientToViewBox(centerClient.x, centerClient.y)
const cpx = pxy.x
const cpy = pxy.y
const vb = zoomAtPoint(state.startVb, factor, cpx, cpy)
setCurVb(vb)
}
}
const onPointerUpOrCancel = e => {
state.pointers.delete(e.pointerId)
if (state.pointers.size === 0) {
state.startVb = null
state.startDist = 0
state.startCenter = null
wrap.__mermaidLastSinglePointer = null
} else if (state.pointers.size === 1) {
// reset single pointer baseline to avoid jump
wrap.__mermaidLastSinglePointer = [...state.pointers.values()][0]
}
}
// Wheel zoom (mouse/trackpad)
const onWheel = e => {
// ctrlKey on mac trackpad pinch; we treat both as zoom
e.preventDefault()
const delta = e.deltaY
const zoomFactor = delta > 0 ? 1.1 : 0.9
const { x, y } = clientToViewBox(e.clientX, e.clientY)
const vb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
setCurVb(zoomAtPoint(vb, zoomFactor, x, y))
}
const onDblClick = () => {
const init = wrap.__mermaidInitViewBox
if (!init) return
wrap.__mermaidCurViewBox = init.slice()
setSvgViewBox(svg, init)
}
svg.addEventListener('pointerdown', onPointerDown)
svg.addEventListener('pointermove', onPointerMove)
svg.addEventListener('pointerup', onPointerUpOrCancel)
svg.addEventListener('pointercancel', onPointerUpOrCancel)
svg.addEventListener('wheel', onWheel, { passive: false })
svg.addEventListener('dblclick', onDblClick)
}
const runMermaid = ele => {
window.loadMermaid = true
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'default'
ele.forEach((item, index) => {
const mermaidSrc = item.firstElementChild
// Clear old render (themeChange/pjax will rerun)
const oldSvg = item.querySelector('svg')
if (oldSvg) oldSvg.remove()
item.__mermaidGestureBound = false
const config = mermaidSrc.dataset.config ? JSON.parse(mermaidSrc.dataset.config) : {}
if (!config.theme) {
config.theme = theme
}
const mermaidThemeConfig = `%%{init: ${JSON.stringify(config)}}%%\n`
const mermaidID = `mermaid-${index}`
const mermaidDefinition = mermaidThemeConfig + mermaidSrc.textContent
const renderFn = mermaid.render(mermaidID, mermaidDefinition)
const renderMermaid = svg => {
mermaidSrc.insertAdjacentHTML('afterend', svg)
if (true) initMermaidGestures(item)
item.__mermaidOriginalSvg = svg
if (true) attachMermaidViewerButton(item)
}
// mermaid v9 and v10 compatibility
typeof renderFn === 'string' ? renderMermaid(renderFn) : renderFn.then(({ svg }) => renderMermaid(svg))
})
}
const codeToMermaid = () => {
const codeMermaidEle = document.querySelectorAll('pre > code.mermaid')
if (codeMermaidEle.length === 0) return
codeMermaidEle.forEach(ele => {
const preEle = document.createElement('pre')
preEle.className = 'mermaid-src'
preEle.hidden = true
preEle.textContent = ele.textContent
const newEle = document.createElement('div')
newEle.className = 'mermaid-wrap'
newEle.appendChild(preEle)
ele.parentNode.replaceWith(newEle)
})
}
const loadMermaid = () => {
if (false) codeToMermaid()
const $mermaid = document.querySelectorAll('#article-container .mermaid-wrap')
if ($mermaid.length === 0) return
const runMermaidFn = () => runMermaid($mermaid)
btf.addGlobalFn('themeChange', runMermaidFn, 'mermaid')
window.loadMermaid ? runMermaidFn() : btf.getScript('https://cdn.jsdelivr.net/npm/mermaid@11.15.0/dist/mermaid.min.js').then(runMermaidFn)
}
btf.addGlobalFn('encrypt', loadMermaid, 'mermaid')
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
})()</script><script>(() => {
const applyThemeDefaultsConfig = theme => {
if (theme === 'dark-mode') {
Chart.defaults.color = "rgba(255, 255, 255, 0.8)"
Chart.defaults.borderColor = "rgba(255, 255, 255, 0.2)"
Chart.defaults.scale.ticks.backdropColor = "transparent"
} else {
Chart.defaults.color = "rgba(0, 0, 0, 0.8)"
Chart.defaults.borderColor = "rgba(0, 0, 0, 0.1)"
Chart.defaults.scale.ticks.backdropColor = "transparent"
}
}
// Recursively traverse the config object and automatically apply theme-specific color schemes
const applyThemeConfig = (obj, theme) => {
if (typeof obj !== 'object' || obj === null) return
Object.keys(obj).forEach(key => {
const value = obj[key]
// If the property is an object and has theme-specific options, apply them
if (typeof value === 'object' && value !== null) {
if (value[theme]) {
obj[key] = value[theme] // Apply the value for the current theme
} else {
// Recursively process child objects
applyThemeConfig(value, theme)
}
}
})
}
const runChartJS = ele => {
window.loadChartJS = true
Array.from(ele).forEach((item, index) => {
const chartSrc = item.firstElementChild
const chartID = item.getAttribute('data-chartjs-id') || ('chartjs-' + index) // Use custom ID or default ID
const width = item.getAttribute('data-width')
const existingCanvas = document.getElementById(chartID)
// If a canvas already exists, remove it to avoid rendering duplicates
if (existingCanvas) {
existingCanvas.parentNode.remove()
}
const chartDefinition = chartSrc.textContent
const canvas = document.createElement('canvas')
canvas.id = chartID
const div = document.createElement('div')
div.className = 'chartjs-wrap'
if (width) {
div.style.width = width
}
div.appendChild(canvas)
chartSrc.insertAdjacentElement('afterend', div)
const ctx = document.getElementById(chartID).getContext('2d')
const config = JSON.parse(chartDefinition)
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark-mode' : 'light-mode'
// Set default styles (initial setup)
applyThemeDefaultsConfig(theme)
// Automatically traverse the config and apply dual-mode color schemes
applyThemeConfig(config, theme)
new Chart(ctx, config)
})
}
const loadChartJS = () => {
const chartJSEle = document.querySelectorAll('#article-container .chartjs-container')
if (chartJSEle.length === 0) return
window.loadChartJS ? runChartJS(chartJSEle) : btf.getScript('https://cdn.jsdelivr.net/npm/chart.js@4.5.1/dist/chart.umd.min.js').then(() => runChartJS(chartJSEle))
}
// Listen for theme change events
btf.addGlobalFn('themeChange', loadChartJS, 'chartjs')
btf.addGlobalFn('encrypt', loadChartJS, 'chartjs')
window.pjax ? loadChartJS() : document.addEventListener('DOMContentLoaded', loadChartJS)
})()</script></div><script>window.newestComments = {
changeContent: content => {
if (content === '') return content
content = content.replace(/<img.*?src="(.*?)"?[^\>]+>/ig, '[图片]') // replace image link
content = content.replace(/<a[^>]+?href=["']?([^"']+)["']?[^>]*>([^<]+)<\/a>/gi, '[链接]') // replace url
content = content.replace(/<pre><code>.*?<\/pre>/gi, '[代码]') // replace code
content = content.replace(/<code>.*?<\/code>/gi, '[代码]') // replace code
content = content.replace(/<[^>]+>/g, "") // remove html tag
if (content.length > 150) {
content = content.substring(0, 150) + '...'
}
return content
},
generateHtml: (array, ele) => {
let result = ''
if (array.length) {
for (let i = 0; i < array.length; i++) {
result += '<div class="aside-list-item">'
if (true && array[i].avatar) {
const imgAttr = 'data-lazy-src'
const lazyloadNative = ''
result += `<a href="${array[i].url}" class="thumbnail"><img ${imgAttr}="${array[i].avatar}" alt="${array[i].nick}" ${lazyloadNative}></a>`
}
result += `<div class="content">
<a class="comment" href="${array[i].url}" title="${array[i].content}">${array[i].content}</a>
<div class="name"><span>${array[i].nick} / </span><time datetime="${array[i].date}">${btf.diffDate(array[i].date, true)}</time></div>
</div></div>`
}
} else {
result += '暂无评论'
}
ele.innerHTML = result
window.lazyLoadInstance && window.lazyLoadInstance.update()
window.pjax && window.pjax.refresh(ele)
},
newestCommentInit: (name, getComment) => {
const $dom = document.querySelector('#card-newest-comments .aside-list')
if ($dom) {
const data = btf.saveToLocal.get(name)
if (data) {
newestComments.generateHtml(JSON.parse(data), $dom)
} else {
getComment($dom)
}
}
},
run: (name, getComment) => {
newestComments.newestCommentInit(name, getComment)
btf.addGlobalFn('pjaxComplete', () => newestComments.newestCommentInit(name, getComment), name)
}
}</script><script>window.addEventListener('load', () => {
const keyName = 'github-newest-comments'
const { changeContent, generateHtml, run } = window.newestComments
const findTrueUrl = (array, ele) => {
Promise.all(array.map(item =>
fetch(item.url).then(resp => resp.json()).then(data => {
let urlArray = data.body ? data.body.match(/(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/ig) : []
if (!Array.isArray(urlArray) || urlArray.length === 0) {
urlArray = [`${data.html_url}`]
}
if (data.user.login === 'utterances-bot') {
return urlArray.pop()
} else {
return urlArray.shift()
}
})
)).then(res => {
array = array.map((i,index)=> {
return {
...i,
url: res[index]
}
})
btf.saveToLocal.set(keyName, JSON.stringify(array), 10/(60*24))
generateHtml(array, ele)
});
}
const getComment = ele => {
fetch('https://api.github.com/repos/CeRu-007/CeRu-007.github.io/issues/comments?sort=updated&direction=desc&per_page=6&page=1',{
"headers": {
Accept: 'application/vnd.github.v3.html+json'
}
})
.then(response => response.json())
.then(data => {
const githubArray = data.map(item => {
return {
'avatar': item.user.avatar_url,
'content': changeContent(item.body_html || item.body),
'nick': item.user.login,
'url': item.issue_url,
'date': item.updated_at
}
})
findTrueUrl(githubArray, ele)
}).catch(e => {
console.error(e)
ele.textContent= "无法获取评论,请确认相关配置是否正确"
})
}
run(keyName, getComment)
})</script><div class="aplayer no-destroy" data-id="633743256" data-server="netease" data-type="playlist" data-fixed="true" data-mini="true" data-listFolded="false" data-order="random" data-preload="auto" data-autoplay="false" data-theme="#1BCDFC" data-lrc-type="0"></div><script id="canvas_nest" defer="defer" color="0,0,255" opacity="0.7" zIndex="-1" count="99" mobile="false" src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1.1.6/dist/canvas-nest.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1.1.6/dist/activate-power-mode.min.js"></script><script>POWERMODE.colorful = true;
POWERMODE.shake = true;
POWERMODE.mobile = true;
document.body.addEventListener('input', POWERMODE);
</script><script>(() => {
btf.getScript('//code.tidio.co/.js').then(() => {
const isChatBtn = true
const isChatHideShow = false
if (isChatBtn) {
let isShow = false
const close = () => {
window.tidioChatApi.hide()
isShow = false
}
const open = () => {
window.tidioChatApi.open()
window.tidioChatApi.show()
isShow = true
}
const onTidioChatApiReady = () => {
window.tidioChatApi.hide()
window.tidioChatApi.on("close", close)
}
if (window.tidioChatApi) {
window.tidioChatApi.on("ready", onTidioChatApiReady)
} else {
document.addEventListener("tidioChat-ready", onTidioChatApiReady)
}
window.chatBtnFn = () => {
if (!window.tidioChatApi) return
isShow ? close() : open()
}
document.getElementById('chat-btn').style.display = 'block'
} else if (isChatHideShow) {
window.chatBtn = {
hide: () => window.tidioChatApi && window.tidioChatApi.hide(),
show: () => window.tidioChatApi && window.tidioChatApi.show()
}
}
})
})()</script><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.css" media="print" onload="this.media='all'"><script src="https://cdn.jsdelivr.net/npm/aplayer@1.10.1/dist/APlayer.min.js"></script><script src="https://cdn.jsdelivr.net/npm/butterfly-extsrc@1.1.6/metingjs/dist/Meting.min.js"></script><script>(() => {
const destroyAplayer = () => {
if (window.aplayers) {
for (let i = 0; i < window.aplayers.length; i++) {
if (!window.aplayers[i].options.fixed) {
window.aplayers[i].destroy()
}
}
}
}
const runMetingJS = () => {
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
}
btf.addGlobalFn('pjaxSend', destroyAplayer, 'destroyAplayer')
btf.addGlobalFn('pjaxComplete', loadMeting, 'runMetingJS')
})()</script><script src="https://cdn.jsdelivr.net/npm/pjax@0.2.8/pjax.min.js" defer="defer"></script><script>document.addEventListener('DOMContentLoaded', () => {
const pjaxSelectors = ["head > title","#config-diff","#body-wrap","#rightside-config-hide","#rightside-config-show",".js-pjax"]
window.pjax = new Pjax({
elements: 'a:not([target="_blank"])',
selectors: pjaxSelectors,
cacheBust: false,
analytics: false,
scrollRestoration: false
})
const triggerPjaxFn = (val) => {
if (!val) return
Object.values(val).forEach(fn => {
try {
fn()
} catch (err) {
console.debug('Pjax callback failed:', err)
}
})
}
document.addEventListener('pjax:send', () => {
// removeEventListener
btf.removeGlobalFnEvent('pjaxSendOnce')
btf.removeGlobalFnEvent('themeChange')
// reset readmode
const $bodyClassList = document.body.classList
if ($bodyClassList.contains('read-mode')) $bodyClassList.remove('read-mode')
triggerPjaxFn(window.globalFn.pjaxSend)
})
document.addEventListener('pjax:complete', () => {
btf.removeGlobalFnEvent('pjaxCompleteOnce')
document.querySelectorAll('script[data-pjax]').forEach(item => {
const newScript = document.createElement('script')
const content = item.text || item.textContent || item.innerHTML || ""
Array.from(item.attributes).forEach(attr => newScript.setAttribute(attr.name, attr.value))
newScript.appendChild(document.createTextNode(content))
item.parentNode.replaceChild(newScript, item)
})
triggerPjaxFn(window.globalFn.pjaxComplete)
})
document.addEventListener('pjax:error', e => {
if (e.request.status === 404) {
true
? pjax.loadUrl('/404.html')
: window.location.href = e.request.responseURL
}
})
})</script><script async data-pjax src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><div id="local-search"><div class="search-dialog"><nav class="search-nav"><span class="search-dialog-title">搜索</span><i class="fas fa-spinner fa-pulse" id="loading-status" hidden="hidden"></i><button class="search-close-button"><i class="fas fa-times"></i></button></nav><div class="text-center" id="loading-database"><i class="fas fa-spinner fa-pulse"></i><span> 数据加载中</span></div><div class="local-search-input"><input placeholder="搜索文章..." type="text"/></div><hr/><div id="local-search-results"></div><div class="ais-Pagination" id="local-search-pagination" style="display:none;"><ul class="ais-Pagination-list"></ul></div><div id="local-search-stats"></div></div><div id="search-mask"></div><script src="/js/search/local-search.js?v=5.5.5"></script></div></div></body></html>