PageSourceSearch

https://agen233.top/js/main.js?v=3.0.19

js agen233.top collected 2026-10-06 16:21:26 UTC 31,976 bytes, 987 lines download raw bytes

1const sidebarFn = () => {
2  const $toggleMenu = document.getElementById("toggle-menu");
3  const $mobileSidebarMenus = document.getElementById("sidebar-menus");
4  const $menuMask = document.getElementById("menu-mask");
5  const $body = document.body;
6
7  const toggleMobileSidebar = (isOpen) => {
8    $body.style.overflow = isOpen ? "hidden" : "";
9    utils[isOpen ? "fadeIn" : "fadeOut"]($menuMask, 0.5);
10    $mobileSidebarMenus.classList.toggle("open", isOpen);
11  };
12
13  const closeMobileSidebar = () => {
14    if ($mobileSidebarMenus.classList.contains("open")) {
15      toggleMobileSidebar(false);
16    }
17  };
18
19  $toggleMenu.addEventListener("click", () => toggleMobileSidebar(true));
20  $menuMask.addEventListener("click", closeMobileSidebar);
21
22  window.addEventListener("resize", () => {
23    if (
24      utils.isHidden($toggleMenu) &&
25      $mobileSidebarMenus.classList.contains("open")
26    ) {
27      closeMobileSidebar();
28    }
29    sco.refreshWaterFall();
30  });
31};
32
33const scrollFn = () => {
34  const $rightside = document.getElementById("rightside");
35  const $header = document.getElementById("page-header");
36  let initTop = 0;
37
38  const updateHeaderAndRightside = (isDown, currentTop) => {
39    if (currentTop > 0) {
40      $header.classList.toggle("nav-visible", !isDown);
41      $header.classList.add("nav-fixed");
42      if ($rightside) {
43        $rightside.style.opacity = "0.8";
44        $rightside.style.transform = "translateX(-58px)";
45      }
46    } else {
47      $header.classList.remove("nav-fixed", "nav-visible");
48      if ($rightside) {
49        $rightside.style.opacity = "";
50        $rightside.style.transform = "";
51      }
52    }
53  };
54
55  const throttledScroll = utils.throttle(() => {
56    initThemeColor();
57    const currentTop = window.scrollY || document.documentElement.scrollTop;
58    const isDown = currentTop > initTop;
59    initTop = currentTop;
60    updateHeaderAndRightside(isDown, currentTop);
61  }, 200);
62
63  window.addEventListener("scroll", (e) => {
64    throttledScroll(e);
65    if (window.scrollY === 0) {
66      $header.classList.remove("nav-fixed", "nav-visible");
67      if ($rightside) {
68        $rightside.style.cssText = "opacity: ''; transform: ''";
69      }
70    }
71  });
72};
73
74const percent = () => {
75  const docEl = document.documentElement;
76  const body = document.body;
77  const scrollPos = window.pageYOffset || docEl.scrollTop;
78  const totalScrollableHeight =
79    Math.max(
80      body.scrollHeight,
81      docEl.scrollHeight,
82      body.offsetHeight,
83      docEl.offsetHeight,
84      body.clientHeight,
85      docEl.clientHeight
86    ) - docEl.clientHeight;
87  const scrolledPercent = Math.round((scrollPos / totalScrollableHeight) * 100);
88  const navToTop = document.querySelector("#nav-totop");
89  const rsToTop = document.querySelector(".rs_show .top i");
90  const percentDisplay = document.querySelector("#percent");
91  const isNearEnd =
92    window.scrollY + docEl.clientHeight >=
93    (
94      document.getElementById("post-comment") ||
95      document.getElementById("footer")
96    ).offsetTop;
97
98  navToTop?.classList.toggle("long", isNearEnd || scrolledPercent > 90);
99  rsToTop?.classList.toggle("show", isNearEnd || scrolledPercent > 90);
100  percentDisplay.textContent =
101    isNearEnd || scrolledPercent > 90
102      ? navToTop
103        ? GLOBAL_CONFIG.lang.backtop
104        : ""
105      : scrolledPercent;
106
107  document
108    .querySelectorAll(".needEndHide")
109    .forEach((item) =>
110      item.classList.toggle("hide", totalScrollableHeight - scrollPos < 100)
111    );
112};
113
114const showTodayCard = () => {
115  const el = document.getElementById("todayCard");
116  const topGroup = document.querySelector(".topGroup");
117  topGroup?.addEventListener("mouseleave", () => el?.classList.remove("hide"));
118};
119
120const initObserver = () => {
121  const commentElement = document.getElementById("post-comment");
122  const paginationElement = document.getElementById("pagination");
123  const commentBarrageElement = document.querySelector(".comment-barrage");
124
125  if (commentElement && paginationElement) {
126    const observer = new IntersectionObserver((entries) => {
127      entries.forEach((entry) => {
128        paginationElement.classList.toggle("show-window", entry.isIntersecting);
129        if (GLOBAL_CONFIG.comment.commentBarrage) {
130          commentBarrageElement.style.bottom = entry.isIntersecting
131            ? "-200px"
132            : "0px";
133        }
134      });
135    });
136    observer.observe(commentElement);
137  }
138};
139
140const addCopyright = () => {
141  if (!GLOBAL_CONFIG.copyright) return;
142  const { limit, author, link, source, info } = GLOBAL_CONFIG.copyright;
143
144  document.body.addEventListener("copy", (e) => {
145    e.preventDefault();
146    const copyText = window.getSelection().toString();
147    const text =
148      copyText.length > limit
149        ? `${copyText}\n\n${author}\n${link}${window.location.href}\n${source}\n${info}`
150        : copyText;
151    e.clipboardData.setData("text", text);
152  });
153};
154
155const asideStatus = () => {
156  const status = utils.saveToLocal.get("aside-status");
157  document.documentElement.classList.toggle("hide-aside", status === "hide");
158};
159
160function initThemeColor() {
161  const currentTop = window.scrollY || document.documentElement.scrollTop;
162  const themeColor =
163    currentTop > 0
164      ? "--efu-card-bg"
165      : PAGE_CONFIG.is_post
166      ? "--efu-main"
167      : "--efu-background";
168  applyThemeColor(
169    getComputedStyle(document.documentElement).getPropertyValue(themeColor)
170  );
171}
172
173function applyThemeColor(color) {
174  const themeColorMeta = document.querySelector('meta[name="theme-color"]');
175  const appleMobileWebAppMeta = document.querySelector(
176    'meta[name="apple-mobile-web-app-status-bar-style"]'
177  );
178  themeColorMeta?.setAttribute("content", color);
179  appleMobileWebAppMeta?.setAttribute("content", color);
180  if (window.matchMedia("(display-mode: standalone)").matches) {
181    document.body.style.backgroundColor = color;
182  }
183}
184
185const handleThemeChange = (mode) => {
186  const themeChange = window.globalFn?.themeChange || {};
187  Object.values(themeChange).forEach((fn) => fn(mode));
188};
189
190const sco = {
191  lastWittyWord: "",
192  wasPageHidden: false,
193  musicPlaying: false,
194  scrollTo(elementId) {
195    const targetElement = document.getElementById(elementId);
196    if (targetElement) {
197      const targetPosition =
198        targetElement.getBoundingClientRect().top + window.pageYOffset - 80;
199      window.scroll({ top: targetPosition, behavior: "smooth" });
200    }
201  },
202  musicToggle(isMeting = true) {
203    if (!this.isMusicBind) {
204      this.musicBind();
205    }
206    const $music = document.querySelector("#nav-music");
207    const $meting = document.querySelector("meting-js");
208    const $console = document.getElementById("consoleMusic");
209    const $rmText = document.querySelector("#menu-music-toggle span");
210    const $rmIcon = document.querySelector("#menu-music-toggle i");
211
212    this.musicPlaying = !this.musicPlaying;
213    $music.classList.toggle("playing", this.musicPlaying);
214    $music.classList.toggle("stretch", this.musicPlaying);
215    $console?.classList.toggle("on", this.musicPlaying);
216
217    if (typeof rm !== "undefined" && rm?.menuItems.music[0]) {
218      $rmText.textContent = this.musicPlaying
219        ? GLOBAL_CONFIG.right_menu.music.stop
220        : GLOBAL_CONFIG.right_menu.music.start;
221      $rmIcon.className = this.musicPlaying
222        ? "solitude fas fa-pause"
223        : "solitude fas fa-play";
224    }
225
226    if (isMeting) {
227      this.musicPlaying ? $meting.aplayer.play() : $meting.aplayer.pause();
228    }
229  },
230  musicBind() {
231    const $music = document.querySelector("#nav-music");
232    const $name = document.querySelector("#nav-music .aplayer-music");
233    const $button = document.querySelector("#nav-music .aplayer-button");
234
235    $name?.addEventListener("click", () => {
236      $music.classList.toggle("stretch");
237    });
238
239    $button?.addEventListener("click", () => {
240      this.musicToggle(false);
241    });
242
243    this.isMusicBind = true;
244  },
245  switchCommentBarrage() {
246    const commentBarrageElement = document.querySelector(".comment-barrage");
247    const consoleCommentBarrage = document.querySelector(
248      "#consoleCommentBarrage"
249    );
250    if (!commentBarrageElement) return;
251
252    const isDisplayed =
253      window.getComputedStyle(commentBarrageElement).display === "flex";
254    commentBarrageElement.style.display = isDisplayed ? "none" : "flex";
255    consoleCommentBarrage?.classList.toggle("on", !isDisplayed);
256    utils.saveToLocal.set("commentBarrageSwitch", !isDisplayed, 0.2);
257    rm?.menuItems.barrage && rm.barrage(isDisplayed);
258  },
259  switchHideAside() {
260    const htmlClassList = document.documentElement.classList;
261    const consoleHideAside = document.querySelector("#consoleHideAside");
262    const isHideAside = htmlClassList.contains("hide-aside");
263    utils.saveToLocal.set("aside-status", isHideAside ? "show" : "hide", 1);
264    htmlClassList.toggle("hide-aside");
265    consoleHideAside.classList.toggle("on", !isHideAside);
266  },
267  switchKeyboard() {
268    this.sco_keyboards = !this.sco_keyboards;
269    const consoleKeyboard = document.querySelector("#consoleKeyboard");
270    const keyboardFunction = this.sco_keyboards ? openKeyboard : closeKeyboard;
271    consoleKeyboard?.classList.toggle("on", this.sco_keyboards);
272    keyboardFunction();
273    localStorage.setItem("keyboard", this.sco_keyboards);
274    document.getElementById("keyboard-tips")?.classList.remove("show");
275  },
276  initConsoleState() {
277    const consoleHideAside = document.querySelector("#consoleHideAside");
278    if (!consoleHideAside) return;
279    consoleHideAside.classList.toggle(
280      "on",
281      document.documentElement.classList.contains("hide-aside")
282    );
283  },
284  changeWittyWord() {
285    const greetings = GLOBAL_CONFIG.aside.witty_words;
286    const greetingElement = document.getElementById("sayhi");
287    let randomGreeting;
288    do {
289      randomGreeting = greetings[Math.floor(Math.random() * greetings.length)];
290    } while (randomGreeting === this.lastWittyWord);
291    greetingElement.textContent = randomGreeting;
292    this.lastWittyWord = randomGreeting;
293  },
294  switchDarkMode() {
295    const isDarkMode =
296      document.documentElement.getAttribute("data-theme") === "dark";
297    const newMode = isDarkMode ? "light" : "dark";
298    document.documentElement.setAttribute("data-theme", newMode);
299    utils.saveToLocal.set("theme", newMode, 0.02);
300    utils.snackbarShow(GLOBAL_CONFIG.lang.theme[newMode], false, 2000);
301    if (typeof rm === "object") rm.mode(!isDarkMode) && rm.hideRightMenu();
302    handleThemeChange(newMode);
303  },
304  hideTodayCard: () =>
305    document.getElementById("todayCard").classList.add("hide"),
306  toTop: () => utils.scrollToDest(0),
307  showConsole: () =>
308    document.getElementById("console")?.classList.toggle("show", true),
309  hideConsole: () =>
310    document.getElementById("console")?.classList.remove("show"),
311  refreshWaterFall() {
312    const observer = new IntersectionObserver((entries) => {
313      entries.forEach((entry) => {
314        if (entry.isIntersecting) {
315          setTimeout(() => {
316            waterfall(entry.target).then(() => {
317              entry.target.classList.add("show");
318            });
319          }, 300);
320        }
321      });
322    });
323    document
324      .querySelectorAll(".waterfall")
325      .forEach((el) => observer.observe(el));
326  },
327  addRuntime() {
328    const el = document.getElementById("runtimeshow");
329    if (el && GLOBAL_CONFIG.runtime) {
330      el.innerText =
331        utils.timeDiff(new Date(GLOBAL_CONFIG.runtime), new Date()) +
332        GLOBAL_CONFIG.lang.day;
333    }
334  },
335  toTalk(txt) {
336    const inputs = [
337      "#wl-edit",
338      ".el-textarea__inner",
339      "#veditor",
340      ".atk-textarea",
341    ];
342    inputs.forEach((selector) => {
343      const el = document.querySelector(selector);
344      if (el) {
345        el.dispatchEvent(
346          new Event("input", { bubble: true, cancelable: true })
347        );
348        el.value = "> " + txt.replace(/\n/g, "\n> ") + "\n\n";
349        utils.scrollToDest(
350          utils.getEleTop(document.getElementById("post-comment")),
351          300
352        );
353        el.focus();
354        el.setSelectionRange(-1, -1);
355      }
356    });
357    utils.snackbarShow(GLOBAL_CONFIG.lang.totalk, false, 2000);
358  },
359  initbbtalk() {
360    const bberTalkElement = document.querySelector("#bber-talk");
361    if (bberTalkElement) {
362      new Swiper(".swiper-container", {
363        direction: "vertical",
364        loop: true,
365        autoplay: {
366          delay: 3000,
367          pauseOnMouseEnter: true,
368        },
369      });
370    }
371  },
372  addPhotoFigcaption() {
373    document
374      .querySelectorAll(".article-container img:not(.gallery-item img)")
375      .forEach((image) => {
376        const captionText = image.getAttribute("alt");
377        if (captionText) {
378          image.insertAdjacentHTML(
379            "afterend",
380            `<div class="img-alt is-center">${utils.escapeHtml(
381              captionText
382            )}</div>`
383          );
384        }
385      });
386  },
387  scrollToComment: () =>
388    utils.scrollToDest(
389      utils.getEleTop(document.getElementById("post-comment")),
390      300
391    ),
392  setTimeState() {
393    const el = document.getElementById("sayhi");
394    if (el) {
395      const hours = new Date().getHours();
396      const lang = GLOBAL_CONFIG.aside.state;
397
398      const localData = getLocalData([
399        "twikoo",
400        "WALINE_USER_META",
401        "WALINE_USER",
402        "_v_Cache_Meta",
403        "ArtalkUser",
404      ]);
405
406      function getLocalData(keys) {
407        for (let key of keys) {
408          const data = localStorage.getItem(key);
409          if (data) {
410            return JSON.parse(data);
411          }
412        }
413        return null;
414      }
415      const nick = localData ? localData.nick || localData.display_name : null;
416
417      const prefix = this.wasPageHidden
418        ? GLOBAL_CONFIG.aside.witty_comment.back + nick
419        : GLOBAL_CONFIG.aside.witty_comment.prefix + nick;
420
421      const greetings = [
422        { start: 0, end: 5, text: nick ? prefix : lang.goodnight },
423        { start: 6, end: 10, text: nick ? prefix : lang.morning },
424        { start: 11, end: 14, text: nick ? prefix : lang.noon },
425        { start: 15, end: 18, text: nick ? prefix : lang.afternoon },
426        { start: 19, end: 24, text: nick ? prefix : lang.night },
427      ];
428      const greeting = greetings.find(
429        (g) => hours >= g.start && hours <= g.end
430      );
431      el.innerText = greeting.text;
432    }
433  },
434  tagPageActive() {
435    const decodedPath = decodeURIComponent(window.location.pathname);
436    const isTagPage = /\/tags\/.*?\//.test(decodedPath);
437    if (isTagPage) {
438      const tag = decodedPath.split("/").slice(-2, -1)[0];
439      const tagElement = document.getElementById(tag);
440      if (tagElement) {
441        document.querySelectorAll("a.select").forEach((link) => {
442          link.classList.remove("select");
443        });
444        tagElement.classList.add("select");
445      }
446    }
447  },
448  categoriesBarActive() {
449    const categoryBar = document.querySelector("#category-bar");
450    const currentPath = decodeURIComponent(window.location.pathname);
451    const isHomePage = currentPath === GLOBAL_CONFIG.root;
452    if (categoryBar) {
453      const categoryItems = categoryBar.querySelectorAll(".category-bar-item");
454      categoryItems.forEach((item) => item.classList.remove("select"));
455      const activeItemId = isHomePage
456        ? "category-bar-home"
457        : currentPath.split("/").slice(-2, -1)[0];
458      const activeItem = document.getElementById(activeItemId);
459      if (activeItem) {
460        activeItem.classList.add("select");
461      }
462    }
463  },
464  scrollCategoryBarToRight() {
465    const scrollBar = document.getElementById("category-bar-items");
466    const nextElement = document.getElementById("category-bar-next");
467    if (scrollBar) {
468      const isScrollBarAtEnd = () =>
469        scrollBar.scrollLeft + scrollBar.clientWidth >=
470        scrollBar.scrollWidth - 8;
471      const scroll = () => {
472        scrollBar.scroll({
473          left: isScrollBarAtEnd() ? 0 : scrollBar.clientWidth,
474          behavior: "smooth",
475        });
476      };
477      scrollBar.addEventListener("scroll", () => {
478        clearTimeout(this.timeoutId);
479        this.timeoutId = setTimeout(() => {
480          nextElement.style.transform = isScrollBarAtEnd()
481            ? "rotate(180deg)"
482            : "";
483        }, 150);
484      });
485      scroll();
486    }
487  },
488  openAllTags() {
489    document
490      .querySelectorAll(".card-allinfo .card-tag-cloud")
491      .forEach((tagCloudElement) => tagCloudElement.classList.add("all-tags"));
492    document.getElementById("more-tags-btn")?.remove();
493  },
494  listenToPageInputPress() {
495    const toGroup = document.querySelector(".toPageGroup");
496    const pageText = document.getElementById("toPageText");
497    if (!pageText) return;
498    const pageButton = document.getElementById("toPageButton");
499    const pageNumbers = document.querySelectorAll(".page-number");
500    const lastPageNumber = +pageNumbers[pageNumbers.length - 1].textContent;
501    if (!pageText || lastPageNumber === 1) {
502      toGroup.style.display = "none";
503      return;
504    }
505    pageText.addEventListener("keydown", (event) => {
506      if (event.key === "Enter") {
507        sco.toPage();
508        pjax.loadUrl(pageButton.href);
509      }
510    });
511    pageText.addEventListener("input", () => {
512      pageButton.classList.toggle(
513        "haveValue",
514        pageText.value !== "" && pageText.value !== "0"
515      );
516      if (+pageText.value > lastPageNumber) {
517        pageText.value = lastPageNumber;
518      }
519    });
520  },
521  addNavBackgroundInit() {
522    const scrollTop = document.documentElement.scrollTop;
523    if (scrollTop !== 0) {
524      document
525        .getElementById("page-header")
526        .classList.add("nav-fixed", "nav-visible");
527    }
528  },
529  toPage() {
530    const pageNumbers = document.querySelectorAll(".page-number");
531    const maxPageNumber = parseInt(
532      pageNumbers[pageNumbers.length - 1].innerHTML
533    );
534    const inputElement = document.getElementById("toPageText");
535    const inputPageNumber = parseInt(inputElement.value);
536    document.getElementById("toPageButton").href =
537      !isNaN(inputPageNumber) &&
538      inputPageNumber <= maxPageNumber &&
539      inputPageNumber > 1
540        ? window.location.href.replace(/\/page\/\d+\/$/, "/") +
541          "page/" +
542          inputPageNumber +
543          "/"
544        : "/";
545  },
546  owoBig(owoSelector) {
547    let owoBig = document.getElementById("owo-big");
548    if (!owoBig) {
549      owoBig = document.createElement("div");
550      owoBig.id = "owo-big";
551      document.body.appendChild(owoBig);
552    }
553    const showOwoBig = (event) => {
554      const target = event.target;
555      const owoItem = target.closest(owoSelector.item);
556      if (owoItem && target.closest(owoSelector.body)) {
557        const imgSrc = owoItem.querySelector("img")?.src;
558        if (imgSrc) {
559          owoBig.innerHTML = `<img src="${imgSrc}" style="max-width: 100%; height: auto;">`;
560          owoBig.style.display = "block";
561          positionOwoBig(owoItem);
562        }
563      }
564    };
565    const hideOwoBig = (event) => {
566      if (
567        event.target.closest(owoSelector.item) &&
568        event.target.closest(owoSelector.body)
569      ) {
570        owoBig.style.display = "none";
571      }
572    };
573    const positionOwoBig = (owoItem) => {
574      const itemRect = owoItem.getBoundingClientRect();
575      owoBig.style.left = `${itemRect.left - owoBig.offsetWidth / 4}px`;
576      owoBig.style.top = `${itemRect.top}px`;
577    };
578    document.addEventListener("mouseover", showOwoBig);
579    document.addEventListener("mouseout", hideOwoBig);
580  },
581  changeTimeFormat(selector) {
582    selector.forEach((item) => {
583      const timeVal = item.getAttribute("datetime");
584      item.textContent = utils.diffDate(timeVal, true);
585      item.style.display = "inline";
586    });
587  },
588  switchComments() {
589    const switchBtn = document.getElementById("switch-btn");
590    if (!switchBtn) return;
591    let switchDone = false;
592    const commentContainer = document.getElementById("post-comment");
593    const handleSwitchBtn = () => {
594      commentContainer.classList.toggle("move");
595      if (!switchDone && typeof loadTwoComment === "function") {
596        switchDone = true;
597        loadTwoComment();
598      }
599    };
600    utils.addEventListenerPjax(switchBtn, "click", handleSwitchBtn);
601  },
602  homeTypeit() {
603    if (typeof home_subtitle === "undefined") return;
604    const ty = new TypeIt(".banners-title-small", {
605      speed: 200,
606      waitUntilVisible: true,
607      loop: true,
608      lifeLike: true,
609    });
610    home_subtitle.forEach((item) => {
611      ty.type(item).pause(500).delete(item);
612    });
613    ty.go();
614  },
615};
616
617const addHighlight = () => {
618  const highlight = GLOBAL_CONFIG.highlight;
619  if (!highlight) return;
620  const { copy, expand, limit, syntax } = highlight;
621  const $isPrismjs = syntax === "prismjs";
622  const $isShowTool = highlight.enable || copy || expand || limit;
623  const expandClass = expand ? "" : "closed";
624  const $syntaxHighlight =
625    syntax === "highlight.js"
626      ? document.querySelectorAll("figure.highlight")
627      : document.querySelectorAll('pre[class*="language-"]');
628
629  if (!(($isShowTool || limit) && $syntaxHighlight.length)) return;
630
631  const copyEle = copy
632    ? `<i class="solitude fas fa-copy copy-button"></i>`
633    : "<i></i>";
634  const expandEle = `<i class="solitude fas fa-angle-down expand"></i>`;
635  const limitEle = limit
636    ? `<i class="solitude fas fa-angles-down"></i>`
637    : "<i></i>";
638
639  const alertInfo = (ele, text) => utils.snackbarShow(text, false, 2000);
640
641  const copyFn = (e) => {
642    const $buttonParent = e.parentNode;
643    $buttonParent.classList.add("copy-true");
644    const selection = window.getSelection();
645    const range = document.createRange();
646    const preCodeSelector = $isPrismjs ? "pre code" : "table .code pre";
647    range.selectNodeContents(
648      $buttonParent.querySelectorAll(`${preCodeSelector}`)[0]
649    );
650    selection.removeAllRanges();
651    selection.addRange(range);
652    document.execCommand("copy");
653    alertInfo(e.lastChild, GLOBAL_CONFIG.lang.copy.success);
654    selection.removeAllRanges();
655    $buttonParent.classList.remove("copy-true");
656  };
657
658  const expandClose = (e) => e.classList.toggle("closed");
659  const shrinkEle = function () {
660    this.classList.toggle("expand-done");
661  };
662
663  const ToolsFn = function (e) {
664    const $target = e.target.classList;
665    if ($target.contains("expand")) expandClose(this);
666    else if ($target.contains("copy-button")) copyFn(this);
667  };
668
669  const createEle = (lang, item, service) => {
670    const fragment = document.createDocumentFragment();
671    if ($isShowTool) {
672      const captionItem = item.querySelector("figcaption");
673      let caption = "";
674      if (captionItem) {
675        caption = `<div class="caption">${captionItem.innerHTML}</div>`;
676        item.removeChild(captionItem);
677      }
678      const hlTools = document.createElement("div");
679      hlTools.className = `highlight-tools ${expandClass}`;
680      hlTools.innerHTML = expandEle + lang + caption + copyEle;
681      utils.addEventListenerPjax(hlTools, "click", ToolsFn);
682      fragment.appendChild(hlTools);
683    }
684    if (limit && item.offsetHeight > limit + 30) {
685      const ele = document.createElement("div");
686      ele.className = "code-expand-btn";
687      ele.innerHTML = limitEle;
688      utils.addEventListenerPjax(ele, "click", shrinkEle);
689      fragment.appendChild(ele);
690    }
691    if (service === "hl") {
692      item.insertBefore(fragment, item.firstChild);
693    } else {
694      item.parentNode.insertBefore(fragment, item);
695    }
696  };
697
698  if ($isPrismjs) {
699    $syntaxHighlight.forEach((item) => {
700      const langName = item.getAttribute("data-language") || "Code";
701      const highlightLangEle = `<div class="code-lang">${utils.escapeHtml(
702        langName
703      )}</div>`;
704      utils.wrap(item, "figure", { class: "highlight" });
705      createEle(highlightLangEle, item);
706    });
707  } else {
708    $syntaxHighlight.forEach((item) => {
709      let langName = item.getAttribute("class").split(" ")[1];
710      if (langName === "plain" || langName === undefined) langName = "Code";
711      const highlightLangEle = `<div class="code-lang">${utils.escapeHtml(
712        langName
713      )}</div>`;
714      createEle(highlightLangEle, item, "hl");
715    });
716  }
717};
718
719class toc {
720  static init() {
721    const tocContainer = document.getElementById("card-toc");
722    if (!tocContainer || !tocContainer.querySelector(".toc a")) {
723      tocContainer.style.display = "none";
724      return;
725    }
726    const el = document.querySelectorAll(".toc a");
727    el.forEach((e) => {
728      e.addEventListener("click", (event) => {
729        event.preventDefault();
730        utils.scrollToDest(
731          utils.getEleTop(
732            document.getElementById(
733              decodeURI(
734                (event.target.className === "toc-text"
735                  ? event.target.parentNode.hash
736                  : event.target.hash
737                ).replace("#", "")
738              )
739            )
740          ),
741          300
742        );
743      });
744    });
745    this.active(el);
746  }
747
748  static active(toc) {
749    const $article = document.querySelector(".article-container");
750    const $tocContent = document.getElementById("toc-content");
751    const list = $article.querySelectorAll("h1,h2,h3,h4,h5,h6");
752    let detectItem = "";
753
754    const autoScroll = (el) => {
755      const activePosition = el.getBoundingClientRect().top;
756      const sidebarScrollTop = $tocContent.scrollTop;
757      if (activePosition > document.documentElement.clientHeight - 100) {
758        $tocContent.scrollTop = sidebarScrollTop + 150;
759      }
760      if (activePosition < 100) {
761        $tocContent.scrollTop = sidebarScrollTop - 150;
762      }
763    };
764
765    const findHeadPosition = (top) => {
766      if (top === 0) return false;
767      let currentIndex = "";
768      list.forEach((ele, index) => {
769        if (top > utils.getEleTop(ele) - 80) {
770          currentIndex = index;
771        }
772      });
773      if (detectItem === currentIndex) return;
774      detectItem = currentIndex;
775      document.querySelectorAll(".toc .active").forEach((i) => {
776        i.classList.remove("active");
777      });
778      const activeitem = toc[detectItem];
779      if (activeitem) {
780        let parent = toc[detectItem].parentNode;
781        activeitem.classList.add("active");
782        autoScroll(activeitem);
783        for (; !parent.matches(".toc"); parent = parent.parentNode) {
784          if (parent.matches("li")) parent.classList.add("active");
785        }
786      }
787    };
788
789    window.tocScrollFn = utils.throttle(() => {
790      const currentTop = window.scrollY || document.documentElement.scrollTop;
791      findHeadPosition(currentTop);
792    }, 100);
793    window.addEventListener("scroll", tocScrollFn);
794  }
795}
796
797class tabs {
798  static init() {
799    this.clickFnOfTabs();
800  }
801
802  static clickFnOfTabs() {
803    document
804      .querySelectorAll(".article-container .tab > button")
805      .forEach((item) => {
806        item.addEventListener("click", function () {
807          const $tabItem = this.parentNode;
808          if (!$tabItem.classList.contains("active")) {
809            const $tabContent = $tabItem.parentNode.nextElementSibling;
810            const $siblings = utils.siblings($tabItem, ".active")[0];
811            $siblings && $siblings.classList.remove("active");
812            $tabItem.classList.add("active");
813            const tabId = this.getAttribute("data-href").replace("#", "");
814            [...$tabContent.children].forEach((item) => {
815              item.classList.toggle("active", item.id === tabId);
816            });
817          }
818        });
819      });
820  }
821
822  static lureAddListener() {
823    if (!GLOBAL_CONFIG.lure) return;
824    const title = document.title;
825    document.addEventListener("visibilitychange", () => {
826      const { lure } = GLOBAL_CONFIG;
827      document.title =
828        document.visibilityState === "hidden" ? lure.jump : lure.back;
829      if (document.visibilityState === "visible") {
830        setTimeout(() => {
831          document.title = title;
832        }, 2000);
833      }
834    });
835  }
836
837  static expireAddListener() {
838    const { expire } = GLOBAL_CONFIG;
839    if (!expire) return;
840    const list = document.querySelectorAll(".post-meta-date time");
841    const post_date = list.length
842      ? list[list.length - 1]
843      : document.querySelector(".datetime");
844    if (!post_date) return;
845    const ex = Math.ceil(
846      (new Date().getTime() -
847        new Date(post_date.getAttribute("datetime")).getTime()) /
848        1000 /
849        60 /
850        60 /
851        24
852    );
853    if (expire.time > ex) return;
854    const ele = document.createElement("div");
855    ele.className = "expire";
856    ele.innerHTML = `<i class="solitude fas fa-circle-exclamation"></i>${
857      expire.text_prev
858    }${-(expire.time - ex)}${expire.text_next}`;
859    const articleContainer = document.querySelector(".article-container");
860    articleContainer.insertAdjacentElement(
861      expire.position === "top" ? "afterbegin" : "beforeend",
862      ele
863    );
864  }
865}
866
867const scrollFnToDo = () => {
868  const { toc } = PAGE_CONFIG;
869
870  if (toc) {
871    const $cardTocLayout = document.getElementById("card-toc");
872    const $cardToc = $cardTocLayout.querySelector(".toc-content");
873    const $tocLink = $cardToc.querySelectorAll(".toc-link");
874    const $tocPercentage = $cardTocLayout.querySelector(".toc-percentage");
875    const isExpand = $cardToc.classList.contains("is-expand");
876
877    const tocItemClickFn = (e) => {
878      const target = e.target.closest(".toc-link");
879      if (!target) return;
880
881      e.preventDefault();
882      utils.scrollToDest(
883        utils.getEleTop(
884          document.getElementById(
885            decodeURI(target.getAttribute("href")).replace("#", "")
886          )
887        ),
888        300
889      );
890      if (window.innerWidth < 900) {
891        $cardTocLayout.classList.remove("open");
892      }
893    };
894    utils.addEventListenerPjax($cardToc, "click", tocItemClickFn);
895  }
896};
897
898const forPostFn = () => {
899  scrollFnToDo();
900};
901
902window.refreshFn = () => {
903  const { is_home, is_page, page, is_post, ai_text } = PAGE_CONFIG;
904  const { runtime, lazyload, lightbox, randomlink, covercolor, lure, expire } =
905    GLOBAL_CONFIG;
906  const timeSelector = ".datetime, .webinfo-item time, .post-meta-date time";
907  document.body.setAttribute("data-type", page);
908  sco.changeTimeFormat(document.querySelectorAll(timeSelector));
909  runtime && sco.addRuntime();
910  [
911    scrollFn,
912    sidebarFn,
913    sco.addPhotoFigcaption,
914    sco.setTimeState,
915    sco.tagPageActive,
916    sco.categoriesBarActive,
917    sco.listenToPageInputPress,
918    sco.addNavBackgroundInit,
919    sco.refreshWaterFall,
920  ].forEach((fn) => fn());
921  lazyload.enable && utils.lazyloadImg();
922  lightbox &&
923    utils.lightbox(
924      document.querySelectorAll(
925        ".article-container img:not(.flink-avatar,.gallery-group img, .no-lightbox)"
926      )
927    );
928  randomlink && randomLinksList();
929  if (is_post) {
930    if (ai_text) {
931      ai.init();
932    }
933  }
934  sco.switchComments();
935  initObserver();
936  if (is_home) {
937    showTodayCard();
938    sco.homeTypeit();
939  }
940  typeof updatePostsBasedOnComments === "function" &&
941    updatePostsBasedOnComments();
942  if (is_post || is_page) {
943    addHighlight();
944    tabs.init();
945  }
946  if (is_post && expire) {
947    tabs.expireAddListener();
948  }
949  if (covercolor.enable) coverColor();
950  if (PAGE_CONFIG.toc) toc.init();
951  if (lure) tabs.lureAddListener();
952  page === "music" && initializeMusicPlayer();
953  forPostFn();
954};
955
956document.addEventListener("DOMContentLoaded", () => {
957  [
958    addCopyright,
959    window.refreshFn,
960    asideStatus,
961    () => (window.onscroll = percent),
962    sco.initConsoleState,
963  ].forEach((fn) => fn());
964});
965
966document.addEventListener("visibilitychange", () => {
967  if (document.hidden) {
968    sco.wasPageHidden = true;
969  }
970});
971
972window.onkeydown = (e) => {
973  const { code, ctrlKey, shiftKey } = e;
974  if (
975    code === "F12" ||
976    (ctrlKey && shiftKey && (code === "KeyI" || code === "KeyC"))
977  ) {
978    utils.snackbarShow(GLOBAL_CONFIG.lang.f12, false, 3000);
979  }
980  if (code === "Escape") {
981    sco.hideConsole();
982  }
983};
984
985document.addEventListener("copy", () => {
986  utils.snackbarShow(GLOBAL_CONFIG.lang.copy.success, false, 3000);
987});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.