1/* global NexT, CONFIG */ 2HTMLElement.prototype.wrap=function(e){this.parentNode.insertBefore(e,this),this.parentNode.removeChild(this),e.appendChild(this)},function(){const e=()=>document.dispatchEvent(new Event("page:loaded",{bubbles:!0}));"loading"===document.readyState?document.addEventListener("readystatechange",e,{once:!0}):e(),document.addEventListener("pjax:success",e)}(),NexT.utils={registerExtURL:function(){document.querySelectorAll("span.exturl").forEach(e=>{const t=document.createElement("a"); 3// https://stackoverflow.com/questions/30106476/using-javascripts-atob-to-decode-base64-doesnt-properly-decode-utf-8-strings 4t.href=decodeURIComponent(atob(e.dataset.url).split("").map(e=>"%"+("00"+e.charCodeAt(0).toString(16)).slice(-2)).join("")),t.rel="noopener external nofollow noreferrer",t.target="_blank",t.className=e.className,t.title=e.title,t.innerHTML=e.innerHTML,e.parentNode.replaceChild(t,e)})}, 5/** 6 * One-click copy code support. 7 */ 8registerCopyCode:function(){let e=document.querySelectorAll("figure.highlight");0===e.length&&(e=document.querySelectorAll("pre:not(.mermaid)")),e.forEach(e=>{if(e.querySelectorAll(".code .line span").forEach(e=>{e.classList.forEach(t=>{e.classList.replace(t,`hljs-${t}`)})}),!CONFIG.copycode.enable)return;let t=e;"mac"!==CONFIG.copycode.style&&(t=e.querySelector(".table-container")||e),t.insertAdjacentHTML("beforeend",'<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>');const n=e.querySelector(".copy-btn");n.addEventListener("click",()=>{const t=(e.querySelector(".code")||e.querySelector("code")).innerText;if(navigator.clipboard) 9// https://caniuse.com/mdn-api_clipboard_writetext 10navigator.clipboard.writeText(t).then(()=>{n.querySelector("i").className="fa fa-check-circle fa-fw"},()=>{n.querySelector("i").className="fa fa-times-circle fa-fw"});else{const e=document.createElement("textarea");
10e.style.top=window.scrollY+"px",// Prevent page scrolling 11e.style.position="absolute",e.style.opacity="0",e.readOnly=!0,e.value=t,document.body.append(e),e.select(),e.setSelectionRange(0,t.length),e.readOnly=!1;const o=document.execCommand("copy");n.querySelector("i").className=o?"fa fa-check-circle fa-fw":"fa fa-times-circle fa-fw",e.blur(),// For iOS 12n.blur(),document.body.removeChild(e)}}),e.addEventListener("mouseleave",()=>{setTimeout(()=>{n.querySelector("i").className="fa fa-copy fa-fw"},300)})})},wrapTableWithBox:function(){document.querySelectorAll("table").forEach(e=>{const t=document.createElement("div");t.className="table-container",e.wrap(t)})},registerVideoIframe:function(){document.querySelectorAll("iframe").forEach(e=>{if(["www.youtube.com","player.vimeo.com","player.youku.com","player.bilibili.com","www.tudou.com"].some(t=>e.src.includes(t))&&!e.parentNode.matches(".video-container")){const t=document.createElement("div");t.className="video-container",e.wrap(t);const n=Number(e.width),o=Number(e.height);n&&o&&(t.style.paddingTop=o/n*100+"%")}})},updateActiveNav:function(){if(!Array.isArray(NexT.utils.sections))return;let e=NexT.utils.sections.findIndex(e=>e&&e.getBoundingClientRect().top>10);-1===e?e=NexT.utils.sections.length-1:e>0&&e--,this.activateNavByIndex(e)},registerScrollPercent:function(){const e=document.querySelector(".back-to-top"),t=document.querySelector(".reading-progress-bar"); 13// For init back to top in sidebar if page was scrolled after page refresh. 14window.addEventListener("scroll",()=>{if(e||t){const n=document.body.scrollHeight-window.innerHeight,o=n>0?Math.min(100*window.scrollY/n,100):0;e&&(e.classList.toggle("back-to-top-on",Math.round(o)>=5),e.querySelector("span").innerText=Math.round(o)+"%"),t&&t.style.setProperty("--progress",o.toFixed(2)+"%")}this.updateActiveNav()},{passive:!0}),e&&e.addEventListener("click",()=>{window.anime({targets:document.scrollingElement,duration:500,easing:"linear",scrollTop:0})})}, 15/** 16 * Tabs tag listener (without twitter bootstrap). 17 */ 18registerTabsTag:function(){ 19// Binding `nav-tabs` & `tab-content` by real time permalink changing. 20document.querySelectorAll(".tabs ul.nav-tabs .tab").forEach(e=>{e.addEventListener("click",t=>{ 21// Prevent selected tab to select again. 22if(t.preventDefault(),e.classList.contains("active"))return;const n=e.parentNode,o=n.nextElementSibling; 23// Get the height of `tab-pane` which is activated before, and set it as the height of `tab-content` with extra margin / paddings. 24o.style.overflow="hidden",o.style.transition="height 1s"; 25// Comment system selection tab does not contain .active class. 26const i=o.querySelector(".active")||o.firstElementChild,r=parseInt(window.getComputedStyle(i).height.replace("px",""),10)||0,c=parseInt(window.getComputedStyle(i).paddingTop.replace("px",""),10),a=parseInt(window.getComputedStyle(i.firstElementChild).marginBottom.replace("px",""),10); 27// Hight might be `auto`. 28o.style.height=r+c+a+"px", 29// Add & Remove active class on `nav-tabs` & `tab-content`. 30[...n.children].forEach(t=>{t.classList.toggle("active",t===e)}); 31// https://stackoverflow.com/questions/20306204/using-queryselector-with-ids-that-are-numbers 32const s=document.getElementById(e.querySelector("a").getAttribute("href").replace("#",""));[...s.parentNode.children].forEach(e=>{e.classList.toggle("active",e===s)}), 33// Trigger event 34s.dispatchEvent(new Event("tabs:click",{bubbles:!0})); 35// Get the height of `tab-pane` which is activated now. 36const l=document.body.scrollHeight>(window.innerHeight||document.documentElement.clientHeight),d=parseInt(window.getComputedStyle(o.querySelector(".active")).height.replace("px",""),10);if( 37// Reset the height of `tab-content` and see the animation. 38o.style.height=d+c+a+"px", 39// Change the height of `tab-content` may cause scrollbar show / disappear, which may result in the change of the `tab-pane`'s height 40setTimeout(()=>{if(document.body.scrollHeight>(window.innerHeight||document.documentElement.clientHeight)!==l){o.style.transition="height 0.3s linear"; 41// After the animation, we need reset the height of `tab-content` again. 42const e=parseInt(window.getComputedStyle(o.querySelector(".active")).height.replace("px",""),10);o.style.height=e+c+a+"px"} 43// Remove all the inline styles, and let the height be adaptive again. 44setTimeout(()=>{o.style.transition="",o.style.height=""},250)},1e3),!CONFIG.stickytabs)return;const u=n.parentNode.getBoundingClientRect().top+window.scrollY+10;window.anime({targets:document.scrollingElement,duration:500,easing:"linear",scrollTop:u})})}),window.dispatchEvent(new Event("tabs:register"))},registerCanIUseTag:function(){ 45// Get responsive height passed from iframe. 46window.addEventListener("message",({data:e})=>
46{if("string"==typeof e&&e.includes("ciu_embed")){const t=e.split(":")[1],n=e.split(":")[2];document.querySelector(`iframe[data-feature=${t}]`).style.height=parseInt(n,10)+5+"px"}},!1)},registerActiveMenuItem:function(){document.querySelectorAll(".menu-item a[href]").forEach(e=>{const t=e.pathname===location.pathname||e.pathname===location.pathname.replace("index.html",""),n=!CONFIG.root.startsWith(e.pathname)&&location.pathname.startsWith(e.pathname);e.classList.toggle("menu-item-active",e.hostname===location.hostname&&(t||n))})},registerLangSelect:function(){document.querySelectorAll(".lang-select").forEach(e=>{e.value=CONFIG.page.lang,e.addEventListener("change",()=>{const t=e.options[e.selectedIndex];document.querySelectorAll(".lang-select-label span").forEach(e=>{e.innerText=t.text}), 47// Disable Pjax to force refresh translation of menu item 48window.location.href=t.dataset.href})})},registerSidebarTOC:function(){this.sections=[...document.querySelectorAll(".post-toc:not(.placeholder-toc) li a.nav-link")].map(e=>{const t=document.getElementById(decodeURI(e.getAttribute("href")).replace("#","")); 49// TOC item animation navigate. 50return e.addEventListener("click",n=>{n.preventDefault();const o=t.getBoundingClientRect().top+window.scrollY;window.anime({targets:document.scrollingElement,duration:500,easing:"linear",scrollTop:o,complete:()=>{history.pushState(null,document.title,e.href)}})}),t}),this.updateActiveNav()},registerPostReward:function(){const e=document.querySelector(".reward-container button");e&&e.addEventListener("click",()=>{document.querySelector(".post-reward").classList.toggle("active")})},activateNavByIndex:function(e){const t=document.querySelector(".post-toc:not(.placeholder-toc) .nav");if(!t)return;const n=t.querySelectorAll(".nav-item"),o=n[e];if(!o||o.classList.contains("active-current"))return;const i=n[n.length-1].offsetHeight;t.querySelectorAll(".active").forEach(e=>{e.classList.remove("active","active-current")}),o.classList.add("active","active-current");let r=o.querySelector(".nav-child")||o.parentElement,c=0;for(;t.contains(r);)r.classList.contains("nav-item")?r.classList.add("active"):(// .nav-child or .nav 51// scrollHeight isn't reliable for transitioning child items. 52// The last nav-item in a list has a margin-bottom of 5px. 53c+=i*r.childElementCount+5,r.style.setProperty("--height",`${c}px`)),r=r.parentElement; 54// Scrolling to center active TOC element if TOC content is taller then viewport. 55const a=document.querySelector("Pisces"===CONFIG.scheme||"Gemini"===CONFIG.scheme?".sidebar-panel-container":".sidebar");document.querySelector(".sidebar-toc-active")&&window.anime({targets:a,duration:200,easing:"linear",scrollTop:a.scrollTop-a.offsetHeight/2+o.getBoundingClientRect().top-a.getBoundingClientRect().top})},updateSidebarPosition:function(){if(window.innerWidth<1200||"Pisces"===CONFIG.scheme||"Gemini"===CONFIG.scheme)return; 56// Expand sidebar on post detail page by default, when post has a toc. 57const e=document.querySelector(".post-toc:not(.placeholder-toc)");let t=CONFIG.page.sidebar;"boolean"!=typeof t&&( 58// There's no definition sidebar in the page front-matter. 59t="always"===CONFIG.sidebar.display||"post"===CONFIG.sidebar.display&&e),t&&window.dispatchEvent(new Event("sidebar:show"))},activateSidebarPanel:function(e){const t=document.querySelector(".sidebar-inner"),n=["sidebar-toc-active","sidebar-overview-active"];if(t.classList.contains(n[e]))return;const o=t.querySelector(".sidebar-panel-container"),i=o.firstElementChild,r=o.lastElementChild;let c=i.scrollHeight; 60// For TOC activation, try to use the animated TOC height 61if(0===e){const e=i.querySelector(".nav");e&&(c=parseInt(e.style.getPropertyValue("--height"),10))}const a=[c,r.scrollHeight];o.style.setProperty("--inactive-panel-height",`${a[1-e]}px`),o.style.setProperty("--active-panel-height",`${a[e]}px`),t.classList.replace(n[1-e],n[e])},getScript:function(e,t={},n){if("function"==typeof t)return this.getScript(e,{condition:n}).then(t);const{condition:o=!1,attributes:{id:i="",async:r=!1,defer:c=!1,crossOrigin:a="",dataset:s={},...l}={},parentNode:d=null}=t;return new Promise((t,n)=>{if(o)t();else{const o=document.createElement("script");
61if(i&&(o.id=i),a&&(o.crossOrigin=a),o.async=r,o.defer=c,Object.assign(o.dataset,s),Object.entries(l).forEach(([e,t])=>{o.setAttribute(e,String(t))}),o.onload=t,o.onerror=n,"object"==typeof e){const{url:t,integrity:n}=e;o.src=t,n&&(o.integrity=n,o.crossOrigin="anonymous")}else o.src=e;(d||document.head).appendChild(o)}})},loadComments:function(e,t){return t?this.loadComments(e).then(t):new Promise(t=>{const n=document.querySelector(e);if(!CONFIG.comments.lazyload||!n)return void t();new IntersectionObserver((e,n)=>{e[0].isIntersecting&&(t(),n.disconnect())}).observe(n)})}};
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.