知乎修改器🤜持续更新🤛努力实现功能最全的知乎配置插件

页面模块自定义隐藏,列表及回答内容过滤,保存浏览历史记录,推荐页内容缓存,一键邀请,复制代码块删除版权信息,列表种类和关键词强过滤并自动调用「不感兴趣」接口,屏蔽用户回答,视频下载,设置自动收起所有长回答或自动展开所有回答,移除登录提示弹窗,设置过滤故事档案局和盐选科普回答等知乎官方账号回答,手动调节文字大小,切换主题及深色模式调整,隐藏知乎热搜,列表添加标签种类,去除广告,设置购买链接显示方式,收藏夹内容、回答、文章导出为PDF,一键移除所有屏蔽选项,外链直接打开,键盘左右切换预览图片,更多功能请在插件里体验...

  1. // ==UserScript==
  2. // @name 知乎修改器🤜持续更新🤛努力实现功能最全的知乎配置插件
  3. // @namespace http://tampermonkey.net/
  4. // @version 4.21.2
  5. // @description 页面模块自定义隐藏,列表及回答内容过滤,保存浏览历史记录,推荐页内容缓存,一键邀请,复制代码块删除版权信息,列表种类和关键词强过滤并自动调用「不感兴趣」接口,屏蔽用户回答,视频下载,设置自动收起所有长回答或自动展开所有回答,移除登录提示弹窗,设置过滤故事档案局和盐选科普回答等知乎官方账号回答,手动调节文字大小,切换主题及深色模式调整,隐藏知乎热搜,列表添加标签种类,去除广告,设置购买链接显示方式,收藏夹内容、回答、文章导出为PDF,一键移除所有屏蔽选项,外链直接打开,键盘左右切换预览图片,更多功能请在插件里体验...
  6. // @compatible edge Violentmonkey
  7. // @compatible edge Tampermonkey
  8. // @compatible chrome Violentmonkey
  9. // @compatible chrome Tampermonkey
  10. // @compatible firefox Violentmonkey
  11. // @compatible firefox Tampermonkey
  12. // @compatible safari Violentmonkey
  13. // @compatible safari Tampermonkey
  14. // @author lyb233
  15. // @license MIT
  16. // @match *://*.zhihu.com/*
  17. // @grant unsafeWindow
  18. // @grant GM_info
  19. // @grant GM_setValue
  20. // @grant GM_getValue
  21. // @grant GM.getValue
  22. // @grant GM.setValue
  23. // @grant GM_registerMenuCommand
  24. // @run-at document-start
  25. // ==/UserScript==
  26.  
  27. "use strict";
  28. (() => {
  29. var THEMES = [
  30. { label: "浅色", value: 0 /* 浅色 */, background: "#fff", color: "#000" },
  31. { label: "深色", value: 1 /* 深色 */, background: "#000", color: "#fff" },
  32. { label: "自动", value: 2 /* 自动 */, background: "linear-gradient(to right, #fff, #000)", color: "#000" }
  33. ];
  34. var THEME_CONFIG_LIGHT = {
  35. [0 /* 默认 */]: { name: "默认", background: "#ffffff", background2: "" },
  36. [1 /* 红 */]: { name: "红", background: "#ffe4c4", background2: "#fff4e7" },
  37. [2 /* 黄 */]: { name: "黄", background: "#faf9de", background2: "#fdfdf2" },
  38. [3 /* 绿 */]: { name: "绿", background: "#cce8cf", background2: "#e5f1e7" },
  39. [4 /* 灰 */]: { name: "灰", background: "#eaeaef", background2: "#f3f3f5" },
  40. [5 /* 紫 */]: { name: "紫", background: "#e9ebfe", background2: "#f2f3fb" },
  41. [6 /* 落日黄 */]: { name: "落日黄", background: "#FFD39B", background2: "#ffe4c4" }
  42. };
  43. var THEME_CONFIG_DARK = {
  44. [0 /* 深色模式默认 */]: { name: "默认", background: "#121212", background2: "#333333" },
  45. [1 /* 深色护眼一 */]: { name: "深色护眼一", background: "#15202b", background2: "#38444d" },
  46. [2 /* 深色护眼二 */]: { name: "深色护眼二", background: "#1f1f1f", background2: "#303030" },
  47. [3 /* 深色护眼三 */]: { name: "深色护眼三", background: "#272822", background2: "#383932" },
  48. [4 /* 深色蓝 */]: { name: "深色蓝", background: "#1c0c59", background2: "#191970" },
  49. [5 /* 深色红 */]: { name: "深色红", background: "#570D0D", background2: "#8B0000" },
  50. [6 /* 深色绿 */]: { name: "深色绿", background: "#093333", background2: "#0c403f" }
  51. };
  52. var INPUT_NAME_THEME = "theme";
  53. var INPUT_NAME_THEME_DARK = "themeDark";
  54. var INPUT_NAME_ThEME_LIGHT = "themeLight";
  55. var CONFIG_HIDDEN_DEFAULT = {
  56. hiddenAnswerRightFooter: true,
  57. hiddenReadMoreText: true,
  58. hiddenAD: true,
  59. hiddenDetailFollow: true,
  60. hidden618HongBao: true,
  61. hiddenZhihuZhiShop: true
  62. };
  63. var CONFIG_FILTER_DEFAULT = {
  64. removeZhihuOfficial: false,
  65. removeStoryAnswer: true,
  66. removeYanxuanAnswer: true,
  67. removeYanxuanRecommend: true,
  68. removeYanxuanCPRecommend: true,
  69. removeFromYanxuan: true,
  70. removeFromEBook: true,
  71. removeUnrealAnswer: false,
  72. removeFollowVoteAnswer: false,
  73. removeFollowVoteArticle: false,
  74. removeFollowFQuestion: false,
  75. removeBlockUserContent: true,
  76. removeBlockUserContentList: [],
  77. removeItemAboutAD: false,
  78. removeItemAboutArticle: false,
  79. removeItemAboutVideo: false,
  80. removeItemAboutPin: false,
  81. removeItemQuestionAsk: false,
  82. removeLessVote: false,
  83. lessVoteNumber: 100,
  84. removeLessVoteDetail: false,
  85. lessVoteNumberDetail: 100,
  86. removeAnonymousAnswer: false,
  87. removeMyOperateAtFollow: false,
  88. removeTopAD: true
  89. };
  90. var CONFIG_SUSPENSION = {
  91. suspensionHomeTab: false,
  92. suspensionHomeTabPo: "left: 20px; top: 100px;",
  93. suspensionHomeTabFixed: true,
  94. suspensionFind: false,
  95. suspensionFindPo: "left: 10px; top: 380px;",
  96. suspensionFindFixed: true,
  97. suspensionSearch: false,
  98. suspensionSearchPo: "left: 10px; top: 400px;",
  99. suspensionSearchFixed: true,
  100. suspensionUser: false,
  101. suspensionUserPo: "right: 60px; top: 100px;",
  102. suspensionUserFixed: true,
  103. suspensionPickUp: true,
  104. suspensionPickupRight: 60
  105. };
  106. var CONFIG_SIMPLE = {
  107. hiddenAnswerRightFooter: true,
  108. hiddenFixedActions: true,
  109. hiddenLogo: true,
  110. hiddenHeader: true,
  111. hiddenHeaderScroll: true,
  112. hiddenItemActions: true,
  113. hiddenAnswerText: true,
  114. hiddenQuestionShare: true,
  115. hiddenQuestionTag: true,
  116. hiddenQuestionActions: true,
  117. hiddenReward: true,
  118. hiddenZhuanlanTag: true,
  119. hiddenListImg: true,
  120. hiddenReadMoreText: true,
  121. hiddenAD: true,
  122. hiddenAnswers: true,
  123. hiddenZhuanlanActions: true,
  124. hiddenZhuanlanTitleImage: true,
  125. hiddenHotItemMetrics: true,
  126. hiddenHotItemIndex: true,
  127. hiddenHotItemLabel: true,
  128. hiddenDetailAvatar: true,
  129. hiddenDetailBadge: true,
  130. hiddenDetailVoters: false,
  131. hiddenWhoVoters: true,
  132. hiddenDetailName: true,
  133. hiddenDetailFollow: true,
  134. hiddenHomeTab: false,
  135. hiddenQuestionSide: true,
  136. hiddenQuestionFollowing: true,
  137. hiddenQuestionAnswer: true,
  138. hiddenQuestionInvite: true,
  139. hiddenSearchBoxTopSearch: true,
  140. hiddenSearchPageTopSearch: true,
  141. hiddenSearchPageFooter: true,
  142. hiddenZhuanlanShare: true,
  143. hiddenZhuanlanVoters: true,
  144. hiddenListAnswerInPerson: true,
  145. hiddenFollowAction: true,
  146. hiddenFollowChooseUser: true,
  147. hidden618HongBao: true,
  148. hiddenZhuanlanFollowButton: true,
  149. hiddenZhuanlanAvatarWrapper: true,
  150. hiddenZhuanlanAuthorInfoHead: true,
  151. hiddenZhuanlanAuthorInfoDetail: true,
  152. hiddenQuestionSpecial: true,
  153. hiddenListVideoContent: true,
  154. hiddenHomeCreatorEntrance: true,
  155. hiddenHomeRecommendFollow: true,
  156. hiddenHomeCategory: true,
  157. hiddenHomeCategoryMore: true,
  158. hiddenHomeFooter: true,
  159. removeZhihuOfficial: false,
  160. removeStoryAnswer: true,
  161. removeYanxuanAnswer: true,
  162. removeYanxuanRecommend: true,
  163. removeYanxuanCPRecommend: true,
  164. removeFromYanxuan: true,
  165. removeUnrealAnswer: false,
  166. removeFollowVoteAnswer: false,
  167. removeFollowVoteArticle: false,
  168. removeFollowFQuestion: false,
  169. removeBlockUserContent: true,
  170. removeItemAboutAD: false,
  171. removeItemQuestionAsk: false,
  172. removeLessVote: false,
  173. lessVoteNumber: 100,
  174. removeLessVoteDetail: false,
  175. lessVoteNumberDetail: 100,
  176. suspensionHomeTab: false,
  177. suspensionHomeTabPo: "left: 20px; top: 100px;",
  178. suspensionHomeTabFixed: true,
  179. suspensionFind: false,
  180. suspensionFindPo: "left: 10px; top: 380px;",
  181. suspensionFindFixed: true,
  182. suspensionSearch: true,
  183. suspensionSearchPo: "left: 10px; top: 400px;",
  184. suspensionSearchFixed: true,
  185. suspensionUser: true,
  186. suspensionUserPo: "right: 60px; top: 100px;",
  187. suspensionUserFixed: true,
  188. suspensionPickUp: true,
  189. answerOpen: "off",
  190. showBlockUser: false,
  191. zoomImageType: "2",
  192. zoomImageSize: "200",
  193. questionTitleTag: true,
  194. listOutPutNotInterested: true,
  195. fixedListItemMore: true,
  196. highlightOriginal: true,
  197. highlightListItem: true,
  198. listItemCreatedAndModifiedTime: true,
  199. answerItemCreatedAndModifiedTime: true,
  200. questionCreatedAndModifiedTime: true,
  201. articleCreateTimeToTop: true,
  202. linkShopping: "1",
  203. hiddenAnswerItemActions: true,
  204. hiddenAnswerItemTime: true,
  205. videoUseLink: true,
  206. commitModalSizeSameVersion: true
  207. };
  208. var CONFIG_DEFAULT = {
  209. ...CONFIG_HIDDEN_DEFAULT,
  210. ...CONFIG_FILTER_DEFAULT,
  211. ...CONFIG_SUSPENSION,
  212. fetchInterceptStatus: true,
  213. customizeCss: "",
  214. answerOpen: "",
  215. filterKeywords: [],
  216. blockWordsAnswer: [],
  217. showBlockUser: true,
  218. versionHome: "1000",
  219. versionAnswer: "1000",
  220. versionArticle: "1000",
  221. versionHomeIsPercent: false,
  222. versionHomePercent: "70",
  223. versionAnswerIsPercent: false,
  224. versionAnswerPercent: "70",
  225. versionArticleIsPercent: false,
  226. versionArticlePercent: "70",
  227. zoomImageType: "0",
  228. zoomImageSize: "600",
  229. showGIFinDialog: false,
  230. globalTitle: "",
  231. titleIco: "",
  232. questionTitleTag: true,
  233. listOutPutNotInterested: false,
  234. fixedListItemMore: false,
  235. highlightOriginal: true,
  236. highlightListItem: false,
  237. listItemCreatedAndModifiedTime: true,
  238. answerItemCreatedAndModifiedTime: true,
  239. questionCreatedAndModifiedTime: true,
  240. articleCreateTimeToTop: true,
  241. linkShopping: "0",
  242. fontSizeForList: 15,
  243. fontSizeForAnswer: 15,
  244. fontSizeForArticle: 16,
  245. fontSizeForListTitle: 18,
  246. fontSizeForAnswerTitle: 22,
  247. fontSizeForArticleTitle: 24,
  248. zoomListVideoType: "0",
  249. zoomListVideoSize: "500",
  250. hotKey: true,
  251. theme: 2 /* 自动 */,
  252. themeLight: 0 /* 默认 */,
  253. themeDark: 1 /* 深色护眼一 */,
  254. colorText1: "",
  255. commitModalSizeSameVersion: true,
  256. listOutputToQuestion: false,
  257. userHomeContentTimeTop: true,
  258. userHomeTopBlockUser: true,
  259. copyAnswerLink: true,
  260. contentRemoveKeywordSearch: false,
  261. topExportContent: true,
  262. zoomImageHeight: "0",
  263. zoomImageHeightSize: "100"
  264. };
  265. var SAVE_HISTORY_NUMBER = 500;
  266. var HTML_HOOTS = ["www.zhihu.com", "zhuanlan.zhihu.com"];
  267. var ID_DIALOG = "CTZ_DIALOG_MAIN";
  268. var ID_BUTTON_SYNC_BLOCK = "CTZ-BUTTON-SYNC-BLOCK";
  269. var CLASS_INPUT_CLICK = "ctz-i";
  270. var CLASS_INPUT_CHANGE = "ctz-i-change";
  271. var CLASS_REMOVE_BLOCK = "ctz-remove-block";
  272. var CLASS_NOT_INTERESTED = "ctz-not-interested";
  273. var CLASS_TO_QUESTION = "ctz-to-question";
  274. var CLASS_TIME_ITEM = "ctz-list-item-time";
  275. var CLASS_MESSAGE = "ctz-message";
  276. var ID_MESSAGE_BOX = "CTZ_MESSAGE_BOX";
  277. var OB_CLASS_FOLD = {
  278. on: "ctz-fold-open",
  279. off: "ctz-fold-close"
  280. };
  281. var EXTRA_CLASS_HTML = {
  282. "zhuanlan.zhihu.com": "zhuanlan",
  283. "www.zhihu.com": "zhihu"
  284. };
  285. var HEADER = [
  286. { href: "#CTZ_BASIS", value: "基础设置" },
  287. { href: "#CTZ_HIDDEN", value: "隐藏模块设置" },
  288. { href: "#CTZ_FILTER", value: "屏蔽内容设置" },
  289. { href: "#CTZ_BLOCK_WORD", value: "屏蔽词设置" },
  290. { href: "#CTZ_BLACKLIST", value: "黑名单设置" },
  291. { href: "#CTZ_HISTORY", value: "历史记录" },
  292. { href: "#CTZ_DEFAULT", value: "默认功能" }
  293. ];
  294. var FONT_SIZE_INPUT = [
  295. [
  296. { value: "fontSizeForListTitle", label: "列表标题文字大小" },
  297. { value: "fontSizeForList", label: "列表内容文字大小" }
  298. ],
  299. [
  300. { value: "fontSizeForAnswerTitle", label: "回答标题文字大小" },
  301. { value: "fontSizeForAnswer", label: "回答内容文字大小" }
  302. ],
  303. [
  304. { value: "fontSizeForArticleTitle", label: "文章标题文字大小" },
  305. { value: "fontSizeForArticle", label: "文章内容文字大小" }
  306. ]
  307. ];
  308. var VERSION_MIN_WIDTH = 600;
  309. var VERSION_RANGE = [
  310. {
  311. label: "列表页内容宽度",
  312. value: "versionHome",
  313. min: VERSION_MIN_WIDTH,
  314. max: 1500,
  315. percentChooseValue: "versionHomeIsPercent",
  316. percentChooseLabel: "列表页内容宽度用百分比设置",
  317. desc: "列表页内容宽度最小为600像素,设置宽度小于此则会用600像素显示",
  318. percentMin: 20,
  319. percentMax: 100,
  320. percentLabel: "列表页内容宽度(百分比)",
  321. percentValue: "versionHomePercent"
  322. },
  323. {
  324. label: "回答页内容宽度",
  325. value: "versionAnswer",
  326. min: VERSION_MIN_WIDTH,
  327. max: 1500,
  328. percentChooseValue: "versionAnswerIsPercent",
  329. percentChooseLabel: "回答页内容宽度用百分比设置",
  330. desc: "回答页内容宽度最小为600像素,设置宽度小于此则会用600像素显示",
  331. percentMin: 20,
  332. percentMax: 100,
  333. percentLabel: "回答页内容宽度(百分比)",
  334. percentValue: "versionAnswerPercent"
  335. },
  336. {
  337. label: "文章页内容宽度",
  338. value: "versionArticle",
  339. min: VERSION_MIN_WIDTH,
  340. max: 1500,
  341. percentChooseValue: "versionArticleIsPercent",
  342. percentChooseLabel: "文章页内容宽度用百分比设置",
  343. desc: "文章页内容宽度最小为600像素,设置宽度小于此则会用600像素显示",
  344. percentMin: 20,
  345. percentMax: 100,
  346. percentLabel: "文章页内容宽度(百分比)",
  347. percentValue: "versionArticlePercent"
  348. }
  349. ];
  350. var FILTER_FOLLOWER_OPERATE = [
  351. { key: "removeFollowVoteAnswer", rep: "赞同了回答" },
  352. { key: "removeFollowVoteArticle", rep: "赞同了文章" },
  353. { key: "removeFollowFQuestion", rep: "关注了问题" }
  354. ];
  355. var HIDDEN_ANSWER_TAG = {
  356. removeFromYanxuan: "盐选专栏",
  357. removeUnrealAnswer: "虚构创作",
  358. removeFromEBook: "电子书"
  359. };
  360. var HIDDEN_ANSWER_ACCOUNT = {
  361. removeStoryAnswer: "故事档案局",
  362. removeYanxuanAnswer: "盐选科普",
  363. removeYanxuanRecommend: "盐选推荐",
  364. removeYanxuanCPRecommend: "盐选测评室"
  365. };
  366. var HIDDEN_ARRAY = [
  367. {
  368. key: "CTZ_HIDDEN_COMMON",
  369. name: "通用隐藏",
  370. desc: "",
  371. content: [
  372. [{ value: "hiddenAD", label: "广告" }],
  373. // [{ value: 'hiddenTopAD', label: '顶部推广(只能物理隐藏,会存在颜色错误)' }],
  374. [
  375. { value: "hiddenLogo", label: "logo" },
  376. { value: "hiddenHeader", label: "顶部悬浮模块" },
  377. { value: "hiddenHeaderScroll", label: "滚动顶部悬浮模块/问题名称" }
  378. ],
  379. [
  380. { value: "hiddenAppHeaderTabHome", label: "发现模块-首页" },
  381. { value: "hiddenAppHeaderTabZhi", label: "发现模块-知学堂" },
  382. // { value: 'hiddenAppHeaderTabVIP', label: '发现模块-会员' },
  383. { value: "hiddenAppHeaderTabWaitingForYou", label: "发现模块-等你来答" },
  384. { value: "hiddenAppHeaderTabFind", label: "发现模块-知乎直达" }
  385. ],
  386. [
  387. { value: "hiddenAnswerText", label: "回答操作文字" },
  388. { value: "hiddenWhoVoters", label: "回答隐藏用户信息下的附加信息,比如:你赞同过、XXX赞同了等..." }
  389. ],
  390. [
  391. { value: "hiddenCommitReply", label: "评论「回复」按钮" },
  392. { value: "hiddenCommitVote", label: "评论「点赞」按钮" },
  393. { value: "hiddenCommitBottom", label: "评论底部信息" }
  394. ],
  395. [{ value: "hiddenZhihuZhiShop", label: "知乎知学堂教育推广商品模块" }]
  396. ]
  397. },
  398. {
  399. key: "CTZ_HIDDEN_LIST",
  400. name: "列表",
  401. desc: "只在列表中隐藏相应内容",
  402. content: [
  403. [
  404. { value: "hiddenHomeCreatorEntrance", label: "创作中心" },
  405. { value: "hiddenHomeRecommendFollow", label: "推荐关注" },
  406. { value: "hiddenHomeCategory", label: "分类圆桌" },
  407. { value: "hiddenHomeCategoryMore", label: "更多分类" },
  408. { value: "hiddenHomeFooter", label: "知乎指南" },
  409. { value: "hiddenYanXuanWriter", label: "盐选作者平台" }
  410. ],
  411. [
  412. { value: "hiddenHomeListTab", label: "首页列表切换模块" },
  413. { value: "hiddenHomeListTabFollow", label: "首页列表切换 - 关注" },
  414. { value: "hiddenHomeListTabRecommend", label: "首页列表切换 - 推荐" },
  415. { value: "hiddenHomeListTabHot", label: "首页列表切换 - 热榜" },
  416. { value: "hiddenHomeListTabVideo", label: "首页列表切换 - 视频" }
  417. ],
  418. [
  419. { value: "hiddenHotItemIndex", label: "热门排序编号" },
  420. { value: "hiddenHotItemLabel", label: '热门"新"元素' },
  421. { value: "hiddenHotItemMetrics", label: "热门热度值" }
  422. ],
  423. [
  424. { value: "hiddenAnswers", label: "列表回答内容" },
  425. { value: "hiddenListVideoContent", label: "列表视频回答的内容" },
  426. { value: "hiddenItemActions", label: "列表回答操作" },
  427. { value: "hiddenListImg", label: "列表图片" },
  428. { value: "hiddenReadMoreText", label: "问题列表阅读全文文字" },
  429. { value: "hiddenListAnswerInPerson", label: "列表「亲自答」标签" }
  430. ],
  431. [
  432. { value: "hiddenFollowAction", label: "关注列表关注人操作栏" },
  433. { value: "hiddenFollowChooseUser", label: "关注列表用户信息" }
  434. ],
  435. [
  436. { value: "hiddenSearchBoxTopSearch", label: "搜索栏知乎热搜" },
  437. { value: "hiddenSearchPageTopSearch", label: "搜索页知乎热搜" },
  438. { value: "hiddenSearchPageFooter", label: "搜索页知乎指南" }
  439. ]
  440. ]
  441. },
  442. {
  443. key: "CTZ_HIDDEN_ANSWER",
  444. name: "问答",
  445. desc: "只在回答页面中隐藏相应内容",
  446. content: [
  447. [
  448. { value: "hiddenQuestionTag", label: "问题话题" },
  449. { value: "hiddenQuestionShare", label: "问题分享" },
  450. { value: "hiddenQuestionGoodQuestion", label: "「好问题」按钮" },
  451. { value: "hiddenQuestionComment", label: "添加评论" },
  452. { value: "hiddenQuestionMore", label: "问题更多「...」按钮" },
  453. { value: "hiddenQuestionActions", label: "问题操作栏" },
  454. { value: "hiddenQuestionSpecial", label: "问题专题收录标签" },
  455. { value: "hiddenQuestionFollowing", label: "问题关注按钮" },
  456. { value: "hiddenQuestionAnswer", label: "问题写回答按钮" },
  457. { value: "hiddenQuestionInvite", label: "问题邀请回答按钮" }
  458. ],
  459. [
  460. { value: "hiddenDetailAvatar", label: "回答人头像" },
  461. { value: "hiddenDetailName", label: "回答人姓名" },
  462. { value: "hiddenDetailBadge", label: "回答人简介" },
  463. { value: "hiddenDetailFollow", label: "回答人关注按钮" },
  464. { value: "hiddenDetailVoters", label: "回答人下赞同数" },
  465. { value: "hiddenQuestionSide", label: "问题关注和被浏览数" },
  466. { value: "hiddenFixedActions", label: "回答底部悬浮操作栏" },
  467. { value: "hiddenAnswerItemActions", label: "回答内容操作栏" },
  468. { value: "hiddenReward", label: "赞赏按钮" },
  469. { value: "hidden618HongBao", label: "618红包链接" }
  470. ],
  471. [
  472. { value: "hiddenAnswerItemTime", label: "回答底部发布编辑时间和IP" },
  473. { value: "hiddenAnswerItemTimeButHaveIP", label: "回答底部发布编辑时间(保留IP)" }
  474. ],
  475. [
  476. { value: "hiddenAnswerRightFooter", label: "详情右侧信息栏" },
  477. { value: "hiddenAnswerRightFooterAnswerAuthor", label: "信息栏关于作者" },
  478. { value: "hiddenAnswerRightFooterFavorites", label: "信息栏被收藏次数" },
  479. { value: "hiddenAnswerRightFooterRelatedQuestions", label: "信息栏相关问题" },
  480. { value: "hiddenAnswerRightFooterContentList", label: "信息栏相关推荐" },
  481. { value: "hiddenAnswerRightFooterFooter", label: "信息栏知乎指南" }
  482. ]
  483. ]
  484. },
  485. {
  486. key: "CTZ_HIDDEN_ARTICLE",
  487. name: "文章",
  488. desc: "只在文章页面中隐藏相应内容",
  489. content: [
  490. [
  491. { value: "hiddenZhuanlanTag", label: "文章关联话题" },
  492. { value: "hiddenZhuanlanActions", label: "文章底部悬浮操作栏" },
  493. { value: "hiddenZhuanlanTitleImage", label: "文章标题图片" },
  494. { value: "hiddenZhuanlanShare", label: "文章悬浮分享按钮" },
  495. { value: "hiddenZhuanlanVoters", label: "文章悬浮赞同按钮" },
  496. { value: "hiddenZhuanlanAvatarWrapper", label: "文章作者头像" },
  497. { value: "hiddenZhuanlanAuthorInfoHead", label: "文章作者姓名" },
  498. { value: "hiddenZhuanlanAuthorInfoDetail", label: "文章作者简介" },
  499. { value: "hiddenZhuanlanFollowButton", label: "文章作者关注按钮" }
  500. ]
  501. ]
  502. },
  503. {
  504. key: "CTZ_HIDDEN_USER_HOME",
  505. name: "用户主页",
  506. desc: "只在用户主页隐藏相应内容",
  507. content: [
  508. [
  509. { value: "hiddenUserHomeOtherCard", label: "用户主页付费咨询、认证和成就" },
  510. { value: "hiddenUserHomePublications", label: "用户主页出版作品" },
  511. { value: "hiddenUserHomeCreateEntrance", label: "用户主页创作中心" },
  512. { value: "hiddenUserHomeFollow", label: "用户主页关注和关注者卡片" },
  513. { value: "hiddenUserHomeLightList", label: "用户主页关注的内容和赞助" },
  514. { value: "hiddenUserHomeFooterOperate", label: "用户主页右侧屏蔽·举报用户、个人主页被浏览次数" },
  515. { value: "hiddenUserHomeFooter", label: "用户主页知乎指南" }
  516. ]
  517. ]
  518. },
  519. {
  520. key: "CTZ_HIDDEN_USER_COLLECTIONS",
  521. name: "收藏夹主页",
  522. desc: "只在我的收藏夹主页隐藏相应内容",
  523. content: [
  524. [
  525. { value: "hiddenCollectionsCreate", label: "收藏夹创作中心" },
  526. { value: "hiddenCollectionsRecommendFollow", label: "收藏夹推荐关注" },
  527. { value: "hiddenCollectionsCategory", label: "收藏夹圆桌入口" },
  528. { value: "hiddenCollectionsComplementary", label: "收藏夹更多分类" },
  529. { value: "hiddenCollectionsFooter", label: "收藏夹知乎指南" }
  530. ]
  531. ]
  532. },
  533. {
  534. key: "CTZ_HIDDEN_TOPIC",
  535. name: "话题",
  536. desc: "只在话题隐藏相应内容",
  537. content: [
  538. [
  539. { value: "hiddenTopicRightNumberBoard", label: "话题主页右侧浏览/讨论量模块" },
  540. { value: "hiddenTopicRightParentChild", label: "话题主页右侧父子话题模块" },
  541. { value: "hiddenTopicRightFooter", label: "话题主页右侧知乎指南" }
  542. ]
  543. ]
  544. }
  545. ];
  546. var FOOTER_HTML = `<a href="https://github.com/liuyubing233/zhihu-custom" target="_blank">Github⭐</a><a href="https://greasyfork.org/zh-CN/scripts/423404-%E7%9F%A5%E4%B9%8E%E6%A0%B7%E5%BC%8F%E4%BF%AE%E6%94%B9%E5%99%A8" target="_blank">GreasyFork</a>`;
  547. var DEFAULT_FUNCTION = [
  548. '外链直接打开<div class="ctz-commit">知乎里所有外部链接的重定向去除,可以直接访问</div>',
  549. "移除登录提示弹窗",
  550. '一键移除所有屏蔽选项,点击「话题黑名单」编辑按钮出现按钮<div class="ctz-commit">知乎<a href="https://www.zhihu.com/settings/filter" target="_blank">屏蔽页面</a>每次只显示部分内容,建议解除屏蔽后刷新页面查看是否仍然存在新的屏蔽标签</div>',
  551. '回答视频下载<div class="ctz-commit">回答内容视频左上角会生成一个下载按钮,点击即可下载视频</div>',
  552. '收藏夹内容导出为 PDF(需开启接口拦截)<div class="ctz-commit">点击收藏夹名称上方「生成PDF」按钮,可导出当前页码的收藏夹详细内容</div>',
  553. '个人主页「我关注的问题」、「我关注的收藏」可以一键移除或将移除的内容添加回关注<div class="ctz-commit">由于知乎接口的限制,关注及移除只能在对应页面中进行操作,所以点击「移除关注」按钮将打开页面到对应页面,取消或关注后此页面自动关闭,如果脚本未加载请刷新页面</div>',
  554. "推荐页内容链接根据有新到旧进行缓存,可缓存 100 条;缓存内容在「编辑器 - 历史记录 - 推荐列表缓存」",
  555. "可保存 100 条浏览历史记录链接,内容为打开的问题、文章、视频;「编辑器 - 历史记录 - 浏览历史记录」",
  556. '静态图片弹窗观看点击键盘左右直接切换到上一张或下一张<div class="ctz-commit">查看图片点击预览大图时,如果当前回答或者文章中存在多个图片,可以使用键盘方向键左右切换图片显示</div>',
  557. "用户主页-回答-导出当前页回答的功能(需开启接口拦截)",
  558. "用户主页-文章-导出当前页文章的功能(需开启接口拦截)"
  559. ];
  560. var ICO_URL = {
  561. zhihu: "https://static.zhihu.com/heifetz/favicon.ico",
  562. github: "https://github.githubassets.com/pinned-octocat.svg",
  563. juejin: "https://lf3-cdn-tos.bytescm.com/obj/static/xitu_juejin_web//static/favicons/favicon-32x32.png",
  564. csdn: "https://g.csdnimg.cn/static/logo/favicon32.ico",
  565. bilibili: "https://www.bilibili.com/favicon.ico",
  566. lanhu: "https://sso-cdn.lanhuapp.com/ssoweb/favicon.ico",
  567. yuque: "https://mdn.alipayobjects.com/huamei_0prmtq/afts/img/A*vMxOQIh4KBMAAAAAAAAAAAAADvuFAQ/original",
  568. mailQQ: "https://mail.qq.com/zh_CN/htmledition/images/favicon/qqmail_favicon_96h.png",
  569. mail163: "https://mail.163.com/favicon.ico",
  570. weibo: "https://weibo.com/favicon.ico",
  571. qzone: "https://qzonestyle.gtimg.cn/aoi/img/logo/favicon.ico?max_age=31536000",
  572. baidu: "https://www.baidu.com/favicon.ico"
  573. };
  574. var myStorage = {
  575. set: async function(name, value) {
  576. value.t = +/* @__PURE__ */ new Date();
  577. const v = JSON.stringify(value);
  578. localStorage.setItem(name, v);
  579. await GM.setValue(name, v);
  580. },
  581. get: async function(name) {
  582. const config = await GM.getValue(name);
  583. const configLocal = localStorage.getItem(name);
  584. const cParse = config ? JSON.parse(config) : null;
  585. const cLParse = configLocal ? JSON.parse(configLocal) : null;
  586. if (!cParse && !cLParse)
  587. return "";
  588. if (!cParse)
  589. return configLocal;
  590. if (!cLParse)
  591. return config;
  592. if (cParse.t < cLParse.t)
  593. return configLocal;
  594. return config;
  595. },
  596. getConfig: async function() {
  597. const nConfig = await this.get("pfConfig");
  598. return Promise.resolve(nConfig ? JSON.parse(nConfig) : {});
  599. },
  600. getHistory: async function() {
  601. const nHistory = await myStorage.get("pfHistory");
  602. const h2 = nHistory ? JSON.parse(nHistory) : { list: [], view: [] };
  603. return Promise.resolve(h2);
  604. },
  605. /** 修改配置中的值 */
  606. setConfigItem: async function(key, value) {
  607. const config = await this.getConfig();
  608. if (typeof key === "string") {
  609. config[key] = value;
  610. } else {
  611. for (let itemKey in key) {
  612. config[itemKey] = key[itemKey];
  613. }
  614. }
  615. await this.setConfig(config);
  616. },
  617. /** 更新配置 */
  618. setConfig: async function(params) {
  619. await this.set("pfConfig", params);
  620. },
  621. setHistoryItem: async function(key, params) {
  622. const pfHistory = await this.getHistory();
  623. pfHistory[key] = params.slice(0, SAVE_HISTORY_NUMBER);
  624. await this.set("pfHistory", pfHistory);
  625. },
  626. setHistory: async function(value) {
  627. await this.set("pfHistory", value);
  628. }
  629. };
  630. var dom = (n2) => document.querySelector(n2);
  631. var domById = (id) => document.getElementById(id);
  632. var domA = (n2) => document.querySelectorAll(n2);
  633. var domC = (name, attrObjs) => {
  634. const node = document.createElement(name);
  635. for (let key in attrObjs) {
  636. node[key] = attrObjs[key];
  637. }
  638. return node;
  639. };
  640. var domP = (node, attrName, attrValue) => {
  641. const nodeP = node.parentElement;
  642. if (!nodeP)
  643. return void 0;
  644. if (!attrName || !attrValue)
  645. return nodeP;
  646. if (nodeP === document.body)
  647. return void 0;
  648. const attrValueList = (nodeP.getAttribute(attrName) || "").split(" ");
  649. return attrValueList.includes(attrValue) ? nodeP : domP(nodeP, attrName, attrValue);
  650. };
  651. var insertAfter = (newElement, targetElement) => {
  652. const parent = targetElement.parentNode;
  653. if (parent.lastChild === targetElement) {
  654. parent.appendChild(newElement);
  655. } else {
  656. parent.insertBefore(newElement, targetElement.nextSibling);
  657. }
  658. };
  659. var fnReturnStr = (str, isHave = false, strFalse = "") => isHave ? str : strFalse;
  660. var fnLog = (...str) => console.log("%c「修改器」", "color: green;font-weight: bold;", ...str);
  661. var fnInitDomStyle = (id, innerHTML) => {
  662. const element = domById(id);
  663. element ? element.innerHTML = innerHTML : document.head.appendChild(domC("style", { id, type: "text/css", innerHTML }));
  664. };
  665. var fnDomReplace = (node, attrObjs) => {
  666. if (!node)
  667. return;
  668. for (let key in attrObjs) {
  669. node[key] = attrObjs[key];
  670. }
  671. };
  672. function throttle(fn, time = 300) {
  673. let tout = void 0;
  674. return function() {
  675. clearTimeout(tout);
  676. tout = setTimeout(() => {
  677. fn.apply(this, arguments);
  678. }, time);
  679. };
  680. }
  681. var pathnameHasFn = (obj) => {
  682. const { pathname } = location;
  683. for (let name in obj) {
  684. pathname.includes(name) && obj[name]();
  685. }
  686. };
  687. var windowResize = () => {
  688. window.dispatchEvent(new Event("resize"));
  689. };
  690. var mouseEventClick = (element) => {
  691. if (!element)
  692. return;
  693. const myWindow = isSafari ? window : unsafeWindow;
  694. const event = new MouseEvent("click", {
  695. view: myWindow,
  696. bubbles: true,
  697. cancelable: true
  698. });
  699. element.dispatchEvent(event);
  700. };
  701. var copy = async (value) => {
  702. if (navigator.clipboard && navigator.permissions) {
  703. await navigator.clipboard.writeText(value);
  704. } else {
  705. const domTextarea = domC("textArea", {
  706. value,
  707. style: "width: 0px;position: fixed;left: -999px;top: 10px;"
  708. });
  709. domTextarea.setAttribute("readonly", "readonly");
  710. document.body.appendChild(domTextarea);
  711. domTextarea.select();
  712. document.execCommand("copy");
  713. document.body.removeChild(domTextarea);
  714. }
  715. };
  716. var messageDoms = [];
  717. var message = (value, t2 = 3e3) => {
  718. const time = +/* @__PURE__ */ new Date();
  719. const classTime = `ctz-message-${time}`;
  720. const nDom = domC("div", {
  721. innerHTML: value,
  722. className: `${CLASS_MESSAGE} ${classTime}`
  723. });
  724. const domBox = domById(ID_MESSAGE_BOX);
  725. if (!domBox)
  726. return;
  727. domBox.appendChild(nDom);
  728. messageDoms.push(nDom);
  729. if (messageDoms.length > 3) {
  730. const prevDom = messageDoms.shift();
  731. prevDom && domBox.removeChild(prevDom);
  732. }
  733. setTimeout(() => {
  734. const nPrevDom = dom(`.${classTime}`);
  735. if (nPrevDom) {
  736. domById(ID_MESSAGE_BOX).removeChild(nPrevDom);
  737. messageDoms.shift();
  738. }
  739. }, t2);
  740. };
  741. var createBtnSmallTran = (innerHTML, extraCLass = "", extra = {}) => domC("button", {
  742. innerHTML,
  743. className: `ctz-button ctz-button-small ctz-button-transparent ${extraCLass}`,
  744. style: "margin: 0 4px;",
  745. ...extra
  746. });
  747. var judgeBrowserType = () => {
  748. const userAgent = navigator.userAgent;
  749. if (userAgent.includes("Firefox"))
  750. return "Firefox";
  751. if (userAgent.includes("Edg"))
  752. return "Edge";
  753. if (userAgent.includes("Chrome"))
  754. return "Chrome";
  755. return "Safari";
  756. };
  757. var isSafari = judgeBrowserType() === "Safari";
  758. var fnHidden = (ev, msg) => {
  759. ev.style.display = "none";
  760. fnLog(msg);
  761. };
  762. var fnJustNum = async (element) => {
  763. if (!element)
  764. return;
  765. const { justVoteNum, justCommitNum } = await myStorage.getConfig();
  766. const nodeVoteUp = element.querySelector(".VoteButton--up");
  767. if (justVoteNum && nodeVoteUp) {
  768. nodeVoteUp.style.cssText = "font-size: 14px!important;";
  769. nodeVoteUp.innerHTML = nodeVoteUp.innerHTML.replace("赞同 ", "");
  770. }
  771. if (justCommitNum) {
  772. const buttons = element.querySelectorAll(".ContentItem-actions button");
  773. for (let i2 = 0; i2 < buttons.length; i2++) {
  774. const btn = buttons[i2];
  775. if (btn.innerHTML.includes("条评论")) {
  776. btn.style.cssText = "font-size: 14px!important;margin-top:-5px;";
  777. btn.innerHTML = btn.innerHTML.replace("条评论", "");
  778. }
  779. }
  780. }
  781. };
  782. var BLOCK_WORDS_LIST = `#CTZ_BLOCK_WORD_LIST .ctz-block-words-content`;
  783. var BLOCK_WORDS_ANSWER = `#CTZ_BLOCK_WORD_CONTENT .ctz-block-words-content`;
  784. var NAME_BY_KEY = {
  785. filterKeywords: BLOCK_WORDS_LIST,
  786. blockWordsAnswer: BLOCK_WORDS_ANSWER
  787. };
  788. var createHTMLBlockText = (w2) => `<span data-title="${w2}">${createHTMLBlockTextContent(w2)}</span>`;
  789. var createHTMLBlockTextContent = (w2) => `<span>${w2}</span><i class="ctz-filter-word-remove">✗</i>`;
  790. var onRemove = async (e2, key) => {
  791. const target = e2.target;
  792. if (!target.classList.contains("ctz-filter-word-remove"))
  793. return;
  794. const domItem = target.parentElement;
  795. const title = domItem.dataset.title;
  796. const config = await myStorage.getConfig();
  797. domItem.remove();
  798. myStorage.setConfigItem(
  799. key,
  800. (config[key] || []).filter((i2) => i2 !== title)
  801. );
  802. };
  803. var onAddWord = async (target, key) => {
  804. const word = target.value;
  805. const config = await myStorage.getConfig();
  806. const configThis = config[key];
  807. if (!Array.isArray(configThis))
  808. return;
  809. configThis.push(word);
  810. await myStorage.setConfigItem(key, configThis);
  811. const domItem = domC("span", { innerHTML: createHTMLBlockTextContent(word) });
  812. domItem.dataset.title = word;
  813. const nodeFilterWords = dom(NAME_BY_KEY[key]);
  814. nodeFilterWords && nodeFilterWords.appendChild(domItem);
  815. target.value = "";
  816. };
  817. var initBlockWords = async () => {
  818. const config = await myStorage.getConfig();
  819. const arr = [
  820. { domFind: dom(BLOCK_WORDS_LIST), name: "filterKeywords", domInput: dom('[name="inputFilterWord"]') },
  821. { domFind: dom(BLOCK_WORDS_ANSWER), name: "blockWordsAnswer", domInput: dom('[name="inputBlockWordsAnswer"]') }
  822. ];
  823. for (let i2 = 0, len = arr.length; i2 < len; i2++) {
  824. const { domFind, name, domInput } = arr[i2];
  825. if (domFind) {
  826. const children = (config[name] || []).map((i3) => createHTMLBlockText(i3)).join("");
  827. domFind.innerHTML = children || "";
  828. domFind.onclick = (e2) => onRemove(e2, name);
  829. }
  830. domInput && (domInput.onchange = (e2) => onAddWord(e2.target, name));
  831. }
  832. };
  833. var echoData = async () => {
  834. const pfConfig = await myStorage.getConfig();
  835. const textSameName = {
  836. globalTitle: (e2) => e2.value = pfConfig.globalTitle || document.title,
  837. customizeCss: (e2) => e2.value = pfConfig.customizeCss || ""
  838. };
  839. const echoText = (even) => {
  840. textSameName[even.name] ? textSameName[even.name](even) : even.value = pfConfig[even.name];
  841. };
  842. const echo = {
  843. radio: (even) => pfConfig.hasOwnProperty(even.name) && String(even.value) === String(pfConfig[even.name]) && (even.checked = true),
  844. checkbox: (even) => even.checked = pfConfig[even.name] || false,
  845. text: echoText,
  846. number: echoText,
  847. range: (even) => {
  848. const nValue = pfConfig[even.name];
  849. const nodeRange = dom(`[name="${even.name}"]`);
  850. const min = nodeRange && nodeRange.min;
  851. const rangeNum = isNaN(+nValue) || !(+nValue > 0) ? min : nValue;
  852. even.value = rangeNum;
  853. const nodeNewOne = domById(even.name);
  854. nodeNewOne && (nodeNewOne.innerText = rangeNum);
  855. }
  856. };
  857. const doEcho = (item) => {
  858. echo[item.type] && echo[item.type](item);
  859. };
  860. const nodeArrInputClick = domA(`.${CLASS_INPUT_CLICK}`);
  861. for (let i2 = 0, len = nodeArrInputClick.length; i2 < len; i2++) {
  862. doEcho(nodeArrInputClick[i2]);
  863. }
  864. const nodeArrInputChange = domA(`.${CLASS_INPUT_CHANGE}`);
  865. for (let i2 = 0, len = nodeArrInputChange.length; i2 < len; i2++) {
  866. doEcho(nodeArrInputChange[i2]);
  867. }
  868. echo.text(dom('[name="globalTitle"]'));
  869. VERSION_RANGE.forEach((item) => {
  870. const isPercent = pfConfig[item.percentChooseValue];
  871. const domRange = dom(`.ctz-range-${item.value}`);
  872. const domRangePercent = dom(`.ctz-range-${item.percentValue}`);
  873. if (domRange && domRangePercent) {
  874. domRange.style.display = isPercent ? "none" : "flex";
  875. domRangePercent.style.display = !isPercent ? "none" : "flex";
  876. }
  877. });
  878. };
  879. var Store = class {
  880. constructor() {
  881. /** 用户信息 更改prev: userInfo */
  882. this.userinfo = void 0;
  883. this.findEvent = {
  884. header: { fun: null, num: 0, isFind: false }
  885. };
  886. /** 脚本内配置缓存 */
  887. this.storageConfig = {
  888. cacheTitle: "",
  889. fetchHeaders: {},
  890. headerDoms: {}
  891. };
  892. this.setUserinfo = this.setUserinfo.bind(this);
  893. this.getUserinfo = this.getUserinfo.bind(this);
  894. this.setFindEventItem = this.setFindEventItem.bind(this);
  895. this.getFindEventItem = this.getFindEventItem.bind(this);
  896. this.setStorageConfigItem = this.setStorageConfigItem.bind(this);
  897. this.getStorageConfigItem = this.getStorageConfigItem.bind(this);
  898. }
  899. setUserinfo(inner) {
  900. this.userinfo = inner;
  901. }
  902. getUserinfo() {
  903. return this.userinfo;
  904. }
  905. setFindEventItem(key, content) {
  906. this.findEvent[key] = content;
  907. }
  908. getFindEventItem(key) {
  909. return this.findEvent[key];
  910. }
  911. setStorageConfigItem(key, content) {
  912. this.storageConfig[key] = content;
  913. }
  914. getStorageConfigItem(key) {
  915. return this.storageConfig[key];
  916. }
  917. };
  918. var store = new Store();
  919. var regexpMessage = /^\([^()]+\)/;
  920. var changeTitle = async () => {
  921. const { getStorageConfigItem } = store;
  922. const { globalTitle, globalTitleRemoveMessage } = await myStorage.getConfig();
  923. const cacheTitle = getStorageConfigItem("cacheTitle");
  924. let prevTitle = globalTitle || cacheTitle;
  925. if (globalTitleRemoveMessage) {
  926. if (regexpMessage.test(prevTitle)) {
  927. prevTitle = prevTitle.replace(regexpMessage, "").trim();
  928. }
  929. }
  930. document.title = prevTitle;
  931. };
  932. var changeICO = async () => {
  933. const { titleIco = "" } = await myStorage.getConfig();
  934. const nId = "CTZ_ICO";
  935. if (!ICO_URL[titleIco])
  936. return;
  937. const nodeXIcon = dom('[type="image/x-icon"]');
  938. const nodeId = domById(nId);
  939. nodeXIcon && nodeXIcon.remove();
  940. nodeId && nodeId.remove();
  941. dom("head").appendChild(
  942. domC("link", {
  943. type: "image/x-icon",
  944. href: ICO_URL[titleIco],
  945. id: nId,
  946. rel: "icon"
  947. })
  948. );
  949. };
  950. var appendClassStart = (str) => appendPrefix(str, (i2) => `[class|="${i2}"]`);
  951. var appendPrefix = (str, mapCB) => str.split(",").map(mapCB).join(",");
  952. var myBackground = {
  953. init: async function() {
  954. const { themeDark = 1 /* 深色护眼一 */, themeLight = 0 /* 默认 */, colorText1 } = await myStorage.getConfig();
  955. const getBackground = async () => {
  956. if (await this.isUseDark())
  957. return this.dark(themeDark);
  958. if (+themeLight === 0 /* 默认 */)
  959. return this.default();
  960. return this.light(themeLight);
  961. };
  962. fnInitDomStyle("CTZ_STYLE_BACKGROUND", await getBackground() + fnReturnStr(`.ContentItem-title, body{color: ${colorText1}!important;}`, !!colorText1));
  963. },
  964. isUseDark: async () => {
  965. const { theme = 2 /* 自动 */ } = await myStorage.getConfig();
  966. if (+theme === 2 /* 自动 */) {
  967. return window.matchMedia("(prefers-color-scheme: dark)").matches;
  968. }
  969. return +theme === 1 /* 深色 */;
  970. },
  971. doSetCSS: function(bg1, bg2) {
  972. return `${this.cssBG1}{background-color: ${bg1}!important;}${this.cssBG2}{background-color:${bg2}!important;background:${bg2}!important;}${this.cssBGTransparent}{background-color: transparent!important;background: transparent!important;}${this.cssBG1Color}{color: ${bg1}!important}.SignContainer-content input:-webkit-autofill{-webkit-box-shadow: inset 0 0 0 30px ${bg2}!important;}`;
  973. },
  974. default: () => ".GlobalSideBar-navList{background: #fff}",
  975. light: function(lightKey) {
  976. const { background, background2 } = THEME_CONFIG_LIGHT[lightKey];
  977. const nodeAppHeader = dom(".AppHeader");
  978. const nodeTopStoryC = dom(".Topstory>div:not(.Topstory-container)");
  979. const elementHC = nodeAppHeader ? nodeAppHeader.classList || [] : [];
  980. const haveTopAD = nodeTopStoryC && nodeTopStoryC.childElementCount;
  981. const headerBelongAd = haveTopAD ? elementHC[elementHC.length - 1] : "";
  982. return this.doSetCSS(background, background2) + `.MenuBar-root-rQeFm{border-color: ${background}!important;}${headerBelongAd ? `.AppHeader:not(.${headerBelongAd})` : ".AppHeader"}{background-color:${background2}!important;background:${background2}!important;}.ctz-menu-top>a.target::before,.ctz-menu-top>a.target::after{${this.menuBeforeAfter(background2)}}`;
  983. },
  984. dark: function(darkKey) {
  985. const { background, background2 } = THEME_CONFIG_DARK[darkKey];
  986. const whiteText = `#${ID_DIALOG},.${CLASS_MESSAGE},#CTZ_MAIN input,#CTZ_MAIN textarea,.ctz-footer,#CTZ_CLOSE_DIALOG,.ctz-commit,#CTZ_OPEN_BUTTON,.ctz-export-collection-box p,.Modal-content,.Modal-content div,.Menu-item.is-active,.Select-list button:active,.Select-list button:hover,.Popover-content button,.Modal-title,.zu-main div,.modal-dialog,.zh-profile-card div,.QuestionAnswers-answerAdd div,.QuestionAnswers-answerAdd label,.Tabs-link,.toolbar-section button,.css-yd95f6,.css-g9ynb2,.css-i9srcr,.css-i9srcr div,.Modal-modal-wf58 div,.css-arjme8 div,.css-arjme8 label,.css-arjme8 h1,.css-13brsx3,.css-1ta275q div,.Creator-mainColumn .Card div,.Comments-container div,.SettingsMain div,.KfeCollection-PayModal-modal div,.KfeCollection-CouponCard-selectLabel,.KfeCollection-CouponCard-optionItem-text,.KfeCollection-PayModal-modal-icon,.NavItemClassName,.LinkCard-title,.Creator div,.Creator span,.Modal-wrapper textarea,.EditorHelpDoc,.EditorHelpDoc div,.EditorHelpDoc h1,.FeedbackModal-title,.css-r38x5n div,.css-1dwlho,.LiveDetailsPage-root-aLVPj div,.css-1b0ypf8 div,.css-1b0ypf8 a,.css-np3nxw div,.css-10ub9de,.css-1wbvd3d,.css-1f4cz9u,.css-y42e6l,.css-jiu0xt,.css-1myqwel,.PostEditor-wrapper>div:last-of-type div,.PostEditor-wrapper>div:last-of-type label,.ToolsQuestion a,.ToolsQuestion font,.utils-frostedGlassEffect-2unM div,.utils-frostedGlassEffect-2unM span,.aria-primary-color-style.aria-secondary-background,.aria-primary-color-style.aria-secondary-background div,.aria-primary-color-style.aria-secondary-background h1,.aria-primary-color-style.aria-secondary-background a,.aria-primary-color-style.aria-secondary-background p,.aria-primary-color-style.aria-secondary-background h2,#feedLives div,#feedLives a,.Card-card-2K6v,.Card-card-2K6v div,.Card-card-2K6v h3,._Invite_container_30SP h2,._Invite_container_30SP h1,.ChatListGroup-SectionTitle .Zi,.Qrcode-container>div,.Qrcode-guide-message>div,.signQr-leftContainer button,.signQr-leftContainer a,.ExploreHomePage-square div,.ExploreHomePage-square a,.jsNavigable a,#TopstoryContent h2,[role="contentinfo"] div,.css-1e1wubc,.css-1e1wubc div,.css-12kq1qx,.css-172osot div,.css-172osot a:last-child,.css-f2jj4r,.css-10u695f,.css-wqf2py,.css-wmwsyx,.css-wmwsyx div,.CreatorSalt-personalInfo-name,.css-c3gbo3,.css-1ygg4xu blockquote,.css-r8ate4,.ant-collapse>.ant-collapse-item>.ant-collapse-header,.Creator-salt-new-author-menu .Creator-salt-new-author-route .ant-menu-submenu-title:hover,.Creator-salt-author-welfare .Creator-salt-author-welfare-card h1,.css-u56wtg,.css-1hrberl,.css-13e6wvn,.css-i0heim,.CommentContent,${appendClassStart("index-title,CourseConsultation-tip,index-text,index-number,CourseDescription-playCount,LecturerList-title,LearningRouteCard-title,index-tabItemLabel,VideoCourseCard-module,TextTruncation-module")}{color: #f7f9f9!important}`;
  987. const blankText = `css-1x3upj1,.PlaceHolder-inner,.PlaceHolder-mask path,.css-1kxql2v{color: ${background2}!important}`;
  988. const linkText = `.css-1esjagr,.css-ruirke,.css-117anjg a.UserLink-link,.RichContent--unescapable.is-collapsed .ContentItem-rightButton,.css-1qap1n7,.ContentItem-more,.ContentItem-title a:hover,.Profile-lightItem:hover,.Profile-lightItem:hover .Profile-lightItemValue,.css-p54aph:hover,.PushNotifications-item a:hover,.PushNotifications-item a,.NotificationList-Item-content .NotificationList-Item-link:hover,.SettingsQA a,a.QuestionMainAction:hover,.SimilarQuestions-item .Button,.CreatorSalt-IdentitySelect-Button,.signQr-leftContainer button:hover,.signQr-leftContainer a:hover,.Profile-sideColumnItemLink:hover,.FollowshipCard-link,.css-zzimsj:hover,.css-vphnkw,.css-1aqu4xd,.css-6m0nd1,.NumberBoard-item.Button:hover .NumberBoard-itemName, .NumberBoard-item.Button:hover .NumberBoard-itemValue, .NumberBoard-itema:hover .NumberBoard-itemName, .NumberBoard-itema:hover .NumberBoard-itemValue,a.external,.RichContent-EntityWord,.SideBarCollectionItem-title,.Tag-content,.LabelContainer div,.LabelContainer a,.KfeCollection-OrdinaryLabel-newStyle-mobile .KfeCollection-OrdinaryLabel-content,.KfeCollection-OrdinaryLabel-newStyle-pc .KfeCollection-OrdinaryLabel-content,.KfeCollection-CreateSaltCard-button,.KfeCollection-PcCollegeCard-searchMore{color: deepskyblue!important;}.css-1tu59u4,.ZDI,.ZDI--PencilCircleFill24,.Zi,.Zi--ArrowDown{fill: deepskyblue!important;}`;
  989. const extraBG1 = `.ztext pre,.ztext code{background: ${background}!important;}`;
  990. return (
  991. // 这里不使用 addPrefix 添加前缀是因为 menuBeforeAfter 方法里背景色存在逗号
  992. `html[data-theme=dark] .ctz-menu-top>a.target::before,html[data-theme=dark] .ctz-menu-top>a.target::after{${this.menuBeforeAfter(background2)}}` + appendPrefix(
  993. this.doSetCSS(background, background2) + whiteText + blankText + linkText + extraBG1 + `#${ID_DIALOG}{border: 1px solid ${background2}}.ctz-button{background: ${background2};border-color: #f7f9f9;color: #f7f9f9;}`,
  994. (i2) => `html[data-theme=dark] ${i2}`
  995. // 添加 html[data-theme=dark] 前缀
  996. )
  997. );
  998. },
  999. /** 使用背景色1的元素名称 */
  1000. cssBG1: `#${ID_DIALOG},.ctz-content-right>div:nth-of-type(2n),.ctz-content-left>a:hover,.ctz-black-item,.ctz-block-words-content>span,body,.Input-wrapper,.toolbar-section button:hover,.VideoAnswerPlayer-stateBar,.skeleton,.Community-ContentLayout,.css-i9srcr,.css-i9srcr div,.css-127i0sx,.css-1wi7vwy,.css-1ta275q,.css-mk7s6o,.css-1o83xzo .section div,.PostItem,.Report-list tr:nth-child(odd),.LinkCard.new,.Post-content,.Post-content .ContentItem-actions,.Messages-newItem,.Modal-wrapper textarea,.New-RightCard-Outer-Dark,.WriteIndexLayout-main,.Messages-item:hover,.Menu-item.is-active,.css-djayhh,.css-5i468k,.css-1iazx5e div,.LiveDetailsPage-root-aLVPj,.WikiLanding,.GlobalSideBar-navLink:hover,.Popover-arrow:after,.Sticky button:hover,.Sticky button:hover div,.Sticky button:hover span,.Sticky a:hover,.Sticky a:hover button,.Sticky a:hover div,.Sticky a:hover span,.Sticky li:hover,.Popover-content button:hover,.css-1j8bif6>.css-11v6bw0,.css-1e1wubc,.css-1svx44c,.css-5d3bqp,.index-videoCardItem-bzeJ1,.KfeCollection-IntroCard-newStyle-mobile,.KfeCollection-IntroCard-newStyle-pc,.FeeConsultCard,.Avatar,.TextMessage-sender,.ChatUserListItem--active,.css-yoby3j,.css-wmwsyx,.css-wmwsyx button,.css-82b621,.Creator-salt-new-author-menu .Creator-salt-new-author-route .ant-menu-submenu-title:hover,.Creator-salt-new-author-menu .Creator-salt-new-author-route .ant-menu-item:hover,.index-learnPath-dfrcu .index-learnContainer-9QR37 .index-learnShow-p3yvw .index-learnCard-vuCza,.index-courseCard-ebw4r,${appendClassStart("Tabs-container,EpisodeList-sectionItem")}`,
  1001. /** 使用背景色2的元素名称 */
  1002. cssBG2: `#CTZ_MAIN input,#CTZ_MAIN textarea,.${CLASS_MESSAGE},.ctz-content,.ctz-menu-top>a.target,.ctz-menu-top>a:hover span,#CTZ_OPEN_BUTTON,#CTZ_CLOSE_DIALOG:hover,.Card,.HotItem,.AppHeader,.Topstory-content>div,.PlaceHolder-inner,.PlaceHolder-bg,.ContentItem-actions,.QuestionHeader,.QuestionHeader-footer ,.QZcfWkCJoarhIYxlM_sG,.Sticky,.SearchTabs,.Modal-inner,.Modal-content,.Modal-content div,.Select-list button:active,.Select-list button:hover,.modal-dialog,.modal-dialog-buttons,.zh-profile-card div,.QuestionAnswers-answerAdd div,.css-1j23ebo,.Modal-modal-wf58 div,.css-arjme8 div,.css-arjme8 h1,.css-2lvw8d,.css-1os3m0m,.css-r38x5n div,.css-1mbpn2d,.css-1yjqd5z,.Creator-mainColumn .Card>div,.Creator-mainColumn section,.Topbar,.AutoInviteItem-wrapper--desktop,.ProfileHeader-wrapper,.NotificationList,.SettingsFAQ,.SelectorField-options .Select-option.is-selected,.SelectorField-options .Select-option:focus,.KfeCollection-PayModal-modal,.KfeCollection-PayModal-modal div,.Community,.Report-header th,.Report-list tr:nth-child(2n),.Report-Pagination,.CreatorIndex-BottomBox-Item,.CreatorSalt-letter-wrapper,.ColumnPageHeader,.WriteIndexLayout-main>div,.EditorHelpDoc,.EditorHelpDoc div,.EditorHelpDoc h1,.PostEditor-wrapper>div:last-of-type div,.Creator-salt-new-author-content,.Select-option:focus,.ToolsQuestion div,[role="tablist"],.Topic-bar,.List-item .ZVideoToolbar button,.Creator-salt-author-welfare .Creator-salt-author-welfare-card,.Creator-salt-author-welfare-banner,#AnswerFormPortalContainer div,.CreatorTable-tableHead,.BalanceTransactionList-Item,.utils-frostedGlassEffect-2unM,#feedLives,#feedLives div,#feedLives a,.aria-primary-color-style.aria-secondary-background,.aria-primary-color-style.aria-secondary-background div,.aria-primary-color-style.aria-secondary-background h1,.aria-primary-color-style.aria-secondary-background a,.css-1o83xzo,.css-1o83xzo .section,.css-1cr4989,.css-xoei2t,.css-slqtjm,.css-1615dnb div,.css-1oqbvad,.css-1oqbvad div,.css-lxxesj div:not(.css-zprod5),.Card-card-2K6v,.Card-card-2K6v div,.LiveDetailsPage-root-aLVPj div,.LiveFooter-root-rXuoG,.css-1b0ypf8 div,.css-np3nxw div,.css-1i12cbe,.PubIndex-CategoriesHeader,.ColumnHomeColumnCard,.Home-tabs,.Home-tabs div,.Home-swiper-container,.Home-swiper-container div,.BottomBarContainer,.ResponderPage-root div,.WikiLandingItemCard,.WikiLandingEntryCard,._Invite_container_30SP,._Invite_container_30SP div,._Coupon_intro_1kIo,._Coupon_list_2uTb div,.ExploreHomePage-square div,.ExploreHomePage-ContentSection-moreButton a,.ExploreSpecialCard,.ExploreRoundtableCard,.ExploreCollectionCard,.ExploreColumnCard,.Notification-white,.QuestionAnswers-answerAdd .InputLike,.QuestionAnswers-answerAdd .InputLike div,.InputLike,.CreatorSalt-community-story-wrapper .CreatorSalt-community-story-table,.Popover-content,.Notifications-footer,.Messages-footer,.Popover-arrow:after,.css-97fdvh>div,.css-4lspwd,.css-1e6hvbc,.css-k32okj,.ant-table-tbody>tr.ant-table-placeholder:hover>td,.SettingsMain>div div:not(.StickerItem-Border):not(.SettingsMain-sideColumn):not(.UserHeader-VipBtn):not(.UserHeader-VipTip):not(.css-60n72z div),.CreatorSalt-community-story-wrapper,.css-guh6n2,.css-yqosku,.css-kt4t4n,.css-1j8bif6>div,.css-nffy12:hover,.css-1eltcns,.css-9kvgnm,.css-jd7qm7,.css-19vq0tc,.css-rzwcnm,.css-1akh9z6,.ListShortcut>div:not(.Question-mainColumn),.Chat,.ActionMenu,.Recommendations-Main,.KfeCollection-PcCollegeCard-root,.CreatorSalt-sideBar-wrapper,.ant-menu,.signQr-container,.signQr-rightContainer>div,.Login-options,.Input-wrapper>input,.SignFlowInput-errorMask,.Write-school-search-bar .CreatorSalt-management-search,.CreatorSalt-Content-Management-Index,.Topstory-container .TopstoryTabs>a::after,.ZVideo,.KfeCollection-CreateSaltCard,.CreatorSalt-personalInfo,.CreatorSalt-sideBar-item,.css-d1sc5t,.css-1gvsmgz,.css-u56wtg,.css-1hrberl,.CreatorSalt-community-story-wrapper .CreatorSalt-community-story-header,.ant-table-tbody>tr>td,.CreatorSalt-management-wrapper .CreatorSalt-management-search,.ant-table-thead .ant-table-cell,.QuestionWaiting-typesTopper,${appendClassStart(
  1003. "App-root,PcContent-root,TopNavBar-root,CourseConsultation-corner,CourseConsultation-cornerButton,CornerButtonToTop-cornerButton,LearningRouteCard-pathContent,index-item,index-hoverCard,ShelfTopNav-root,ProductCard-root,NewOrderedLayout-root,Tabs-tabHeader,ButtonBar-root,WebPage-root,LearningPathWayCard-pathItem,VideoCourseList-title,Article-header,PcContent-coverFix,index-module,TopNavBar-module,PcContent-module,CourseRecord-module,Learned-module,Tab-module,PcContentBought-module,Media-module"
  1004. )}`,
  1005. /** 背景色透明的元素名称 */
  1006. cssBGTransparent: `.zhuanlan .Post-content .RichContent-actions.is-fixed,.AnnotationTag,.ProfileHeader-wrapper,.css-1ggwojn,.css-3dzt4y,.css-u4sx7k,.VideoPlaceholderContainer>section,.MoreAnswers .List-headerText,.ColumnHomeTop:before,.ColumnHomeBottom,.Popover button,.ChatUserListItem .Chat-ActionMenuPopover-Button`,
  1007. cssBG1Color: `.css-z0izby`,
  1008. menuBeforeAfter: (color, size = "12px") => `background: radial-gradient(circle at top left, transparent ${size}, ${color} 0) top left,radial-gradient(circle at top right, transparent ${size}, ${color} 0) top right,radial-gradient(circle at bottom right, transparent ${size}, ${color} 0) bottom right,radial-gradient(circle at bottom left, transparent ${size}, ${color} 0) bottom left;background-size: 50% 50%;background-repeat: no-repeat;`
  1009. };
  1010. var myCustomStyle = {
  1011. init: async function() {
  1012. const { customizeCss = "" } = await myStorage.getConfig();
  1013. dom('[name="textStyleCustom"]').value = customizeCss;
  1014. this.change(customizeCss);
  1015. },
  1016. change: (innerCus) => fnInitDomStyle("CTZ_STYLE_CUSTOM", innerCus)
  1017. };
  1018. var onUseThemeDark = async () => {
  1019. dom("html").setAttribute("data-theme", await isDark() ? "dark" : "light");
  1020. };
  1021. var loadFindTheme = () => {
  1022. onUseThemeDark();
  1023. const elementHTML = dom("html");
  1024. const muConfig = { attribute: true, attributeFilter: ["data-theme"] };
  1025. if (!elementHTML)
  1026. return;
  1027. const muCallback = async function() {
  1028. const themeName = elementHTML.getAttribute("data-theme");
  1029. const dark = await isDark();
  1030. if (themeName === "dark" && !dark || themeName === "light" && dark) {
  1031. onUseThemeDark();
  1032. }
  1033. };
  1034. const muObserver = new MutationObserver(muCallback);
  1035. muObserver.observe(elementHTML, muConfig);
  1036. };
  1037. var isDark = async () => await myBackground.isUseDark();
  1038. var radioBackground = (name, value, background, color, label) => `<label><input class="${CLASS_INPUT_CLICK}" name="${name}" type="radio" value="${value}"/><div style="background: ${background};color: ${color}">${label}</div></label>`;
  1039. var themeToRadio = (o2, className, color) => Object.keys(o2).map((key) => radioBackground(className, key, o2[key].background, color, o2[key].name)).join("");
  1040. var addBackgroundSetting = () => {
  1041. dom(".ctz-set-background").innerHTML = `<div id="CTZ_BACKGROUND">${THEMES.map((i2) => radioBackground(INPUT_NAME_THEME, i2.value, i2.background, i2.color, i2.label)).join("")}</div><div class="ctz-commit">浅色颜色选择:</div><div id="CTZ_BACKGROUND_LIGHT">${themeToRadio(THEME_CONFIG_LIGHT, INPUT_NAME_ThEME_LIGHT, "#000")}</div><div class="ctz-commit">深色颜色选择:</div><div id="CTZ_BACKGROUND_DARK">${themeToRadio(THEME_CONFIG_DARK, INPUT_NAME_THEME_DARK, "#f7f9f9")}</div>`;
  1042. };
  1043. var myLock = {
  1044. append: async function(e2, name) {
  1045. if (!e2)
  1046. return;
  1047. const lock = this.lock.class;
  1048. const unlock = this.unlock.class;
  1049. const lockMask = this.lockMask.class;
  1050. const classRemove = "ctz-move-this";
  1051. const iLock = domC("i", { className: `${this.lock.name}`, innerHTML: "☑︎" });
  1052. const iUnlock = domC("i", { className: `${this.unlock.name}`, innerHTML: "☒" });
  1053. const dLockMask = domC("div", { className: this.lockMask.name });
  1054. !e2.querySelector(lock) && e2.appendChild(iLock);
  1055. !e2.querySelector(unlock) && e2.appendChild(iUnlock);
  1056. !e2.querySelector(lockMask) && e2.appendChild(dLockMask);
  1057. const pfConfig = await myStorage.getConfig();
  1058. e2.querySelector(lock).onclick = async () => {
  1059. await myStorage.setConfigItem(name + "Fixed", true);
  1060. e2.classList.remove(classRemove);
  1061. };
  1062. e2.querySelector(unlock).onclick = async () => {
  1063. await myStorage.setConfigItem(name + "Fixed", false);
  1064. e2.classList.add(classRemove);
  1065. };
  1066. if (pfConfig[name + "Fixed"] === false) {
  1067. e2.classList.add(classRemove);
  1068. }
  1069. },
  1070. remove: function(e2) {
  1071. if (!e2)
  1072. return;
  1073. const nodeLock = e2.querySelector(this.lock.class);
  1074. const nodeUnlock = e2.querySelector(this.unlock.class);
  1075. const nodeLockMask = e2.querySelector(this.lockMask.class);
  1076. nodeLock && nodeLock.remove();
  1077. nodeUnlock && nodeUnlock.remove();
  1078. nodeLockMask && nodeLockMask.remove();
  1079. },
  1080. lock: { class: ".ctz-lock", name: "ctz-lock" },
  1081. unlock: { class: ".ctz-unlock", name: "ctz-unlock" },
  1082. lockMask: { class: ".ctz-lock-mask", name: "ctz-lock-mask" }
  1083. };
  1084. var myMove = {
  1085. init: function(eventName, configName, name) {
  1086. const e2 = dom(eventName);
  1087. if (e2) {
  1088. this.clicks[configName] = e2.click;
  1089. e2.onmousedown = async (ev) => {
  1090. const pfConfig = await myStorage.getConfig();
  1091. if (pfConfig[`${name}Fixed`])
  1092. return;
  1093. const event = window.event || ev;
  1094. const bodyW = document.body.offsetWidth;
  1095. const windowW = window.innerWidth;
  1096. const windowH = window.innerHeight;
  1097. const eW = e2.offsetWidth;
  1098. const eH = e2.offsetHeight;
  1099. const eL = e2.offsetLeft;
  1100. const eT = e2.offsetTop;
  1101. const evX = event.clientX;
  1102. const evY = event.clientY;
  1103. const dx = evX - eL;
  1104. const dy = evY - eT;
  1105. const rx = eW + eL - evX;
  1106. document.onmousemove = (ev2) => {
  1107. const eventN = window.event || ev2;
  1108. const evNX = eventN.clientX;
  1109. let evenLeft = 0;
  1110. let evenRight = 0;
  1111. const isR = this.useR.find((i2) => i2 === name);
  1112. if (isR) {
  1113. const right = bodyW - evNX - rx;
  1114. evenRight = right <= 0 ? 0 : right >= bodyW - eW ? bodyW - eW : right;
  1115. e2.style.right = evenRight + "px";
  1116. } else {
  1117. const left = evNX - dx;
  1118. evenLeft = left <= 0 ? 0 : left >= windowW - eW ? windowW - eW : left;
  1119. e2.style.left = evenLeft + "px";
  1120. }
  1121. const top = eventN.clientY - dy;
  1122. const evenTop = top <= 0 ? 0 : top >= windowH - eH ? windowH - eH : top;
  1123. e2.style.top = evenTop + "px";
  1124. this.isMove = true;
  1125. this.timer[configName] && clearTimeout(this.timer[configName]);
  1126. this.timer[configName] = setTimeout(async () => {
  1127. clearTimeout(this.timer[configName]);
  1128. await myStorage.setConfigItem(configName, `${isR ? `right: ${evenRight}px;` : `left: ${evenLeft}px;`}top: ${evenTop}px;`);
  1129. }, 500);
  1130. };
  1131. document.onmouseup = () => {
  1132. document.onmousemove = null;
  1133. document.onmouseup = null;
  1134. e2.onclick = (e3) => {
  1135. if (this.isMove) {
  1136. this.isMove = false;
  1137. return e3.preventDefault && e3.preventDefault();
  1138. } else {
  1139. return this.clicks[configName];
  1140. }
  1141. };
  1142. };
  1143. if (e2.preventDefault) {
  1144. e2.preventDefault();
  1145. } else {
  1146. return false;
  1147. }
  1148. };
  1149. }
  1150. },
  1151. destroy: function(eventName) {
  1152. const e2 = dom(eventName);
  1153. e2 && (e2.onmousedown = null);
  1154. },
  1155. isMove: false,
  1156. clicks: {},
  1157. timer: {},
  1158. useL: ["suspensionHomeTab", "suspensionFind", "suspensionSearch"],
  1159. // 使用left定位的name
  1160. useR: ["suspensionUser"]
  1161. // 使用right定位的name
  1162. };
  1163. var CLASS_VIDEO_ONE = ".css-1h1xzpn";
  1164. var CLASS_VIDEO_TWO = ".VideoAnswerPlayer-video";
  1165. var NEED_LINK_CLASS = [CLASS_VIDEO_ONE, CLASS_VIDEO_TWO];
  1166. var findDoms = (nodeFound, domNames) => {
  1167. const doms = domNames.map((i2) => nodeFound.querySelectorAll(i2));
  1168. for (let i2 = 0, len = doms.length; i2 < len; i2++) {
  1169. if (doms[i2].length) {
  1170. return doms[i2];
  1171. }
  1172. }
  1173. return doms[doms.length - 1];
  1174. };
  1175. var initVideoDownload = async (nodeFound) => {
  1176. const { videoUseLink } = await myStorage.getConfig();
  1177. const domVideos = findDoms(
  1178. nodeFound,
  1179. [".ZVideo-player>div", CLASS_VIDEO_ONE, CLASS_VIDEO_TWO].filter((i2) => {
  1180. return videoUseLink ? !NEED_LINK_CLASS.includes(i2) : true;
  1181. })
  1182. );
  1183. for (let i2 = 0, len = domVideos.length; i2 < len; i2++) {
  1184. const domVideoBox = domVideos[i2];
  1185. const nDomDownload = domC("i", { className: "ctz-video-download", innerHTML: "⤓" });
  1186. const nDomLoading = domC("i", { className: "ctz-loading", innerHTML: "↻" });
  1187. nDomDownload.onclick = () => {
  1188. const srcVideo = domVideoBox.querySelector("video").src;
  1189. if (srcVideo) {
  1190. nDomDownload.style.display = "none";
  1191. domVideoBox.appendChild(nDomLoading);
  1192. videoDownload(srcVideo, `video${+/* @__PURE__ */ new Date()}`).then(() => {
  1193. nDomDownload.style.display = "block";
  1194. nDomLoading.remove();
  1195. });
  1196. }
  1197. };
  1198. const nodeDownload = domVideoBox.querySelector(".ctz-video-download");
  1199. nodeDownload && nodeDownload.remove();
  1200. domVideoBox.style.cssText += `position: relative;`;
  1201. domVideoBox.appendChild(nDomDownload);
  1202. }
  1203. };
  1204. var videoDownload = async (url, name) => {
  1205. return fetch(url).then((res) => res.blob()).then((blob) => {
  1206. const objectUrl = window.URL.createObjectURL(blob);
  1207. const elementA = domC("a", {
  1208. download: name,
  1209. href: objectUrl
  1210. });
  1211. elementA.click();
  1212. window.URL.revokeObjectURL(objectUrl);
  1213. elementA.remove();
  1214. });
  1215. };
  1216. var fixVideoAutoPlay = () => {
  1217. var originalPlay = HTMLMediaElement.prototype.play;
  1218. HTMLMediaElement.prototype.play = function() {
  1219. if (!this.offsetHeight) {
  1220. return;
  1221. }
  1222. return originalPlay.apply(this, arguments);
  1223. };
  1224. };
  1225. var myVersion = {
  1226. init: async function() {
  1227. fnInitDomStyle(
  1228. "CTZ_STYLE_VERSION",
  1229. await this.versionWidth() + await this.vImgSize() + await this.vQuestionTitleTag() + await this.vSusHomeTab() + await this.vSusHeader() + await this.vFixedListMore() + await this.vHighlightListItem() + await this.vShoppingLink() + await this.vFontSizeContent() + await this.vListVideoSize() + await this.vVideoLink()
  1230. );
  1231. },
  1232. initAfterLoad: async function() {
  1233. const pfConfig = await myStorage.getConfig();
  1234. domById("CTZ_IMAGE_SIZE_CUSTOM").style.display = pfConfig.zoomImageType === "2" ? "block" : "none";
  1235. domById("CTZ_IMAGE_HEIGHT_CUSTOM").style.display = pfConfig.zoomImageHeight === "1" ? "block" : "none";
  1236. domById("CTZ_LIST_VIDEO_SIZE_CUSTOM").style.display = pfConfig.zoomListVideoType === "2" ? "block" : "none";
  1237. },
  1238. change: function() {
  1239. this.initAfterLoad();
  1240. this.init();
  1241. },
  1242. /** 页面内容宽度修改 */
  1243. versionWidth: async function() {
  1244. const {
  1245. commitModalSizeSameVersion,
  1246. versionHome,
  1247. versionAnswer,
  1248. versionArticle,
  1249. versionHomeIsPercent,
  1250. versionHomePercent,
  1251. versionAnswerIsPercent,
  1252. versionAnswerPercent,
  1253. versionArticleIsPercent,
  1254. versionArticlePercent
  1255. } = await myStorage.getConfig();
  1256. const widthHome = !versionHomeIsPercent ? `${versionHome || "1000"}px` : `${versionHomePercent || "70"}vw`;
  1257. const widthAnswer = !versionAnswerIsPercent ? `${versionAnswer || "1000"}px` : `${versionAnswerPercent || "70"}vw`;
  1258. const widthArticle = !versionArticleIsPercent ? `${versionArticle || "1000"}px` : `${versionArticlePercent || "70"}vw`;
  1259. const rightArticleActions = !versionArticleIsPercent ? `calc(50vw - ${+(versionArticle || "1000") / 2 + 150}px)` : `calc(50vw - ${+(versionArticlePercent || "70") / 2}vw + 150px)`;
  1260. const CLASS_MODAL = ".css-1aq8hf9";
  1261. const sizeModalInAnswer = fnReturnStr(`${CLASS_MODAL}{width: ${widthAnswer}!important;}`, location.pathname.includes("question"));
  1262. const sizeModal = fnReturnStr(
  1263. `.Topstory-body ${CLASS_MODAL}{width: ${widthHome}!important;}` + sizeModalInAnswer + `.PostIndex-body ${CLASS_MODAL}{width: ${widthArticle}!important;}`,
  1264. commitModalSizeSameVersion
  1265. );
  1266. const sizeHome = `.Topstory-mainColumn,.SearchMain{width: ${widthHome}!important;}.Topstory-container,.css-knqde,.Search-container{width: fit-content!important;}`;
  1267. const sizeAnswer = `.Question-main .Question-mainColumn,.QuestionHeader-main{flex: 1;}.Question-main .Question-sideColumn{margin-left: 12px;}.QuestionHeader .QuestionHeader-content{margin: 0 auto;padding: 0;max-width: initial!important;}.Question-main,.QuestionHeader-footer-inner,.QuestionHeader .QuestionHeader-content{width: ${widthAnswer}!important;}.Question-main .List-item{border-bottom: 1px dashed #ddd;}`;
  1268. const sizeArticle = `.zhuanlan .AuthorInfo,.zhuanlan .css-1xy3kyp{max-width: initial;}.Post-NormalMain .Post-Header,.Post-NormalMain>div,.Post-NormalSub>div,.zhuanlan .css-1xy3kyp,.zhuanlan .css-1voxft1,.zhuanlan .css-9w3zhd{width: ${widthArticle}!important;}.zhuanlan .Post-SideActions{right: ${rightArticleActions}}`;
  1269. const sizeMinWidth = `.Topstory-mainColumn,.SearchMain,.Question-main,.QuestionHeader-footer-inner,.QuestionHeader .QuestionHeader-content,.Post-NormalMain .Post-Header,.Post-NormalMain>div,.Post-NormalSub>div,${CLASS_MODAL},.Topstory-body ${CLASS_MODAL},.PostIndex-body ${CLASS_MODAL}{min-width: ${VERSION_MIN_WIDTH}px!important;}`;
  1270. return sizeHome + sizeAnswer + sizeArticle + sizeModal + sizeMinWidth;
  1271. },
  1272. /** 图片尺寸修改 */
  1273. vImgSize: async function() {
  1274. const { zoomImageType, zoomImageHeight, zoomImageHeightSize, zoomImageSize } = await myStorage.getConfig();
  1275. const nWidth = zoomImageType === "2" ? `width: ${zoomImageSize}px!important;cursor: zoom-in!important;max-width: 100%!important;` : "";
  1276. const nHeight = zoomImageHeight === "1" ? `max-height: ${zoomImageHeightSize}px!important;width: auto!important;` : "";
  1277. return `.GifPlayer.isPlaying img {cursor:pointer!important;}img.lazy,img.origin_image,.GifPlayer img,.ArticleItem-image,.ztext figure .content_image,.ztext figure .origin_image,.TitleImage{${nHeight || nWidth}}`;
  1278. },
  1279. /** 列表视频回答内容尺寸修改 */
  1280. vListVideoSize: async function() {
  1281. const pfConfig = await myStorage.getConfig();
  1282. return `.ZVideoItem>div:first-of-type{${fnReturnStr(`width: ${pfConfig.zoomListVideoSize}px!important;`, pfConfig.zoomListVideoType === "2")}}`;
  1283. },
  1284. /** 列表更多按钮移动至题目右侧 */
  1285. vFixedListMore: async function() {
  1286. const pfConfig = await myStorage.getConfig();
  1287. return fnReturnStr(
  1288. `.Topstory-container .ContentItem-actions .ShareMenu ~ div.ContentItem-action{visibility: visible!important;position: absolute;top: 20px;right: 10px;}`,
  1289. pfConfig.fixedListItemMore
  1290. );
  1291. },
  1292. /** 内容标题添加类别显示 */
  1293. vQuestionTitleTag: async function() {
  1294. const pfConfig = await myStorage.getConfig();
  1295. const cssTag = "margin-right:6px;font-weight:normal;display:inline;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff";
  1296. return fnReturnStr(
  1297. `.AnswerItem .ContentItem-title::before{content:'问答';background:#ec7259}.TopstoryItem .PinItem::before{content:'想法';background:#9c27b0;${cssTag}}.PinItem>.ContentItem-title{margin-top:4px;}.ZvideoItem .ContentItem-title::before{content:'视频';background:#12c2e9}.ZVideoItem .ContentItem-title::before{content:'视频';background:#12c2e9}.ArticleItem .ContentItem-title::before{content:'文章';background:#00965e}.ContentItem .ContentItem-title::before{margin-right:6px;font-weight:normal;display:inline;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff}.TopstoryQuestionAskItem .ContentItem-title::before{content:'提问';background:#533b77}`,
  1298. pfConfig.questionTitleTag
  1299. );
  1300. },
  1301. /** 首页问题列表切换模块悬浮 */
  1302. vSusHomeTab: async function() {
  1303. const pfConfig = await myStorage.getConfig();
  1304. const { themeDark = 1 /* 深色护眼一 */, themeLight = 0 /* 默认 */ } = pfConfig;
  1305. const dark = await isDark();
  1306. const background = dark ? THEME_CONFIG_DARK[themeDark].background : THEME_CONFIG_LIGHT[themeLight].background;
  1307. return fnReturnStr(
  1308. `.Topstory-container .TopstoryTabs{${pfConfig.suspensionHomeTabPo}position:fixed;z-index:100;display:flex;flex-direction:column;height:initial!important;}.Topstory-container .TopstoryTabs>a{font-size:0 !important;border-radius:50%}.Topstory-container .TopstoryTabs>a::after{font-size:16px !important;display:inline-block;padding:6px 8px;margin-bottom:4px;border:1px solid #999999;color:#999999;background: ${background || "transparent"};}.Topstory-container .TopstoryTabs>a.TopstoryTabs-link {margin:0!important}.Topstory-container .TopstoryTabs>a.TopstoryTabs-link.is-active::after{color:#0066ff!important;border-color:#0066ff!important;}.Topstory [aria-controls='Topstory-recommend']::after{content:'推';}.Topstory [aria-controls='Topstory-follow']::after{content:'关';border-top-left-radius:4px;border-top-right-radius:4px;}.Topstory [aria-controls='Topstory-hot']::after{content:'热';}.Topstory [aria-controls="Topstory-zvideo"]::after{content:'视';border-bottom-left-radius:4px;border-bottom-right-radius:4px}.Topstory-tabs{border-color: transparent!important;}`,
  1309. pfConfig.suspensionHomeTab
  1310. );
  1311. },
  1312. /** 顶部三大块悬浮 */
  1313. vSusHeader: async function() {
  1314. const pfConfig = await myStorage.getConfig();
  1315. const { themeDark = 1 /* 深色护眼一 */, themeLight = 0 /* 默认 */ } = pfConfig;
  1316. const dark = await isDark();
  1317. const background = dark ? THEME_CONFIG_DARK[themeDark].background : THEME_CONFIG_LIGHT[themeLight].background;
  1318. return `.position-suspensionFind{${pfConfig.suspensionFindPo}}.position-suspensionUser{${pfConfig.suspensionUserPo}}.position-suspensionSearch{${pfConfig.suspensionSearchPo}}.position-suspensionFind .Tabs-link{border:1px solid #999999;color:#999999;background: ${background || "transparent"};}.position-suspensionFind .Tabs-link.is-active{color:#0066ff!important;border-color:#0066ff!important;}.position-suspensionUser .css-1m60na {display: none;}.position-suspensionUser .css-1n0eufo{margin-right: 0;}`;
  1319. },
  1320. /** 列表内容点击高亮边框 */
  1321. vHighlightListItem: async function() {
  1322. const { highlightListItem } = await myStorage.getConfig();
  1323. return highlightListItem ? `.List-item:focus,.TopstoryItem:focus,.HotItem:focus{box-shadow:0 0 0 2px #fff,0 0 0 5px rgba(0, 102, 255, 0.3)!important;outline:none!important;transition:box-shadow 0.3s!important;}` : `.List-item:focus,.Card:focus::before{box-shadow: none!important;}`;
  1324. },
  1325. vShoppingLink: async function() {
  1326. const pfConfig = await myStorage.getConfig();
  1327. const cssObj = {
  1328. 0: "",
  1329. 1: '.MCNLinkCard-imageContainer,.MCNLinkCard-button,.MCNLinkCard-source,.ecommerce-ad-commodity-img,.ecommerce-ad-commodity-box-icon,.RichText-MCNLinkCardContainer .BottomInfo,.CPSCommonCard-imageBox,.RedPacketCard-imageBox,.CPSCommonCard-tool,.CPSCommonCard-subtitle,.RedPacketCard-subtitle,.RedPacketCard-tool{display: none!important;}.MCNLinkCard,.MCNLinkCard-card,.ecommerce-ad-commodity,.RichText-MCNLinkCardContainer .GoodsRecommendCard,.CPSCommonCard,.RedPacketCard-info,.RedPacketCard{min-height: 0!important;background: transparent!important;width:100%!important;max-width:100%!important;}.MCNLinkCard-cardContainer,.ecommerce-ad-commodity,.ecommerce-ad-commodity-main,.RedPacketCard,.CPSCommonCard{padding: 0!important;}.MCNLinkCard,.MCNLinkCard-info{margin: 0!important;}.MCNLinkCard-info,.ecommerce-ad-commodity-main{flex-direction: row!important;}.MCNLinkCard-price{padding-left: 12px;}.ecommerce-ad-commodity-box .ecommerce-ad-commodity{height: auto!important;}.ecommerce-ad-commodity-box-main-second{width: auto!important;}.MCNLinkCard-titleContainer,.ecommerce-ad-commodity-main-content-des span,.CPSCommonCard-title,.RedPacketCard-title{color: #fd8d55!important;justify-content: start!important;}.MCNLinkCard-titleContainer::before,.ecommerce-ad-commodity-main-content-des span::before,.CPSCommonCard-title::before,.RedPacketCard-title::before{content: "购物链接:"}.MCNLinkCard-title{color: #fd8d55!important;}',
  1330. 2: "a.MCNLinkCard,.RichText-ADLinkCardContainer,.ecommerce-ad-commodity-box,.ecommerce-ad-box,.RichText-MCNLinkCardContainer{display: none!important;}"
  1331. };
  1332. return cssObj[pfConfig.linkShopping || "0"];
  1333. },
  1334. vFontSizeContent: async function() {
  1335. const { fontSizeForList, fontSizeForAnswer, fontSizeForArticle, fontSizeForListTitle, fontSizeForAnswerTitle, fontSizeForArticleTitle } = await myStorage.getConfig();
  1336. const list = `.Topstory-body .RichContent-inner,.Topstory-body .ctz-list-item-time,.Topstory-body .CommentContent,.SearchResult-Card .RichContent-inner,.SearchResult-Card .CommentContent,.HotItem-excerpt--multiLine{font-size: ${fontSizeForList}px!important;}`;
  1337. const answer = `.Question-main .RichContent-inner,.Question-main .ctz-list-item-time,.Question-main .CommentContent{font-size: ${fontSizeForAnswer}px}`;
  1338. const article = `.zhuanlan .Post-RichTextContainer,.zhuanlan .ctz-article-create-time,.zhuanlan .CommentContent{font-size: ${fontSizeForArticle}px}`;
  1339. const articleTitle = `.zhuanlan .Post-Main .Post-Title{font-size: ${fontSizeForArticleTitle}px;}`;
  1340. const listTitle = `.ContentItem-title,.HotItem-title{font-size: ${fontSizeForListTitle}px!important;}`;
  1341. const answerTitle = `.QuestionHeader-title{font-size: ${fontSizeForAnswerTitle}px!important;}`;
  1342. return list + answer + article + articleTitle + listTitle + answerTitle;
  1343. },
  1344. vVideoLink: async () => {
  1345. const { videoUseLink } = await myStorage.getConfig();
  1346. return fnReturnStr(
  1347. `${CLASS_VIDEO_ONE}>div,${CLASS_VIDEO_ONE}>i{display: none;}${CLASS_VIDEO_ONE}{padding: 0!important;height:24px!important;width: fit-content!important;}${CLASS_VIDEO_ONE}::before{content: '视频链接,点击跳转 >>';cursor:pointer;color: #1677ff}${CLASS_VIDEO_ONE}:hover::before{color: #b0b0b0}${CLASS_VIDEO_TWO}::before,${CLASS_VIDEO_TWO}>i{display: none;}`,
  1348. videoUseLink
  1349. );
  1350. }
  1351. };
  1352. var suspensionPackUp = async (elements) => {
  1353. const { themeLight = 0 /* 默认 */, themeDark = 1 /* 深色护眼一 */, suspensionPickupRight = 60 } = await myStorage.getConfig();
  1354. for (let i2 = 0; i2 < elements.length; i2++) {
  1355. const even = elements[i2];
  1356. const evenPrev = i2 > 0 ? elements[i2 - 1] : null;
  1357. const evenBottom = even.offsetTop + even.offsetHeight;
  1358. const evenPrevBottom = evenPrev ? evenPrev.offsetTop + evenPrev.offsetHeight : 0;
  1359. const hST = dom("html").scrollTop;
  1360. const evenButton = even.querySelector(".ContentItem-actions .ContentItem-rightButton");
  1361. if (!evenButton)
  1362. continue;
  1363. const needStyle = evenBottom > hST + window.innerHeight && evenPrevBottom < hST;
  1364. const dark = await isDark();
  1365. evenButton.style.cssText = needStyle ? `visibility:visible!important;position: fixed!important;bottom: 60px;z-index:200;right: ${(document.body.offsetWidth - even.offsetWidth) / 2 + +suspensionPickupRight}px;box-shadow: 0 1px 3px rgb(18 18 18 / 10%);height: 40px!important;padding: 0 12px!important;background: ${dark ? THEME_CONFIG_DARK[themeDark].background2 : THEME_CONFIG_LIGHT[themeLight][+themeLight !== 0 /* 默认 */ ? "background2" : "background"]}!important;` : "";
  1366. }
  1367. };
  1368. var changeSuspensionTab = async () => {
  1369. const name = "suspensionHomeTab";
  1370. const pfConfig = await myStorage.getConfig();
  1371. cSuspensionStyle(name);
  1372. const even = dom(".Topstory-container .TopstoryTabs");
  1373. if (!even)
  1374. return;
  1375. pfConfig[name] ? myLock.append(even, name) : myLock.remove(even);
  1376. };
  1377. var cacheHeader = async () => {
  1378. const headerEventNames = ["suspensionFind", "suspensionSearch", "suspensionUser"];
  1379. const { getFindEventItem, setFindEventItem, setStorageConfigItem, getStorageConfigItem } = store;
  1380. const pfConfig = await myStorage.getConfig();
  1381. const eventHeader = getFindEventItem("header");
  1382. if (!eventHeader.isFind) {
  1383. eventHeader.fun && clearTimeout(eventHeader.fun);
  1384. eventHeader.fun = setTimeout(() => {
  1385. if (eventHeader.num < 100) {
  1386. if (dom(".AppHeader-inner")) {
  1387. eventHeader.isFind = true;
  1388. setStorageConfigItem("headerDoms", {
  1389. suspensionFind: {
  1390. class: ".AppHeader-inner .AppHeader-Tabs",
  1391. even: dom(".AppHeader-inner .AppHeader-Tabs"),
  1392. index: 1
  1393. },
  1394. suspensionSearch: {
  1395. class: ".AppHeader-inner .SearchBar",
  1396. even: dom(".AppHeader-inner .SearchBar"),
  1397. index: 2
  1398. },
  1399. suspensionUser: {
  1400. class: ".AppHeader-inner .AppHeader-userInfo",
  1401. even: dom(".AppHeader-inner .AppHeader-userInfo"),
  1402. index: 3
  1403. }
  1404. });
  1405. }
  1406. eventHeader.num++;
  1407. setFindEventItem("header", eventHeader);
  1408. cacheHeader();
  1409. }
  1410. }, 100);
  1411. return;
  1412. }
  1413. const classIcon = ".ctz-search-icon";
  1414. const classPickup = ".ctz-search-pick-up";
  1415. const classNameFocus = "focus";
  1416. headerEventNames.forEach((name) => {
  1417. const headerDoms = getStorageConfigItem("headerDoms");
  1418. const { even } = headerDoms[name];
  1419. if (pfConfig[name]) {
  1420. if (name === "suspensionSearch") {
  1421. !dom(classIcon) && even.appendChild(domC("i", { className: "ctz-search-icon", innerHTML: "⚲" }));
  1422. !dom(classPickup) && even.appendChild(domC("i", { className: "ctz-search-pick-up", innerHTML: "⇤" }));
  1423. if (dom(classIcon)) {
  1424. dom(classIcon).onclick = () => even.classList.add(classNameFocus);
  1425. }
  1426. if (dom(classPickup)) {
  1427. dom(classPickup).onclick = () => even.classList.remove(classNameFocus);
  1428. }
  1429. }
  1430. myLock.append(even, name);
  1431. even.classList.add(`position-${name}`);
  1432. const nodeRoot = dom("#root");
  1433. nodeRoot && nodeRoot.appendChild(even);
  1434. } else {
  1435. if (name === "suspensionSearch") {
  1436. const nodeIcon = dom(classIcon);
  1437. const nodePickup = dom(classPickup);
  1438. nodeIcon && nodeIcon.remove();
  1439. nodePickup && nodePickup.remove();
  1440. even.classList.remove(classNameFocus);
  1441. }
  1442. myLock.remove(even);
  1443. even.classList.remove(`position-${name}`);
  1444. even.setAttribute("style", "");
  1445. const nodeHeaderInner = dom(".AppHeader-inner");
  1446. nodeHeaderInner && nodeHeaderInner.appendChild(even);
  1447. }
  1448. cSuspensionStyle(name);
  1449. });
  1450. myVersion.change();
  1451. };
  1452. var cSuspensionStyle = async (name) => {
  1453. const cssObj = {
  1454. suspensionHomeTab: ".Topstory-container .TopstoryTabs",
  1455. suspensionFind: ".AppHeader-Tabs",
  1456. suspensionSearch: ".SearchBar",
  1457. // 搜索框使用自己添加的元素
  1458. suspensionUser: ".AppHeader-userInfo"
  1459. };
  1460. const nodeCTZName = dom(`.ctz-${name}`);
  1461. const pfConfig = await myStorage.getConfig();
  1462. nodeCTZName && (nodeCTZName.style.cssText = pfConfig[name] ? "display: inline-block;" : "display: none;");
  1463. if (cssObj[name]) {
  1464. pfConfig[name] ? myMove.init(cssObj[name], `${name}Po`, name) : myMove.destroy(cssObj[name]);
  1465. }
  1466. };
  1467. var initData = () => {
  1468. store.setStorageConfigItem("cacheTitle", document.title);
  1469. echoData();
  1470. changeICO();
  1471. changeTitle();
  1472. changeSuspensionTab();
  1473. setTimeout(() => {
  1474. cacheHeader();
  1475. }, 300);
  1476. };
  1477. var initHistoryView = async () => {
  1478. const { href, origin, pathname } = location;
  1479. setTimeout(async () => {
  1480. let name = "";
  1481. const isQuestion = href.includes("www.zhihu.com/question/");
  1482. isQuestion && dom('.QuestionPage [itemprop="name"]') && (name = dom('.QuestionPage [itemprop="name"]').content);
  1483. href.includes("zhuanlan.zhihu.com/p/") && dom(".Post-Title") && (name = dom(".Post-Title").innerText);
  1484. href.includes("www.zhihu.com/zvideo/") && dom(".ZVideo .ZVideo-title") && (name = dom(".ZVideo .ZVideo-title").innerText);
  1485. if (!name) {
  1486. initHistoryView();
  1487. return;
  1488. }
  1489. let extra = "";
  1490. const questionAnswerId = pathname.replace(/\/question\/\d+\/answer\//, "");
  1491. if (isQuestion && questionAnswerId) {
  1492. extra = ` ---- 回答: ${questionAnswerId}`;
  1493. }
  1494. const nA = `<a href="${origin + pathname}" target="_blank">${name + extra}</a>`;
  1495. const { view } = await myStorage.getHistory();
  1496. if (!view.includes(nA)) {
  1497. view.unshift(nA);
  1498. myStorage.setHistoryItem("view", view);
  1499. }
  1500. }, 500);
  1501. };
  1502. function md5(s2) {
  1503. function f12(t2, e2, n2) {
  1504. var r2;
  1505. !function(o3) {
  1506. "use strict";
  1507. function i2(t3, e3) {
  1508. var n3 = (65535 & t3) + (65535 & e3);
  1509. return (t3 >> 16) + (e3 >> 16) + (n3 >> 16) << 16 | 65535 & n3;
  1510. }
  1511. function a2(t3, e3, n3, r3, o4, a3) {
  1512. return i2((u2 = i2(i2(e3, t3), i2(r3, a3))) << (c3 = o4) | u2 >>> 32 - c3, n3);
  1513. var u2, c3;
  1514. }
  1515. function u(t3, e3, n3, r3, o4, i3, u2) {
  1516. return a2(e3 & n3 | ~e3 & r3, t3, e3, o4, i3, u2);
  1517. }
  1518. function c2(t3, e3, n3, r3, o4, i3, u2) {
  1519. return a2(e3 & r3 | n3 & ~r3, t3, e3, o4, i3, u2);
  1520. }
  1521. function s3(t3, e3, n3, r3, o4, i3, u2) {
  1522. return a2(e3 ^ n3 ^ r3, t3, e3, o4, i3, u2);
  1523. }
  1524. function l2(t3, e3, n3, r3, o4, i3, u2) {
  1525. return a2(n3 ^ (e3 | ~r3), t3, e3, o4, i3, u2);
  1526. }
  1527. function f(t3, e3) {
  1528. var n3, r3, o4, a3, f2;
  1529. t3[e3 >> 5] |= 128 << e3 % 32, t3[14 + (e3 + 64 >>> 9 << 4)] = e3;
  1530. var d2 = 1732584193, p2 = -271733879, h3 = -1732584194, v2 = 271733878;
  1531. for (n3 = 0; n3 < t3.length; n3 += 16)
  1532. r3 = d2, o4 = p2, a3 = h3, f2 = v2, d2 = u(d2, p2, h3, v2, t3[n3], 7, -680876936), v2 = u(v2, d2, p2, h3, t3[n3 + 1], 12, -389564586), h3 = u(h3, v2, d2, p2, t3[n3 + 2], 17, 606105819), p2 = u(p2, h3, v2, d2, t3[n3 + 3], 22, -1044525330), d2 = u(d2, p2, h3, v2, t3[n3 + 4], 7, -176418897), v2 = u(v2, d2, p2, h3, t3[n3 + 5], 12, 1200080426), h3 = u(h3, v2, d2, p2, t3[n3 + 6], 17, -1473231341), p2 = u(p2, h3, v2, d2, t3[n3 + 7], 22, -45705983), d2 = u(d2, p2, h3, v2, t3[n3 + 8], 7, 1770035416), v2 = u(v2, d2, p2, h3, t3[n3 + 9], 12, -1958414417), h3 = u(h3, v2, d2, p2, t3[n3 + 10], 17, -42063), p2 = u(p2, h3, v2, d2, t3[n3 + 11], 22, -1990404162), d2 = u(d2, p2, h3, v2, t3[n3 + 12], 7, 1804603682), v2 = u(v2, d2, p2, h3, t3[n3 + 13], 12, -40341101), h3 = u(h3, v2, d2, p2, t3[n3 + 14], 17, -1502002290), d2 = c2(d2, p2 = u(p2, h3, v2, d2, t3[n3 + 15], 22, 1236535329), h3, v2, t3[n3 + 1], 5, -165796510), v2 = c2(v2, d2, p2, h3, t3[n3 + 6], 9, -1069501632), h3 = c2(h3, v2, d2, p2, t3[n3 + 11], 14, 643717713), p2 = c2(p2, h3, v2, d2, t3[n3], 20, -373897302), d2 = c2(d2, p2, h3, v2, t3[n3 + 5], 5, -701558691), v2 = c2(v2, d2, p2, h3, t3[n3 + 10], 9, 38016083), h3 = c2(h3, v2, d2, p2, t3[n3 + 15], 14, -660478335), p2 = c2(p2, h3, v2, d2, t3[n3 + 4], 20, -405537848), d2 = c2(d2, p2, h3, v2, t3[n3 + 9], 5, 568446438), v2 = c2(v2, d2, p2, h3, t3[n3 + 14], 9, -1019803690), h3 = c2(h3, v2, d2, p2, t3[n3 + 3], 14, -187363961), p2 = c2(p2, h3, v2, d2, t3[n3 + 8], 20, 1163531501), d2 = c2(d2, p2, h3, v2, t3[n3 + 13], 5, -1444681467), v2 = c2(v2, d2, p2, h3, t3[n3 + 2], 9, -51403784), h3 = c2(h3, v2, d2, p2, t3[n3 + 7], 14, 1735328473), d2 = s3(d2, p2 = c2(p2, h3, v2, d2, t3[n3 + 12], 20, -1926607734), h3, v2, t3[n3 + 5], 4, -378558), v2 = s3(v2, d2, p2, h3, t3[n3 + 8], 11, -2022574463), h3 = s3(h3, v2, d2, p2, t3[n3 + 11], 16, 1839030562), p2 = s3(p2, h3, v2, d2, t3[n3 + 14], 23, -35309556), d2 = s3(d2, p2, h3, v2, t3[n3 + 1], 4, -1530992060), v2 = s3(v2, d2, p2, h3, t3[n3 + 4], 11, 1272893353), h3 = s3(h3, v2, d2, p2, t3[n3 + 7], 16, -155497632), p2 = s3(p2, h3, v2, d2, t3[n3 + 10], 23, -1094730640), d2 = s3(d2, p2, h3, v2, t3[n3 + 13], 4, 681279174), v2 = s3(v2, d2, p2, h3, t3[n3], 11, -358537222), h3 = s3(h3, v2, d2, p2, t3[n3 + 3], 16, -722521979), p2 = s3(p2, h3, v2, d2, t3[n3 + 6], 23, 76029189), d2 = s3(d2, p2, h3, v2, t3[n3 + 9], 4, -640364487), v2 = s3(v2, d2, p2, h3, t3[n3 + 12], 11, -421815835), h3 = s3(h3, v2, d2, p2, t3[n3 + 15], 16, 530742520), d2 = l2(d2, p2 = s3(p2, h3, v2, d2, t3[n3 + 2], 23, -995338651), h3, v2, t3[n3], 6, -198630844), v2 = l2(v2, d2, p2, h3, t3[n3 + 7], 10, 1126891415), h3 = l2(h3, v2, d2, p2, t3[n3 + 14], 15, -1416354905), p2 = l2(p2, h3, v2, d2, t3[n3 + 5], 21, -57434055), d2 = l2(d2, p2, h3, v2, t3[n3 + 12], 6, 1700485571), v2 = l2(v2, d2, p2, h3, t3[n3 + 3], 10, -1894986606), h3 = l2(h3, v2, d2, p2, t3[n3 + 10], 15, -1051523), p2 = l2(p2, h3, v2, d2, t3[n3 + 1], 21, -2054922799), d2 = l2(d2, p2, h3, v2, t3[n3 + 8], 6, 1873313359), v2 = l2(v2, d2, p2, h3, t3[n3 + 15], 10, -30611744), h3 = l2(h3, v2, d2, p2, t3[n3 + 6], 15, -1560198380), p2 = l2(p2, h3, v2, d2, t3[n3 + 13], 21, 1309151649), d2 = l2(d2, p2, h3, v2, t3[n3 + 4], 6, -145523070), v2 = l2(v2, d2, p2, h3, t3[n3 + 11], 10, -1120210379), h3 = l2(h3, v2, d2, p2, t3[n3 + 2], 15, 718787259), p2 = l2(p2, h3, v2, d2, t3[n3 + 9], 21, -343485551), d2 = i2(d2, r3), p2 = i2(p2, o4), h3 = i2(h3, a3), v2 = i2(v2, f2);
  1533. return [d2, p2, h3, v2];
  1534. }
  1535. function d(t3) {
  1536. var e3, n3 = "", r3 = 32 * t3.length;
  1537. for (e3 = 0; e3 < r3; e3 += 8)
  1538. n3 += String.fromCharCode(t3[e3 >> 5] >>> e3 % 32 & 255);
  1539. return n3;
  1540. }
  1541. function p(t3) {
  1542. var e3, n3 = [];
  1543. for (n3[(t3.length >> 2) - 1] = void 0, e3 = 0; e3 < n3.length; e3 += 1)
  1544. n3[e3] = 0;
  1545. var r3 = 8 * t3.length;
  1546. for (e3 = 0; e3 < r3; e3 += 8)
  1547. n3[e3 >> 5] |= (255 & t3.charCodeAt(e3 / 8)) << e3 % 32;
  1548. return n3;
  1549. }
  1550. function h2(t3) {
  1551. var e3, n3, r3 = "0123456789abcdef", o4 = "";
  1552. for (n3 = 0; n3 < t3.length; n3 += 1)
  1553. e3 = t3.charCodeAt(n3), o4 += r3.charAt(e3 >>> 4 & 15) + r3.charAt(15 & e3);
  1554. return o4;
  1555. }
  1556. function v(t3) {
  1557. return unescape(encodeURIComponent(t3));
  1558. }
  1559. function A2(t3) {
  1560. return function(t4) {
  1561. return d(f(p(t4), 8 * t4.length));
  1562. }(v(t3));
  1563. }
  1564. function m(t3, e3) {
  1565. return function(t4, e4) {
  1566. var n3, r3, o4 = p(t4), i3 = [], a3 = [];
  1567. for (i3[15] = a3[15] = void 0, o4.length > 16 && (o4 = f(o4, 8 * t4.length)), n3 = 0; n3 < 16; n3 += 1)
  1568. i3[n3] = 909522486 ^ o4[n3], a3[n3] = 1549556828 ^ o4[n3];
  1569. return r3 = f(i3.concat(p(e4)), 512 + 8 * e4.length), d(f(a3.concat(r3), 640));
  1570. }(v(t3), v(e3));
  1571. }
  1572. function g2(t3, e3, n3) {
  1573. return e3 ? n3 ? m(e3, t3) : h2(m(e3, t3)) : n3 ? A2(t3) : h2(A2(t3));
  1574. }
  1575. void 0 === (r2 = function() {
  1576. return g2;
  1577. }.call(e2, n2, e2, t2)) || (t2.exports = r2);
  1578. }();
  1579. }
  1580. var o2 = {};
  1581. f12(o2);
  1582. return o2.exports(s2);
  1583. }
  1584. function zhihu_enc(s) {
  1585. function f1(__unused_webpack_module, exports) {
  1586. "use strict";
  1587. var __webpack_unused_export__;
  1588. function o(t2) {
  1589. return (o = "function" == typeof Symbol && "symbol" == typeof Symbol.A ? function(t3) {
  1590. return typeof t3;
  1591. } : function(t3) {
  1592. return t3 && "function" == typeof Symbol && t3.constructor === Symbol && t3 !== Symbol.prototype ? "symbol" : typeof t3;
  1593. })(t2);
  1594. }
  1595. function x(e2) {
  1596. return C(e2) || s(e2) || t();
  1597. }
  1598. function C(t2) {
  1599. if (Array.isArray(t2)) {
  1600. for (var e2 = 0, n2 = new Array(t2.length); e2 < t2.length; e2++)
  1601. n2[e2] = t2[e2];
  1602. return n2;
  1603. }
  1604. }
  1605. function s(t2) {
  1606. if (Symbol.A in Object(t2) || "[object Arguments]" === Object.prototype.toString.call(t2))
  1607. return Array.from(t2);
  1608. }
  1609. function t() {
  1610. throw new TypeError("Invalid attempt to spread non-iterable instance");
  1611. }
  1612. __webpack_unused_export__ = {
  1613. value: true
  1614. };
  1615. var A = "3.0", S = "undefined" != typeof window ? window : {}, h;
  1616. function i(t2, e2, n2) {
  1617. e2[n2] = 255 & t2 >>> 24, e2[n2 + 1] = 255 & t2 >>> 16, e2[n2 + 2] = 255 & t2 >>> 8, e2[n2 + 3] = 255 & t2;
  1618. }
  1619. function B(t2, e2) {
  1620. return (255 & t2[e2]) << 24 | (255 & t2[e2 + 1]) << 16 | (255 & t2[e2 + 2]) << 8 | 255 & t2[e2 + 3];
  1621. }
  1622. function Q(t2, e2) {
  1623. return (4294967295 & t2) << e2 | t2 >>> 32 - e2;
  1624. }
  1625. function G(t2) {
  1626. var e2 = new Array(4), n2 = new Array(4);
  1627. i(t2, e2, 0), n2[0] = h.zb[255 & e2[0]], n2[1] = h.zb[255 & e2[1]], n2[2] = h.zb[255 & e2[2]], n2[3] = h.zb[255 & e2[3]];
  1628. var r2 = B(n2, 0);
  1629. return r2 ^ Q(r2, 2) ^ Q(r2, 10) ^ Q(r2, 18) ^ Q(r2, 24);
  1630. }
  1631. var __g = {
  1632. x: function(t2, e2) {
  1633. for (var n2 = [], r2 = t2.length, o2 = 0; 0 < r2; r2 -= 16) {
  1634. for (var i2 = t2.slice(16 * o2, 16 * (o2 + 1)), a2 = new Array(16), u = 0; u < 16; u++)
  1635. a2[u] = i2[u] ^ e2[u];
  1636. e2 = __g.r(a2), n2 = n2.concat(e2), o2++;
  1637. }
  1638. return n2;
  1639. },
  1640. r: function(t2) {
  1641. var e2 = new Array(16), n2 = new Array(36);
  1642. n2[0] = B(t2, 0), n2[1] = B(t2, 4), n2[2] = B(t2, 8), n2[3] = B(t2, 12);
  1643. for (var r2 = 0; r2 < 32; r2++) {
  1644. var o2 = G(n2[r2 + 1] ^ n2[r2 + 2] ^ n2[r2 + 3] ^ h.zk[r2]);
  1645. n2[r2 + 4] = n2[r2] ^ o2;
  1646. }
  1647. return i(n2[35], e2, 0), i(n2[34], e2, 4), i(n2[33], e2, 8), i(n2[32], e2, 12), e2;
  1648. }
  1649. };
  1650. function l() {
  1651. this.C = [0, 0, 0, 0], this.s = +[], this.t = [], this.S = [], this.h = [], this.i = [], this.B = [], this.Q = false, this.G = [], this.D = [], this.w = 1024, this.g = null, this.a = Date.now(), this.e = +[], this.T = 255, this.V = null, this.U = Date.now, this.M = new Array(32);
  1652. }
  1653. l.prototype.O = function(A, C, s) {
  1654. for (var t, S, h, i, B, Q, G, D, w, g, a, e, E, T, r, V, U, M, O, c, I; this.T < this.w; )
  1655. try {
  1656. switch (this.T) {
  1657. case 27:
  1658. this.C[this.c] = this.C[this.I] >> this.C[this.F], this.M[12] = 35, this.T = this.T * (this.C.length + (this.M[13] ? 3 : 9)) + 1;
  1659. break;
  1660. case 34:
  1661. this.C[this.c] = this.C[this.I] & this.C[this.F], this.T = this.T * (this.M[15] - 6) + 12;
  1662. break;
  1663. case 41:
  1664. this.C[this.c] = this.C[this.I] <= this.C[this.F], this.T = 8 * this.T + 27;
  1665. break;
  1666. case 48:
  1667. this.C[this.c] = !this.C[this.I], this.T = 7 * this.T + 16;
  1668. break;
  1669. case 50:
  1670. this.C[this.c] = this.C[this.I] | this.C[this.F], this.T = 6 * this.T + 52;
  1671. break;
  1672. case 57:
  1673. this.C[this.c] = this.C[this.I] >>> this.C[this.F], this.T = 7 * this.T - 47;
  1674. break;
  1675. case 64:
  1676. this.C[this.c] = this.C[this.I] << this.C[this.F], this.T = 5 * this.T + 32;
  1677. break;
  1678. case 71:
  1679. this.C[this.c] = this.C[this.I] ^ this.C[this.F], this.T = 6 * this.T - 74;
  1680. break;
  1681. case 78:
  1682. this.C[this.c] = this.C[this.I] & this.C[this.F], this.T = 4 * this.T + 40;
  1683. break;
  1684. case 80:
  1685. this.C[this.c] = this.C[this.I] < this.C[this.F], this.T = 5 * this.T - 48;
  1686. break;
  1687. case 87:
  1688. this.C[this.c] = -this.C[this.I], this.T = 3 * this.T + 91;
  1689. break;
  1690. case 94:
  1691. this.C[this.c] = this.C[this.I] > this.C[this.F], this.T = 4 * this.T - 24;
  1692. break;
  1693. case 101:
  1694. this.C[this.c] = this.C[this.I] in this.C[this.F], this.T = 3 * this.T + 49;
  1695. break;
  1696. case 108:
  1697. this.C[this.c] = o(this.C[this.I]), this.T = 2 * this.T + 136;
  1698. break;
  1699. case 110:
  1700. this.C[this.c] = this.C[this.I] !== this.C[this.F], this.T += 242;
  1701. break;
  1702. case 117:
  1703. this.C[this.c] = this.C[this.I] && this.C[this.F], this.T = 3 * this.T + 1;
  1704. break;
  1705. case 124:
  1706. this.C[this.c] = this.C[this.I] || this.C[this.F], this.T += 228;
  1707. break;
  1708. case 131:
  1709. this.C[this.c] = this.C[this.I] >= this.C[this.F], this.T = 3 * this.T - 41;
  1710. break;
  1711. case 138:
  1712. this.C[this.c] = this.C[this.I] == this.C[this.F], this.T = 2 * this.T + 76;
  1713. break;
  1714. case 140:
  1715. this.C[this.c] = this.C[this.I] % this.C[this.F], this.T += 212;
  1716. break;
  1717. case 147:
  1718. this.C[this.c] = this.C[this.I] / this.C[this.F], this.T += 205;
  1719. break;
  1720. case 154:
  1721. this.C[this.c] = this.C[this.I] * this.C[this.F], this.T += 198;
  1722. break;
  1723. case 161:
  1724. this.C[this.c] = this.C[this.I] - this.C[this.F], this.T += 191;
  1725. break;
  1726. case 168:
  1727. this.C[this.c] = this.C[this.I] + this.C[this.F], this.T = 2 * this.T + 16;
  1728. break;
  1729. case 254:
  1730. this.C[this.c] = eval(i), this.T += 20 < this.M[11] ? 98 : 89;
  1731. break;
  1732. case 255:
  1733. this.s = C || 0, this.M[26] = 52, this.T += this.M[13] ? 8 : 6;
  1734. break;
  1735. case 258:
  1736. g = {};
  1737. for (var F = 0; F < this.k; F++)
  1738. e = this.i.pop(), a = this.i.pop(), g[a] = e;
  1739. this.C[this.W] = g, this.T += 94;
  1740. break;
  1741. case 261:
  1742. this.D = s || [], this.M[11] = 68, this.T += this.M[26] ? 3 : 5;
  1743. break;
  1744. case 264:
  1745. this.M[15] = 16, this.T = "string" == typeof A ? 331 : 336;
  1746. break;
  1747. case 266:
  1748. this.C[this.I][i] = this.i.pop(), this.T += 86;
  1749. break;
  1750. case 278:
  1751. this.C[this.c] = this.C[this.I][i], this.T += this.M[22] ? 63 : 74;
  1752. break;
  1753. case 283:
  1754. this.C[this.c] = eval(String.fromCharCode(this.C[this.I]));
  1755. break;
  1756. case 300:
  1757. S = this.U(), this.M[0] = 66, this.T += this.M[11];
  1758. break;
  1759. case 331:
  1760. D = atob(A), w = D.charCodeAt(0) << 16 | D.charCodeAt(1) << 8 | D.charCodeAt(2);
  1761. for (var k = 3; k < w + 3; k += 3)
  1762. this.G.push(D.charCodeAt(k) << 16 | D.charCodeAt(k + 1) << 8 | D.charCodeAt(k + 2));
  1763. for (V = w + 3; V < D.length; )
  1764. E = D.charCodeAt(V) << 8 | D.charCodeAt(V + 1), T = D.slice(V + 2, V + 2 + E), this.D.push(T), V += E + 2;
  1765. this.M[21] = 8, this.T += 1e3 < V ? 21 : 35;
  1766. break;
  1767. case 336:
  1768. this.G = A, this.D = s, this.M[18] = 134, this.T += this.M[15];
  1769. break;
  1770. case 344:
  1771. this.T = 3 * this.T - 8;
  1772. break;
  1773. case 350:
  1774. U = 66, M = [], I = this.D[this.k];
  1775. for (var W = 0; W < I.length; W++)
  1776. M.push(String.fromCharCode(24 ^ I.charCodeAt(W) ^ U)), U = 24 ^ I.charCodeAt(W) ^ U;
  1777. r = parseInt(M.join("").split("|")[1]), this.C[this.W] = this.i.slice(this.i.length - r), this.i = this.i.slice(0, this.i.length - r), this.T += 2;
  1778. break;
  1779. case 352:
  1780. this.e = this.G[this.s++], this.T -= this.M[26];
  1781. break;
  1782. case 360:
  1783. this.a = S, this.T += this.M[0];
  1784. break;
  1785. case 368:
  1786. this.T -= 500 < S - this.a ? 24 : 8;
  1787. break;
  1788. case 380:
  1789. this.i.push(16383 & this.e), this.T -= 28;
  1790. break;
  1791. case 400:
  1792. this.i.push(this.S[16383 & this.e]), this.T -= 48;
  1793. break;
  1794. case 408:
  1795. this.T -= 64;
  1796. break;
  1797. case 413:
  1798. this.C[this.e >> 15 & 7] = (this.e >> 18 & 1) == +[] ? 32767 & this.e : this.S[32767 & this.e], this.T -= 61;
  1799. break;
  1800. case 418:
  1801. this.S[65535 & this.e] = this.C[this.e >> 16 & 7], this.T -= this.e >> 16 < 20 ? 66 : 80;
  1802. break;
  1803. case 423:
  1804. this.c = this.e >> 16 & 7, this.I = this.e >> 13 & 7, this.F = this.e >> 10 & 7, this.J = 1023 & this.e, this.T -= 255 + 6 * this.J + this.J % 5;
  1805. break;
  1806. case 426:
  1807. this.T += 5 * (this.e >> 19) - 18;
  1808. break;
  1809. case 428:
  1810. this.W = this.e >> 16 & 7, this.k = 65535 & this.e, this.t.push(this.s), this.h.push(this.S), this.s = this.C[this.W], this.S = [];
  1811. for (var J = 0; J < this.k; J++)
  1812. this.S.unshift(this.i.pop());
  1813. this.B.push(this.i), this.i = [], this.T -= 76;
  1814. break;
  1815. case 433:
  1816. this.s = this.t.pop(), this.S = this.h.pop(), this.i = this.B.pop(), this.T -= 81;
  1817. break;
  1818. case 438:
  1819. this.Q = this.C[this.e >> 16 & 7], this.T -= 86;
  1820. break;
  1821. case 440:
  1822. U = 66, M = [], I = this.D[16383 & this.e];
  1823. for (var b = 0; b < I.length; b++)
  1824. M.push(String.fromCharCode(24 ^ I.charCodeAt(b) ^ U)), U = 24 ^ I.charCodeAt(b) ^ U;
  1825. M = M.join("").split("|"), O = parseInt(M.shift()), this.i.push(O === +[] ? M.join("|") : O === +!+[] ? -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()) : O === !+[] + !+[] ? eval(M.join()) : 3 === O ? null : void 0), this.T -= 88;
  1826. break;
  1827. case 443:
  1828. this.b = this.e >> 2 & 65535, this.J = 3 & this.e, this.J === +[] ? this.s = this.b : this.J === +!+[] ? !!this.Q && (this.s = this.b) : 2 === this.J ? !this.Q && (this.s = this.b) : this.s = this.b, this.g = null, this.T -= 91;
  1829. break;
  1830. case 445:
  1831. this.i.push(this.C[this.e >> 14 & 7]), this.T -= 93;
  1832. break;
  1833. case 448:
  1834. this.W = this.e >> 16 & 7, this.k = this.e >> 2 & 4095, this.J = 3 & this.e, Q = this.J === +!+[] && this.i.pop(), G = this.i.slice(this.i.length - this.k, this.i.length), this.i = this.i.slice(0, this.i.length - this.k), c = 2 < G.length ? 3 : G.length, this.T += 6 * this.J + 1 + 10 * c;
  1835. break;
  1836. case 449:
  1837. this.C[3] = this.C[this.W](), this.T -= 97 - G.length;
  1838. break;
  1839. case 455:
  1840. this.C[3] = this.C[this.W][Q](), this.T -= 103 + G.length;
  1841. break;
  1842. case 453:
  1843. B = this.e >> 17 & 3, this.T = B === +[] ? 445 : B === +!+[] ? 380 : B === !+[] + !+[] ? 400 : 440;
  1844. break;
  1845. case 458:
  1846. this.J = this.e >> 17 & 3, this.c = this.e >> 14 & 7, this.I = this.e >> 11 & 7, i = this.i.pop(), this.T -= 12 * this.J + 180;
  1847. break;
  1848. case 459:
  1849. this.C[3] = this.C[this.W](G[+[]]), this.T -= 100 + 7 * G.length;
  1850. break;
  1851. case 461:
  1852. this.C[3] = new this.C[this.W](), this.T -= 109 - G.length;
  1853. break;
  1854. case 463:
  1855. U = 66, M = [], I = this.D[65535 & this.e];
  1856. for (var n = 0; n < I.length; n++)
  1857. M.push(String.fromCharCode(24 ^ I.charCodeAt(n) ^ U)), U = 24 ^ I.charCodeAt(n) ^ U;
  1858. M = M.join("").split("|"), O = parseInt(M.shift()), this.T += 10 * O + 3;
  1859. break;
  1860. case 465:
  1861. this.C[3] = this.C[this.W][Q](G[+[]]), this.T -= 13 * G.length + 100;
  1862. break;
  1863. case 466:
  1864. this.C[this.e >> 16 & 7] = M.join("|"), this.T -= 114 * M.length;
  1865. break;
  1866. case 468:
  1867. this.g = 65535 & this.e, this.T -= 116;
  1868. break;
  1869. case 469:
  1870. this.C[3] = this.C[this.W](G[+[]], G[1]), this.T -= 119 - G.length;
  1871. break;
  1872. case 471:
  1873. this.C[3] = new this.C[this.W](G[+[]]), this.T -= 118 + G.length;
  1874. break;
  1875. case 473:
  1876. throw this.C[this.e >> 16 & 7];
  1877. case 475:
  1878. this.C[3] = this.C[this.W][Q](G[+[]], G[1]), this.T -= 123;
  1879. break;
  1880. case 476:
  1881. this.C[this.e >> 16 & 7] = -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()), this.T -= this.M[21] < 10 ? 124 : 126;
  1882. break;
  1883. case 478:
  1884. t = [0].concat(x(this.S)), this.V = 65535 & this.e, h = this, this.C[3] = function(e2) {
  1885. var n2 = new l();
  1886. return n2.S = t, n2.S[0] = e2, n2.O(h.G, h.V, h.D), n2.C[3];
  1887. }, this.T -= 50 < this.M[3] ? 120 : 126;
  1888. break;
  1889. case 479:
  1890. this.C[3] = this.C[this.W].apply(null, G), this.M[3] = 168, this.T -= this.M[9] ? 127 : 128;
  1891. break;
  1892. case 481:
  1893. this.C[3] = new this.C[this.W](G[+[]], G[1]), this.T -= 10 * G.length + 109;
  1894. break;
  1895. case 483:
  1896. this.J = this.e >> 15 & 15, this.W = this.e >> 12 & 7, this.k = 4095 & this.e, this.T = 0 === this.J ? 258 : 350;
  1897. break;
  1898. case 485:
  1899. this.C[3] = this.C[this.W][Q].apply(null, G), this.T -= this.M[15] % 2 == 1 ? 143 : 133;
  1900. break;
  1901. case 486:
  1902. this.C[this.e >> 16 & 7] = eval(M.join()), this.T -= this.M[18];
  1903. break;
  1904. case 491:
  1905. this.C[3] = new this.C[this.W].apply(null, G), this.T -= this.M[8] / this.M[1] < 10 ? 139 : 130;
  1906. break;
  1907. case 496:
  1908. this.C[this.e >> 16 & 7] = null, this.T -= 10 < this.M[5] - this.M[3] ? 160 : 144;
  1909. break;
  1910. case 506:
  1911. this.C[this.e >> 16 & 7] = void 0, this.T -= this.M[18] % this.M[12] == 1 ? 154 : 145;
  1912. break;
  1913. default:
  1914. this.T = this.w;
  1915. }
  1916. } catch (A2) {
  1917. this.g && (this.s = this.g), this.T -= 114;
  1918. }
  1919. }, "undefined" != typeof window && (S.__ZH__ = S.__ZH__ || {}, h = S.__ZH__.zse = S.__ZH__.zse || {}, new l().O("ABt7CAAUSAAACADfSAAACAD1SAAACAAHSAAACAD4SAAACAACSAAACADCSAAACADRSAAACABXSAAACAAGSAAACADjSAAACAD9SAAACADwSAAACACASAAACADeSAAACABbSAAACADtSAAACAAJSAAACAB9SAAACACdSAAACADmSAAACABdSAAACAD8SAAACADNSAAACABaSAAACABPSAAACACQSAAACADHSAAACACfSAAACADFSAAACAC6SAAACACnSAAACAAnSAAACAAlSAAACACcSAAACADGSAAACAAmSAAACAAqSAAACAArSAAACACoSAAACADZSAAACACZSAAACAAPSAAACABnSAAACABQSAAACAC9SAAACABHSAAACAC/SAAACABhSAAACABUSAAACAD3SAAACABfSAAACAAkSAAACABFSAAACAAOSAAACAAjSAAACAAMSAAACACrSAAACAAcSAAACABySAAACACySAAACACUSAAACABWSAAACAC2SAAACAAgSAAACABTSAAACACeSAAACABtSAAACAAWSAAACAD/SAAACABeSAAACADuSAAACACXSAAACABVSAAACABNSAAACAB8SAAACAD+SAAACAASSAAACAAESAAACAAaSAAACAB7SAAACACwSAAACADoSAAACADBSAAACACDSAAACACsSAAACACPSAAACACOSAAACACWSAAACAAeSAAACAAKSAAACACSSAAACACiSAAACAA+SAAACADgSAAACADaSAAACADESAAACADlSAAACAABSAAACADASAAACADVSAAACAAbSAAACABuSAAACAA4SAAACADnSAAACAC0SAAACACKSAAACABrSAAACADySAAACAC7SAAACAA2SAAACAB4SAAACAATSAAACAAsSAAACAB1SAAACADkSAAACADXSAAACADLSAAACAA1SAAACADvSAAACAD7SAAACAB/SAAACABRSAAACAALSAAACACFSAAACABgSAAACADMSAAACACESAAACAApSAAACABzSAAACABJSAAACAA3SAAACAD5SAAACACTSAAACABmSAAACAAwSAAACAB6SAAACACRSAAACABqSAAACAB2SAAACABKSAAACAC+SAAACAAdSAAACAAQSAAACACuSAAACAAFSAAACACxSAAACACBSAAACAA/SAAACABxSAAACABjSAAACAAfSAAACAChSAAACABMSAAACAD2SAAACAAiSAAACADTSAAACAANSAAACAA8SAAACABESAAACADPSAAACACgSAAACABBSAAACABvSAAACABSSAAACAClSAAACABDSAAACACpSAAACADhSAAACAA5SAAACABwSAAACAD0SAAACACbSAAACAAzSAAACADsSAAACADISAAACADpSAAACAA6SAAACAA9SAAACAAvSAAACABkSAAACACJSAAACAC5SAAACABASAAACAARSAAACABGSAAACADqSAAACACjSAAACADbSAAACABsSAAACACqSAAACACmSAAACAA7SAAACACVSAAACAA0SAAACABpSAAACAAYSAAACADUSAAACABOSAAACACtSAAACAAtSAAACAAASAAACAB0SAAACADiSAAACAB3SAAACACISAAACADOSAAACACHSAAACACvSAAACADDSAAACAAZSAAACABcSAAACAB5SAAACADQSAAACAB+SAAACACLSAAACAADSAAACABLSAAACACNSAAACAAVSAAACACCSAAACABiSAAACADxSAAACAAoSAAACACaSAAACABCSAAACAC4SAAACAAxSAAACAC1SAAACAAuSAAACADzSAAACABYSAAACABlSAAACAC3SAAACAAISAAACAAXSAAACABISAAACAC8SAAACABoSAAACACzSAAACADSSAAACACGSAAACAD6SAAACADJSAAACACkSAAACABZSAAACADYSAAACADKSAAACADcSAAACAAySAAACADdSAAACACYSAAACACMSAAACAAhSAAACADrSAAACADWSAAAeIAAEAAACAB4SAAACAAySAAACABiSAAACABlSAAACABjSAAACABiSAAACAB3SAAACABkSAAACABnSAAACABrSAAACABjSAAACAB3SAAACABhSAAACABjSAAACABuSAAACABvSAAAeIABEAABCABkSAAACAAzSAAACABkSAAACAAySAAACABlSAAACAA3SAAACAAySAAACAA2SAAACABmSAAACAA1SAAACAAwSAAACABkSAAACAA0SAAACAAxSAAACAAwSAAACAAxSAAAeIABEAACCAAgSAAATgACVAAAQAAGEwADDAADSAAADAACSAAADAAASAAACANcIAADDAADSAAASAAATgADVAAATgAEUAAATgAFUAAATgAGUgAADAAASAAASAAATgADVAAATgAEUAAATgAFUAAATgAHUgAADAABSAAASAAATgADVAAATgAEUAAATgAFUAAATgAIUgAAcAgUSMAATgAJVAAATgAKUgAAAAAADAABSAAADAAAUAAACID/GwQPCAAYG2AREwAGDAABCIABGwQASMAADAAAUAAACID/GwQPCAAQG2AREwAHDAABCIACGwQASMAADAAAUAAACID/GwQPCAAIG2AREwAIDAABCIADGwQASMAADAAAUAAACID/GwQPEwAJDYAGDAAHG2ATDAAIG2ATDAAJG2ATKAAACAD/DIAACQAYGygSGwwPSMAASMAADAACSAAADAABUgAACAD/DIAACQAQGygSGwwPSMAASMAADAACCIABGwQASMAADAABUgAACAD/DIAACQAIGygSGwwPSMAASMAADAACCIACGwQASMAADAABUgAACAD/DIAAGwQPSMAASMAADAACCIADGwQASMAADAABUgAAKAAACAAgDIABGwQBEwANDAAAWQALGwQPDAABG2AREwAODAAODIAADQANGygSGwwTEwAPDYAPKAAACAAESAAATgACVAAAQAAGEwAQCAAESAAATgACVAAAQAAGEwAFDAAASAAADAAQSAAACAAASAAACAKsIAADCAAASAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAAASAAADAAFUgAACAABSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAABSAAADAAFUgAACAACSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAACSAAADAAFUgAACAADSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAADSAAADAAFUgAADAAFSAAACAAASAAACAJ8IAACEwARDAARSAAACAANSAAACALdIAACEwASDAARSAAACAAXSAAACALdIAACEwATDAARDIASGwQQDAATG2AQEwAUDYAUKAAAWAAMSAAAWAANSAAAWAAOSAAAWAAPSAAAWAAQSAAAWAARSAAAWAASSAAAWAATSAAAWAAUSAAAWAAVSAAAWAAWSAAAWAAXSAAAWAAYSAAAWAAZSAAAWAAaSAAAWAAbSAAAWAAcSAAAWAAdSAAAWAAeSAAAWAAfSAAAWAAgSAAAWAAhSAAAWAAiSAAAWAAjSAAAWAAkSAAAWAAlSAAAWAAmSAAAWAAnSAAAWAAoSAAAWAApSAAAWAAqSAAAWAArSAAAeIAsEAAXWAAtSAAAWAAuSAAAWAAvSAAAWAAwSAAAeIAxEAAYCAAESAAATgACVAAAQAAGEwAZCAAkSAAATgACVAAAQAAGEwAaDAABSAAACAAASAAACAJ8IAACSMAASMAACAAASAAADAAZUgAADAABSAAACAAESAAACAJ8IAACSMAASMAACAABSAAADAAZUgAADAABSAAACAAISAAACAJ8IAACSMAASMAACAACSAAADAAZUgAADAABSAAACAAMSAAACAJ8IAACSMAASMAACAADSAAADAAZUgAACAAASAAADAAZUAAACIAASEAADIAYUEgAGwQQSMAASMAACAAASAAADAAaUgAACAABSAAADAAZUAAACIABSEAADIAYUEgAGwQQSMAASMAACAABSAAADAAaUgAACAACSAAADAAZUAAACIACSEAADIAYUEgAGwQQSMAASMAACAACSAAADAAaUgAACAADSAAADAAZUAAACIADSEAADIAYUEgAGwQQSMAASMAACAADSAAADAAaUgAACAAAEAAJDAAJCIAgGwQOMwAGOBG2DAAJCIABGwQASMAADAAaUAAAEAAbDAAJCIACGwQASMAADAAaUAAAEAAcDAAJCIADGwQASMAADAAaUAAAEAAdDAAbDIAcGwQQDAAdG2AQDAAJSAAADAAXUAAAG2AQEwAeDAAeSAAADAACSAAACALvIAACEwAfDAAJSAAADAAaUAAADIAfGwQQSMAASMAADAAJCIAEGwQASMAADAAaUgAADAAJCIAEGwQASMAADAAaUAAASAAASAAADAAJSAAADAAAUgAADAAJCIABGQQAEQAJOBCIKAAADAABTgAyUAAACIAQGwQEEwAVCAAQDIAVGwQBEwAKCAAAEAAhDAAhDIAKGwQOMwAGOBImDAAKSAAADAABTgAzQAAFDAAhCIABGQQAEQAhOBHoCAAASAAACAAQSAAADAABTgA0QAAJEwAiCAAQSAAATgACVAAAQAAGEwAjCAAAEAALDAALCIAQGwQOMwAGOBLSDAALSAAADAAiUAAADIALSEAADIAAUEgAGwQQCAAqG2AQSMAASMAADAALSAAADAAjUgAADAALCIABGQQAEQALOBJkDAAjSAAATgAJVAAATgA1QAAFEwAkDAAkTgA0QAABEwAlCAAQSAAADAABTgAyUAAASAAADAABTgA0QAAJEwAmDAAmSAAADAAkSAAATgAJVAAATgA2QAAJEwAnDAAnSAAADAAlTgA3QAAFSMAAEwAlDYAlKAAAeIA4EAApDAAATgAyUAAAEAAqCAAAEAAMDAAMDIAqGwQOMwAGOBPqDAAMSAAADAAATgA5QAAFEwArDAArCID/GwQPSMAADAApTgAzQAAFDAAMCIABGQQAEQAMOBOMDYApKAAAEwAsTgADVAAAGAAKWQA6GwQFMwAGOBQeCAABSAAAEAAsOCBJTgA7VAAAGAAKWQA6GwQFMwAGOBRKCAACSAAAEAAsOCBJTgA8VAAAGAAKWQA6GwQFMwAGOBR2CAADSAAAEAAsOCBJTgA9VAAAGAAKWQA6GwQFMwAGOBSiCAAESAAAEAAsOCBJTgA+VAAAGAAKWQA6GwQFMwAGOBTOCAAFSAAAEAAsOCBJTgA/VAAAGAAKWQA6GwQFMwAGOBT6CAAGSAAAEAAsOCBJTgA8VAAATgBAUAAAGAAKWQA6GwQFMwAGOBUuCAAHSAAAEAAsOCBJTgADVAAATgBBUAAAWQBCGwQFMwAGOBVeCAAISAAAEAAsOCBJWABDSAAATgA7VAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBWiCAAKSAAAEAAsOCBJWABGSAAATgA8VAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBXmCAALSAAAEAAsOCBJWABHSAAATgA9VAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBYqCAAMSAAAEAAsOCBJWABISAAATgA+VAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBZuCAANSAAAEAAsOCBJWABJSAAATgA/VAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBayCAAOSAAAEAAsOCBJWABKSAAATgA8VAAATgBAUAAATgBLQAABTgBFQwAFCAABGAANG2AJMwAGOBb+CAAPSAAAEAAsOCBJTgBMVAAATgBNUAAAEAAtWABOSAAADAAtTgBEQAABTgBFQwAFCAABGAANG2AFMwAGOBdSCAAQSAAAEAAsOCBJTgA7VAAATgBPUAAAGAAKWQA6GwQFMwAGOBeGCAARSAAAEAAsOCBJWABQSAAAWABRSAAAWABSSAAATgA7VAAATgBPQAAFTgBTQwAFTgBEQwABTgBFQwAFCAABGAANG2AFMwAGOBfqCAAWSAAAEAAsOCBJTgADVAAATgBUUAAAGAAKWQA6GwQJMwAGOBgeCAAYSAAAEAAsOCBJTgADVAAATgBVUAAAGAAKWQA6GwQJMwAGOBhSCAAZSAAAEAAsOCBJTgADVAAATgBWUAAAGAAKWQA6GwQJMwAGOBiGCAAaSAAAEAAsOCBJTgADVAAATgBXUAAAGAAKWQA6GwQJMwAGOBi6CAAbSAAAEAAsOCBJTgADVAAATgBYUAAAGAAKWQA6GwQJMwAGOBjuCAAcSAAAEAAsOCBJTgADVAAATgBZUAAAGAAKWQA6GwQJMwAGOBkiCAAdSAAAEAAsOCBJTgADVAAATgBaUAAAGAAKWQA6GwQJMwAGOBlWCAAeSAAAEAAsOCBJTgADVAAATgBbUAAAGAAKWQA6GwQJMwAGOBmKCAAfSAAAEAAsOCBJTgADVAAATgBcUAAAGAAKWQA6GwQJMwAGOBm+CAAgSAAAEAAsOCBJTgADVAAATgBdUAAAGAAKWQA6GwQJMwAGOBnyCAAhSAAAEAAsOCBJTgADVAAATgBeUAAAGAAKWQA6GwQJMwAGOBomCAAiSAAAEAAsOCBJTgADVAAATgBfUAAAGAAKWQA6GwQJMwAGOBpaCAAjSAAAEAAsOCBJTgADVAAATgBgUAAAGAAKWQA6GwQJMwAGOBqOCAAkSAAAEAAsOCBJTgA7VAAATgBhUAAAGAAKWQA6GwQJMwAGOBrCCAAlSAAAEAAsOCBJTgA8VAAATgBiUAAAWQBjGwQFMwAGOBryCAAmSAAAEAAsOCBJTgA7VAAATgBkUAAAGAAKWQA6GwQJMwAGOBsmCAAnSAAAEAAsOCBJTgADVAAATgBlUAAAGAAKWQA6GwQJMwAGOBtaCAAoSAAAEAAsOCBJTgADVAAATgBmUAAAGAAKWQA6GwQJMwAGOBuOCAApSAAAEAAsOCBJTgADVAAATgBnUAAAGAAKWQA6GwQJMwAGOBvCCAAqSAAAEAAsOCBJTgBoVAAASAAATgBMVAAATgBpQAAFG2AKWABqG2AJMwAGOBwCCAArSAAAEAAsOCBJTgA7VAAATgBrUAAAGAAKWQA6GwQFMwAGOBw2CAAsSAAAEAAsOCBJTgA7VAAATgBrUAAASAAATgBMVAAATgBpQAAFG2AKWABqG2AJMwAGOBx+CAAtSAAAEAAsOCBJTgA7VAAATgBsUAAAGAAKWQA6GwQFMwAGOByyCAAuSAAAEAAsOCBJWABtSAAATgADVAAATgBuUAAATgBvUAAATgBEQAABTgBFQwAFCAABGAANG2AFMwAGOB0GCAAwSAAAEAAsOCBJTgADVAAATgBwUAAAGAAKWQA6GwQJMwAGOB06CAAxSAAAEAAsOCBJWABxSAAATgByVAAAQAACTgBzUNgATgBFQwAFCAABGAANG2AJMwAGOB2CCAAySAAAEAAsOCBJWAB0SAAATgByVAAAQAACTgBzUNgATgBFQwAFCAABGAANG2AJMwAGOB3KCAAzSAAAEAAsOCBJWAB1SAAATgA8VAAATgBAUAAATgBLQAABTgBFQwAFCAABGAANG2AJMwAGOB4WCAA0SAAAEAAsOCBJWAB2SAAATgA8VAAATgBAUAAATgBLQAABTgBFQwAFCAABGAANG2AJMwAGOB5iCAA1SAAAEAAsOCBJWABxSAAATgA9VAAATgB3UAAATgBFQAAFCAABGAANG2AJMwAGOB6mCAA2SAAAEAAsOCBJTgADVAAATgB4UAAAMAAGOB7OCAA4SAAAEAAsOCBJTgADVAAATgB5UAAAGAAKWQA6GwQJMwAGOB8CCAA5SAAAEAAsOCBJTgADVAAATgB6UAAAGAAKWQA6GwQJMwAGOB82CAA6SAAAEAAsOCBJTgADVAAATgB7UAAAGAAKWQA6GwQJMwAGOB9qCAA7SAAAEAAsOCBJTgADVAAATgB8UAAAGAAKWQA6GwQJMwAGOB+eCAA8SAAAEAAsOCBJTgADVAAATgB9UAAAGAAKWQA6GwQJMwAGOB/SCAA9SAAAEAAsOCBJTgADVAAATgB+UAAAGAAKWQA6GwQJMwAGOCAGCAA+SAAAEAAsOCBJTgADVAAATgB/UAAAGAAKWQA6GwQJMwAGOCA6CAA/SAAAEAAsOCBJCAAASAAAEAAsDYAsKAAATgCAVAAATgCBQAABEwAvCAAwSAAACAA1SAAACAA5SAAACAAwSAAACAA1SAAACAAzSAAACABmSAAACAA3SAAACABkSAAACAAxSAAACAA1SAAACABlSAAACAAwSAAACAAxSAAACABkSAAACAA3SAAAeIABEAAwCAT8IAAAEwAxDAAASAAACATbIAABEwAyTgCAVAAATgCBQAABDAAvG2ABEwAzDAAzWQCCGwQMMwAGOCFKCAB+SAAAEAAxOCFNTgCDVAAATgCEQAABCAB/G2ACSMAATgCDVAAATgCFQAAFEwA0DAAxSAAADAAyTgCGQAAFDAA0SAAADAAyTgCGQAAFDAAwSAAADAAySAAACARuIAACEwA1DAA1TgAyUAAACIADGwQEEwA2DAA2CIABGwQFMwAGOCIWWACHSAAADAA1TgAzQAAFWACHSAAADAA1TgAzQAAFOCIZDAA2CIACGwQFMwAGOCJCWACHSAAADAA1TgAzQAAFOCJFWACIWQCJGwQAWACKG2AAWACLG2AAWACMG2AAEwA3CAAAEAA4WACNEAA5DAA1TgAyUAAACIABGwQBEwANDAANCIAAGwQGMwAGOCSeCAAIDIA4CQABGigAEgA4CQAEGygEGwwCEwA6DAANSAAADAA1UAAACIA6DQA6GygSCID/G2QPGwwQEwA7CAAIDIA4CQABGigAEgA4CQAEGygEGwwCSMAAEwA6DAA7DIANCQABGygBSMAADIA1UEgACQA6DYA6G0wSCQD/G2gPGywQCIAIG2QRGQwTEQA7CAAIDIA4CQABGigAEgA4CQAEGygEGwwCSMAAEwA6DAA7DIANCQACGygBSMAADIA1UEgACQA6DYA6G0wSCQD/G2gPGywQCIAQG2QRGQwTEQA7DAA5DIA7CQA/GygPSMAADIA3TgCOQQAFGQwAEQA5DAA5DIA7CQAGGygSCIA/G2QPSMAADIA3TgCOQQAFGQwAEQA5DAA5DIA7CQAMGygSCIA/G2QPSMAADIA3TgCOQQAFGQwAEQA5DAA5DIA7CQASGygSCIA/G2QPSMAADIA3TgCOQQAFGQwAEQA5DAANCIADGQQBEQANOCKUDYA5KAAAAAVrVVYfGwAEa1VVHwAHalQlKxgLAAAIalQTBh8SEwAACGpUOxgdCg8YAAVqVB4RDgAEalQeCQAEalQeAAAEalQeDwAFalQ7GCAACmpUOyITFQkTERwADGtVUB4TFRUXGR0TFAAIa1VQGhwZHhoAC2tVUBsdGh4YGB4RAAtrVV0VHx0ZHxAWHwAMa1VVHR0cHx0aHBgaAAxrVVURGBYWFxYSHRsADGtVVhkeFRQUEx0fHgAMa1VWEhMbGBAXFxYXAAxrVVcYGxkfFxMbGxsADGtVVxwYHBkTFx0cHAAMa1VQHhgSEB0aGR8eAAtrVVAcHBoXFRkaHAALa1VcFxkcExkYEh8ADGtVVRofGxYRGxsfGAAMa1VVEREQFB0fHBkTAAxrVVYYExAYGBgcFREADGtVVh0ZHB0eHBUTGAAMa1VXGRkfHxkaGBAVAAxrVVccHx0UEx4fGBwADGtVUB0eGBsaHB0WFgALa1VXGBwcGRgfHhwAC2tVXBAQGRMcGRcZAAxrVVUbEhAdHhoZHB0ADGtVVR4aHxsaHh8TEgAMa1VWGBgZHBwSFBkZAAxrVVYcFxQeHx8cFhYADGtVVxofGBcVFBAcFQAMa1VXHR0TFRgfGRsZAAxrVVAdGBkYEREfGR8AC2tVVhwXGBQdHR0ZAAtrVVMbHRwYGRsaHgAMa1VVGxsaGhwUERgdAAxrVVUfFhQbGR0ZHxoABGtVVxkADGtVVh0bGh0YGBMZFQAMa1VVHRkeEhgVFBMZAAxrVVUeHB0cEhIfHBAADGtVVhMYEh0XEh8cHAADa1VQAAhqVAgRExELBAAGalQUHR4DAAdqVBcHHRIeAANqVBYAA2pUHAAIalQHFBkVGg0AA2tVVAAMalQHExELKTQTGTwtAAtqVBEDEhkbFx8TGQAKalQAExQOABATAgALalQKFw8HFh4NAwUACmpUCBsUGg0FHhkACWpUDBkCHwMFEwAIalQXCAkPGBMAC2pUER4ODys+GhMCAAZqVAoXFBAACGpUChkTGRcBAA5qVCwEARkQMxQOABATAgAKalQQAyQ/HgMfEQAJalQNHxIZBS8xAAtqVCo3DwcWHg0DBQAGalQMBBgcAAlqVCw5Ah8DBRMACGpUNygJDxgTAApqVAwVHB0QEQ4YAA1qVBADOzsACg8pOgoOAAhqVCs1EBceDwAaalQDGgkjIAEmOgUHDQ8eFSU5DggJAwEcAwUADWpUChcNBQcLXVsUExkAD2pUBwkPHA0JODEREBATAgAIalQnOhcADwoABGpUVk4ACGpUBxoXAA8KAAxqVAMaCS80GQIJBRQACGpUBg8LGBsPAAZqVAEQHAUADWpUBxoVGCQgERcCAxoADWpUOxg3ABEXAgMaFAoACmpUOzcAERcCAxoACWpUMyofKikeGgANalQCBgQOAwcLDzUuFQAWalQ7GCEGBA4DBwsPNTIDAR0LCRgNGQAPalQAExo0LBkDGhQNBR4ZAAZqVBEPFQMADWpUJzoKGw0PLy8YBQUACGpUBxoKGw0PAA5qVBQJDQ8TIi8MHAQDDwAealRAXx8fJCYKDxYUEhUKHhkDBw4WBg0hDjkWHRIrAAtqVBMKHx4OAwcLDwAGaFYQHh8IABdqVDsYMAofHg4DBwsPNTQICQMBHDMhEAARalQ7NQ8OBAIfCR4xOxYdGQ8AEWpUOzQODhgCHhk+OQIfAwUTAAhqVAMTGxUbFQAHalQFFREPHgAQalQDGgk8OgUDAwMVEQ0yMQAKalQCCwMVDwUeGQAQalQDGgkpMREQEBMCLiMoNQAYalQDGgkpMREQEBMCHykjIjcVChglNxQQAA9qVD8tFw0FBwtdWxQTGSAAC2pUOxg3GgUDAygYAA1qVAcUGQUfHh8ODwMFAA1qVDsYKR8WFwQBFAsPAAtqVAgbFBoVHB8EHwAHalQhLxgFBQAHalQXHw0aEAALalQUHR0YDQkJGA8AC2pUFAARFwIDGh8BAApqVAERER4PHgUZAAZqVAwCDxsAB2pUFxsJDgEAGGpUOxQuERETHwQAKg4VGQIVLx4UBQ4ZDwALalQ7NA4RERMfBAAAFmpUOxgwCh8eDgMHCw81IgsPFQEMDQkAFWpUOxg0DhEREx8EACoiCw8VAQwNCQAdalQ7GDAKHx4OAwcLDzU0CAkDARwzIQsDFQ8FHhkAFWpUOxghBgQOAwcLDzUiCw8VAQwNCQAUalQ7GCMOAwcLDzUyAwEdCwkYDRkABmpUID0NCQAFalQKGQAAB2tVVRkYGBgABmpUKTQNBAAIalQWCxcSExoAB2pUAhIbGAUACWpUEQMFAxkXCgADalRkAAdqVFJIDiQGAAtqVBUjHW9telRIQQAJalQKLzkmNSYbABdqVCdvdgsWbht5IjltEFteRS0EPQM1DQAZalQwPx4aWH4sCQ4xNxMnMSA1X1s+b1MNOgACalQACGpUBxMRCyst"));
  1920. var D = function(t2) {
  1921. return __g._encrypt(encodeURIComponent(t2));
  1922. };
  1923. exports.XL = A, exports.ZP = D;
  1924. }
  1925. var o = {};
  1926. f1(void 0, o);
  1927. return o.ZP(s);
  1928. }
  1929. var createHeaders = (url) => {
  1930. function K() {
  1931. var t2 = new RegExp("d_c0=([^;]+)").exec(document.cookie);
  1932. return t2 && t2[1];
  1933. }
  1934. var z = function(t2) {
  1935. var e2 = new URL(t2, "https://www.zhihu.com");
  1936. return "" + e2.pathname + e2.search;
  1937. };
  1938. var S2 = function(t2, e2, n2, r2) {
  1939. var o2 = n2.zse93, i2 = n2.dc0, a2 = n2.xZst81, u = z(t2), c2 = "", s2 = [o2, u, i2, "", a2].filter(Boolean).join("+");
  1940. return {
  1941. source: s2,
  1942. signature: zhihu_enc(md5(s2))
  1943. };
  1944. }(url, void 0, {
  1945. zse93: "101_3_3.0",
  1946. dc0: K(),
  1947. xZst81: null
  1948. });
  1949. return {
  1950. "x-zse-93": "101_3_3.0",
  1951. "x-zse-96": "2.0_" + S2.signature
  1952. };
  1953. };
  1954. var doFetchNotInterested = ({ id, type }) => {
  1955. const nHeader = store.getStorageConfigItem("fetchHeaders");
  1956. delete nHeader["vod-authorization"];
  1957. delete nHeader["content-encoding"];
  1958. delete nHeader["Content-Type"];
  1959. delete nHeader["content-type"];
  1960. const idToNum = +id;
  1961. if (String(idToNum) === "NaN") {
  1962. fnLog(`调用不感兴趣接口错误,idNaN, ID${id}`);
  1963. return;
  1964. }
  1965. fetch("/api/v3/feed/topstory/uninterestv2", {
  1966. body: `item_brief=${encodeURIComponent(JSON.stringify({ source: "TS", type, id: idToNum }))}`,
  1967. method: "POST",
  1968. headers: new Headers({
  1969. ...nHeader,
  1970. "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8"
  1971. })
  1972. }).then((res) => res.json());
  1973. };
  1974. var fetchGetUserinfo = () => {
  1975. const headers = store.getStorageConfigItem("fetchHeaders");
  1976. return new Promise((resolve) => {
  1977. fetch(
  1978. `https://www.zhihu.com/api/v4/me?include=is_realname%2Cad_type%2Cavailable_message_types%2Cdefault_notifications_count%2Cfollow_notifications_count%2Cvote_thank_notifications_count%2Cmessages_count%2Cemail%2Caccount_status%2Cis_bind_phone%2Cfollowing_question_count%2Cis_force_renamed%2Crenamed_fullname%2Cis_destroy_waiting`,
  1979. {
  1980. method: "GET",
  1981. headers: new Headers(headers),
  1982. credentials: "include"
  1983. }
  1984. ).then((response) => response.json()).then((res) => {
  1985. resolve(res);
  1986. });
  1987. });
  1988. };
  1989. var doHomeFetch = (url, headers) => {
  1990. return new Promise((resolve) => {
  1991. if (!url) {
  1992. resolve([]);
  1993. } else {
  1994. fetch(url, {
  1995. method: "GET",
  1996. headers: new Headers(headers)
  1997. }).then((response) => response.json()).then((res) => resolve(res.data));
  1998. }
  1999. });
  2000. };
  2001. var BASIC_SHOW_CONTENT = [
  2002. { label: "去除热词点击搜索", value: "contentRemoveKeywordSearch" },
  2003. {
  2004. label: `<b>列表</b>标题类别显示<span class="ctz-label-tag ctz-label-tag-Answer">问答</span><span class="ctz-label-tag ctz-label-tag-Article">文章</span><span class="ctz-label-tag ctz-label-tag-ZVideo">视频</span><span class="ctz-label-tag ctz-label-tag-Pin">想法</span>`,
  2005. value: "questionTitleTag"
  2006. },
  2007. { label: "<b>列表</b>更多「···」按钮移动到最右侧", value: "fixedListItemMore" },
  2008. { label: "<b>列表</b>点击高亮边框", value: "highlightListItem" },
  2009. { label: "<b>推荐列表</b>「不感兴趣」按钮", value: "listOutPutNotInterested", needFetch: true },
  2010. { label: "<b>推荐列表</b>「直达问题」按钮", value: "listOutputToQuestion" },
  2011. { label: "<b>关注列表</b>高亮原创内容", value: "highlightOriginal" },
  2012. { label: "<b>推荐、关注列表</b>内容置顶发布时间和最后修改时间", value: "listItemCreatedAndModifiedTime" },
  2013. { label: "赞同按钮仅显示数字", value: "justVoteNum" },
  2014. { label: "评论按钮仅显示数字", value: "justCommitNum" },
  2015. { label: "<b>问题详情</b>置顶创建时间和最后修改时间", value: "questionCreatedAndModifiedTime" },
  2016. { label: "<b>回答</b>顶部显示赞同人数", value: "topVote" },
  2017. { label: "<b>回答</b>一键获取回答链接", value: "copyAnswerLink" },
  2018. { label: "<b>回答</b>置顶创建时间与最后修改时间", value: "answerItemCreatedAndModifiedTime" },
  2019. { label: "<b>文章</b>发布时间置顶", value: "articleCreateTimeToTop" },
  2020. { label: "<b>回答、文章</b>顶部显示导出当前内容/回答按钮", value: "topExportContent" },
  2021. { label: "<b>回答、文章</b>中视频替换为链接", value: "videoUseLink" },
  2022. { label: "<b>用户主页</b>内容置顶发布、修改时间", value: "userHomeContentTimeTop" },
  2023. { label: "<b>用户主页</b>置顶「屏蔽用户」按钮", value: "userHomeTopBlockUser" }
  2024. ];
  2025. var ID_BLOCK_LIST = "CTZ-BLOCK-LIST";
  2026. var myBlack = {
  2027. messageCancel: "取消屏蔽之后,对方将可以:关注你、给你发私信、向你提问、评论你的答案、邀请你回答问题。",
  2028. /** 初始化黑名单列表 */
  2029. init: async function() {
  2030. const me = this;
  2031. const elementBlock = domById(ID_BLOCK_LIST);
  2032. if (!elementBlock)
  2033. return;
  2034. const { removeBlockUserContentList = [] } = await myStorage.getConfig();
  2035. elementBlock.innerHTML = removeBlockUserContentList.map((i2) => this.createItem(i2)).join("");
  2036. elementBlock.onclick = (event) => {
  2037. const target = event.target;
  2038. if (!target || !target.classList.contains(CLASS_REMOVE_BLOCK))
  2039. return;
  2040. const item = target.parentElement;
  2041. const info = item.dataset.info ? JSON.parse(item.dataset.info) : {};
  2042. confirm(me.messageCancel) && me.serviceRemove(info);
  2043. };
  2044. },
  2045. /** 黑名单元素 */
  2046. createItem: function(info) {
  2047. return `<div class="ctz-black-item ctz-black-id-${info.id}" data-info='${JSON.stringify(info)}'>${this.createItemContent(info)}</div>`;
  2048. },
  2049. createItemContent: ({ id, name, avatar }) => {
  2050. return `<img src="${avatar}"/><a href="/people/${id}" target="_blank">${name}</a><i class="${CLASS_REMOVE_BLOCK}" style="margin-left:4px;cursor:pointer;">✗</i>`;
  2051. },
  2052. /** 添加「屏蔽用户」按钮,第二个参数为监听方法对象 */
  2053. addButton: async function(event, objMy) {
  2054. const me = this;
  2055. const classBox = "ctz-block-box";
  2056. const nodeBlockBox = event.querySelector(`.${classBox}`);
  2057. if (nodeBlockBox)
  2058. return;
  2059. const nodeUser = event.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
  2060. if (!nodeUser || !nodeUser.offsetHeight)
  2061. return;
  2062. const userUrl = nodeUser.querySelector('meta[itemprop="url"]').content;
  2063. const userName = nodeUser.querySelector('meta[itemprop="name"]').content;
  2064. const avatar = nodeUser.querySelector('meta[itemprop="image"]').content;
  2065. const nodeAnswerItem = event.querySelector(".AnswerItem");
  2066. const mo = nodeAnswerItem ? nodeAnswerItem.getAttribute("data-za-extra-module") || "{}" : "{}";
  2067. if (!JSON.parse(mo).card)
  2068. return;
  2069. const aContent = JSON.parse(mo).card.content;
  2070. const userId = aContent.author_member_hash_id || "";
  2071. if (!userUrl.replace(/https:\/\/www.zhihu.com\/people\//, ""))
  2072. return;
  2073. const { removeBlockUserContentList = [] } = await myStorage.getConfig();
  2074. const isAlreadyBlack = removeBlockUserContentList.findIndex((i2) => i2.id === userId) >= 0;
  2075. const message2 = `是否要屏蔽${userName}?
  2076. 屏蔽后,对方将不能关注你、向你发私信、评论你的实名回答、使用「@」提及你、邀请你回答问题,但仍然可以查看你的公开信息。
  2077. 如果开启了「不再显示已屏蔽用户发布的内容」那么也不会看到对方发布的回答`;
  2078. const classBlack = "ctz-black";
  2079. const classBlackRemove = "ctz-black-remove";
  2080. const classBlackFilter = "ctz-black-filter";
  2081. const classJustFilter = "ctz-just-filter";
  2082. const createClass = (value) => `${value} ctz-button ctz-button-small ctz-button-transparent`;
  2083. const innerHTML = isAlreadyBlack ? `<button class="${createClass(classBlackRemove)}">解除屏蔽</button>` + fnReturnStr(`<button class="${createClass(classJustFilter)}">隐藏该回答</button>`, !!objMy) : `<button class="${createClass(classBlack)}">屏蔽用户</button>` + fnReturnStr(`<button class="${createClass(classBlackFilter)}">屏蔽用户并隐藏该回答</button>`, !!objMy);
  2084. const nodeBox = domC("div", { className: classBox, innerHTML });
  2085. nodeBox.onclick = function(ev) {
  2086. const target = ev.target;
  2087. const matched = userUrl.match(/(?<=people\/)[\w\W]+/);
  2088. const urlToken = matched ? matched[0] : "";
  2089. if (target.classList.contains(classBlack)) {
  2090. if (!confirm(message2))
  2091. return;
  2092. me.serviceAdd(urlToken, userName, userId, avatar);
  2093. fnDomReplace(this.querySelector(`.${classBlackFilter}`), { className: createClass(classJustFilter), innerText: "隐藏该回答" });
  2094. fnDomReplace(target, { className: createClass(classBlackRemove), innerText: "解除屏蔽" });
  2095. return;
  2096. }
  2097. if (target.classList.contains(classBlackRemove)) {
  2098. if (!confirm(me.messageCancel))
  2099. return;
  2100. me.serviceRemove({ urlToken, id: userId, name: userName });
  2101. fnDomReplace(target, { className: createClass(classBlack), innerText: "屏蔽用户" });
  2102. fnDomReplace(this.querySelector(`.${classJustFilter}`), {
  2103. className: createClass(classBlackFilter),
  2104. innerText: "屏蔽用户并隐藏该回答"
  2105. });
  2106. return;
  2107. }
  2108. if (target.classList.contains(classBlackFilter) || target.classList.contains(classJustFilter)) {
  2109. if (target.classList.contains(classBlackFilter)) {
  2110. if (!confirm(message2))
  2111. return;
  2112. me.serviceAdd(urlToken, userName, userId, avatar);
  2113. }
  2114. event.style.display = "none";
  2115. if (objMy) {
  2116. objMy.index = objMy.index - 1 > 0 ? objMy.index - 1 : 0;
  2117. }
  2118. return;
  2119. }
  2120. };
  2121. nodeUser.appendChild(nodeBox);
  2122. },
  2123. /** 添加屏蔽用户 */
  2124. addBlackItem: async function(info) {
  2125. const pfConfig = await myStorage.getConfig();
  2126. const nL = pfConfig.removeBlockUserContentList || [];
  2127. nL.push(info);
  2128. myStorage.setConfigItem("removeBlockUserContentList", nL);
  2129. const nodeBlackItem = domC("div", { className: `ctz-black-item ctz-black-id-${info.id}`, innerHTML: this.createItemContent(info) });
  2130. nodeBlackItem.dataset.info = JSON.stringify(info);
  2131. domById(ID_BLOCK_LIST).appendChild(nodeBlackItem);
  2132. },
  2133. /** 调用「屏蔽用户」接口 */
  2134. serviceAdd: function(urlToken, userName, userId, avatar) {
  2135. const me = this;
  2136. const headers = this.getHeaders();
  2137. fetch(`https://www.zhihu.com/api/v4/members/${urlToken}/actions/block`, {
  2138. method: "POST",
  2139. headers: new Headers({
  2140. ...headers,
  2141. "x-xsrftoken": document.cookie.match(/(?<=_xsrf=)[\w-]+(?=;)/)[0] || ""
  2142. }),
  2143. credentials: "include"
  2144. }).then(() => {
  2145. me.addBlackItem({ id: userId, name: userName, avatar, userType: "people", urlToken });
  2146. });
  2147. },
  2148. /** 解除拉黑用户接口 */
  2149. serviceRemove: function(info) {
  2150. const { urlToken, id } = info;
  2151. const headers = this.getHeaders();
  2152. fetch(`https://www.zhihu.com/api/v4/members/${urlToken}/actions/block`, {
  2153. method: "DELETE",
  2154. headers: new Headers({
  2155. ...headers,
  2156. "x-xsrftoken": document.cookie.match(/(?<=_xsrf=)[\w-]+(?=;)/)[0] || ""
  2157. }),
  2158. credentials: "include"
  2159. }).then(async () => {
  2160. const pfConfig = await myStorage.getConfig();
  2161. const nL = pfConfig.removeBlockUserContentList || [];
  2162. const itemIndex = nL.findIndex((i2) => i2.id === info.id);
  2163. if (itemIndex >= 0) {
  2164. nL.splice(itemIndex, 1);
  2165. const removeItem = dom(`.ctz-black-id-${id}`);
  2166. removeItem && removeItem.remove();
  2167. myStorage.setConfigItem("removeBlockUserContentList", nL);
  2168. }
  2169. });
  2170. },
  2171. /** 同步黑名单列表 */
  2172. sync: function(offset = 0, l2 = []) {
  2173. const nodeList = domById(ID_BLOCK_LIST);
  2174. !l2.length && nodeList && (nodeList.innerHTML = "");
  2175. fnDomReplace(domById(ID_BUTTON_SYNC_BLOCK), { innerHTML: '<i class="ctz-loading">↻</i>', disabled: true });
  2176. const limit = 20;
  2177. const headers = this.getHeaders();
  2178. fetch(`https://www.zhihu.com/api/v3/settings/blocked_users?offset=${offset}&limit=${limit}`, {
  2179. method: "GET",
  2180. headers: new Headers(headers),
  2181. credentials: "include"
  2182. }).then((response) => response.json()).then(({ data, paging }) => {
  2183. data.forEach(({ id, name, avatar_url, user_type, url_token }) => {
  2184. l2.push({ id, name, avatar: avatar_url, userType: user_type, urlToken: url_token });
  2185. });
  2186. if (!paging.is_end) {
  2187. this.sync(offset + limit, l2);
  2188. } else {
  2189. myStorage.setConfigItem("removeBlockUserContentList", l2);
  2190. myBlack.init();
  2191. fnDomReplace(domById(ID_BUTTON_SYNC_BLOCK), { innerHTML: "同步黑名单", disabled: false });
  2192. }
  2193. });
  2194. },
  2195. getHeaders: () => store.getStorageConfigItem("fetchHeaders")
  2196. };
  2197. var initFetchInterceptStatus = async () => {
  2198. const { fetchInterceptStatus } = await myStorage.getConfig();
  2199. changeHTML(!!fetchInterceptStatus);
  2200. domById("CTZ_CHANGE_FETCH").onclick = function() {
  2201. if (confirm(
  2202. fetchInterceptStatus ? "关闭接口拦截,确认后将刷新页面。\n「黑名单设置;外置不感兴趣;快速屏蔽用户;回答、文章和收藏夹导出」功能将不可用。" : "开启接口拦截,确认后将刷新页面。\n如遇到知乎页面无法显示数据的情况请尝试关闭接口拦截。"
  2203. )) {
  2204. myStorage.setConfigItem("fetchInterceptStatus", !fetchInterceptStatus);
  2205. window.location.reload();
  2206. }
  2207. };
  2208. };
  2209. var changeHTML = (status) => {
  2210. domById("CTZ_FETCH_STATUS").innerHTML = status ? '<b style="color: green;">已开启接口拦截</b>,如遇到知乎页面无法显示数据的情况请尝试关闭接口拦截' : '<b style="color: red;">已关闭接口拦截</b>,部分功能不可用';
  2211. domById("CTZ_CHANGE_FETCH").innerHTML = status ? "关闭接口拦截" : "开启接口拦截";
  2212. if (!status) {
  2213. domA(".ctz-fetch-intercept").forEach((item) => {
  2214. item.classList.add("ctz-fetch-intercept-close");
  2215. item.querySelectorAll("input").forEach((it) => {
  2216. it.disabled = true;
  2217. });
  2218. item.querySelectorAll("button").forEach((it) => {
  2219. it.disabled = true;
  2220. });
  2221. });
  2222. }
  2223. };
  2224. var myMenu = {
  2225. init: function() {
  2226. const { hash } = location;
  2227. const nodeMenuTop = dom(".ctz-menu-top");
  2228. if (!nodeMenuTop)
  2229. return;
  2230. const chooseId = [...nodeMenuTop.children].map((i2) => i2.hash).find((i2) => i2 === hash || hash.replace(i2, "") !== hash);
  2231. if (chooseId) {
  2232. this.click({ target: dom(`a[href="${chooseId}"]`) });
  2233. return;
  2234. }
  2235. this.click({ target: dom(`a[href="${HEADER[0].href}"]`) });
  2236. },
  2237. click: function({ target }) {
  2238. const targetForA = target.tagName === "A" ? target : target.parentElement;
  2239. if (!(targetForA.hash && targetForA.tagName === "A"))
  2240. return;
  2241. const isThis = targetForA.hash.replace(/#/, "");
  2242. if (!isThis)
  2243. return;
  2244. const nodesA = domA(".ctz-menu-top>a");
  2245. for (let i2 = 0, len = nodesA.length; i2 < len; i2++) {
  2246. const itemA = nodesA[i2];
  2247. itemA.classList.remove("target");
  2248. }
  2249. targetForA.classList.add("target");
  2250. const nodesDiv = domA(".ctz-content>div");
  2251. for (let i2 = 0, len = nodesDiv.length; i2 < len; i2++) {
  2252. const item = nodesDiv[i2];
  2253. item.style.display = isThis === item.id ? "flex" : "none";
  2254. }
  2255. }
  2256. };
  2257. var INNER_HTML = `<div id="CTZ_DIALOG_MAIN" style="display: none"><div class="ctz-header"><span>修改器</span><span class="ctz-version"></span><div class="ctz-top-operate"><span id="CTZ_FETCH_STATUS">状态获取中...</span><button class="ctz-button" id="CTZ_CHANGE_FETCH" size="small">切换接口拦截</button></div><button id="CTZ_CLOSE_DIALOG">✗</button></div><div class="ctz-center"><div class="ctz-menu-top"></div><div class="ctz-content"><div id="CTZ_BASIS" style="display: none"><div class="ctz-content-left"><a href="#CTZ_BASIS_DEFAULT">基本设置</a><a href="#CTZ_BASIS_SHOW_CONTENT">显示修改</a><a href="#CTZ_BASIS_SIZE">页面尺寸</a><a href="#CTZ_BASIS_FLOAT">悬浮模块</a><a href="#CTZ_BASIS_COLOR">颜色设置</a><a href="#CTZ_BASIS_CONFIG">配置操作</a></div><div class="ctz-content-right"><div id="CTZ_BASIS_DEFAULT"><div class="ctz-set-title"><span>基本设置</span></div><div class="ctz-set-content"><label class="ctz-flex-wrap"><span class="ctz-label">不显示修改器唤醒图标 ⚙︎</span><input class="ctz-i" name="hiddenOpenButton" type="checkbox" value="on" /></label><label class="ctz-flex-wrap"><span class="ctz-label">快捷键唤起编辑器<span class="key-shadow">></span>(<span class="key-shadow">Shift</span>+<span class="key-shadow">.</span>)</span><input class="ctz-i" name="hotKey" type="checkbox" value="on" /></label><div><div class="ctz-label">修改浏览器标签</div><div class="ctz-flex-wrap"><input type="text" name="globalTitle" style="width: 250px" /><button class="ctz-button" name="buttonConfirmTitle" style="margin: 0 4px">确认</button><button class="ctz-button" name="buttonResetTitle">还原</button></div></div><label class="ctz-flex-wrap"><span class="ctz-label">去除浏览器标签上<b>XX条私信/未读消息</b>的提示</span><input class="ctz-i" name="globalTitleRemoveMessage" type="checkbox" value="on" /></label><div><div class="ctz-label">修改网页标题图片(图标可能会因为网络问题丢失)</div><div class="ctz-flex-wrap" id="CTZ_TITLE_ICO"></div></div></div></div><div id="CTZ_BASIS_SHOW_CONTENT"><div class="ctz-set-title"><span>显示修改<span class="ctz-desc" style="color: red">修改后刷新页面生效</span></span></div><div class="ctz-set-content"><div class="ctz-flex-wrap"><span class="ctz-label">购物链接显示设置</span><label><input class="ctz-i" name="linkShopping" type="radio" value="0" />默认</label><label><input class="ctz-i" name="linkShopping" type="radio" value="1" />仅文字</label><label><input class="ctz-i" name="linkShopping" type="radio" value="2" />隐藏</label></div><div class="ctz-flex-wrap"><span class="ctz-label">回答内容展开/收起</span><label><input class="ctz-i" type="radio" name="answerOpen" value="" />知乎默认</label><label><input class="ctz-i" type="radio" name="answerOpen" value="on" />自动展开所有回答</label><label><input class="ctz-i" type="radio" name="answerOpen" value="off" />默认收起所有长回答</label></div></div></div><div id="CTZ_BASIS_SIZE"><div class="ctz-set-title"><span>页面尺寸</span></div><div class="ctz-set-content"><div id="CTZ_VERSION_RANGE_ZHIHU"></div><label class="ctz-flex-wrap"><span class="ctz-label">评论弹窗匹配页面宽度</span><input class="ctz-i" name="commitModalSizeSameVersion" type="checkbox" value="on" /></label><div id="CTZ_FONT_SIZE_IN_ZHIHU"></div><div><div class="ctz-flex-wrap"><div class="ctz-label">回答和文章图片尺寸</div><label><input class="ctz-i" name="zoomImageType" type="radio" value="0" />默认</label><label><input class="ctz-i" name="zoomImageType" type="radio" value="1" />原图</label><label><input class="ctz-i" name="zoomImageType" type="radio" value="2" />自定义</label></div><div id="CTZ_IMAGE_SIZE_CUSTOM" style="display: none"></div></div><div><div class="ctz-flex-wrap"><div class="ctz-label">图片最大高度限制</div><label><input class="ctz-i" name="zoomImageHeight" type="radio" value="0" />不限制</label><label><input class="ctz-i" name="zoomImageHeight" type="radio" value="1" />限制</label><span class="ctz-commit">限制图片最大高度后,图片将按照高度等比例缩放</span></div><div id="CTZ_IMAGE_HEIGHT_CUSTOM" style="display: none"></div></div><label class="ctz-flex-wrap"><span class="ctz-label">使用弹窗打开动图</span><input class="ctz-i" name="showGIFinDialog" type="checkbox" value="on" /></label><div><div class="ctz-flex-wrap"><div class="ctz-label">列表视频回答的视频内容尺寸</div><label><input class="ctz-i" name="zoomListVideoType" type="radio" value="0" />默认</label><label><input class="ctz-i" name="zoomListVideoType" type="radio" value="2" />自定义</label></div><div id="CTZ_LIST_VIDEO_SIZE_CUSTOM"></div></div></div></div><div id="CTZ_BASIS_FLOAT"><div class="ctz-set-title"><span>悬浮模块</span></div><div class="ctz-set-content"><div class="ctz-flex-wrap"><label><span class="ctz-label">回答内容「收起」按钮悬浮</span><input class="ctz-i" name="suspensionPickUp" type="checkbox" value="on" /></label></div><div class="ctz-flex-wrap" style="align-items: center"><span>悬浮收起按钮位置,数字越大离右侧越远:</span><input name="suspensionPickupRight" type="number" class="ctz-i-change" /></div><div><div class="ctz-label">信息模块悬浮</div><div class="ctz-commit">拖动悬浮模块定位位置,鼠标放置显示点击 按钮即可拖动</div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="suspensionHomeTab" type="checkbox" value="on" />首页列表切换</label><label><input class="ctz-i" name="suspensionFind" type="checkbox" value="on" />顶部发现模块</label><label><input class="ctz-i" name="suspensionUser" type="checkbox" value="on" />个人中心模块</label><label><input class="ctz-i" name="suspensionSearch" type="checkbox" value="on" />搜索栏模块</label></div></div></div></div><div id="CTZ_BASIS_COLOR"><div class="ctz-set-title"><span>颜色设置</span></div><div class="ctz-set-content"><div class="ctz-set-background"></div><div class="ctz-set-color ctz-flex-wrap"><div class="ctz-label">修改文字颜色(例: #f7f9f9)</div><input type="text" class="ctz-i" name="colorText1" style="width: 200px" /></div></div></div><div id="CTZ_BASIS_CONFIG"><div class="ctz-set-title"><span>配置操作</span></div><div class="ctz-set-content"><div class="ctz-flex-wrap ctz-config-buttons"><button class="ctz-button" name="useSimple">启用极简模式</button><button class="ctz-button" name="configReset">恢复默认配置</button><button class="ctz-button" name="configExport">配置导出</button><div id="IMPORT_BY_FILE"><input type="file" class="ctz-input-config-import" id="readTxt" accept=".txt" /><button class="ctz-button" name="configImport">配置导入</button></div></div><div class="ctz-customize-css"><div class="ctz-label">自定义样式</div><div style="display: flex"><textarea name="textStyleCustom" placeholder="格式为CSS"></textarea><button class="ctz-button" name="styleCustom">确 定</button></div></div></div></div></div></div><div id="CTZ_FILTER" style="display: none"><div class="ctz-content-left"><a href="#CTZ_FILTER_LIST">列表内容屏蔽</a><a href="#CTZ_FILTER_ANSWER">回答内容屏蔽</a></div><div class="ctz-content-right"><h5 class="ctz-alert-red">此部分更改后请重新刷新页面</h5><div id="CTZ_FILTER_LIST" class="ctz-filter-block"><div class="ctz-set-title">列表内容屏蔽</div><div class="ctz-set-content"><div><label style="display: flex; align-items: center"><span class="ctz-label">屏蔽顶部活动推广</span><input class="ctz-i" name="removeTopAD" type="checkbox" value="on" /></label></div><div class="ctz-filter-follow"><div class="ctz-label">关注列表关注人操作屏蔽</div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="removeFollowVoteAnswer" type="checkbox" value="on" />赞同回答</label><label><input class="ctz-i" name="removeFollowVoteArticle" type="checkbox" value="on" />赞同文章</label><label><input class="ctz-i" name="removeFollowFQuestion" type="checkbox" value="on" />关注问题</label></div></div><div class="ctz-filter-me"><label style="display: flex; align-items: center"><span class="ctz-label">关注列表屏蔽自己的操作</span><input class="ctz-i" name="removeMyOperateAtFollow" type="checkbox" value="on" /></label></div><div class="ctz-filter-type"><div class="ctz-label">列表类别屏蔽</div><div class="ctz-commit" style="line-height: 22px">勾选后「关注、推荐、搜索」将屏蔽所勾选的类别内容</div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="removeItemQuestionAsk" type="checkbox" value="on" />邀请回答</label><label><input class="ctz-i" name="removeItemAboutAD" type="checkbox" value="on" />商业推广</label><label><input class="ctz-i" name="removeItemAboutArticle" type="checkbox" value="on" />文章</label><label><input class="ctz-i" name="removeItemAboutVideo" type="checkbox" value="on" />视频</label><label><input class="ctz-i" name="removeItemAboutPin" type="checkbox" value="on" />想法</label></div></div><div class="ctz-filter-list-vote"><label style="display: flex; align-items: center"><span class="ctz-label">列表低赞内容屏蔽</span><input class="ctz-i" name="removeLessVote" type="checkbox" value="on" /></label><div style="font-size: 12px; color: #999; line-height: 22px">勾选后「关注、推荐、搜索」列表屏蔽点赞量少于<input name="lessVoteNumber" class="ctz-i-change" type="number" style="width: 100px; margin: 0 4px" />的内容</div></div></div></div><div id="CTZ_FILTER_ANSWER" class="ctz-filter-block"><div class="ctz-set-title">回答内容屏蔽</div><div class="ctz-set-content"><div class="ctz-filter-defail-who"><div class="ctz-label">屏蔽以下官方账号的回答</div><div style="margin: 4px 0; border-bottom: 1px solid #ebebeb; padding-bottom: 4px"><label><input class="ctz-i" name="removeZhihuOfficial" type="checkbox" value="on" />所有知乎官方账号</label></div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="removeStoryAnswer" type="checkbox" value="on" />故事档案局</label><label><input class="ctz-i" name="removeYanxuanAnswer" type="checkbox" value="on" />盐选科普</label><label><input class="ctz-i" name="removeYanxuanRecommend" type="checkbox" value="on" />盐选推荐</label><label><input class="ctz-i" name="removeYanxuanCPRecommend" type="checkbox" value="on" />盐选测评室</label></div></div><div class="ctz-flex-wrap"><label><span class="ctz-label">屏蔽「匿名用户」回答</span><input class="ctz-i" name="removeAnonymousAnswer" type="checkbox" value="on" /></label></div><div class="ctz-filter-defail-tag"><div class="ctz-label">屏蔽带有以下标签的回答</div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="removeFromYanxuan" type="checkbox" value="on" />选自盐选专栏</label><label><input class="ctz-i" name="removeUnrealAnswer" type="checkbox" value="on" />带有虚构创作</label><label><input class="ctz-i" name="removeFromEBook" type="checkbox" value="on" />选自电子书</label></div></div><div class="ctz-filter-detail-vote"><label style="display: flex; align-items: center"><span class="ctz-label">回答内容低赞回答屏蔽</span><input class="ctz-i" name="removeLessVoteDetail" type="checkbox" value="on" /></label><div style="font-size: 12px; color: #999; line-height: 22px">勾选后问题详情页将屏蔽点赞量少于<input name="lessVoteNumberDetail" class="ctz-i-change" type="number" style="width: 100px; margin: 0 4px" />的回答</div></div></div></div></div></div><div id="CTZ_HIDDEN" style="display: none"></div><div id="CTZ_BLOCK_WORD" style="display: none"><div class="ctz-content-left"><a href="#CTZ_BLOCK_WORD_LIST">标题屏蔽词</a><a href="#CTZ_BLOCK_WORD_CONTENT">内容屏蔽词</a></div><div class="ctz-content-right"><div id="CTZ_BLOCK_WORD_LIST"><div class="ctz-set-title"><span>标题屏蔽词</span><span class="ctz-desc">匹配位置:「关注页、推荐页」列表<b>标题</b></span></div><input name="inputFilterWord" type="text" placeholder="输入后回车或失去焦点(不区分大小写)" class="input-block-words" /><div class="ctz-block-words-content"></div></div><div id="CTZ_BLOCK_WORD_CONTENT"><div class="ctz-set-title"><span>内容屏蔽词</span><span class="ctz-desc">匹配位置:「关注页、推荐页」列表<b>内容</b>,回答页<b>回答内容</b></span></div><input name="inputBlockWordsAnswer" type="text" placeholder="输入后回车或失去焦点(不区分大小写)" class="input-block-words" /><div class="ctz-block-words-content"></div></div></div></div><div id="CTZ_BLACKLIST" style="display: none"><div class="ctz-content-left"><a href="#CTZ_BASIS_BLOCK">黑名单设置</a></div><div class="ctz-content-right ctz-fetch-intercept"><h5 class="ctz-alert-red ctz-need-fetch">接口拦截已关闭,此部分功能无法使用</h5><div id="CTZ_BASIS_BLOCK"><div class="ctz-set-title"><span>黑名单设置</span></div><div class="ctz-set-content"><button id="CTZ-BUTTON-SYNC-BLOCK" name="syncBlack" class="ctz-button">同步黑名单</button><label class="ctz-flex-wrap"><span class="ctz-label">回答列表用户名后显示「屏蔽用户」按钮</span><input class="ctz-i" name="showBlockUser" type="checkbox" value="on" /></label><label class="ctz-flex-wrap"><span class="ctz-label">屏蔽黑名单用户发布的内容</span><input class="ctz-i" name="removeBlockUserContent" type="checkbox" value="on" /></label><div><div class="ctz-label">黑名单列表</div><div id="CTZ-BLOCK-LIST"></div></div></div></div></div></div><div id="CTZ_HISTORY" style="display: none"><div class="ctz-content-left"><a href="#CTZ_HISTORY_LIST">推荐列表缓存</a><a href="#CTZ_HISTORY_VIEW">浏览历史记录</a></div><div class="ctz-content-right"><div id="CTZ_HISTORY_LIST"><div class="ctz-set-title"><span>推荐列表缓存<span class="ctz-desc">最多缓存500条,包含已过滤项</span></span></div><button class="ctz-button" name="button_history_clear" data-id="list">清空推荐列表缓存</button><div class="ctz-set-content"></div></div><div id="CTZ_HISTORY_VIEW"><div class="ctz-set-title"><span>浏览历史记录<span class="ctz-desc">最多缓存500条</span></span></div><button class="ctz-button" name="button_history_clear" data-id="view">清空浏览历史记录</button><div class="ctz-set-content"></div></div></div></div><div id="CTZ_DEFAULT" style="display: none"><div class="ctz-content-left"><a href="#CTZ_DEFAULT_CONTENT">默认功能</a></div><div class="ctz-content-right"><div id="CTZ_DEFAULT_CONTENT"><div class="ctz-set-title"><span>默认功能<span class="ctz-desc">此部分功能为编辑器默认功能,不需要额外开启</span></span></div><div class="ctz-set-content"><div id="CTZ_DEFAULT_SELF"></div><div class="ctz-zhihu-self"><div class="ctz-zhihu-key">更加方便的浏览,按<span class="key-shadow">?</span>(<span class="key-shadow">Shift</span>+<span class="key-shadow">/</span>) 查看所有快捷键。<a href="/settings/preference" target="_blank">前往开启快捷键功能</a></div></div></div></div></div></div></div></div><div class="ctz-footer"><div class="ctz-footer-left"></div><div class="ctz-footer-right"></div></div></div><div id="CTZ_OPEN_BUTTON">⚙︎</div><div style="display: none" class="ctz-preview" id="CTZ_PREVIEW_IMAGE"><div><img src="" /></div></div><div style="display: none" class="ctz-preview" id="CTZ_PREVIEW_VIDEO"><div><video src="" autoplay loop></video></div></div><iframe class="ctz-pdf-box-content" style="display: none"></iframe><div id="CTZ_MESSAGE_BOX"></div>`;
  2258. var INNER_CSS = `.hover-style{cursor:pointer}.hover-style:hover{color:#1677ff !important}.ctz-button{outline:none;position:relative;display:inline-block;font-weight:400;white-space:nowrap;text-align:center;border:1px solid transparent;cursor:pointer;transition:all .3s;user-select:none;touch-action:manipulation;line-height:1.5;font-size:14px;height:32px;padding:4px 15px;border-radius:6px;background-color:#ffffff;border-color:#d9d9d9;color:rgba(0,0,0,0.88);box-shadow:0 2px 0 rgba(0,0,0,0.02)}.ctz-button:hover{color:#1677ff;border-color:#1677ff}.ctz-button:active{background:rgba(0,0,0,0.08) !important}.ctz-button[size='small'],.ctz-button.ctz-button-small{padding:2px 6px;font-size:12px;height:24px}.ctz-button.ctz-button-transparent{background:transparent}.ctz-button-red{color:#e55353 !important;border:1px solid #e55353 !important}.ctz-button-red:hover{color:#ec7259 !important;border:1px solid #ec7259 !important}.ctz-button:disabled{border-color:#d0d0d0;background-color:rgba(0,0,0,0.08);color:#b0b0b0;cursor:not-allowed}.Profile-mainColumn,.Collections-mainColumn{flex:1}#root .css-1liaddi{margin-right:0}.ContentItem-title div{display:inline}.css-1acwmmj:empty{display:none !important}.css-hr0k1l::after{content:'点击键盘左、右按键切换图片';position:absolute;bottom:20px;left:50%;transform:translateX(-50%);color:#fff}#CTZ_OPEN_BUTTON{position:fixed;left:0;top:100px;font-size:48px;color:rgba(0,0,0,0.8);height:48px;line-height:42px;text-align:center;width:48px;border-radius:0 12px 12px 0;background:#f5f5f5;box-shadow:0 0 8px #d0d4d6,0 0 8px #e6eaec;cursor:pointer;user-select:none;transform:translate(-30px);transition:transform .5s;z-index:200}#CTZ_OPEN_BUTTON:hover{transform:translate(0)}#CTZ_DIALOG_MAIN{position:fixed;top:50%;left:50%;transform:translate(-50%, -50%);width:800px;height:600px;max-width:100%;max-height:100%;border-radius:12px;box-shadow:0 6px 16px 0 rgba(0,0,0,0.08),0 3px 6px -4px rgba(0,0,0,0.12),0 9px 28px 8px rgba(0,0,0,0.05);background:#f5f5f5;z-index:201;flex-direction:column;font-size:14px;padding:16px;transition:all .2s}#CTZ_DIALOG_MAIN input[type='text'],#CTZ_DIALOG_MAIN input[type='number']{box-sizing:border-box;margin:0;padding:4px 11px;font-size:14px;line-height:1.5;list-style:none;position:relative;display:inline-block;min-width:0;border-width:1px;border-style:solid;border-color:#d9d9d9;border-radius:6px;transition:all .2s}#CTZ_DIALOG_MAIN textarea{box-sizing:border-box;margin:0;padding:4px 11px;font-size:14px;line-height:1.5;list-style:none;position:relative;display:inline-block;min-width:0;border-width:1px;border-style:solid;border-color:#d9d9d9;border-radius:6px;transition:all .2s}#CTZ_DIALOG_MAIN label{cursor:pointer;transition:all .2s}#CTZ_DIALOG_MAIN label:hover{color:#1677ff !important}#CTZ_DIALOG_MAIN a{transition:all .2s;text-decoration:none;color:inherit}.ctz-center{flex:1;flex-direction:column;display:flex;overflow:hidden}.ctz-header{font-size:16px;margin-bottom:12px;display:flex;align-items:center}.ctz-top-operate{flex:1;padding:0 8px;font-size:12px}#CTZ_FETCH_STATUS{padding-right:8px;font-weight:bold}.ctz-version{padding-left:8px;font-size:12px}#CTZ_CLOSE_DIALOG{color:rgba(0,0,0,0.45);font-weight:600;line-height:18px;background:transparent;border-radius:6px;width:22px;height:22px;transition:all .2s;border:0}#CTZ_CLOSE_DIALOG i{font-size:8px}#CTZ_CLOSE_DIALOG:hover{background-color:#fff;text-decoration:none}.ctz-menu-top{height:36px;display:flex}.ctz-menu-top>a{border-radius:12px 12px 0 0;flex:1;text-align:center;cursor:pointer;transition:initial !important;position:relative;display:flex;align-items:center;justify-content:center}.ctz-menu-top>a span{border-radius:8px;transition:all .3s;margin:0 6px;flex:1;box-sizing:border-box;align-items:center;line-height:26px}.ctz-menu-top>a:hover span{background:#fff}.ctz-menu-top>a.target{background:#fff}.ctz-menu-top>a.target::after,.ctz-menu-top>a.target::before{position:absolute;bottom:-12px;content:' ';background:radial-gradient(circle at top left, transparent 12px, #fff 0) top left,radial-gradient(circle at top right, transparent 12px, #fff 0) top right,radial-gradient(circle at bottom right, transparent 12px, #fff 0) bottom right,radial-gradient(circle at bottom left, transparent 12px, #fff 0) bottom left;background-size:50% 50%;background-repeat:no-repeat;width:24px;height:24px}.ctz-menu-top>a.target::before{left:-12px;z-index:-1}.ctz-menu-top>a.target::after{right:-12px;z-index:-1}.ctz-content{flex:1;display:flex;overflow:hidden;background:#fff;border-radius:12px;padding:8px 0}.ctz-content>div{width:100%}.ctz-content ::-webkit-scrollbar{width:8px;height:8px}.ctz-content ::-webkit-scrollbar-track{border-radius:0}.ctz-content ::-webkit-scrollbar-thumb{background:#bbb;transition:all .2s;border-radius:8px}.ctz-content ::-webkit-scrollbar-thumb:hover{background-color:rgba(95,95,95,0.7)}.ctz-content-left{width:130px;border-right:1px solid #e0e0e0}.ctz-content-left a{transition:all .2s;margin:2px 5px;height:40px;line-height:40px;display:block;font-size:14px;border-radius:12px;padding-left:24px}.ctz-content-left a:hover{background:#f5f5f5}.ctz-content-right{flex:1;overflow-y:auto;scroll-behavior:smooth;padding:0 8px}.ctz-content-right>div:nth-of-type(2n){padding:0 8px;margin:0 -8px;box-shadow:#999 0 0 5px inset;border-radius:0 12px 12px 0}.ctz-set-title{font-weight:bold;height:36px;line-height:36px;font-size:16px;overflow:hidden;vertical-align:middle}.ctz-set-title>span{vertical-align:middle;display:inline-block}.ctz-set-content:not(.ctz-flex-wrap)>div,.ctz-set-content:not(.ctz-flex-wrap)>label{padding-bottom:8px;margin-bottom:8px;border-bottom:1px dashed #ddd}.ctz-set-content:not(.ctz-flex-wrap)>div:last-child,.ctz-set-content:not(.ctz-flex-wrap)>label:last-child{border-bottom:0}.ctz-footer{display:flex;align-items:end;font-size:14px;margin-top:12px}.ctz-footer a{margin-right:16px;cursor:pointer}.ctz-footer a:hover{color:#1677ff !important}.ctz-footer-left{flex:1}.ctz-dark{display:flex;height:28px;align-items:center}.ctz-desc,.ctz-commit{font-size:12px;color:#999}.ctz-desc b,.ctz-commit b{color:#e55353}.ctz-desc{padding-left:4px}.ctz-alert-red{text-align:center;font-size:14px;color:#e55353;height:24px;line-height:24px;background-color:#fff2f0;border:1px solid #ffccc7;border-radius:12px;margin:0;font-weight:400}.ctz-label{font-size:14px;line-height:24px}.ctz-label::after{content:':'}#CTZ_BACKGROUND,#CTZ_BACKGROUND_LIGHT,#CTZ_BACKGROUND_DARK{display:grid;grid-template-columns:30% 30% 30%;gap:8px}#CTZ_BACKGROUND>label,#CTZ_BACKGROUND_LIGHT>label,#CTZ_BACKGROUND_DARK>label{position:relative}#CTZ_BACKGROUND>label input,#CTZ_BACKGROUND_LIGHT>label input,#CTZ_BACKGROUND_DARK>label input{position:absolute;visibility:hidden}#CTZ_BACKGROUND>label input:checked+div,#CTZ_BACKGROUND_LIGHT>label input:checked+div,#CTZ_BACKGROUND_DARK>label input:checked+div{border:4px solid #1677ff;margin:0 !important}#CTZ_BACKGROUND>label div,#CTZ_BACKGROUND_LIGHT>label div,#CTZ_BACKGROUND_DARK>label div{font-size:14px;border-radius:12px;line-height:50px;padding-left:30px;margin:4px}#CTZ_BACKGROUND_LIGHT{color:#000}.ctz-set-background .ctz-commit{line-height:24px;font-size:14px}#CTZ_BASIS_CONFIG .ctz-config-buttons{padding:8px 0}#CTZ_BASIS_CONFIG .ctz-config-buttons button{margin-right:8px}#CTZ_BASIS_CONFIG textarea{margin-right:8px;flex:1}#CTZ_BLOCK_WORD .ctz-content-right>div{padding-bottom:12px}#CTZ_BLOCK_WORD input{height:24px;width:300px;margin:4px 0;width:100%}.ctz-block-words-content{display:flex;flex-wrap:wrap;cursor:default}.ctz-block-words-content>span{padding:2px 8px;border-radius:4px;font-size:12px;background:#fafafa;border:1px solid #d9d9d9;margin:4px 4px 0 0;display:flex;align-items:center}.ctz-block-words-content>span>i{margin-left:2px;cursor:pointer}.ctz-block-words-content>span>i:hover{color:#1677ff !important}.ctz-flex-wrap{display:flex;flex-wrap:wrap;line-height:24px}.ctz-flex-wrap label{margin-right:4px;display:flex;align-items:center}.ctz-flex-wrap label input[type='radio']{margin:0 4px 0 0}.ctz-video-download,.ctz-loading{position:absolute;top:20px;left:20px;font-size:24px;color:rgba(255,255,255,0.9);cursor:pointer}.ctz-loading{animation:loadingAnimation 2s infinite}@keyframes loadingAnimation{from{transform:rotate(0)}to{transform:rotate(360deg)}}#CTZ-BLOCK-LIST{display:flex;flex-wrap:wrap;margin:0 -8px;padding:8px}.ctz-black-item{height:30px;line-height:30px;box-sizing:content-box;padding:4px 8px;margin:0 8px 8px 0;display:flex;align-items:center;background:#fff;border-radius:8px;border:1px solid #e0e0e0}.ctz-black-item img{width:30px;height:30px;margin-right:4px}.ctz-black-item .ctz-remove-block:hover,.ctz-black-item a:hover{color:#1677ff;transition:all .2s}.ctz-black-item .ctz-remove-block{width:30px;height:30px;text-align:center;border-radius:8px}.ctz-black-item .ctz-remove-block:hover{background:#d9d9d9}.ctz-block-box>button,.ctz-button-block{margin-left:8px}.ctz-preview{box-sizing:border-box;position:fixed;height:100%;width:100%;top:0;left:0;overflow-y:auto;z-index:200;background-color:rgba(18,18,18,0.4)}.ctz-preview div{display:flex;justify-content:center;align-items:center;min-height:100%;width:100%}.ctz-preview div img{cursor:zoom-out;user-select:none}#CTZ_TITLE_ICO label{margin:0 4px 4px 0}#CTZ_TITLE_ICO label input{display:none}#CTZ_TITLE_ICO label input:checked+img{border:4px solid #0461cf;border-radius:12px}#CTZ_TITLE_ICO label img{width:40px;height:40px;border:4px solid transparent}.ctz-label-tag{font-weight:normal;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff;margin:0 2px}.ctz-label-tag-Answer{background:#ec7259}.ctz-label-tag-ZVideo{background:#12c2e9}.ctz-label-tag-Article{background:#00965e}.ctz-label-tag-Pin{background:#9c27b0}.ctz-question-time{color:#999 !important;font-size:14px !important;font-weight:normal !important;line-height:24px}.ctz-stop-scroll{height:100% !important;overflow:hidden !important}#CTZ_DEFAULT_SELF>div{line-height:24px;margin-bottom:4px}#CTZ_DEFAULT_SELF>div .ctz-commit{font-weight:normal}#CTZ_DEFAULT_SELF>div a{color:#1677ff}#CTZ_DEFAULT_SELF>div a:hover{color:#bbb}.ctz-export-collection-box{float:right;text-align:right}.ctz-export-collection-box button{font-size:16px}.ctz-export-collection-box p{font-size:14px;color:#666;margin:4px 0}.ctz-pdf-dialog-item{padding:12px;border-bottom:1px solid #eee;margin:12px;background:#ffffff}.ctz-pdf-dialog-title{margin:0 0 1.4em;font-size:20px;font-weight:bold}.ctz-pdf-box-content{width:100%;background:#ffffff}.ctz-pdf-view{width:100%;background:#ffffff;word-break:break-all;white-space:pre-wrap;font-size:14px;overflow-x:hidden}.ctz-pdf-view a{color:#0066ff}.ctz-pdf-view img{max-width:100%}.ctz-pdf-view p{margin:1.4em 0}.ctz-unlock,.ctz-lock,.ctz-lock-mask{display:none;color:#999;cursor:pointer}.ctz-unlock,.ctz-lock{margin:4px}.ctz-lock-mask{position:absolute;width:100%;height:100%;background:rgba(0,0,0,0.4);z-index:198}.position-suspensionSearch,.position-suspensionFind,.position-suspensionUser{position:fixed;z-index:100}.position-suspensionSearch:hover .ctz-unlock,.position-suspensionFind:hover .ctz-unlock,.position-suspensionUser:hover .ctz-unlock,.Topstory-container .TopstoryTabs:hover .ctz-unlock{display:block}.position-suspensionSearch.ctz-move-this .ctz-unlock,.position-suspensionFind.ctz-move-this .ctz-unlock,.position-suspensionUser.ctz-move-this .ctz-unlock,.Topstory-container .TopstoryTabs.ctz-move-this .ctz-unlock{display:none !important}.position-suspensionSearch.ctz-move-this .ctz-lock,.position-suspensionFind.ctz-move-this .ctz-lock,.position-suspensionUser.ctz-move-this .ctz-lock,.Topstory-container .TopstoryTabs.ctz-move-this .ctz-lock,.position-suspensionSearch.ctz-move-this .ctz-lock-mask,.position-suspensionFind.ctz-move-this .ctz-lock-mask,.position-suspensionUser.ctz-move-this .ctz-lock-mask,.Topstory-container .TopstoryTabs.ctz-move-this .ctz-lock-mask{display:block}.position-suspensionSearch.ctz-move-this .ctz-lock,.position-suspensionFind.ctz-move-this .ctz-lock,.position-suspensionUser.ctz-move-this .ctz-lock,.Topstory-container .TopstoryTabs.ctz-move-this .ctz-lock{z-index:199;color:#cccccc}.position-suspensionFind{display:flex;flex-direction:column;margin:0 !important}.position-suspensionFind .Tabs-item{padding:0 !important;margin-bottom:4px}.position-suspensionFind .Tabs-item .Tabs-link{padding:8px !important;border-radius:4px}.position-suspensionFind .Tabs-item .Tabs-link::after{content:'' !important;display:none !important}.position-suspensionUser{width:fit-content !important;margin:0 !important;display:flex;flex-direction:column}.position-suspensionUser .AppHeader-messages,.position-suspensionUser .AppHeader-notifications,.position-suspensionUser .css-18vqx7l{margin-right:0 !important;margin-bottom:12px}.position-suspensionUser .AppHeader-login,.position-suspensionUser .AppHeader-login~button{display:none}.position-suspensionSearch{line-height:30px;border-radius:16px;width:20px;transition:width .5s}.position-suspensionSearch .ctz-search-icon{font-size:24px;transform:rotate(-60deg)}.position-suspensionSearch .SearchBar-input-focus .ctz-search-pick-up{display:none}.position-suspensionSearch.focus{width:300px}.position-suspensionSearch.focus>form,.position-suspensionSearch.focus>button,.position-suspensionSearch.focus .ctz-search-pick-up{display:block}.position-suspensionSearch.focus .ctz-search-icon{display:none}.position-suspensionSearch.focus:hover{width:324px}.position-suspensionSearch .ctz-search-icon,.position-suspensionSearch .ctz-search-pick-up{cursor:pointer;color:#0066ff}.position-suspensionSearch .ctz-search-icon:hover,.position-suspensionSearch .ctz-search-pick-up:hover{color:#005ce6}.position-suspensionSearch .ctz-search-pick-up{font-size:24px;margin-left:4px}.position-suspensionSearch>form,.position-suspensionSearch>button,.position-suspensionSearch .ctz-search-pick-up{display:none}.position-suspensionSearch .ctz-search-icon{display:block}.key-shadow{border:1px solid #e0e0e0;border-radius:4px;box-shadow:rgba(0,0,0,0.06) 0 1px 1px 0;font-weight:600;min-width:26px;height:26px;padding:0px 6px;text-align:center}#CTZ_HISTORY_LIST .ctz-set-content a,#CTZ_HISTORY_VIEW .ctz-set-content a{cursor:pointer;word-break:break-all;display:block;margin-bottom:4px;padding:6px 12px;border:1px solid #ccc;border-radius:4px}#CTZ_HISTORY_LIST .ctz-set-content a:hover,#CTZ_HISTORY_VIEW .ctz-set-content a:hover{color:#1677ff !important}#CTZ_HISTORY_LIST .ctz-set-content a:hover,#CTZ_HISTORY_VIEW .ctz-set-content a:hover{border-color:#1677ff}[name='button_history_clear'],[name='button_history_clear'],#CTZ-BUTTON-SYNC-BLOCK{min-width:88px;margin-bottom:8px}[name='button_history_clear'] i,[name='button_history_clear'] i,#CTZ-BUTTON-SYNC-BLOCK i{top:0px;left:28px;color:#909090}.ctz-zhihu-key a{color:#1677ff !important}.ctz-zhihu-key a:hover{color:#bbb !important}.ctz-video-link{border:1px solid #ccc;display:inline-block;height:98px;width:fit-content;border-radius:4px;box-sizing:border-box;overflow:hidden;transition:all .3s}.ctz-video-link img{width:98px;height:98px;vertical-align:bottom}.ctz-video-link span{padding:4px 12px;display:inline-block}.ctz-video-link:hover{border-color:#005ce6;color:#005ce6}#CTZ_VERSION_RANGE_ZHIHU,#CTZ_FONT_SIZE_IN_ZHIHU{padding-bottom:0}#CTZ_VERSION_RANGE_ZHIHU>div,#CTZ_FONT_SIZE_IN_ZHIHU>div{align-items:center;margin-bottom:8px}.ctz-fetch-intercept .ctz-need-fetch{display:none}.ctz-fetch-intercept.ctz-fetch-intercept-close{color:#b0b0b0 !important;cursor:not-allowed}.ctz-fetch-intercept.ctz-fetch-intercept-close span.ctz-need-fetch{display:inline}.ctz-fetch-intercept.ctz-fetch-intercept-close div.ctz-need-fetch{display:block}.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-remove-block{cursor:not-allowed !important}.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-black-item .ctz-remove-block:hover,.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-black-item a:hover{background:transparent !important;color:#b0b0b0 !important}#CTZ_MESSAGE_BOX{position:fixed;left:0;top:10px;width:100%;z-index:999}.ctz-message{margin:0 auto;width:500px;height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;border-radius:8px;box-shadow:0 0 8px #d0d4d6,0 0 8px #e6eaec;margin-bottom:12px;background:#fff}#IMPORT_BY_FILE{display:inline-flex}#IMPORT_BY_FILE input{display:none}`;
  2259. var createHiddenItem = (arrHidden) => {
  2260. if (!arrHidden || !arrHidden.length)
  2261. return;
  2262. const itemLabel = (item = []) => {
  2263. return item.map((i2) => `<label style="display: inline-flex; algin-item: center;"><input class="ctz-i" name="${i2.value}" type="checkbox" value="on" />${i2.label}</label>`).join("") + `<br>`;
  2264. };
  2265. return `<div class="ctz-set-content">${arrHidden.map((i2) => itemLabel(i2)).join("")}</div>`;
  2266. };
  2267. var initInputRange = () => {
  2268. const createRangeInnerHTML = (label, value, min, max) => `<div class="ctz-flex-wrap ctz-range-${value}">${label ? `<div class="ctz-label">${label}</div>` : ""}<input class="ctz-i" type="range" min="${min}" max="${max}" name="${value}" style="width: 300px" /><span id="${value}" style="margin: 0 8px">0</span><span class="ctz-commit">滑动条范围: ${min} ~ ${max}</span></div>`;
  2269. const versionCallback = (item, index) => {
  2270. return createRangeInnerHTML(item.label, item.value, item.min, item.max) + createRangeInnerHTML(item.percentLabel, item.percentValue, item.percentMin, item.percentMax) + `<label class="ctz-flex-wrap"><span class="ctz-label">${item.percentChooseLabel}</span><input class="ctz-i" name="${item.percentChooseValue}" type="checkbox" value="on" /></label><div class="ctz-commit" style="${index < VERSION_RANGE.length - 1 ? "border-bottom: 1px solid #e0e0e0;" : "margin:0;"}padding:8px 0;"><b>${item.desc}</b></div>`;
  2271. };
  2272. domById("CTZ_VERSION_RANGE_ZHIHU").innerHTML = VERSION_RANGE.map(versionCallback).join("");
  2273. domById("CTZ_IMAGE_SIZE_CUSTOM").innerHTML = createRangeInnerHTML("", "zoomImageSize", 0, 1e3);
  2274. domById("CTZ_IMAGE_HEIGHT_CUSTOM").innerHTML = createRangeInnerHTML("", "zoomImageHeightSize", 0, 1e3);
  2275. domById("CTZ_LIST_VIDEO_SIZE_CUSTOM").innerHTML = createRangeInnerHTML("", "zoomListVideoSize", 0, 1e3);
  2276. };
  2277. var initHTML = () => {
  2278. document.body.appendChild(domC("div", { id: "CTZ_MAIN", innerHTML: INNER_HTML }));
  2279. dom(".ctz-version").innerText = `version: ${GM_info.script.version}`;
  2280. dom(".ctz-footer-left").innerHTML = FOOTER_HTML;
  2281. dom(".ctz-menu-top").innerHTML = HEADER.map(({ href, value }) => `<a href="${href}"><span>${value}</span></a>`).join("");
  2282. addBackgroundSetting();
  2283. initInputRange();
  2284. domById("CTZ_FONT_SIZE_IN_ZHIHU").innerHTML = FONT_SIZE_INPUT.map(
  2285. (item) => `<div class="ctz-flex-wrap">` + item.map(
  2286. (i2, index) => `<span class="ctz-label" style="margin-left: ${index !== 0 ? "24px" : "0"};">${i2.label}</span><input type="number" name="${i2.value}" class="ctz-i-change" style="width: 80px;" />`
  2287. ).join("") + `</div>`
  2288. ).join("");
  2289. domById("CTZ_HIDDEN").innerHTML = `<div class="ctz-content-left">${HIDDEN_ARRAY.map((i2) => `<a href="#${i2.key}">${i2.name}</a>`).join("")}</div><div class="ctz-content-right">${HIDDEN_ARRAY.map(
  2290. (i2) => `<div id="${i2.key}"><div class="ctz-set-title">${i2.name}<span class="ctz-desc">${i2.desc}</span></div>${createHiddenItem(i2.content)}</div>`
  2291. ).join("")}</div>`;
  2292. domById("CTZ_TITLE_ICO").innerHTML = Object.keys(ICO_URL).map((key) => `<label><input class="ctz-i" name="titleIco" type="radio" value="${key}" /><img src="${ICO_URL[key]}" alt="${key}"></label>`).join("");
  2293. domById("CTZ_DEFAULT_SELF").innerHTML = DEFAULT_FUNCTION.map((elementItem, index) => `<div>${index + 1}. ${elementItem}</div>`).join("");
  2294. dom("#CTZ_BASIS_SHOW_CONTENT .ctz-set-content").innerHTML += BASIC_SHOW_CONTENT.map(
  2295. ({ label, value, needFetch }) => `<label class="ctz-flex-wrap ${needFetch ? "ctz-fetch-intercept" : ""}"><span class="ctz-label">${label}${needFetch ? '<span class="ctz-need-fetch">(接口拦截已关闭,此功能无法使用)</span>' : ""}</span><input class="ctz-i" name="${value}" type="checkbox" value="on" /></label>`
  2296. ).join("");
  2297. initFetchInterceptStatus();
  2298. myBlack.init();
  2299. myMenu.init();
  2300. dom(".ctz-footer-right").appendChild(
  2301. domC("a", {
  2302. href: "https://www.zhihu.com",
  2303. target: "_self",
  2304. innerText: "返回主页"
  2305. })
  2306. );
  2307. domAddUserinfo();
  2308. };
  2309. var domAddUserinfo = async () => {
  2310. const { setUserinfo } = store;
  2311. const userinfo = await fetchGetUserinfo();
  2312. setUserinfo(userinfo);
  2313. const hrefUser = userinfo.url ? userinfo.url.replace("/api/v4", "") : "";
  2314. if (!hrefUser)
  2315. return;
  2316. const homeLink = domC("a", {
  2317. href: hrefUser,
  2318. target: "_blank",
  2319. innerText: "前往个人主页>>"
  2320. });
  2321. dom(".ctz-footer-right").appendChild(homeLink);
  2322. };
  2323. var initInviteOnce = () => {
  2324. setTimeout(() => {
  2325. const domInvitation = dom(".QuestionInvitation");
  2326. if (!domInvitation || dom(".ctz-invite-once"))
  2327. return;
  2328. const nButton = domC("button", {
  2329. className: "ctz-button ctz-invite-once",
  2330. innerHTML: "一键邀请",
  2331. style: "margin-left: 12px;"
  2332. });
  2333. nButton.onclick = () => {
  2334. const fnToMore = () => {
  2335. const moreAction = dom(".QuestionMainAction");
  2336. if (moreAction) {
  2337. moreAction.click();
  2338. setTimeout(() => {
  2339. fnToMore();
  2340. }, 50);
  2341. } else {
  2342. fnToInviteAll();
  2343. }
  2344. };
  2345. const fnToInviteAll = () => {
  2346. const nodeInvites = domA(".QuestionInvitation .ContentItem-extra button");
  2347. nodeInvites.forEach((item) => {
  2348. !item.disabled && !item.classList.contains("AutoInviteItem-button--closed") && item.click();
  2349. });
  2350. };
  2351. fnToMore();
  2352. };
  2353. const nodeTopBar = domInvitation.querySelector(".Topbar");
  2354. nodeTopBar && nodeTopBar.appendChild(nButton);
  2355. }, 500);
  2356. };
  2357. var fnContentRemoveKeywordSearch = (domFind) => {
  2358. const domKeywords = domFind.querySelectorAll(".RichContent-EntityWord");
  2359. for (let i2 = 0, len = domKeywords.length; i2 < len; i2++) {
  2360. const domItem = domKeywords[i2];
  2361. if (domItem.href === "javascript:;") {
  2362. continue;
  2363. }
  2364. domItem.href = "javascript:;";
  2365. domItem.style.cssText += `color: inherit!important; cursor: default!important;`;
  2366. const domSvg = domItem.querySelector("svg");
  2367. if (domSvg) {
  2368. domSvg.style.display = "none";
  2369. }
  2370. }
  2371. };
  2372. var myScroll = {
  2373. stop: () => dom("body").classList.add("ctz-stop-scroll"),
  2374. on: () => dom("body").classList.remove("ctz-stop-scroll")
  2375. };
  2376. var myPreview = {
  2377. // 开启预览弹窗
  2378. open: function(src, even, isVideo) {
  2379. const nameDom = isVideo ? this.evenPathVideo : this.evenPathImg;
  2380. const idDom = isVideo ? this.idVideo : this.idImg;
  2381. const nodeName = dom(nameDom);
  2382. const nodeId = domById(idDom);
  2383. nodeName && (nodeName.src = src);
  2384. nodeId && (nodeId.style.display = "block");
  2385. even && (this.even = even);
  2386. myScroll.stop();
  2387. },
  2388. // 关闭预览弹窗
  2389. hide: function(pEvent) {
  2390. if (this.even) {
  2391. this.even.click();
  2392. this.even = null;
  2393. }
  2394. pEvent.style.display = "none";
  2395. const nodeImg = dom(this.evenPathImg);
  2396. const nodeVideo = dom(this.evenPathVideo);
  2397. nodeImg && (nodeImg.src = "");
  2398. nodeVideo && (nodeVideo.src = "");
  2399. myScroll.on();
  2400. },
  2401. even: null,
  2402. evenPathImg: "#CTZ_PREVIEW_IMAGE img",
  2403. evenPathVideo: "#CTZ_PREVIEW_VIDEO video",
  2404. idImg: "CTZ_PREVIEW_IMAGE",
  2405. idVideo: "CTZ_PREVIEW_VIDEO"
  2406. };
  2407. var callbackGIF = async (mutationsList) => {
  2408. const target = mutationsList[0].target;
  2409. const targetClassList = target.classList;
  2410. const { showGIFinDialog } = await myStorage.getConfig();
  2411. if (!(targetClassList.contains("isPlaying") && !targetClassList.contains("css-1isopsn") && showGIFinDialog))
  2412. return;
  2413. const nodeVideo = target.querySelector("video");
  2414. const nodeImg = target.querySelector("img");
  2415. const srcImg = nodeImg ? nodeImg.src : "";
  2416. nodeVideo ? myPreview.open(nodeVideo.src, target, true) : myPreview.open(srcImg, target);
  2417. };
  2418. var observerGIF = new MutationObserver(callbackGIF);
  2419. async function previewGIF() {
  2420. const { showGIFinDialog } = await myStorage.getConfig();
  2421. if (showGIFinDialog) {
  2422. const nodeGIFs = domA(".GifPlayer:not(.ctz-processed)");
  2423. for (let i2 = 0, len = nodeGIFs.length; i2 < len; i2++) {
  2424. const item = nodeGIFs[i2];
  2425. item.classList.add("ctz-processed");
  2426. observerGIF.observe(item, { attributes: true, attributeFilter: ["class"] });
  2427. }
  2428. } else {
  2429. observerGIF.disconnect();
  2430. }
  2431. }
  2432. var keydownNextImage = (event) => {
  2433. const { key } = event;
  2434. const nodeImgDialog = dom(".css-ypb3io");
  2435. if ((key === "ArrowRight" || key === "ArrowLeft") && nodeImgDialog) {
  2436. const src = nodeImgDialog.src;
  2437. const nodeImage = dom(`img[src="${src}"]`);
  2438. const nodeContentInner = domP(nodeImage, "class", "RichContent-inner") || domP(nodeImage, "class", "Post-RichTextContainer") || domP(nodeImage, "class", "QuestionRichText");
  2439. if (nodeContentInner) {
  2440. const images = Array.from(nodeContentInner.querySelectorAll("img"));
  2441. const index = images.findIndex((i2) => i2.src === src);
  2442. const dialogChange = (nodeDialog, nodeImage2) => {
  2443. const { width, height, src: src2 } = nodeImage2;
  2444. const { innerWidth, innerHeight } = window;
  2445. const aspectRatioWindow = innerWidth / innerHeight;
  2446. const aspectRatioImage = width / height;
  2447. const scale = aspectRatioImage > aspectRatioWindow ? (innerWidth - 200) / width : (innerHeight - 50) / height;
  2448. const top = document.documentElement.scrollTop;
  2449. const left = innerWidth / 2 - width * scale / 2;
  2450. nodeDialog.src = src2;
  2451. nodeDialog.style.cssText = nodeDialog.style.cssText + `width: ${width}px;height: ${height}px;top: ${top}px;left: ${left}px;transform: translateX(0) translateY(0) scale(${scale}) translateZ(0px);will-change:unset;transform-origin: 0 0;`;
  2452. };
  2453. if (key === "ArrowRight" && index < images.length - 1) {
  2454. dialogChange(nodeImgDialog, images[index + 1]);
  2455. return;
  2456. }
  2457. if (key === "ArrowLeft" && index > 0) {
  2458. dialogChange(nodeImgDialog, images[index - 1]);
  2459. return;
  2460. }
  2461. }
  2462. }
  2463. };
  2464. var initLinkChanger = () => {
  2465. const esName = ["a.external", "a.LinkCard"];
  2466. const operaLink = "ctz-link-changed";
  2467. const hrefChanger = (item) => {
  2468. const hrefFormat = item.href.replace(/^(https|http):\/\/link\.zhihu\.com\/\?target\=/, "") || "";
  2469. let href = "";
  2470. try {
  2471. href = decodeURIComponent(hrefFormat);
  2472. } catch {
  2473. href = hrefFormat;
  2474. }
  2475. item.href = href;
  2476. item.classList.add(operaLink);
  2477. };
  2478. for (let i2 = 0, len = esName.length; i2 < len; i2++) {
  2479. const name = esName[i2];
  2480. const links = domA(`${name}:not(.${operaLink})`);
  2481. for (let index = 0, linkLen = links.length; index < linkLen; index++) {
  2482. hrefChanger(links[index]);
  2483. }
  2484. }
  2485. };
  2486. var CLASS_COPY_LINK = "ctz-copy-answer-link";
  2487. var addAnswerCopyLink = async (nodeItem) => {
  2488. const { copyAnswerLink } = await myStorage.getConfig();
  2489. if (!copyAnswerLink)
  2490. return;
  2491. const prevButton = nodeItem.querySelector(`.${CLASS_COPY_LINK}`);
  2492. prevButton && prevButton.remove();
  2493. const nodeUser = nodeItem.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
  2494. if (!nodeUser)
  2495. return;
  2496. const nDomButton = createBtnSmallTran("一键获取回答链接", CLASS_COPY_LINK);
  2497. nDomButton.onclick = function() {
  2498. const metaUrl = nodeItem.querySelector('.ContentItem>[itemprop="url"]');
  2499. if (!metaUrl)
  2500. return;
  2501. const link = metaUrl.getAttribute("content") || "";
  2502. if (link) {
  2503. copy(link);
  2504. message("链接复制成功");
  2505. return;
  2506. }
  2507. };
  2508. nodeUser.appendChild(nDomButton);
  2509. };
  2510. var loadIframePrint = (eventBtn, arrHTML, btnText) => {
  2511. let max = 0;
  2512. let finish = 0;
  2513. let error = 0;
  2514. const innerHTML = arrHTML.join("");
  2515. const iframe = dom(".ctz-pdf-box-content");
  2516. if (!iframe.contentWindow)
  2517. return;
  2518. const doc = iframe.contentWindow.document;
  2519. doc.body.innerHTML = "";
  2520. if (!doc.head.querySelector("style")) {
  2521. doc.write(`<style type="text/css" id="ctz-css-own">${INNER_CSS}</style>`);
  2522. }
  2523. doc.write(`<div class="ctz-pdf-view"></div>`);
  2524. const nodePDFView = doc.querySelector(".ctz-pdf-view");
  2525. const domInner = domC("div", { innerHTML });
  2526. max = domInner.querySelectorAll("img").length;
  2527. domInner.querySelectorAll("img").forEach((imageItem) => {
  2528. const dataOriginal = imageItem.getAttribute("data-original");
  2529. if (!dataOriginal) {
  2530. imageItem.setAttribute("data-original", imageItem.src);
  2531. }
  2532. imageItem.src = "";
  2533. });
  2534. nodePDFView.appendChild(domInner);
  2535. const doPrint = () => {
  2536. eventBtn.innerText = btnText;
  2537. eventBtn.disabled = false;
  2538. iframe.contentWindow.print();
  2539. };
  2540. const imageLoaded = () => {
  2541. eventBtn.innerText = `资源加载进度 ${Math.floor(finish / max * 100)}%:${finish}/${max}${error > 0 ? `,${error}张图片资源已失效` : ""}`;
  2542. if (finish + error === max) {
  2543. doPrint();
  2544. }
  2545. };
  2546. if (nodePDFView.querySelectorAll("img").length) {
  2547. nodePDFView.querySelectorAll("img").forEach((imageItem, index) => {
  2548. setTimeout(function() {
  2549. imageItem.src = imageItem.getAttribute("data-original");
  2550. imageItem.onload = function() {
  2551. finish++;
  2552. imageLoaded();
  2553. };
  2554. imageItem.onerror = function() {
  2555. error++;
  2556. imageLoaded();
  2557. };
  2558. }, Math.floor(index / 5) * 100);
  2559. });
  2560. } else {
  2561. doPrint();
  2562. }
  2563. };
  2564. var myCollectionExport = {
  2565. init: async function() {
  2566. const { fetchInterceptStatus } = await myStorage.getConfig();
  2567. if (!fetchInterceptStatus)
  2568. return;
  2569. const { pathname } = location;
  2570. const elementBox = domC("div", { className: `${this.className}`, innerHTML: this.element });
  2571. const nodeThis = dom(`.${this.className}`);
  2572. nodeThis && nodeThis.remove();
  2573. const elementTypeSpan = this.elementTypeSpan;
  2574. const nodeCollection = elementBox.querySelector('[name="ctz-export-collection"]');
  2575. nodeCollection && (nodeCollection.onclick = function() {
  2576. const me = this;
  2577. me.innerText = "加载中...";
  2578. me.disabled = true;
  2579. const matched = pathname.match(/(?<=\/collection\/)\d+/);
  2580. const id = matched ? matched[0] : "";
  2581. if (!id)
  2582. return;
  2583. const nodeCurrent = dom(".Pagination .PaginationButton--current");
  2584. const offset = 20 * (nodeCurrent ? Number(nodeCurrent.innerText) - 1 : 0);
  2585. const fetchHeaders = store.getStorageConfigItem("fetchHeaders");
  2586. fetch(`/api/v4/collections/${id}/items?offset=${offset}&limit=20`, {
  2587. method: "GET",
  2588. headers: new Headers(fetchHeaders)
  2589. }).then((response) => {
  2590. return response.json();
  2591. }).then((res) => {
  2592. const collectionsHTMLMap = (res.data || []).map((item) => {
  2593. const { type, url, question, content, title } = item.content;
  2594. switch (type) {
  2595. case "zvideo":
  2596. return `<div class="ctz-pdf-dialog-item"><div class="ctz-pdf-dialog-title">${elementTypeSpan(type)}${title}</div><div>视频链接:<a href="${url}" target="_blank">${url}</a></div></div>`;
  2597. case "answer":
  2598. case "article":
  2599. default:
  2600. return `<div class="ctz-pdf-dialog-item"><div class="ctz-pdf-dialog-title">${elementTypeSpan(type)}${title || question.title}</div><div>内容链接:<a href="${url}" target="_blank">${url}</a></div><div>${content}</div></div>`;
  2601. }
  2602. });
  2603. loadIframePrint(me, collectionsHTMLMap, "生成PDF");
  2604. });
  2605. });
  2606. const nodePageHeaderTitle = dom(".CollectionDetailPageHeader-title");
  2607. nodePageHeaderTitle && nodePageHeaderTitle.appendChild(elementBox);
  2608. },
  2609. className: "ctz-export-collection-box",
  2610. element: `<button class="ctz-button" name="ctz-export-collection">生成PDF</button><p>仅对当前页内容进行导出</p>`,
  2611. elementTypeSpan: (type) => {
  2612. const typeObj = {
  2613. zvideo: '<span class="ctz-label-tag" style="color: #12c2e9;">视频</span>',
  2614. answer: '<span class="ctz-label-tag" style="color: #ec7259;">问答</span>',
  2615. article: '<span class="ctz-label-tag" style="color: #00965e;">文章</span>'
  2616. };
  2617. return typeObj[type] || "";
  2618. }
  2619. };
  2620. var printAnswer = (e2) => {
  2621. const prevButton = e2.querySelector(".ctz-answer-print");
  2622. if (prevButton)
  2623. return;
  2624. const nodeUser = e2.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
  2625. if (!nodeUser)
  2626. return;
  2627. const nButton = createBtnSmallTran("导出当前回答", "ctz-answer-print");
  2628. nButton.onclick = function() {
  2629. const nodeUser2 = e2.querySelector(".AuthorInfo-name .UserLink-link");
  2630. const nodeContent = e2.querySelector(".RichContent-inner");
  2631. const innerHTML = `<h1>${JSON.parse(e2.querySelector(".AnswerItem").getAttribute("data-zop") || "{}").title}</h1>${nodeUser2.outerHTML + nodeContent.innerHTML}`;
  2632. loadIframePrint(this, [innerHTML], "导出当前回答");
  2633. };
  2634. nodeUser.appendChild(nButton);
  2635. };
  2636. var printArticle = async (e2) => {
  2637. const { topExportContent } = await myStorage.getConfig();
  2638. const prevButton = e2.querySelector(".ctz-article-print");
  2639. if (prevButton || !topExportContent)
  2640. return;
  2641. const nodeHeader = e2.querySelector(".ArticleItem-authorInfo") || e2.querySelector(".Post-Header .Post-Title");
  2642. if (!nodeHeader)
  2643. return;
  2644. const nButton = createBtnSmallTran("导出当前文章", "ctz-article-print", { style: "margin: 12px 0;" });
  2645. nButton.onclick = function() {
  2646. const nodeTitle = e2.querySelector(".ContentItem.ArticleItem .ContentItem-title>span") || e2.querySelector(".Post-Header .Post-Title");
  2647. const nodeUser = e2.querySelector(".AuthorInfo-name");
  2648. const nodeContent = e2.querySelector(".RichContent-inner") || e2.querySelector(".Post-RichTextContainer");
  2649. const innerHTML = `<h1>${nodeTitle.innerHTML}</h1>${nodeUser.innerHTML + nodeContent.innerHTML}`;
  2650. loadIframePrint(this, [innerHTML], "导出当前文章");
  2651. };
  2652. insertAfter(nButton, nodeHeader);
  2653. setTimeout(() => {
  2654. printArticle(e2);
  2655. }, 500);
  2656. };
  2657. var printPeopleAnswer = async () => {
  2658. const { fetchInterceptStatus } = await myStorage.getConfig();
  2659. const nodeListHeader = dom(".Profile-main .List-headerText");
  2660. const prevButton = dom(`.ctz-people-answer-print`);
  2661. if (!nodeListHeader || prevButton || !fetchInterceptStatus)
  2662. return;
  2663. const nButton = createBtnSmallTran("导出当前页回答", "ctz-people-answer-print");
  2664. nButton.onclick = async function() {
  2665. const eventBtn = this;
  2666. eventBtn.innerText = "加载回答内容中...";
  2667. eventBtn.disabled = true;
  2668. const { search, pathname } = location;
  2669. const matchPageArr = search.match(/page=(\d+)?/);
  2670. const page = matchPageArr && matchPageArr.length ? matchPageArr[1] : "1";
  2671. const matchUsernameArr = pathname.match(/people\/([\W\w]+)\//);
  2672. const username = matchUsernameArr && matchUsernameArr.length ? matchUsernameArr[1] : "";
  2673. if (!username)
  2674. return;
  2675. const requestUrl = `/api/v4/members/${username}/answers?include=data%5B*%5D.is_normal%2Cadmin_closed_comment%2Creward_info%2Cis_collapsed%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cattachment%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Cexcerpt%2Cpaid_info%2Creaction_instruction%2Cis_labeled%2Clabel_info%2Crelationship.is_authorized%2Cvoting%2Cis_author%2Cis_thanked%2Cis_nothelp%3Bdata%5B*%5D.vessay_info%3Bdata%5B*%5D.author.badge%5B%3F%28type%3Dbest_answerer%29%5D.topics%3Bdata%5B*%5D.author.vip_info%3Bdata%5B*%5D.question.has_publishing_draft%2Crelationship&offset=${(+page - 1) * 20}&limit=20&sort_by=created`;
  2676. const header = createHeaders(requestUrl);
  2677. const data = await doHomeFetch(requestUrl, header);
  2678. const content = data.map((item) => `<h1>${item.question.title}</h1><div>${item.content}</div>`);
  2679. loadIframePrint(eventBtn, content, "导出当前页回答");
  2680. };
  2681. nodeListHeader.appendChild(nButton);
  2682. setTimeout(() => {
  2683. printPeopleAnswer();
  2684. }, 500);
  2685. };
  2686. var printPeopleArticles = async () => {
  2687. const { fetchInterceptStatus } = await myStorage.getConfig();
  2688. const nodeListHeader = dom(".Profile-main .List-headerText");
  2689. const prevButton = dom(".ctz-people-export-articles-once");
  2690. if (!nodeListHeader || prevButton || !fetchInterceptStatus)
  2691. return;
  2692. const nButton = createBtnSmallTran("导出当前页文章", "ctz-people-export-articles-once");
  2693. nButton.onclick = async function() {
  2694. const eventBtn = this;
  2695. const { search, pathname } = location;
  2696. const page = search.replace("?page=", "") || "1";
  2697. eventBtn.innerText = "加载文章内容中...";
  2698. eventBtn.disabled = true;
  2699. const prevData = [];
  2700. if (page === "1") {
  2701. const domScript = dom("#js-initialData");
  2702. if (!domScript)
  2703. return;
  2704. const scriptData = JSON.parse(domScript.innerText);
  2705. const articles = scriptData.initialState.entities.articles;
  2706. for (let key in articles) {
  2707. prevData.push(articles[key]);
  2708. }
  2709. }
  2710. const matchUsernameArr = pathname.match(/people\/([\W\w]+)\//) || pathname.match(/org\/([\W\w]+)\//);
  2711. const username = matchUsernameArr && matchUsernameArr.length ? matchUsernameArr[1] : "";
  2712. if (!username)
  2713. return;
  2714. const requestUrl = `https://www.zhihu.com/api/v4/members/${username}/articles?include=data%5B*%5D.comment_count%2Csuggest_edit%2Cis_normal%2Cthumbnail_extra_info%2Cthumbnail%2Ccan_comment%2Ccomment_permission%2Cadmin_closed_comment%2Ccontent%2Cvoteup_count%2Ccreated%2Cupdated%2Cupvoted_followees%2Cvoting%2Creview_info%2Creaction_instruction%2Cis_labeled%2Clabel_info%3Bdata%5B*%5D.vessay_info%3Bdata%5B*%5D.author.badge%5B%3F%28type%3Dbest_answerer%29%5D.topics%3Bdata%5B*%5D.author.vip_info%3B&offset=${(+page - 1) * 20}&limit=20&sort_by=created`;
  2715. const header = createHeaders(requestUrl);
  2716. const data = await doHomeFetch(requestUrl, header);
  2717. const content = data.map((item) => `<h1>${item.title}</h1><div>${item.content}</div>`);
  2718. loadIframePrint(eventBtn, content, "导出当前页文章");
  2719. };
  2720. nodeListHeader.appendChild(nButton);
  2721. setTimeout(() => {
  2722. printPeopleArticles();
  2723. }, 500);
  2724. };
  2725. var formatTime = (t2, f = "YYYY-MM-DD HH:mm:ss") => {
  2726. if (!t2)
  2727. return "";
  2728. const d = new Date(t2);
  2729. const year = d.getFullYear();
  2730. const month = d.getMonth() + 1;
  2731. const day = d.getDate();
  2732. const hour = d.getHours();
  2733. const min = d.getMinutes();
  2734. const sec = d.getSeconds();
  2735. const preArr = (num) => String(num).length !== 2 ? "0" + String(num) : String(num);
  2736. return f.replace(/YYYY/g, String(year)).replace(/MM/g, preArr(month)).replace(/DD/g, preArr(day)).replace(/HH/g, preArr(hour)).replace(/mm/g, preArr(min)).replace(/ss/g, preArr(sec));
  2737. };
  2738. var updateItemTime = (e2) => {
  2739. const nodeCreated = e2.querySelector('[itemprop="dateCreated"]');
  2740. const nodePublished = e2.querySelector('[itemprop="datePublished"]');
  2741. const nodeModified = e2.querySelector('[itemprop="dateModified"]');
  2742. const crTime = nodeCreated ? nodeCreated.content : "";
  2743. const puTime = nodePublished ? nodePublished.content : "";
  2744. const muTime = nodeModified ? nodeModified.content : "";
  2745. const timeCreated = formatTime(crTime || puTime);
  2746. const timeModified = formatTime(muTime);
  2747. const nodeBox = e2.querySelector(".ContentItem-meta");
  2748. if (!timeCreated || !nodeBox)
  2749. return;
  2750. const innerHTML = `<div>创建时间:${timeCreated}</div><div>最后修改时间:${timeModified}</div>`;
  2751. const domTime = e2.querySelector(`.${CLASS_TIME_ITEM}`);
  2752. if (domTime) {
  2753. domTime.innerHTML = innerHTML;
  2754. } else {
  2755. nodeBox.appendChild(
  2756. domC("div", {
  2757. className: CLASS_TIME_ITEM,
  2758. innerHTML,
  2759. style: "line-height: 24px;padding-top: 2px;font-size: 14px;"
  2760. })
  2761. );
  2762. }
  2763. };
  2764. var questionTimeout;
  2765. var questionFindIndex = 0;
  2766. var resetQuestionTime = () => {
  2767. if (questionFindIndex > 5 || !dom(".ctz-question-time")) {
  2768. return;
  2769. }
  2770. questionFindIndex++;
  2771. clearTimeout(questionTimeout);
  2772. questionTimeout = setTimeout(addQuestionTime, 500);
  2773. };
  2774. var addQuestionTime = async () => {
  2775. const nodeTime = dom(".ctz-question-time");
  2776. nodeTime && nodeTime.remove();
  2777. const { questionCreatedAndModifiedTime } = await myStorage.getConfig();
  2778. const nodeCreated = dom('[itemprop="dateCreated"]');
  2779. const nodeModified = dom('[itemprop="dateModified"]');
  2780. const nodeBox = dom(".QuestionPage .QuestionHeader-title");
  2781. if (!questionCreatedAndModifiedTime || !nodeCreated || !nodeModified || !nodeBox) {
  2782. resetQuestionTime();
  2783. return;
  2784. }
  2785. nodeBox?.appendChild(
  2786. domC("div", {
  2787. className: "ctz-question-time",
  2788. innerHTML: `<div>创建时间:${formatTime(nodeCreated.content)}</div><div>最后修改时间:${formatTime(nodeModified.content)}</div>`
  2789. })
  2790. );
  2791. resetQuestionTime();
  2792. };
  2793. var C_ARTICLE_TIME = "ctz-article-time";
  2794. var addArticleTime = async () => {
  2795. const { articleCreateTimeToTop } = await myStorage.getConfig();
  2796. const nodeT = dom(`.${C_ARTICLE_TIME}`);
  2797. if (nodeT)
  2798. return;
  2799. const nodeContentTime = dom(".ContentItem-time");
  2800. const nodeBox = dom(".Post-Header");
  2801. if (!articleCreateTimeToTop || !nodeContentTime || !nodeBox)
  2802. return;
  2803. nodeBox.appendChild(
  2804. domC("span", {
  2805. className: C_ARTICLE_TIME,
  2806. style: "color: #8590a6;line-height: 30px;",
  2807. innerHTML: nodeContentTime.innerText || ""
  2808. })
  2809. );
  2810. setTimeout(() => {
  2811. addArticleTime();
  2812. }, 500);
  2813. };
  2814. var updateTopVote = async (nodeItem) => {
  2815. if (!nodeItem)
  2816. return;
  2817. const nodeItemMeta = nodeItem.querySelector(".ContentItem-meta");
  2818. const nodeVote = nodeItem.querySelector('[itemprop="upvoteCount"]');
  2819. const { topVote } = await myStorage.getConfig();
  2820. if (!nodeVote || !topVote || !nodeItemMeta)
  2821. return;
  2822. const vote = nodeVote.content;
  2823. if (+vote === 0)
  2824. return;
  2825. const className = "ctz-top-vote";
  2826. const domVotePrev = nodeItemMeta.querySelector(`.${className}`);
  2827. const innerHTML = `${vote} 人赞同了该回答`;
  2828. if (domVotePrev) {
  2829. domVotePrev.innerHTML = innerHTML;
  2830. } else {
  2831. const domVote = domC("div", {
  2832. className,
  2833. innerHTML,
  2834. style: "font-size: 14px;padding-top: 2px;color: rgb(132, 145, 165);margin: 8px 0;"
  2835. });
  2836. nodeItemMeta.appendChild(domVote);
  2837. const metaObserver = new MutationObserver(() => {
  2838. updateTopVote(nodeItem);
  2839. });
  2840. metaObserver.observe(nodeVote, {
  2841. attributes: true,
  2842. childList: false,
  2843. characterData: false,
  2844. characterDataOldValue: false,
  2845. subtree: false
  2846. });
  2847. }
  2848. };
  2849. var myListenAnswerItem = {
  2850. index: 0,
  2851. init: async function() {
  2852. const nodes = domA(".AnswersNavWrapper .List-item");
  2853. if (this.index + 1 === nodes.length)
  2854. return;
  2855. const config = await myStorage.getConfig();
  2856. const {
  2857. removeLessVoteDetail,
  2858. lessVoteNumberDetail = 0,
  2859. answerOpen,
  2860. removeZhihuOfficial,
  2861. removeBlockUserContent,
  2862. removeBlockUserContentList,
  2863. showBlockUser,
  2864. removeAnonymousAnswer,
  2865. topExportContent,
  2866. blockWordsAnswer = [],
  2867. fetchInterceptStatus,
  2868. answerItemCreatedAndModifiedTime
  2869. } = config;
  2870. const addFnInNodeItem = (nodeItem, initThis) => {
  2871. if (!nodeItem)
  2872. return;
  2873. updateTopVote(nodeItem);
  2874. answerItemCreatedAndModifiedTime && updateItemTime(nodeItem);
  2875. initVideoDownload(nodeItem);
  2876. addAnswerCopyLink(nodeItem);
  2877. if (fetchInterceptStatus) {
  2878. showBlockUser && myBlack.addButton(nodeItem, initThis);
  2879. if (topExportContent) {
  2880. printAnswer(nodeItem);
  2881. printArticle(nodeItem);
  2882. }
  2883. }
  2884. };
  2885. addFnInNodeItem(dom(".QuestionAnswer-content"));
  2886. const hiddenTags = Object.keys(HIDDEN_ANSWER_TAG);
  2887. let hiddenUsers = [];
  2888. for (let i2 in HIDDEN_ANSWER_ACCOUNT) {
  2889. config[i2] && hiddenUsers.push(HIDDEN_ANSWER_ACCOUNT[i2]);
  2890. }
  2891. removeBlockUserContent && (hiddenUsers = hiddenTags.concat((removeBlockUserContentList || []).map((i2) => i2.name || "")));
  2892. for (let i2 = this.index === 0 ? 0 : this.index + 1, len = nodes.length; i2 < len; i2++) {
  2893. let message2 = "";
  2894. const nodeItem = nodes[i2];
  2895. const nodeItemContent = nodeItem.querySelector(".ContentItem");
  2896. if (!nodeItemContent)
  2897. continue;
  2898. let dataZop = {};
  2899. let dataCardContent = {};
  2900. try {
  2901. dataZop = JSON.parse(nodeItemContent.getAttribute("data-zop") || "{}");
  2902. dataCardContent = JSON.parse(nodeItemContent.getAttribute("data-za-extra-module") || "{}").card.content;
  2903. } catch {
  2904. }
  2905. (dataCardContent["upvote_num"] || 0) < lessVoteNumberDetail && removeLessVoteDetail && (message2 = `过滤低赞回答: ${dataCardContent["upvote_num"]}赞`);
  2906. if (!message2 && removeZhihuOfficial) {
  2907. const labelE = nodeItem.querySelector(".AuthorInfo-name .css-n99yhz");
  2908. const label = labelE ? labelE.getAttribute("aria-label") || "" : "";
  2909. /知乎[\s]*官方帐号/.test(label) && (message2 = "已删除一条知乎官方帐号的回答");
  2910. }
  2911. if (!message2) {
  2912. const nodeTag1 = nodeItem.querySelector(".KfeCollection-AnswerTopCard-Container");
  2913. const nodeTag2 = nodeItem.querySelector(".LabelContainer-wrapper");
  2914. const tagNames = (nodeTag1 ? nodeTag1.innerText : "") + (nodeTag2 ? nodeTag2.innerText : "");
  2915. for (let i3 of hiddenTags) {
  2916. if (config[i3]) {
  2917. const nReg = new RegExp(HIDDEN_ANSWER_TAG[i3]);
  2918. nReg.test(tagNames) && (message2 = `已删除一条标签${HIDDEN_ANSWER_TAG[i3]}的回答`);
  2919. }
  2920. }
  2921. }
  2922. if (!message2) {
  2923. hiddenUsers.length && hiddenUsers.includes(dataZop.authorName || "") && (message2 = `已删除${dataZop.authorName}的回答`);
  2924. }
  2925. if (!message2 && removeAnonymousAnswer) {
  2926. const userName = nodeItem.querySelector('[itemprop="name"]').content;
  2927. userName === "匿名用户" && (message2 = `已屏蔽一条「匿名用户」回答`);
  2928. }
  2929. if (!message2) {
  2930. const domRichContent = nodeItem.querySelector(".RichContent");
  2931. const innerText = domRichContent ? domRichContent.innerText : "";
  2932. if (innerText) {
  2933. let matchedWord = "";
  2934. for (let itemWord of blockWordsAnswer) {
  2935. const rep = new RegExp(itemWord.toLowerCase());
  2936. if (rep.test(innerText.toLowerCase())) {
  2937. matchedWord += `「${itemWord}」`;
  2938. break;
  2939. }
  2940. }
  2941. if (matchedWord) {
  2942. message2 = `匹配到屏蔽词${matchedWord},已屏蔽该回答内容`;
  2943. }
  2944. }
  2945. }
  2946. if (message2) {
  2947. fnHidden(nodeItem, message2);
  2948. } else {
  2949. addFnInNodeItem(nodeItem, this);
  2950. fnJustNum(nodeItem);
  2951. if (answerOpen) {
  2952. const unFoldButton = nodeItem.querySelector(".ContentItem-expandButton");
  2953. const foldButton = nodeItem.querySelector(".RichContent-collapsedText");
  2954. const isNotOpen = !nodeItem.classList.contains(OB_CLASS_FOLD.on);
  2955. const isNotClose = !nodeItem.classList.contains(OB_CLASS_FOLD.off);
  2956. if (answerOpen === "on" && isNotOpen) {
  2957. unFoldButton && unFoldButton.click();
  2958. nodeItem.classList.add(OB_CLASS_FOLD.on);
  2959. }
  2960. const isF = foldButton && nodeItem.offsetHeight > 939;
  2961. const isFC = unFoldButton;
  2962. if (answerOpen === "off" && isNotClose && (isF || isFC)) {
  2963. nodeItem.classList.add(OB_CLASS_FOLD.off);
  2964. isF && foldButton && foldButton.click();
  2965. }
  2966. }
  2967. }
  2968. if (i2 === len - 1) {
  2969. this.index = i2;
  2970. }
  2971. }
  2972. },
  2973. reset: function() {
  2974. this.index = 0;
  2975. },
  2976. restart: function() {
  2977. this.reset();
  2978. this.init();
  2979. }
  2980. };
  2981. var myListenListItem = {
  2982. index: 0,
  2983. init: async function() {
  2984. await this.traversal(domA(".TopstoryItem"));
  2985. setTimeout(() => {
  2986. this.traversal(domA(".TopstoryItem:not(.ctz-listened)"), false);
  2987. }, 500);
  2988. },
  2989. traversal: async function(nodes, needIndex = true) {
  2990. const index = needIndex ? this.index : 0;
  2991. if (!nodes.length)
  2992. return;
  2993. if (needIndex && index + 1 === nodes.length)
  2994. return;
  2995. const userinfo = store.getUserinfo();
  2996. const pfConfig = await myStorage.getConfig();
  2997. const {
  2998. filterKeywords = [],
  2999. blockWordsAnswer = [],
  3000. removeItemAboutVideo,
  3001. removeItemAboutPin,
  3002. removeItemAboutArticle,
  3003. removeLessVote,
  3004. lessVoteNumber = 0,
  3005. removeItemQuestionAsk,
  3006. removeFollowVoteAnswer,
  3007. removeFollowVoteArticle,
  3008. removeFollowFQuestion,
  3009. listOutPutNotInterested,
  3010. highlightOriginal,
  3011. themeDark = 1 /* 深色护眼一 */,
  3012. themeLight = 0 /* 默认 */,
  3013. removeMyOperateAtFollow,
  3014. listOutputToQuestion,
  3015. fetchInterceptStatus
  3016. } = pfConfig;
  3017. const pfHistory = await myStorage.getHistory();
  3018. const historyList = pfHistory.list;
  3019. for (let i2 = index === 0 ? 0 : index + 1, len = nodes.length; i2 < len; i2++) {
  3020. const nodeItem = nodes[i2];
  3021. nodeItem.classList.add("ctz-listened");
  3022. const nodeItemContent = nodeItem.querySelector(".ContentItem");
  3023. if (!nodeItem.scrollHeight || !nodeItemContent)
  3024. continue;
  3025. let message2 = "";
  3026. let dataZop = {};
  3027. let cardContent = {};
  3028. const isVideo = nodeItemContent.classList.contains("ZVideoItem");
  3029. const isArticle = nodeItemContent.classList.contains("ArticleItem");
  3030. const isTip = nodeItemContent.classList.contains("PinItem");
  3031. try {
  3032. dataZop = JSON.parse(nodeItemContent.getAttribute("data-zop") || "{}");
  3033. cardContent = JSON.parse(nodeItemContent.getAttribute("data-za-extra-module") || "{}").card.content;
  3034. } catch {
  3035. }
  3036. const { title = "" } = dataZop || {};
  3037. if (removeMyOperateAtFollow && nodeItem.classList.contains("TopstoryItem-isFollow")) {
  3038. try {
  3039. const findUserId = nodeItem.querySelector(".UserLink .UserLink-link").href.match(/[^\/]+$/)[0];
  3040. const myUserId = userinfo.url.match(/[^\/]+$/)[0];
  3041. findUserId === myUserId && (message2 = "关注列表屏蔽自己的操作");
  3042. } catch {
  3043. }
  3044. }
  3045. if (!message2 && (isVideo && removeItemAboutVideo || isArticle && removeItemAboutArticle || isTip && removeItemAboutPin)) {
  3046. message2 = `列表种类屏蔽,${nodeItemContent.classList.value}`;
  3047. }
  3048. if (!message2 && removeLessVote && (cardContent["upvote_num"] || 0) < lessVoteNumber) {
  3049. message2 = `屏蔽低赞内容: ${title}, ${cardContent["upvote_num"] || 0}`;
  3050. }
  3051. if (!message2 && removeItemQuestionAsk && nodeItem.querySelector(".TopstoryQuestionAskItem")) {
  3052. message2 = "屏蔽邀请回答";
  3053. }
  3054. if (!message2 && (removeFollowVoteAnswer || removeFollowVoteArticle || removeFollowFQuestion) && nodeItem.classList.contains("TopstoryItem-isFollow")) {
  3055. const nodeFirstLine = nodeItem.querySelector(".FeedSource-firstline");
  3056. const textFollowerOperate = nodeFirstLine ? nodeFirstLine.innerText : "";
  3057. for (let itemOperate of FILTER_FOLLOWER_OPERATE) {
  3058. const thisRep = new RegExp(itemOperate.rep);
  3059. if (pfConfig[itemOperate.key] && thisRep.test(textFollowerOperate)) {
  3060. message2 = `屏蔽关注人操作: ${textFollowerOperate}`;
  3061. break;
  3062. }
  3063. }
  3064. }
  3065. !message2 && (message2 = this.replaceBlockWord(title, nodeItemContent, filterKeywords, title, "标题"));
  3066. if (!message2) {
  3067. const domRichContent = nodeItem.querySelector(".RichContent");
  3068. const innerText = domRichContent ? domRichContent.innerText : "";
  3069. message2 = this.replaceBlockWord(innerText, nodeItemContent, blockWordsAnswer, title, "内容");
  3070. }
  3071. if (message2) {
  3072. fnHidden(nodeItem, message2);
  3073. } else {
  3074. if (highlightOriginal) {
  3075. const userNameE = nodeItem.querySelector(".FeedSource-firstline .UserLink-link");
  3076. const userName = userNameE ? userNameE.innerText : "";
  3077. if (dataZop && dataZop.authorName === userName) {
  3078. const dark = await isDark();
  3079. const highlight = `background: ${dark ? `${THEME_CONFIG_DARK[themeDark].background2}!important;` : +themeLight === 0 /* 默认 */ ? "#fff3d4!important;" : `${THEME_CONFIG_LIGHT[themeLight].background}!important;`}`;
  3080. const nodeActions = nodeItem.querySelector(".ContentItem-actions");
  3081. nodeItem.style.cssText = `${highlight}border: 1px solid #aaa;`;
  3082. nodeActions && (nodeActions.style.cssText = highlight);
  3083. }
  3084. }
  3085. const nodeItemTitle = nodeItem.querySelector(".ContentItem-title");
  3086. if (nodeItemTitle) {
  3087. if (listOutPutNotInterested && fetchInterceptStatus && !nodeItem.querySelector(`.${CLASS_NOT_INTERESTED}`)) {
  3088. nodeItemTitle.appendChild(createBtnSmallTran("不感兴趣", CLASS_NOT_INTERESTED, { _params: { id: dataZop.itemId, type: dataZop.type } }));
  3089. }
  3090. if (listOutputToQuestion && !isVideo && !isArticle && !isTip && !nodeItem.querySelector(`.${CLASS_TO_QUESTION}`)) {
  3091. const domUrl = nodeItemContent.querySelector('[itemprop="url"]');
  3092. const pathAnswer = domUrl ? domUrl.getAttribute("content") || "" : "";
  3093. nodeItemTitle.appendChild(createBtnSmallTran("直达问题", CLASS_TO_QUESTION, { _params: { path: pathAnswer.replace(/\/answer[\W\w]+/, "") } }));
  3094. }
  3095. }
  3096. }
  3097. if (domP(nodeItem, "class", "Topstory-recommend") && nodeItem.querySelector(".ContentItem-title a")) {
  3098. const nodeA = nodeItem.querySelector(".ContentItem-title a");
  3099. if (nodeA) {
  3100. const itemT = isVideo ? RECOMMEND_TYPE.zvideo : isArticle ? RECOMMEND_TYPE.article : isTip ? RECOMMEND_TYPE.pin : RECOMMEND_TYPE.answer;
  3101. historyList.unshift(`<a href="${nodeA.href}" target="_blank"><b style="${itemT.style}">「${itemT.name}」</b>${nodeA.innerText}</a>`);
  3102. }
  3103. }
  3104. fnJustNum(nodeItem);
  3105. if (i2 === len - 1) {
  3106. needIndex && (this.index = i2);
  3107. myStorage.setHistoryItem("list", historyList);
  3108. }
  3109. }
  3110. },
  3111. reset: function() {
  3112. this.index = 0;
  3113. },
  3114. restart: function() {
  3115. this.reset();
  3116. this.init();
  3117. },
  3118. replaceBlockWord: function(innerText, nodeItemContent, blockWords, title, byWhat) {
  3119. if (innerText) {
  3120. let matchedWord = "";
  3121. for (let word of blockWords) {
  3122. const rep = new RegExp(word.toLowerCase());
  3123. if (rep.test(innerText.toLowerCase())) {
  3124. matchedWord += `「${word}」`;
  3125. break;
  3126. }
  3127. }
  3128. if (matchedWord) {
  3129. const elementItemProp = nodeItemContent.querySelector('[itemprop="url"]');
  3130. const routeURL = elementItemProp && elementItemProp.getAttribute("content");
  3131. return `${byWhat}屏蔽词匹配,匹配内容:${matchedWord},《${title}》,链接:${routeURL}`;
  3132. }
  3133. }
  3134. return "";
  3135. }
  3136. };
  3137. var RECOMMEND_TYPE = {
  3138. answer: {
  3139. name: "问题",
  3140. style: "color: #ec7259"
  3141. },
  3142. article: {
  3143. name: "文章",
  3144. style: "color: #00965e"
  3145. },
  3146. zvideo: {
  3147. name: "视频",
  3148. style: "color: #12c2e9"
  3149. },
  3150. pin: {
  3151. name: "想法",
  3152. style: "color: #9c27b0"
  3153. }
  3154. };
  3155. var myListenSearchListItem = {
  3156. index: 0,
  3157. init: async function() {
  3158. const nodes = domA('.SearchResult-Card[role="listitem"]');
  3159. if (this.index + 1 === nodes.length)
  3160. return;
  3161. const { removeItemAboutVideo, removeItemAboutArticle, removeItemAboutAD, removeLessVote, lessVoteNumber = 0 } = await myStorage.getConfig();
  3162. for (let i2 = this.index === 0 ? 0 : this.index + 1, len = nodes.length; i2 < len; i2++) {
  3163. let message2 = "";
  3164. const elementThis = nodes[i2];
  3165. if (!elementThis)
  3166. continue;
  3167. const haveAD = removeItemAboutAD && elementThis.querySelector(".KfeCollection-PcCollegeCard-root");
  3168. const haveArticle = removeItemAboutArticle && elementThis.querySelector(".ArticleItem");
  3169. const haveVideo = removeItemAboutVideo && elementThis.querySelector(".ZvideoItem");
  3170. (haveAD || haveArticle || haveVideo) && (message2 = "列表种类屏蔽");
  3171. if (removeLessVote && !message2) {
  3172. const elementUpvote = elementThis.querySelector(".ContentItem-actions .VoteButton--up");
  3173. if (elementUpvote) {
  3174. const ariaLabel = elementUpvote.getAttribute("aria-label");
  3175. if (ariaLabel) {
  3176. const upvoteText = ariaLabel.trim().replace(/\W+/, "");
  3177. const upvote = upvoteText.includes("万") ? +upvoteText.replace("万", "").trim() * 1e4 : +upvoteText;
  3178. if (upvote > -1 && upvote < lessVoteNumber) {
  3179. message2 = `屏蔽低赞内容: ${upvote || 0}赞`;
  3180. }
  3181. }
  3182. }
  3183. }
  3184. fnJustNum(elementThis);
  3185. message2 && fnHidden(elementThis, message2);
  3186. if (i2 === len - 1) {
  3187. this.index = i2;
  3188. }
  3189. }
  3190. },
  3191. reset: function() {
  3192. this.index = 0;
  3193. },
  3194. restart: function() {
  3195. this.reset();
  3196. this.init();
  3197. }
  3198. };
  3199. var initImagePreview = async () => {
  3200. const { zoomImageType } = await myStorage.getConfig();
  3201. const images = [domA(".TitleImage:not(.ctz-processed)"), domA(".ArticleItem-image:not(.ctz-processed)"), domA(".ztext figure .content_image:not(.ctz-processed)")];
  3202. for (let i2 = 0, imageLen = images.length; i2 < imageLen; i2++) {
  3203. const ev = images[i2];
  3204. for (let index = 0, len = ev.length; index < len; index++) {
  3205. const nodeItem = ev[index];
  3206. nodeItem.classList.add("ctz-processed");
  3207. const src = nodeItem.src || nodeItem.style.backgroundImage && nodeItem.style.backgroundImage.split('("')[1].split('")')[0];
  3208. nodeItem.onclick = () => myPreview.open(src);
  3209. }
  3210. }
  3211. if (zoomImageType === "2") {
  3212. const originImages = domA(".origin_image:not(.ctz-processed)");
  3213. for (let i2 = 0, len = originImages.length; i2 < len; i2++) {
  3214. const nodeItem = originImages[i2];
  3215. nodeItem.src = nodeItem.getAttribute("data-original") || nodeItem.src;
  3216. nodeItem.classList.add("ctz-processed");
  3217. nodeItem.style.cssText = "max-width: 100%;";
  3218. }
  3219. }
  3220. };
  3221. var classTarget = ["RichContent-cover", "RichContent-inner", "ContentItem-more", "ContentItem-arrowIcon"];
  3222. var canFindTargeted = (e2) => {
  3223. let isFind = false;
  3224. classTarget.forEach((item) => {
  3225. (e2.classList.contains(item) || e2.parentElement.classList.contains(item)) && (isFind = true);
  3226. });
  3227. return isFind;
  3228. };
  3229. var cbEventListener = async (event) => {
  3230. const target = event.target;
  3231. const nodeItem = domP(target, "class", "ContentItem");
  3232. if (!nodeItem)
  3233. return;
  3234. const { showBlockUser, topExportContent, fetchInterceptStatus, listItemCreatedAndModifiedTime } = await myStorage.getConfig();
  3235. if (target.classList.contains(CLASS_NOT_INTERESTED) && fetchInterceptStatus) {
  3236. const { id, type } = target._params;
  3237. doFetchNotInterested({ id, type });
  3238. const nodeTopStoryItem = domP(target, "class", "TopstoryItem");
  3239. nodeTopStoryItem && (nodeTopStoryItem.style.display = "none");
  3240. }
  3241. if (target.classList.contains(CLASS_TO_QUESTION)) {
  3242. const { path } = target._params;
  3243. path && window.open(path);
  3244. }
  3245. if (canFindTargeted(target)) {
  3246. setTimeout(() => {
  3247. updateTopVote(nodeItem);
  3248. listItemCreatedAndModifiedTime && updateItemTime(nodeItem);
  3249. initVideoDownload(nodeItem);
  3250. addAnswerCopyLink(nodeItem);
  3251. if (fetchInterceptStatus) {
  3252. showBlockUser && myBlack.addButton(nodeItem.parentElement);
  3253. if (topExportContent) {
  3254. printAnswer(nodeItem.parentElement);
  3255. printArticle(nodeItem.parentElement);
  3256. }
  3257. }
  3258. }, 0);
  3259. }
  3260. };
  3261. var recommendTimeout;
  3262. var indexTopStoryInit = 0;
  3263. var initTopStoryRecommendEvent = () => {
  3264. const nodeTopStoryRecommend = dom(".Topstory-recommend") || dom(".Topstory-follow") || dom(".zhuanlan .css-1voxft1");
  3265. if (nodeTopStoryRecommend) {
  3266. nodeTopStoryRecommend.removeEventListener("click", cbEventListener);
  3267. nodeTopStoryRecommend.addEventListener("click", cbEventListener);
  3268. }
  3269. if (indexTopStoryInit < 5) {
  3270. indexTopStoryInit++;
  3271. clearTimeout(recommendTimeout);
  3272. recommendTimeout = setTimeout(initTopStoryRecommendEvent, 500);
  3273. } else {
  3274. indexTopStoryInit = 0;
  3275. }
  3276. };
  3277. var initRootEvent = async () => {
  3278. const domRoot = dom("#root");
  3279. if (!domRoot)
  3280. return;
  3281. const classForVideoOne = CLASS_VIDEO_ONE.replace(".", "");
  3282. const { videoUseLink } = await myStorage.getConfig();
  3283. domRoot.addEventListener("click", function(event) {
  3284. const target = event.target;
  3285. if (videoUseLink) {
  3286. if (target.classList.contains(classForVideoOne)) {
  3287. const domVideo = target.querySelector("video");
  3288. const videoSrc = domVideo ? domVideo.src : "";
  3289. if (!videoSrc)
  3290. return;
  3291. window.open(videoSrc, "_blank");
  3292. }
  3293. }
  3294. });
  3295. };
  3296. var initResizeObserver = () => {
  3297. const resizeObserver = new ResizeObserver(throttle(resizeFun, 500));
  3298. resizeObserver.observe(document.body);
  3299. };
  3300. async function resizeFun() {
  3301. if (!HTML_HOOTS.includes(location.hostname))
  3302. return;
  3303. const { hiddenSearchBoxTopSearch, contentRemoveKeywordSearch, globalTitle } = await myStorage.getConfig();
  3304. const nodeTopStoryC = domById("TopstoryContent");
  3305. if (nodeTopStoryC) {
  3306. const heightTopStoryContent = nodeTopStoryC.offsetHeight;
  3307. if (heightTopStoryContent < 200) {
  3308. myListenListItem.restart();
  3309. initTopStoryRecommendEvent();
  3310. } else {
  3311. myListenListItem.init();
  3312. }
  3313. heightTopStoryContent < window.innerHeight && windowResize();
  3314. }
  3315. contentRemoveKeywordSearch && fnContentRemoveKeywordSearch(document.body);
  3316. initLinkChanger();
  3317. previewGIF();
  3318. initImagePreview();
  3319. myListenSearchListItem.init();
  3320. myListenAnswerItem.init();
  3321. pathnameHasFn({
  3322. collection: () => myCollectionExport.init()
  3323. });
  3324. globalTitle !== document.title && changeTitle();
  3325. const nodeSearchBarInput = dom(".SearchBar-input input");
  3326. if (hiddenSearchBoxTopSearch && nodeSearchBarInput) {
  3327. nodeSearchBarInput.placeholder = "";
  3328. }
  3329. }
  3330. var echoHistory = async () => {
  3331. const history = await myStorage.getHistory();
  3332. const { list, view } = history;
  3333. const nodeList = dom("#CTZ_HISTORY_LIST .ctz-set-content");
  3334. const nodeView = dom("#CTZ_HISTORY_VIEW .ctz-set-content");
  3335. nodeList && (nodeList.innerHTML = list.join(""));
  3336. nodeView && (nodeView.innerHTML = view.join(""));
  3337. };
  3338. var myDialog = {
  3339. open: async () => {
  3340. const nodeDialog = domById(ID_DIALOG);
  3341. nodeDialog && (nodeDialog.style.display = "flex");
  3342. myScroll.stop();
  3343. echoData();
  3344. echoHistory();
  3345. },
  3346. hide: () => {
  3347. const nodeDialog = domById(ID_DIALOG);
  3348. nodeDialog && (nodeDialog.style.display = "none");
  3349. myScroll.on();
  3350. }
  3351. };
  3352. var myHidden = {
  3353. init: async function() {
  3354. const changeValue = await this.change();
  3355. fnInitDomStyle("CTZ_STYLE_HIDDEN", changeValue || "");
  3356. },
  3357. change: async function() {
  3358. const pfConfig = await myStorage.getConfig();
  3359. const cssHidden = Object.keys(this.cssForKey).map((key) => pfConfig[key] ? this.cssForKey[key] : "").join("");
  3360. let cssHiddenMore = "";
  3361. this.cssForKeysArray.forEach(({ keys, value }) => {
  3362. let trueNumber = 0;
  3363. keys.forEach((key) => pfConfig[key] && trueNumber++);
  3364. trueNumber === keys.length && (cssHiddenMore += value);
  3365. });
  3366. return cssHidden + cssHiddenMore;
  3367. },
  3368. cssForKey: {
  3369. hiddenLogo: `.ZhihuLogoLink,.TopTabNavBar-logo-3d0k,[aria-label="知乎"],.TopNavBar-logoContainer-vDhU2,.zu-top-link-logo{display: none!important;}`,
  3370. hiddenHeader: `.AppHeader,.ColumnPageHeader-Wrapper{display: none!important;}.PubIndex-CategoriesHeader{top: 0!important;}`,
  3371. hiddenHeaderScroll: `.AppHeader.is-fixed{display:none!important;}`,
  3372. hiddenYanXuanWriter: `.KfeCollection-CreateSaltCard{display:none!important;}`,
  3373. hiddenItemActions: `.Topstory-container .ContentItem-actions>span,.Topstory-container .ContentItem-actions>button,.Topstory-container .ContentItem-actions>div,.Topstory-container .ContentItem-actions>a,.TopstoryQuestionAskItem-writeAnswerButton,.TopstoryQuestionAskItem-hint{visibility:hidden!important;height:0!important;padding:0!important;}.TopstoryQuestionAskItem-hint{margin: 0!important;}.Topstory .ContentItem-actions{padding: 0!important;}.zhuanlan .ContentItem .ContentItem-actions:not(.Sticky){visibility:hidden!important;height:0!important;}`,
  3374. hiddenAnswerText: `.ContentItem-actions{padding: 0 20px!important;line-height: 38px!important;}.ContentItem-action,.ContentItem-action button,.ContentItem-actions button{font-size: 0!important;padding: 0!important;background: none!important;line-height:inherit!important;}.ContentItem-action span,.ContentItem-actions button span{font-size: 16px!important;}.ContentItem-action svg,.ContentItem-actions svg{width: 16px!important;height:16px!important;}.VoteButton{color: #8590a6!important; }.VoteButton.is-active{color: #056de8!important;}.ContentItem-action{margin-left:8px!important;}.Search-questionFollowButton{display: none}`,
  3375. hiddenQuestionTag: ".QuestionHeader-tags{display: none!important;}",
  3376. hiddenQuestionShare: ".zhihu .Popover.ShareMenu{display: none!important;}",
  3377. hiddenQuestionActions: ".QuestionButtonGroup,.QuestionHeaderActions{display: none!important;}",
  3378. hiddenReward: ".Reward{display: none!important;}",
  3379. hiddenZhuanlanTag: ".Post-topicsAndReviewer{display: none!important;}",
  3380. hiddenListImg: `.RichContent-cover,.HotItem-img,.TopstoryItem .Image-Wrapper-Preview{display:none!important;}.HotItem-metrics--bottom{position: initial!important;}`,
  3381. hiddenReadMoreText: ".ContentItem-more{font-size:0!important;}",
  3382. hiddenAD: ".TopstoryItem--advertCard,.Pc-card,.Pc-word,.RichText-ADLinkCardContainer,.Pc-Business-Card-PcTopFeedBanner{display: none!important;}",
  3383. hiddenAnswers: `.Topstory-container .RichContent.is-collapsed .RichContent-inner,.HotItem-excerpt--multiLine,.TopstoryQuestionAskItem .RichContent .RichContent-inner,.HotItem-content .HotItem-excerpt,.Topstory-recommend .ZVideoItem-video, .Topstory-recommend .VideoAnswerPlayer{display: none;}`,
  3384. hiddenListVideoContent: `.Topstory-recommend .ZVideoItem-video,.Topstory-recommend .VideoAnswerPlayer,.Topstory-recommend .ZVideoItem .RichContent{display: none;}`,
  3385. hiddenZhuanlanActions: ".RichContent-actions.is-fixed>.ContentItem-actions{display: none;}.zhuanlan .ContentItem .RichContent-actions.is-fixed,.zhuanlan .List-item .RichContent-actions.is-fixed{visibility: hidden!important;}",
  3386. hiddenZhuanlanTitleImage: ".css-1ntkiwo,.TitleImage,.css-78p1r9,.ArticleItem .RichContent>div:first-of-type:not(.RichContent-cover)>div:last-of-type{display: none!important;}",
  3387. hiddenFixedActions: `.zhihu .ContentItem .RichContent-actions.is-fixed,.zhihu .List-item .RichContent-actions.is-fixed{visibility: hidden!important;}`,
  3388. hiddenHotItemMetrics: ".HotItem-content .HotItem-metrics{display: none;}",
  3389. hiddenHotItemIndex: ".HotItem-index{display: none;}.HotItem{padding: 16px!important;}",
  3390. hiddenHotItemLabel: ".HotItem-label{display: none;}",
  3391. hiddenDetailAvatar: ".AnswerItem .AuthorInfo .AuthorInfo-avatarWrapper{display: none;}.AnswerItem .AuthorInfo .AuthorInfo-content{margin-left:0!important;}",
  3392. hiddenDetailBadge: ".AnswerItem .AuthorInfo .AuthorInfo-detail{display: none;}",
  3393. hiddenDetailVoters: ".AnswerItem .css-dvccr2{display: none;}",
  3394. hiddenWhoVoters: ".css-1vqda4a{display: none!important;}",
  3395. hiddenDetailName: ".AnswerItem .AuthorInfo .AuthorInfo-head{display: none;}",
  3396. hiddenDetailFollow: ".AnswerItem .AuthorInfo .FollowButton{display: none;}",
  3397. hiddenHomeTab: ".Topstory-container .TopstoryTabs{display: none!important;}",
  3398. hiddenQuestionSide: ".QuestionHeader-side{display: none;}.QuestionHeader-main{flex: 1!important;}",
  3399. hiddenQuestionFollowing: ".QuestionHeader .FollowButton{display: none;}",
  3400. hiddenQuestionAnswer: ".QuestionHeader .FollowButton ~ a{display: none;}",
  3401. hiddenQuestionInvite: ".QuestionHeader .QuestionHeaderActions>button:first-child{display: none;}",
  3402. hiddenSearchPageTopSearch: ".Search-container .TopSearch{display: none;}",
  3403. hiddenSearchPageFooter: ".Search-container .Footer,.Search-container footer{display: none;}",
  3404. hiddenSearchBoxTopSearch: ".SearchBar-noValueMenu .AutoComplete-group:first-child{display:none;}",
  3405. hiddenZhuanlanShare: ".zhuanlan .Post-SideActions .Popover.ShareMenu{display: none!important;}",
  3406. hiddenZhuanlanVoters: ".zhuanlan .Post-SideActions .like{display: none!important;}",
  3407. hiddenFollowAction: ".TopstoryItem-isFollow .FeedSource-firstline{display: none;}",
  3408. hiddenFollowChooseUser: ".TopstoryItem-isFollow .AuthorInfo{display: none;}",
  3409. hiddenAnswerRightFooter: ".Question-sideColumn{display: none!important;}.Question-main .Question-mainColumn,.ListShortcut{width: inherit;}",
  3410. hiddenAnswerRightFooterAnswerAuthor: ".Question-sideColumn .AnswerAuthor{display: none;}",
  3411. hiddenAnswerRightFooterFavorites: ".Question-sideColumn .AnswerAuthor + .Card{display: none;}",
  3412. hiddenAnswerRightFooterRelatedQuestions: '.Question-sideColumn [data-za-detail-view-path-module="RelatedQuestions"]{display: none;}',
  3413. hiddenAnswerRightFooterContentList: '.Question-sideColumn [data-za-detail-view-path-module="ContentList"]{display: none;}',
  3414. hiddenAnswerRightFooterFooter: ".Question-sideColumn .Footer{display: none;}",
  3415. hidden618HongBao: '.MCNLinkCard[data-mcn-source="淘宝"],.MCNLinkCard[data-mcn-source="京东"],.MCNLinkCard[data-mcn-source="知乎"]{display:none;}',
  3416. hiddenZhuanlanFollowButton: ".zhuanlan .FollowButton{display: none;}",
  3417. hiddenZhuanlanAvatarWrapper: ".zhuanlan .AuthorInfo-avatarWrapper{display: none;}",
  3418. hiddenZhuanlanAuthorInfoHead: ".zhuanlan .AuthorInfo-head{display: none;}",
  3419. hiddenZhuanlanAuthorInfoDetail: ".zhuanlan .AuthorInfo-detail{display: none;}",
  3420. hiddenListAnswerInPerson: ".Topstory-mainColumn .LabelContainer{display: none;}",
  3421. hiddenQuestionSpecial: ".QuestionHeader .LabelContainer-wrapper{display: none;}",
  3422. hiddenHomeCreatorEntrance: ".Topstory .css-19idom{display: none;}",
  3423. hiddenHomeRecommendFollow: ".Topstory .css-173vipd{display: none;}",
  3424. hiddenHomeCategory: ".Topstory .GlobalSideBar-category{display: none;}",
  3425. hiddenHomeCategoryMore: '.Topstory .Card[aria-label="更多分类入口"]{display:none;}',
  3426. hiddenHomeFooter: ".Topstory .Footer,.Topstory footer{display: none;}",
  3427. hiddenAnswerItemActions: `.Question-main .ContentItem-actions>span,.Question-main .ContentItem-actions>button,.Question-main .ContentItem-actions>div,.Question-main .ContentItem-actions>a{visibility:hidden!important;height:0!important;padding:0!important;}`,
  3428. hiddenAnswerItemTime: ".Question-main .ContentItem-time{display: none;margin: 0;}",
  3429. hiddenAnswerItemTimeButHaveIP: ".Question-main .ContentItem-time>a{display: none;}.Question-main .ContentItem-time:empty{display: none;margin: 0;}",
  3430. hiddenAppHeaderTabHome: ".AppHeader-Tab:nth-of-type(1){display: none}",
  3431. hiddenAppHeaderTabZhi: ".AppHeader-Tab:nth-of-type(2){display: none}",
  3432. hiddenAppHeaderTabWaitingForYou: ".AppHeader-Tab:nth-of-type(3){display: none}",
  3433. hiddenAppHeaderTabFind: ".AppHeader-Tab:nth-of-type(4){display: none}",
  3434. hiddenHomeListTabFollow: '.Topstory-container .TopstoryTabs [aria-controls="Topstory-follow"]{display: none}',
  3435. hiddenHomeListTabRecommend: '.Topstory-container .TopstoryTabs [aria-controls="Topstory-recommend"]{display: none}',
  3436. hiddenHomeListTabHot: '.Topstory-container .TopstoryTabs [aria-controls="Topstory-hot"]{display: none}',
  3437. hiddenHomeListTabVideo: '.Topstory-container .TopstoryTabs [aria-controls="Topstory-zvideo"]{display: none}',
  3438. hiddenHomeListTab: ".Topstory-container .TopstoryTabs{display: none}",
  3439. hiddenQuestionGoodQuestion: ".QuestionPage .QuestionHeader .GoodQuestionAction{display: none}",
  3440. hiddenQuestionComment: ".QuestionPage .QuestionHeader .QuestionHeader-Comment{display: none}",
  3441. hiddenQuestionMore: '.QuestionPage .QuestionHeader [aria-label="更多"]{display: none;}',
  3442. hiddenOpenButton: "#CTZ_OPEN_BUTTON{display: none;}",
  3443. hiddenCommitReply: ".Comments-container .css-140jo2 button:first-of-type{display:none;}",
  3444. hiddenCommitVote: ".Comments-container .css-140jo2 button:last-of-type{display:none;}",
  3445. hiddenCommitBottom: ".Comments-container .css-140jo2{display:none;}",
  3446. hiddenUserHomeOtherCard: ".Profile-sideColumn .Card:not(.Publications):not(.FollowshipCard){display:none;}",
  3447. hiddenUserHomePublications: ".Profile-sideColumn .Card.Publications{display:none;}",
  3448. hiddenUserHomeCreateEntrance: ".Profile-sideColumn .CreatorEntrance{display:none;}",
  3449. hiddenUserHomeFollow: ".Profile-sideColumn .FollowshipCard{display:none;}",
  3450. hiddenUserHomeLightList: ".Profile-sideColumn .Profile-lightList{display:none;}",
  3451. hiddenUserHomeFooterOperate: ".Profile-sideColumn .Profile-footerOperations{display:none;}",
  3452. hiddenUserHomeFooter: ".Profile-sideColumn footer{display:none;}",
  3453. hiddenCollectionsCreate: ".Collections-container .Card.CreatorEntrance{display:none;}",
  3454. hiddenCollectionsRecommendFollow: '.Collections-container [data-za-detail-view-path-module="RightSideBar"]>div:last-of-type>.Card{display:none;}',
  3455. hiddenCollectionsCategory: ".Collections-container .Card.GlobalSideBar-category{display:none;}",
  3456. hiddenCollectionsComplementary: '.Collections-container .Card[aria-label="更多分类入口"]{display:none;}',
  3457. hiddenCollectionsFooter: ".Collections-container footer{display:none;}",
  3458. hiddenZhihuZhiShop: ".RichText-EduCardContainer{display:none;}",
  3459. hiddenTopicRightNumberBoard: '[data-za-detail-view-path-module="TopicItem"] .Card .NumberBoard{display:none;}',
  3460. hiddenTopicRightParentChild: '[data-za-detail-view-path-module="TopicItem"] .Card .Card-section{display:none;}',
  3461. hiddenTopicRightFooter: '[data-za-detail-view-path-module="TopicItem"] footer{display:none;}'
  3462. },
  3463. cssForKeysArray: [
  3464. {
  3465. keys: [
  3466. "hiddenUserHomeOtherCard",
  3467. "hiddenUserHomePublications",
  3468. "hiddenUserHomeCreateEntrance",
  3469. "hiddenUserHomeFollow",
  3470. "hiddenUserHomeLightList",
  3471. "hiddenUserHomeFooterOperate",
  3472. "hiddenUserHomeFooter"
  3473. ],
  3474. value: ".Profile-sideColumn{display: none}"
  3475. },
  3476. {
  3477. keys: ["hiddenSearchPageTopSearch", "hiddenSearchPageFooter"],
  3478. value: ".SearchSideBar{display: none}"
  3479. },
  3480. {
  3481. keys: ["hiddenHomeCreatorEntrance", "hiddenHomeRecommendFollow", "hiddenHomeCategory", "hiddenHomeCategoryMore", "hiddenHomeFooter"],
  3482. value: ".Topstory-mainColumn{margin: 0 auto;}"
  3483. },
  3484. {
  3485. keys: ["hiddenHomeListTabFollow", "hiddenHomeListTabRecommend", "hiddenHomeListTabHot", "hiddenHomeListTabVideo"],
  3486. value: ".Topstory-container .TopstoryTabs{display: none}"
  3487. },
  3488. {
  3489. keys: ["hiddenTopicRightNumberBoard", "hiddenTopicRightParentChild", "hiddenTopicRightFooter"],
  3490. value: '[data-za-detail-view-path-module="TopicItem"]>div:nth-child(2){display: none;}'
  3491. }
  3492. ]
  3493. };
  3494. var fnChanger = async (ev) => {
  3495. const doCssVersion = [
  3496. "questionTitleTag",
  3497. "fixedListItemMore",
  3498. "linkShopping",
  3499. "highlightListItem",
  3500. "zoomImageSize",
  3501. "zoomImageHeight",
  3502. "zoomImageHeightSize",
  3503. "versionHome",
  3504. "versionAnswer",
  3505. "versionArticle",
  3506. "versionHomePercent",
  3507. "versionAnswerPercent",
  3508. "versionArticlePercent",
  3509. "fontSizeForListTitle",
  3510. "fontSizeForAnswerTitle",
  3511. "fontSizeForArticleTitle",
  3512. "fontSizeForList",
  3513. "fontSizeForAnswer",
  3514. "fontSizeForArticle",
  3515. "zoomListVideoType",
  3516. "zoomListVideoSize",
  3517. "commitModalSizeSameVersion",
  3518. "videoUseLink"
  3519. ];
  3520. const { name, value, checked, type } = ev;
  3521. const changeBackground = () => {
  3522. myVersion.change();
  3523. myBackground.init();
  3524. myListenListItem.restart();
  3525. onUseThemeDark();
  3526. };
  3527. const rangeChoosePercent = () => {
  3528. const rangeName = name.replace("IsPercent", "");
  3529. const rangeNamePercent = `${rangeName}Percent`;
  3530. const domRange = dom(`.ctz-range-${rangeName}`);
  3531. const domRangePercent = dom(`.ctz-range-${rangeNamePercent}`);
  3532. if (domRange && domRangePercent) {
  3533. domRange.style.display = checked ? "none" : "flex";
  3534. domRangePercent.style.display = !checked ? "none" : "flex";
  3535. }
  3536. myVersion.change();
  3537. };
  3538. const ob = {
  3539. [INPUT_NAME_THEME]: changeBackground,
  3540. [INPUT_NAME_ThEME_LIGHT]: changeBackground,
  3541. [INPUT_NAME_THEME_DARK]: changeBackground,
  3542. colorText1: changeBackground,
  3543. suspensionHomeTab: () => {
  3544. myVersion.change();
  3545. changeSuspensionTab();
  3546. },
  3547. suspensionFind: cacheHeader,
  3548. suspensionSearch: cacheHeader,
  3549. suspensionUser: cacheHeader,
  3550. titleIco: changeICO,
  3551. showGIFinDialog: previewGIF,
  3552. questionCreatedAndModifiedTime: addQuestionTime,
  3553. highlightOriginal: myListenListItem.restart,
  3554. listOutPutNotInterested: myListenListItem.restart,
  3555. articleCreateTimeToTop: addArticleTime,
  3556. versionHomeIsPercent: rangeChoosePercent,
  3557. versionAnswerIsPercent: rangeChoosePercent,
  3558. versionArticleIsPercent: rangeChoosePercent,
  3559. zoomImageType: () => {
  3560. myVersion.change();
  3561. initImagePreview();
  3562. },
  3563. globalTitleRemoveMessage: changeTitle
  3564. };
  3565. await myStorage.setConfigItem(name, type === "checkbox" ? checked : value);
  3566. const nodeName = domById(name);
  3567. type === "range" && nodeName && (nodeName.innerText = value);
  3568. if (/^hidden/.test(name)) {
  3569. myHidden.init();
  3570. return;
  3571. }
  3572. if (doCssVersion.includes(name)) {
  3573. myVersion.change();
  3574. return;
  3575. }
  3576. ob[name] && ob[name]();
  3577. };
  3578. var onInitStyleExtra = () => {
  3579. myHidden.init();
  3580. myBackground.init();
  3581. myVersion.init();
  3582. loadFindTheme();
  3583. };
  3584. var initOperate = () => {
  3585. const nodeContent = dom(".ctz-content");
  3586. nodeContent.onclick = (e2) => {
  3587. const target = e2.target;
  3588. if (target.classList.contains(CLASS_INPUT_CLICK)) {
  3589. fnChanger(target);
  3590. }
  3591. if (target.classList.contains("ctz-button")) {
  3592. myButtonOperation[target.name] && myButtonOperation[target.name]();
  3593. }
  3594. };
  3595. nodeContent.onchange = (e2) => {
  3596. const target = e2.target;
  3597. if (target.classList.contains(CLASS_INPUT_CHANGE)) {
  3598. fnChanger(target);
  3599. return;
  3600. }
  3601. if (target.classList.contains("ctz-input-config-import")) {
  3602. configImport(e2);
  3603. return;
  3604. }
  3605. };
  3606. dom(".ctz-menu-top").onclick = myMenu.click;
  3607. domA(".ctz-preview").forEach((item) => {
  3608. item.onclick = function() {
  3609. myPreview.hide(this);
  3610. };
  3611. });
  3612. domA('[name="button_history_clear"]').forEach((item) => {
  3613. item.onclick = async (event) => {
  3614. const prevHistory = await myStorage.getHistory();
  3615. const target = event.target;
  3616. const dataId = target.getAttribute("data-id");
  3617. const isClear = confirm(`是否清空${target.innerText}`);
  3618. if (!isClear)
  3619. return;
  3620. prevHistory[dataId] = [];
  3621. await myStorage.setHistory(prevHistory);
  3622. echoHistory();
  3623. };
  3624. });
  3625. const nodeOpenButton = domById("CTZ_OPEN_BUTTON");
  3626. const nodeCloseDialog = domById("CTZ_CLOSE_DIALOG");
  3627. nodeOpenButton && (nodeOpenButton.onclick = myDialog.open);
  3628. nodeCloseDialog && (nodeCloseDialog.onclick = myDialog.hide);
  3629. initTopStoryRecommendEvent();
  3630. initRootEvent();
  3631. };
  3632. var myButtonOperation = {
  3633. /** 导出配置 */
  3634. configExport: async () => {
  3635. const config = await myStorage.get("pfConfig") || "{}";
  3636. const link = domC("a", {
  3637. href: "data:text/csv;charset=utf-8,\uFEFF" + encodeURIComponent(config),
  3638. download: `知乎编辑器配置-${+/* @__PURE__ */ new Date()}.txt`
  3639. });
  3640. document.body.appendChild(link);
  3641. link.click();
  3642. document.body.removeChild(link);
  3643. },
  3644. configReset: async function() {
  3645. const isUse = confirm("是否启恢复默认配置?\n该功能会覆盖当前配置,建议先将配置导出保存");
  3646. if (!isUse)
  3647. return;
  3648. const { filterKeywords = [], removeBlockUserContentList = [] } = await myStorage.getConfig();
  3649. await myStorage.setConfig({
  3650. ...CONFIG_DEFAULT,
  3651. filterKeywords,
  3652. removeBlockUserContentList
  3653. });
  3654. resetData();
  3655. },
  3656. /** 自定义样式 */
  3657. styleCustom: async function() {
  3658. const nodeText = dom('[name="textStyleCustom"]');
  3659. const value = nodeText ? nodeText.value : "";
  3660. await myStorage.setConfigItem("customizeCss", value);
  3661. myCustomStyle.change(value);
  3662. },
  3663. syncBlack: () => myBlack.sync(0),
  3664. /** 确认更改网页标题 */
  3665. buttonConfirmTitle: async function() {
  3666. const nodeTitle = dom('[name="globalTitle"]');
  3667. await myStorage.setConfigItem("globalTitle", nodeTitle ? nodeTitle.value : "");
  3668. changeTitle();
  3669. message("网页标题修改成功");
  3670. },
  3671. /** 还原网页标题 */
  3672. buttonResetTitle: async function() {
  3673. const { getStorageConfigItem } = store;
  3674. const nodeTitle = dom('[name="globalTitle"]');
  3675. nodeTitle && (nodeTitle.value = getStorageConfigItem("cacheTitle"));
  3676. await myStorage.setConfigItem("globalTitle", "");
  3677. changeTitle();
  3678. message("网页标题已还原");
  3679. },
  3680. configImport: () => {
  3681. dom("#IMPORT_BY_FILE input").click();
  3682. }
  3683. };
  3684. var configImport = (e2) => {
  3685. const target = e2.target;
  3686. const configFile = (target.files || [])[0];
  3687. if (!configFile)
  3688. return;
  3689. const reader = new FileReader();
  3690. reader.readAsText(configFile);
  3691. reader.onload = async (oFREvent) => {
  3692. let config = oFREvent.target ? oFREvent.target.result : "";
  3693. if (typeof config === "string") {
  3694. const nConfig = JSON.parse(config);
  3695. await myStorage.setConfig(nConfig);
  3696. resetData();
  3697. }
  3698. };
  3699. target.value = "";
  3700. };
  3701. var resetData = () => {
  3702. onInitStyleExtra();
  3703. initData();
  3704. onUseThemeDark();
  3705. };
  3706. var needRedirect = () => {
  3707. const { pathname, origin } = location;
  3708. const phoneQuestion = "/tardis/sogou/qus/";
  3709. const phoneArt = "/tardis/zm/art/";
  3710. if (pathname.includes(phoneQuestion)) {
  3711. const questionId = pathname.replace(phoneQuestion, "");
  3712. location.href = origin + "/question/" + questionId;
  3713. return true;
  3714. }
  3715. if (pathname.includes(phoneArt)) {
  3716. const questionId = pathname.replace(phoneArt, "");
  3717. location.href = "https://zhuanlan.zhihu.com/p/" + questionId;
  3718. return true;
  3719. }
  3720. return false;
  3721. };
  3722. var myCtzTypeOperation = {
  3723. init: function() {
  3724. const params = new URLSearchParams(location.search);
  3725. let ctzType = params.get("ctzType");
  3726. this[ctzType] && this[ctzType]();
  3727. },
  3728. /** 移除、关注问题并关闭网页 */
  3729. "1": function() {
  3730. const domQuestion = dom(".QuestionPage");
  3731. if (domQuestion && domQuestion.getAttribute("data-za-extra-module")) {
  3732. this.clickAndClose(".QuestionButtonGroup button");
  3733. } else {
  3734. setTimeout(() => {
  3735. this["1"]();
  3736. }, 500);
  3737. }
  3738. },
  3739. /** 移除、关注话题并关闭网页 */
  3740. "2": function() {
  3741. this.clickAndClose(".TopicActions .FollowButton");
  3742. },
  3743. /** 移除、关注收藏夹并关闭网页 */
  3744. "3": function() {
  3745. const domQuestion = dom(".CollectionsDetailPage");
  3746. if (domQuestion && domQuestion.getAttribute("data-za-extra-module")) {
  3747. this.clickAndClose(".CollectionDetailPageHeader-actions .FollowButton");
  3748. } else {
  3749. setTimeout(() => {
  3750. this["3"]();
  3751. }, 500);
  3752. }
  3753. },
  3754. clickAndClose: function(eventname) {
  3755. const nodeItem = dom(eventname);
  3756. if (nodeItem) {
  3757. nodeItem.click();
  3758. setTimeout(() => {
  3759. window.close();
  3760. }, 300);
  3761. }
  3762. }
  3763. };
  3764. var myFollowRemove = {
  3765. init: function() {
  3766. clearTimeout(this.timer);
  3767. this.timer = setTimeout(() => {
  3768. pathnameHasFn({
  3769. questions: () => this.addButtons(this.classOb.questions),
  3770. // topics: () => this.addButtons(this.classOb.topics), // 话题跳转页面内会重定向,暂时隐藏
  3771. collections: () => this.addButtons(this.classOb.collections)
  3772. });
  3773. }, 500);
  3774. },
  3775. addButtons: function(initTypeOb) {
  3776. const me = this;
  3777. const { classNameItem, classHref, ctzType } = initTypeOb;
  3778. if (dom(`div.PlaceHolder.${classNameItem}`)) {
  3779. this.init();
  3780. return;
  3781. }
  3782. domA(`.${classNameItem}`).forEach((item) => {
  3783. const elementButton = domC("button", {
  3784. className: `${me.className} ${me.classNameRemove} ctz-button-block ctz-button`,
  3785. innerText: "移除关注",
  3786. style: "position: absolute;right: 16px;bottom: 16px;background: transparent;"
  3787. });
  3788. elementButton.onclick = function() {
  3789. const nodeThis = this;
  3790. const nItem = domP(nodeThis, "class", classNameItem);
  3791. const nodeHref = nItem ? nItem.querySelector(classHref) : void 0;
  3792. const qHref = nodeHref ? nodeHref.href : "";
  3793. if (!qHref)
  3794. return;
  3795. const nHref = qHref + `?ctzType=${ctzType}`;
  3796. window.open(nHref);
  3797. if (nodeThis.classList.contains(me.classNameRemove)) {
  3798. nodeThis.innerText = "添加关注";
  3799. nodeThis.classList.remove(me.classNameRemove);
  3800. } else {
  3801. nodeThis.innerText = "移除关注";
  3802. nodeThis.classList.add(me.classNameRemove);
  3803. }
  3804. };
  3805. const nodeClassName = item.querySelector(`.${me.className}`);
  3806. nodeClassName && nodeClassName.remove();
  3807. item.appendChild(elementButton);
  3808. });
  3809. },
  3810. className: "ctz-remove-follow",
  3811. classNameRemove: "ctz-button-red",
  3812. classOb: {
  3813. questions: {
  3814. // 关注的问题
  3815. classNameItem: "List-item",
  3816. classHref: ".QuestionItem-title a",
  3817. ctzType: 1
  3818. },
  3819. topics: {
  3820. // 关注的话题
  3821. classNameItem: "List-item",
  3822. classHref: ".ContentItem-title .TopicLink",
  3823. ctzType: 2
  3824. },
  3825. collections: {
  3826. // 关注的收藏夹
  3827. classNameItem: "List-item",
  3828. classHref: ".ContentItem-title a",
  3829. ctzType: 3
  3830. }
  3831. },
  3832. timer: void 0
  3833. };
  3834. var myPageFilterSetting = {
  3835. timeout: void 0,
  3836. init: function() {
  3837. clearTimeout(this.timeout);
  3838. if (/\/settings\/filter/.test(location.pathname)) {
  3839. this.timeout = setTimeout(() => {
  3840. this.addHTML();
  3841. this.init();
  3842. }, 500);
  3843. }
  3844. },
  3845. addHTML: () => {
  3846. const nButton = domC("button", {
  3847. className: "ctz-button",
  3848. style: "margin-left: 12px;",
  3849. innerHTML: "移除当前页所有屏蔽话题"
  3850. });
  3851. nButton.onclick = () => {
  3852. domA(".Tag button").forEach((item) => item.click());
  3853. };
  3854. domA(".css-j2uawy").forEach((item) => {
  3855. if (/已屏蔽话题/.test(item.innerText) && !item.querySelector(".ctz-button")) {
  3856. item.appendChild(nButton);
  3857. }
  3858. });
  3859. }
  3860. };
  3861. var timer = void 0;
  3862. var userHomeAnswers = async () => {
  3863. const { userHomeContentTimeTop } = await myStorage.getConfig();
  3864. if (!userHomeContentTimeTop)
  3865. return;
  3866. const doContent = (domList) => {
  3867. for (let i2 = 0, len = domList.length; i2 < len; i2++) {
  3868. const nodeItem = domList[i2];
  3869. const nodeTitle = nodeItem.querySelector(".ContentItem-title");
  3870. if (!nodeTitle || nodeItem.querySelector(`.${CLASS_TIME_ITEM}`))
  3871. continue;
  3872. const nodeDateCreate = nodeItem.querySelector('[itemprop="dateCreated"]');
  3873. const nodeDatePublished = nodeItem.querySelector('[itemprop="datePublished"]');
  3874. const nodeDateModified = nodeItem.querySelector('[itemprop="dateModified"]');
  3875. let innerHTML = "";
  3876. if (nodeDateCreate) {
  3877. const dateCreate = nodeDateCreate.getAttribute("content") || "";
  3878. const dateCreateFormatter = formatTime(dateCreate);
  3879. innerHTML += `<div>创建时间:${dateCreateFormatter}</div>`;
  3880. }
  3881. if (nodeDatePublished) {
  3882. const datePublished = nodeDatePublished.getAttribute("content") || "";
  3883. const datePublishedFormatter = formatTime(datePublished);
  3884. innerHTML += `<div>发布时间:${datePublishedFormatter}</div>`;
  3885. }
  3886. if (nodeDateModified) {
  3887. const dateModified = nodeDateModified.getAttribute("content") || "";
  3888. const dateModifiedFormatter = formatTime(dateModified);
  3889. innerHTML += `<div>最后修改时间:${dateModifiedFormatter}</div>`;
  3890. }
  3891. insertAfter(
  3892. domC("div", {
  3893. className: CLASS_TIME_ITEM,
  3894. innerHTML,
  3895. style: "line-height: 24px;padding-top: 2px;font-size: 14px;"
  3896. }),
  3897. nodeTitle
  3898. );
  3899. }
  3900. };
  3901. timer && clearTimeout(timer);
  3902. timer = setTimeout(() => {
  3903. const domPlaceHolder = dom(".List-item.PlaceHolder");
  3904. const domList = domA(".List-item:not(.PlaceHolder)");
  3905. !domPlaceHolder ? doContent(domList) : userHomeAnswers();
  3906. }, 500);
  3907. };
  3908. var CLASS_TOP_BLOCK = "ctz-top-block-in-user-home";
  3909. var blockObserver;
  3910. var topBlockUser = async () => {
  3911. const { userHomeTopBlockUser } = await myStorage.getConfig();
  3912. const nodeUserHeaderOperate = dom(".ProfileHeader-contentFooter .MemberButtonGroup");
  3913. const nodeFooterOperations = dom(".Profile-footerOperations");
  3914. if (!nodeUserHeaderOperate || !userHomeTopBlockUser || !nodeFooterOperations)
  3915. return;
  3916. const isMe = nodeUserHeaderOperate.innerText.includes("编辑个人资料");
  3917. if (isMe)
  3918. return;
  3919. const isBlocked = nodeUserHeaderOperate.innerText.includes("已屏蔽");
  3920. const domFind = dom(`.${CLASS_TOP_BLOCK}`);
  3921. domFind && domFind.remove();
  3922. const nDomButton = domC("button", {
  3923. className: `Button Button--primary Button--red ${CLASS_TOP_BLOCK}`,
  3924. innerText: isBlocked ? "解除屏蔽" : "屏蔽用户"
  3925. });
  3926. const domUnblock = nodeUserHeaderOperate.firstChild;
  3927. const domBlock = nodeFooterOperations.firstChild;
  3928. nDomButton.onclick = function() {
  3929. isBlocked ? domUnblock.click() : domBlock.click();
  3930. };
  3931. nodeUserHeaderOperate.insertBefore(nDomButton, domUnblock);
  3932. blockObserver = new MutationObserver(() => {
  3933. topBlockUser();
  3934. });
  3935. blockObserver.observe(nodeFooterOperations, {
  3936. attributes: false,
  3937. childList: true,
  3938. characterData: false,
  3939. characterDataOldValue: false,
  3940. subtree: true
  3941. });
  3942. };
  3943. (function() {
  3944. if (needRedirect())
  3945. return;
  3946. GM_registerMenuCommand("⚙️ 设置", () => {
  3947. myDialog.open();
  3948. });
  3949. const T0 = performance.now();
  3950. const { hostname, href } = location;
  3951. const { setStorageConfigItem, getStorageConfigItem } = store;
  3952. let isHaveHeadWhenInit = true;
  3953. async function onDocumentStart() {
  3954. if (!HTML_HOOTS.includes(hostname) || window.frameElement)
  3955. return;
  3956. if (!document.head) {
  3957. fnLog("not find document.head, waiting for reload...");
  3958. isHaveHeadWhenInit = false;
  3959. return;
  3960. }
  3961. fixVideoAutoPlay();
  3962. fnInitDomStyle("CTZ_STYLE", INNER_CSS);
  3963. const config = await myStorage.getConfig();
  3964. await myStorage.getHistory();
  3965. initHistoryView();
  3966. onInitStyleExtra();
  3967. (() => {
  3968. if (/www\.zhihu\.com\/column/.test(href)) {
  3969. dom("html").classList.add("zhuanlan");
  3970. return;
  3971. }
  3972. dom("html").classList.add(EXTRA_CLASS_HTML[hostname]);
  3973. })();
  3974. const { fetchInterceptStatus } = config;
  3975. if (fetchInterceptStatus) {
  3976. fnLog("已开启 fetch 接口拦截");
  3977. const prevHeaders = getStorageConfigItem("fetchHeaders");
  3978. const originFetch = fetch;
  3979. const myWindow = isSafari ? window : unsafeWindow;
  3980. myWindow.fetch = (url, opt) => {
  3981. if (opt && opt.headers) {
  3982. setStorageConfigItem("fetchHeaders", {
  3983. ...prevHeaders,
  3984. ...opt.headers
  3985. });
  3986. }
  3987. return originFetch(url, opt);
  3988. };
  3989. }
  3990. }
  3991. onDocumentStart();
  3992. const timerLoadHead = () => {
  3993. setTimeout(() => {
  3994. if (!isHaveHeadWhenInit) {
  3995. document.head ? onDocumentStart() : timerLoadHead();
  3996. }
  3997. }, 100);
  3998. };
  3999. timerLoadHead();
  4000. const timerLoadBody = () => {
  4001. setTimeout(() => {
  4002. document.body ? createLoad() : timerLoadBody();
  4003. }, 100);
  4004. };
  4005. timerLoadBody();
  4006. const createLoad = async () => {
  4007. if (HTML_HOOTS.includes(hostname) && !window.frameElement) {
  4008. const { removeTopAD } = await myStorage.getConfig();
  4009. initHTML();
  4010. initOperate();
  4011. initData();
  4012. myBackground.init();
  4013. myVersion.initAfterLoad();
  4014. myCustomStyle.init();
  4015. initBlockWords();
  4016. initResizeObserver();
  4017. myCtzTypeOperation.init();
  4018. echoHistory();
  4019. dom('[name="useSimple"]').onclick = async function() {
  4020. const isUse = confirm("是否启用极简模式?\n该功能会覆盖当前配置,建议先将配置导出保存");
  4021. if (!isUse)
  4022. return;
  4023. const prevConfig = await myStorage.getConfig();
  4024. myStorage.setConfig({
  4025. ...prevConfig,
  4026. ...CONFIG_SIMPLE
  4027. });
  4028. onDocumentStart();
  4029. initData();
  4030. };
  4031. if (removeTopAD) {
  4032. setTimeout(() => {
  4033. mouseEventClick(dom("svg.css-1p094v5"));
  4034. }, 300);
  4035. }
  4036. }
  4037. historyToChangePathname();
  4038. if (hostname === "zhuanlan.zhihu.com") {
  4039. addArticleTime();
  4040. const nodeArticle = dom(".Post-content");
  4041. if (nodeArticle) {
  4042. printArticle(nodeArticle);
  4043. initVideoDownload(nodeArticle);
  4044. }
  4045. }
  4046. fnLog(`加载完毕, 加载时长: ${Math.floor((performance.now() - T0) / 10) / 100}s, 可使用 shift + . 或点击左侧眼睛按钮唤起修改器弹窗`);
  4047. };
  4048. const historyToChangePathname = () => {
  4049. pathnameHasFn({
  4050. question: () => {
  4051. addQuestionTime();
  4052. const nodeQuestionAnswer = dom(".QuestionAnswer-content");
  4053. nodeQuestionAnswer && fnJustNum(nodeQuestionAnswer);
  4054. initInviteOnce();
  4055. },
  4056. filter: () => myPageFilterSetting.init(),
  4057. collection: () => myCollectionExport.init(),
  4058. following: () => myFollowRemove.init(),
  4059. answers: () => {
  4060. throttle(printPeopleAnswer)();
  4061. userHomeAnswers();
  4062. },
  4063. posts: () => {
  4064. throttle(printPeopleArticles)();
  4065. userHomeAnswers();
  4066. },
  4067. people: topBlockUser
  4068. });
  4069. };
  4070. const changeHistory = () => {
  4071. historyToChangePathname();
  4072. myListenListItem.reset();
  4073. myListenSearchListItem.reset();
  4074. myListenAnswerItem.reset();
  4075. };
  4076. window.addEventListener("popstate", throttle(changeHistory));
  4077. window.addEventListener("pushState", throttle(changeHistory));
  4078. window.addEventListener("load", () => {
  4079. const nodeSignModal = dom(".signFlowModal");
  4080. const nodeSignClose = nodeSignModal && nodeSignModal.querySelector(".Modal-closeButton");
  4081. nodeSignClose && nodeSignClose.click();
  4082. if (hostname === "zhuanlan.zhihu.com") {
  4083. const nodeArticle = dom(".Post-content");
  4084. if (nodeArticle) {
  4085. initVideoDownload(nodeArticle);
  4086. }
  4087. }
  4088. pathnameHasFn({
  4089. zvideo: () => {
  4090. const domFind = dom(".ZVideo-mainColumn");
  4091. domFind && initVideoDownload(domFind);
  4092. }
  4093. });
  4094. });
  4095. window.addEventListener("keydown", async (event) => {
  4096. const { hotKey } = await myStorage.getConfig();
  4097. if (hotKey) {
  4098. if (event.key === ">" || event.key === "》") {
  4099. const nodeDialog = domById(ID_DIALOG);
  4100. nodeDialog && nodeDialog.style.display === "none" ? myDialog.open() : myDialog.hide();
  4101. }
  4102. }
  4103. if (event.key === "Escape") {
  4104. myDialog.hide();
  4105. }
  4106. keydownNextImage(event);
  4107. });
  4108. document.addEventListener("copy", function(event) {
  4109. let clipboardData = event.clipboardData || window.clipboardData;
  4110. if (!clipboardData)
  4111. return;
  4112. const selection = window.getSelection();
  4113. let text = selection ? selection.toString() : "";
  4114. if (text) {
  4115. event.preventDefault();
  4116. clipboardData.setData("text/plain", text);
  4117. }
  4118. });
  4119. window.addEventListener(
  4120. "scroll",
  4121. throttle(async () => {
  4122. const { suspensionPickUp } = await myStorage.getConfig();
  4123. if (suspensionPickUp) {
  4124. suspensionPackUp(domA(".List-item"));
  4125. suspensionPackUp(domA(".TopstoryItem"));
  4126. suspensionPackUp(domA(".AnswerCard"));
  4127. }
  4128. }, 100),
  4129. false
  4130. );
  4131. })();
  4132. })();