class Util { forEach(elements, handler) { elements = elements || []; for (let i = 0; i < elements.length; i++) handler(elements[i]); } getScrollTop() { return ( (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop ); } isMobile() { return window.matchMedia("only screen and (max-width: 680px)").matches; } isTocStatic() { return window.matchMedia("only screen and (max-width: 960px)").matches; } animateCSS(element, animation, reserved, callback) { if (!Array.isArray(animation)) animation = [animation]; element.classList.add("animated", ...animation); const handler = () => { element.classList.remove("animated", ...animation); element.removeEventListener("animationend", handler); if (typeof callback === "function") callback(); }; if (!reserved) element.addEventListener("animationend", handler, false); } } class Theme { constructor() { this.config = window.config; this.data = this.config.data; this.isDark = document.body.getAttribute("theme") === "dark"; this.util = new Util(); this.newScrollTop = this.util.getScrollTop(); this.oldScrollTop = this.newScrollTop; this.scrollEventSet = new Set(); this.resizeEventSet = new Set(); this.switchThemeEventSet = new Set(); this.clickMaskEventSet = new Set(); if (window.objectFitImages) objectFitImages(); } initSVGIcon() { this.util.forEach(document.querySelectorAll("[data-svg-src]"), ($icon) => { fetch($icon.getAttribute("data-svg-src")) .then((response) => response.text()) .then((svg) => { const $temp = document.createElement("div"); $temp.insertAdjacentHTML("afterbegin", svg); const $svg = $temp.firstChild; $svg.setAttribute("data-svg-src", $icon.getAttribute("data-svg-src")); $svg.classList.add("icon"); const $titleElements = $svg.getElementsByTagName("title"); if ($titleElements.length) $svg.removeChild($titleElements[0]); $icon.parentElement.replaceChild($svg, $icon); }) .catch((err) => { console.error(err); }); }); } initTwemoji() { if (this.config.twemoji) twemoji.parse(document.body); } initMenuMobile() { const $menuToggleMobile = document.getElementById("menu-toggle-mobile"); const $menuMobile = document.getElementById("menu-mobile"); $menuToggleMobile.addEventListener( "click", () => { document.body.classList.toggle("blur"); $menuToggleMobile.classList.toggle("active"); $menuMobile.classList.toggle("active"); }, false ); this._menuMobileOnClickMask = this._menuMobileOnClickMask || (() => { $menuToggleMobile.classList.remove("active"); $menuMobile.classList.remove("active"); }); this.clickMaskEventSet.add(this._menuMobileOnClickMask); } initSwitchTheme() { this.util.forEach( document.getElementsByClassName("theme-switch"), ($themeSwitch) => { $themeSwitch.addEventListener( "click", () => { if (document.body.getAttribute("theme") === "dark") document.body.setAttribute("theme", "light"); else document.body.setAttribute("theme", "dark"); this.isDark = !this.isDark; this.config.cookieconsent && window.localStorage && localStorage.setItem("theme", this.isDark ? "dark" : "light"); for (let event of this.switchThemeEventSet) event(); }, false ); } ); } initSearch() { const searchConfig = this.config.search; const isMobile = this.util.isMobile(); if ( !searchConfig || (isMobile && this._searchMobileOnce) || (!isMobile && this._searchDesktopOnce) ) return; const maxResultLength = searchConfig.maxResultLength ? searchConfig.maxResultLength : 10; const snippetLength = searchConfig.snippetLength ? searchConfig.snippetLength : 50; const highlightTag = searchConfig.highlightTag ? searchConfig.highlightTag : "em"; const suffix = isMobile ? "mobile" : "desktop"; const $header = document.getElementById(`header-${suffix}`); const $searchInput = document.getElementById(`search-input-${suffix}`); const $searchToggle = document.getElementById(`search-toggle-${suffix}`); const $searchLoading = document.getElementById(`search-loading-${suffix}`); const $searchClear = document.getElementById(`search-clear-${suffix}`); if (isMobile) { this._searchMobileOnce = true; $searchInput.addEventListener( "focus", () => { document.body.classList.add("blur"); $header.classList.add("open"); }, false ); document.getElementById("search-cancel-mobile").addEventListener( "click", () => { $header.classList.remove("open"); document.body.classList.remove("blur"); document .getElementById("menu-toggle-mobile") .classList.remove("active"); document.getElementById("menu-mobile").classList.remove("active"); $searchLoading.style.display = "none"; $searchClear.style.display = "none"; this._searchMobile && this._searchMobile.autocomplete.setVal(""); }, false ); $searchClear.addEventListener( "click", () => { $searchClear.style.display = "none"; this._searchMobile && this._searchMobile.autocomplete.setVal(""); }, false ); this._searchMobileOnClickMask = this._searchMobileOnClickMask || (() => { $header.classList.remove("open"); $searchLoading.style.display = "none"; $searchClear.style.display = "none"; this._searchMobile && this._searchMobile.autocomplete.setVal(""); }); this.clickMaskEventSet.add(this._searchMobileOnClickMask); } else { this._searchDesktopOnce = true; $searchToggle.addEventListener( "click", () => { document.body.classList.add("blur"); $header.classList.add("open"); $searchInput.focus(); }, false ); $searchClear.addEventListener( "click", () => { $searchClear.style.display = "none"; this._searchDesktop && this._searchDesktop.autocomplete.setVal(""); }, false ); this._searchDesktopOnClickMask = this._searchDesktopOnClickMask || (() => { $header.classList.remove("open"); $searchLoading.style.display = "none"; $searchClear.style.display = "none"; this._searchDesktop && this._searchDesktop.autocomplete.setVal(""); }); this.clickMaskEventSet.add(this._searchDesktopOnClickMask); } $searchInput.addEventListener( "input", () => { if ($searchInput.value === "") $searchClear.style.display = "none"; else $searchClear.style.display = "inline"; }, false ); const initAutosearch = () => { const autosearch = autocomplete( `#search-input-${suffix}`, { hint: false, autoselect: true, dropdownMenuContainer: `#search-dropdown-${suffix}`, clearOnSelected: true, cssClasses: { noPrefix: true }, debug: true, }, { name: "search", source: (query, callback) => { $searchLoading.style.display = "inline"; $searchClear.style.display = "none"; const finish = (results) => { $searchLoading.style.display = "none"; $searchClear.style.display = "inline"; callback(results); }; if (searchConfig.type === "lunr") { const search = () => { if (lunr.queryHandler) query = lunr.queryHandler(query); const results = {}; this._index .search(query) .forEach(({ ref, matchData: { metadata } }) => { const matchData = this._indexData[ref]; let { uri, title, content: context } = matchData; if (results[uri]) return; let position = 0; Object.values(metadata).forEach(({ content }) => { if (content) { const matchPosition = content.position[0][0]; if (matchPosition < position || position === 0) position = matchPosition; } }); position -= snippetLength / 5; if (position > 0) { position += context.substr(position, 20).lastIndexOf(" ") + 1; context = "..." + context.substr(position, snippetLength); } else { context = context.substr(0, snippetLength); } Object.keys(metadata).forEach((key) => { title = title.replace( new RegExp(`(${key})`, "gi"), `<${highlightTag}>$1` ); context = context.replace( new RegExp(`(${key})`, "gi"), `<${highlightTag}>$1` ); }); results[uri] = { uri: uri, title: title, date: matchData.date, context: context, }; }); return Object.values(results).slice(0, maxResultLength); }; if (!this._index) { fetch(searchConfig.lunrIndexURL) .then((response) => response.json()) .then((data) => { const indexData = {}; this._index = lunr(function () { if (searchConfig.lunrLanguageCode) this.use(lunr[searchConfig.lunrLanguageCode]); this.ref("objectID"); this.field("title", { boost: 50 }); this.field("tags", { boost: 20 }); this.field("categories", { boost: 20 }); this.field("content", { boost: 10 }); this.metadataWhitelist = ["position"]; data.forEach((record) => { indexData[record.objectID] = record; this.add(record); }); }); this._indexData = indexData; finish(search()); }) .catch((err) => { console.error(err); finish([]); }); } else finish(search()); } else if (searchConfig.type === "algolia") { this._algoliaIndex = this._algoliaIndex || algoliasearch( searchConfig.algoliaAppID, searchConfig.algoliaSearchKey ).initIndex(searchConfig.algoliaIndex); this._algoliaIndex .search(query, { offset: 0, length: maxResultLength * 8, attributesToHighlight: ["title"], attributesToSnippet: [`content:${snippetLength}`], highlightPreTag: `<${highlightTag}>`, highlightPostTag: ``, }) .then(({ hits }) => { const results = {}; hits.forEach( ({ uri, date, _highlightResult: { title }, _snippetResult: { content }, }) => { if ( results[uri] && results[uri].context.length > content.value ) return; results[uri] = { uri: uri, title: title.value, date: date, context: content.value, }; } ); finish(Object.values(results).slice(0, maxResultLength)); }) .catch((err) => { console.error(err); finish([]); }); } }, templates: { suggestion: ({ title, date, context }) => `
${title}${date}
${context}
`, empty: ({ query }) => `
${searchConfig.noResultsFound}: "${query}"
`, footer: ({}) => { const { searchType, icon, href } = searchConfig.type === "algolia" ? { searchType: "algolia", icon: '', href: "https://www.algolia.com/", } : { searchType: "Lunr.js", icon: "", href: "https://lunrjs.com/", }; return ``; }, }, } ); autosearch.on( "autocomplete:selected", (_event, suggestion, _dataset, _context) => { window.location.assign(suggestion.uri); } ); if (isMobile) this._searchMobile = autosearch; else this._searchDesktop = autosearch; }; if ( searchConfig.lunrSegmentitURL && !document.getElementById("lunr-segmentit") ) { const script = document.createElement("script"); script.id = "lunr-segmentit"; script.type = "text/javascript"; script.src = searchConfig.lunrSegmentitURL; script.async = true; if (script.readyState) { script.onreadystatechange = () => { if ( script.readyState == "loaded" || script.readyState == "complete" ) { script.onreadystatechange = null; initAutosearch(); } }; } else { script.onload = () => { initAutosearch(); }; } document.body.appendChild(script); } else initAutosearch(); } initDetails() { this.util.forEach( document.getElementsByClassName("details"), ($details) => { const $summary = $details.getElementsByClassName("details-summary")[0]; $summary.addEventListener( "click", () => { $details.classList.toggle("open"); }, false ); } ); } initLightGallery() { if (this.config.lightGallery) lightGallery( document.getElementById("content"), this.config.lightGallery ); } initHighlight() { this.util.forEach( document.querySelectorAll(".highlight > pre.chroma"), ($preChroma) => { const $chroma = document.createElement("div"); $chroma.className = $preChroma.className; const $table = document.createElement("table"); $chroma.appendChild($table); const $tbody = document.createElement("tbody"); $table.appendChild($tbody); const $tr = document.createElement("tr"); $tbody.appendChild($tr); const $td = document.createElement("td"); $tr.appendChild($td); $preChroma.parentElement.replaceChild($chroma, $preChroma); $td.appendChild($preChroma); } ); this.util.forEach( document.querySelectorAll(".highlight > .chroma"), ($chroma) => { const $codeElements = $chroma.querySelectorAll("pre.chroma > code"); if ($codeElements.length) { const $code = $codeElements[$codeElements.length - 1]; const $header = document.createElement("div"); $header.className = "code-header " + $code.className.toLowerCase(); const $title = document.createElement("span"); $title.classList.add("code-title"); $title.insertAdjacentHTML( "afterbegin", '' ); $title.addEventListener( "click", () => { $chroma.classList.toggle("open"); }, false ); $header.appendChild($title); const $ellipses = document.createElement("span"); $ellipses.insertAdjacentHTML( "afterbegin", '' ); $ellipses.classList.add("ellipses"); $ellipses.addEventListener( "click", () => { $chroma.classList.add("open"); }, false ); $header.appendChild($ellipses); const $copy = document.createElement("span"); $copy.insertAdjacentHTML( "afterbegin", '' ); $copy.classList.add("copy"); const code = $code.innerText; if ( this.config.code.maxShownLines < 0 || code.split("\n").length < this.config.code.maxShownLines + 2 ) $chroma.classList.add("open"); if (this.config.code.copyTitle) { $copy.setAttribute("data-clipboard-text", code); $copy.title = this.config.code.copyTitle; const clipboard = new ClipboardJS($copy); clipboard.on("success", (_e) => { this.util.animateCSS($code, "flash"); }); $header.appendChild($copy); } $chroma.insertBefore($header, $chroma.firstChild); } } ); } initTable() { this.util.forEach(document.querySelectorAll(".content table"), ($table) => { const $wrapper = document.createElement("div"); $wrapper.className = "table-wrapper"; $table.parentElement.replaceChild($wrapper, $table); $wrapper.appendChild($table); }); } initHeaderLink() { for (let num = 1; num <= 6; num++) { this.util.forEach( document.querySelectorAll(".single .content > h" + num), ($header) => { $header.classList.add("headerLink"); $header.insertAdjacentHTML( "afterbegin", `` ); } ); } } initToc() { const $tocCore = document.getElementById("TableOfContents"); if ($tocCore === null) return; if ( document.getElementById("toc-static").getAttribute("kept") || this.util.isTocStatic() ) { const $tocContentStatic = document.getElementById("toc-content-static"); if ($tocCore.parentElement !== $tocContentStatic) { $tocCore.parentElement.removeChild($tocCore); $tocContentStatic.appendChild($tocCore); } if (this._tocOnScroll) this.scrollEventSet.delete(this._tocOnScroll); } else { const $tocContentAuto = document.getElementById("toc-content-auto"); if ($tocCore.parentElement !== $tocContentAuto) { $tocCore.parentElement.removeChild($tocCore); $tocContentAuto.appendChild($tocCore); } const $toc = document.getElementById("toc-auto"); const $page = document.getElementsByClassName("page")[0]; const rect = $page.getBoundingClientRect(); $toc.style.left = `${rect.left + rect.width + 20}px`; $toc.style.maxWidth = `${$page.getBoundingClientRect().left - 20}px`; $toc.style.visibility = "visible"; const $tocLinkElements = $tocCore.querySelectorAll("a:first-child"); const $tocLiElements = $tocCore.getElementsByTagName("li"); const $headerLinkElements = document.getElementsByClassName("headerLink"); const headerIsFixed = document.body.getAttribute("header-desktop") !== "normal"; const headerHeight = document.getElementById("header-desktop").offsetHeight; const TOP_SPACING = 20 + (headerIsFixed ? headerHeight : 0); const minTocTop = $toc.offsetTop; const minScrollTop = minTocTop - TOP_SPACING + (headerIsFixed ? 0 : headerHeight); this._tocOnScroll = this._tocOnScroll || (() => { const footerTop = document.getElementById("post-footer").offsetTop; const maxTocTop = footerTop - $toc.getBoundingClientRect().height; const maxScrollTop = maxTocTop - TOP_SPACING + (headerIsFixed ? 0 : headerHeight); if (this.newScrollTop < minScrollTop) { $toc.style.position = "absolute"; $toc.style.top = `${minTocTop}px`; } else if (this.newScrollTop > maxScrollTop) { $toc.style.position = "absolute"; $toc.style.top = `${maxTocTop}px`; } else { $toc.style.position = "fixed"; $toc.style.top = `${TOP_SPACING}px`; } this.util.forEach($tocLinkElements, ($tocLink) => { $tocLink.classList.remove("active"); }); this.util.forEach($tocLiElements, ($tocLi) => { $tocLi.classList.remove("has-active"); }); const INDEX_SPACING = 20 + (headerIsFixed ? headerHeight : 0); let activeTocIndex = $headerLinkElements.length - 1; for (let i = 0; i < $headerLinkElements.length - 1; i++) { const thisTop = $headerLinkElements[i].getBoundingClientRect().top; const nextTop = $headerLinkElements[i + 1].getBoundingClientRect().top; if ( (i == 0 && thisTop > INDEX_SPACING) || (thisTop <= INDEX_SPACING && nextTop > INDEX_SPACING) ) { activeTocIndex = i; break; } } if (activeTocIndex !== -1) { $tocLinkElements[activeTocIndex].classList.add("active"); let $parent = $tocLinkElements[activeTocIndex].parentElement; while ($parent !== $tocCore) { $parent.classList.add("has-active"); $parent = $parent.parentElement.parentElement; } } }); this._tocOnScroll(); this.scrollEventSet.add(this._tocOnScroll); } } initMath() { if (this.config.math) renderMathInElement(document.body, this.config.math); } initMermaid() { const $mermaidElements = document.getElementsByClassName("mermaid"); if ($mermaidElements.length) { mermaid.initialize({ startOnLoad: false, theme: "null" }); this.util.forEach($mermaidElements, ($mermaid) => { mermaid.mermaidAPI.render( "svg-" + $mermaid.id, this.data[$mermaid.id], (svgCode) => { $mermaid.insertAdjacentHTML("afterbegin", svgCode); }, $mermaid ); }); } } initEcharts() { this._echartsOnSwitchTheme = this._echartsOnSwitchTheme || (() => { this._echartsArr = this._echartsArr || []; for (let i = 0; i < this._echartsArr.length; i++) { this._echartsArr[i].dispose(); } this._echartsArr = []; this.util.forEach( document.getElementsByClassName("echarts"), ($echarts) => { const chart = echarts.init( $echarts, this.isDark ? "dark" : "macarons", { renderer: "svg" } ); chart.setOption(JSON.parse(this.data[$echarts.id])); this._echartsArr.push(chart); } ); }); this.switchThemeEventSet.add(this._echartsOnSwitchTheme); this._echartsOnSwitchTheme(); this._echartsOnResize = this._echartsOnResize || (() => { for (let i = 0; i < this._echartsArr.length; i++) { this._echartsArr[i].resize(); } }); this.resizeEventSet.add(this._echartsOnResize); } initMapbox() { if (this.config.mapbox) { mapboxgl.accessToken = this.config.mapbox.accessToken; mapboxgl.setRTLTextPlugin(this.config.mapbox.RTLTextPlugin); this._mapboxArr = this._mapboxArr || []; this.util.forEach( document.getElementsByClassName("mapbox"), ($mapbox) => { const { lng, lat, zoom, lightStyle, darkStyle, marked, navigation, geolocate, scale, fullscreen, optionsJson, } = this.data[$mapbox.id]; const mapbox = new mapboxgl.Map({ container: $mapbox, center: [lng, lat], zoom: zoom, minZoom: 0.2, style: this.isDark ? darkStyle : lightStyle, attributionControl: false, }); if (marked) { new mapboxgl.Marker().setLngLat([lng, lat]).addTo(mapbox); } if (navigation) { mapbox.addControl(new mapboxgl.NavigationControl(), "bottom-right"); } if (geolocate) { mapbox.addControl( new mapboxgl.GeolocateControl({ positionOptions: { enableHighAccuracy: true, }, showUserLocation: true, trackUserLocation: true, }), "bottom-right" ); } if (scale) { mapbox.addControl(new mapboxgl.ScaleControl()); } if (fullscreen) { mapbox.addControl(new mapboxgl.FullscreenControl()); } if (typeof optionsJson === "object" && optionsJson !== null) { console.log(optionsJson); mapbox.on("load", function () { for (const source of optionsJson.sources) { mapbox.addSource(source.id, source.properties); } for (const layer of optionsJson.layers) { mapbox.addLayer(layer); } }); } mapbox.addControl(new MapboxLanguage()); this._mapboxArr.push(mapbox); } ); this._mapboxOnSwitchTheme = this._mapboxOnSwitchTheme || (() => { this.util.forEach(this._mapboxArr, (mapbox) => { const $mapbox = mapbox.getContainer(); const { lightStyle, darkStyle } = this.data[$mapbox.id]; mapbox.setStyle(this.isDark ? darkStyle : lightStyle); mapbox.addControl(new MapboxLanguage()); }); }); this.switchThemeEventSet.add(this._mapboxOnSwitchTheme); } } initTypeit() { if (this.config.typeit) { const typeitConfig = this.config.typeit; const speed = typeitConfig.speed ? typeitConfig.speed : 100; const cursorSpeed = typeitConfig.cursorSpeed ? typeitConfig.cursorSpeed : 1000; const cursorChar = typeitConfig.cursorChar ? typeitConfig.cursorChar : "|"; Object.values(typeitConfig.data).forEach((group) => { const typeone = (i) => { const id = group[i]; const instance = new TypeIt(`#${id}`, { strings: this.data[id], speed: speed, lifeLike: true, cursorSpeed: cursorSpeed, cursorChar: cursorChar, waitUntilVisible: true, afterComplete: () => { if (i === group.length - 1) { if (typeitConfig.duration >= 0) window.setTimeout(() => { instance.destroy(); }, typeitConfig.duration); return; } instance.destroy(); typeone(i + 1); }, }).go(); }; typeone(0); }); } } initComment() { if (this.config.comment) { if (this.config.comment.gitalk) { this.config.comment.gitalk.body = decodeURI(window.location.href); const gitalk = new Gitalk(this.config.comment.gitalk); gitalk.render("gitalk"); } if (this.config.comment.valine) new Valine(this.config.comment.valine); if (this.config.comment.utterances) { const utterancesConfig = this.config.comment.utterances; const script = document.createElement("script"); script.src = "https://utteranc.es/client.js"; script.type = "text/javascript"; script.setAttribute("repo", utterancesConfig.repo); script.setAttribute("issue-term", utterancesConfig.issueTerm); if (utterancesConfig.label) script.setAttribute("label", utterancesConfig.label); script.setAttribute( "theme", this.isDark ? utterancesConfig.darkTheme : utterancesConfig.lightTheme ); script.crossOrigin = "anonymous"; script.async = true; document.getElementById("utterances").appendChild(script); this._utterancesOnSwitchTheme = this._utterancesOnSwitchTheme || (() => { const message = { type: "set-theme", theme: this.isDark ? utterancesConfig.darkTheme : utterancesConfig.lightTheme, }; const iframe = document.querySelector(".utterances-frame"); iframe.contentWindow.postMessage(message, "https://utteranc.es"); }); this.switchThemeEventSet.add(this._utterancesOnSwitchTheme); } } } initSmoothScroll() { if (SmoothScroll) new SmoothScroll('[href^="#"]', { speed: 300, speedAsDuration: true, header: "#header-desktop", }); } initCookieconsent() { if (this.config.cookieconsent) cookieconsent.initialise(this.config.cookieconsent); } onScroll() { const $headers = []; if (document.body.getAttribute("header-desktop") === "auto") $headers.push(document.getElementById("header-desktop")); if (document.body.getAttribute("header-mobile") === "auto") $headers.push(document.getElementById("header-mobile")); if (document.getElementById("comments")) { const $viewComments = document.getElementById("view-comments"); $viewComments.href = `#comments`; $viewComments.style.display = "block"; } const $fixedButtons = document.getElementById("fixed-buttons"); const ACCURACY = 20, MINIMUM = 100; window.addEventListener( "scroll", () => { this.newScrollTop = this.util.getScrollTop(); const scroll = this.newScrollTop - this.oldScrollTop; const isMobile = this.util.isMobile(); this.util.forEach($headers, ($header) => { if (scroll > ACCURACY) { $header.classList.remove("fadeInDown"); this.util.animateCSS($header, ["fadeOutUp", "faster"], true); } else if (scroll < -ACCURACY) { $header.classList.remove("fadeOutUp"); this.util.animateCSS($header, ["fadeInDown", "faster"], true); } }); if (this.newScrollTop > MINIMUM) { if (isMobile && scroll > ACCURACY) { $fixedButtons.classList.remove("fadeIn"); this.util.animateCSS($fixedButtons, ["fadeOut", "faster"], true); } else if (!isMobile || scroll < -ACCURACY) { $fixedButtons.style.display = "block"; $fixedButtons.classList.remove("fadeOut"); this.util.animateCSS($fixedButtons, ["fadeIn", "faster"], true); } } else { if (!isMobile) { $fixedButtons.classList.remove("fadeIn"); this.util.animateCSS($fixedButtons, ["fadeOut", "faster"], true); } $fixedButtons.style.display = "none"; } for (let event of this.scrollEventSet) event(); this.oldScrollTop = this.newScrollTop; }, false ); } onResize() { window.addEventListener( "resize", () => { if (!this._resizeTimeout) { this._resizeTimeout = window.setTimeout(() => { this._resizeTimeout = null; for (let event of this.resizeEventSet) event(); this.initToc(); this.initMermaid(); this.initSearch(); }, 100); } }, false ); } onClickMask() { document.getElementById("mask").addEventListener( "click", () => { for (let event of this.clickMaskEventSet) event(); document.body.classList.remove("blur"); }, false ); } init() { try { this.initSVGIcon(); this.initTwemoji(); this.initMenuMobile(); this.initSwitchTheme(); this.initSearch(); this.initDetails(); this.initLightGallery(); this.initHighlight(); this.initTable(); this.initHeaderLink(); this.initSmoothScroll(); this.initMath(); this.initMermaid(); this.initEcharts(); this.initTypeit(); this.initMapbox(); this.initCookieconsent(); } catch (err) { console.error(err); } window.setTimeout(() => { this.initToc(); this.initComment(); this.onScroll(); this.onResize(); this.onClickMask(); }, 100); } } const themeInit = () => { const theme = new Theme(); theme.init(); }; if (document.readyState !== "loading") { themeInit(); } else { document.addEventListener("DOMContentLoaded", themeInit, false); }