Files
website/public/js/main.min.e60ab79dca7b920b4dc5cf3163ad5ce8794839b60f27778db65782f087be3e27.js
T
2026-03-29 17:20:43 +02:00

29 lines
19 KiB
JavaScript
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const MIN_SEARCH_QUERY_LENGTH=2,SEARCH_RESULTS_LIMIT=10,SEARCH_DEBOUNCE_DELAY=200,SEARCH_INDEX_URL="/index.json",MODAL_FOCUS_DELAY=100,SCROLL_THRESHOLD=300,WIDE_SCREEN_BREAKPOINT=1024,MOBILE_BREAKPOINT=768,TOC_SCROLL_OFFSET=100,TOC_RESIZE_DEBOUNCE=150,DEBOUNCE_DELAY=200;function debounce(e,t){let n;return function(...s){const o=()=>{clearTimeout(n),e(...s)};clearTimeout(n),n=setTimeout(o,t)}}function throttle(e){let t=!1;return function(...n){t||(window.requestAnimationFrame(()=>{e(...n),t=!1}),t=!0)}}function isWideScreen(){return window.innerWidth>WIDE_SCREEN_BREAKPOINT}function isMobileScreen(){return window.innerWidth<=MOBILE_BREAKPOINT}function escapeRegex(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function formatDate(e){if(!e)return"";try{const t=new Date(e),n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];return`${n[t.getMonth()]} ${t.getDate()}, ${t.getFullYear()}`}catch(t){return console.error("Error formatting date:",t),e}}function initOnReady(e){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e()}const THEME_STORAGE_KEY="theme",THEME_LIGHT="light",THEME_DARK="dark";function getInitialTheme(){const e=localStorage.getItem(THEME_STORAGE_KEY);if(e)return e;const t=window.matchMedia("(prefers-color-scheme: light)").matches;return t?THEME_LIGHT:THEME_DARK}function setTheme(e){const t=document.documentElement;t.setAttribute("data-theme",e),localStorage.setItem(THEME_STORAGE_KEY,e),updateThemeToggleIcon(e)}function updateThemeToggleIcon(e){const t=document.getElementById("theme-toggle");if(!t)return;const n=t.querySelector(".icon-sun"),s=t.querySelector(".icon-moon");e===THEME_LIGHT?(n?.setAttribute("style","display: none;"),s?.setAttribute("style","display: block;")):(n?.setAttribute("style","display: block;"),s?.setAttribute("style","display: none;"))}function toggleTheme(){const e=document.documentElement,t=e.getAttribute("data-theme"),n=t===THEME_LIGHT?THEME_DARK:THEME_LIGHT;setTheme(n)}function initThemeToggle(){const e=document.getElementById("theme-toggle");if(!e)return;const t=getInitialTheme();setTheme(t),window.matchMedia("(prefers-color-scheme: light)").addEventListener("change",e=>{localStorage.getItem(THEME_STORAGE_KEY)||setTheme(e.matches?THEME_LIGHT:THEME_DARK)}),e.addEventListener("click",toggleTheme)}initOnReady(initThemeToggle);let searchIndex=[],searchTimeout=null;async function loadSearchIndex(){try{const e=await fetch(SEARCH_INDEX_URL);e.ok?searchIndex=await e.json():console.error("Failed to load search index:",e.status)}catch(e){console.error("Failed to load search index:",e)}}function toggleSearchResultsVisibility(){const e=document.getElementById("search-results");if(!e)return;const t=e.innerHTML.trim().length>0;e.style.display=t?"block":"none"}function highlightMatch(e,t){if(!e||!t)return e;const s=t.endsWith(" "),n=t.trim();if(!n)return e;const o=escapeRegex(n),i=new RegExp(`(${o})`,"gi");return e.replace(i,e=>s?`<mark>${e} </mark>`:`<mark>${e}</mark>`)}function performSearch(e){const t=document.getElementById("search-results");if(!t)return;const s=e?e.trim():"";if(!s||s.length<MIN_SEARCH_QUERY_LENGTH){t.innerHTML="",toggleSearchResultsVisibility();return}const n=s.toLowerCase(),o=new Set,i=searchIndex.filter(e=>{if(!e||!e.permalink)return!1;if(o.has(e.permalink))return!1;o.add(e.permalink);const t=e.title?.toLowerCase().includes(n),s=e.summary?.toLowerCase().includes(n),i=e.content?.toLowerCase().includes(n),a=e.tags?.some(e=>e.toLowerCase().includes(n));return t||s||i||a}).slice(0,SEARCH_RESULTS_LIMIT);if(i.length===0){t.innerHTML='<div class="search-result-empty">No results found</div>',toggleSearchResultsVisibility();return}t.innerHTML=i.map(t=>`
<a href="${t.permalink}" class="search-result-item">
<div class="search-result-title">${highlightMatch(t.title||"",e)}</div>
${t.summary?`<div class="search-result-summary">${highlightMatch(t.summary.substring(0,150),e)}...</div>`:""}
${t.date?`<div class="search-result-date">
<svg class="search-result-date-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
${formatDate(t.date)}
</div>`:""}
</a>
`).join(""),toggleSearchResultsVisibility()}function toggleClearButton(){const e=document.getElementById("search-input-clear"),t=document.getElementById("search-input");if(!e||!t)return;t.value.length>0?e.classList.add("visible"):e.classList.remove("visible")}function openSearchModal(){const e=document.getElementById("search-modal");if(!e)return;e.setAttribute("aria-hidden","false"),document.body.style.overflow="hidden",setTimeout(()=>{const e=document.getElementById("search-input");e?.focus(),toggleClearButton()},MODAL_FOCUS_DELAY)}function closeSearchModal(){const t=document.getElementById("search-modal");if(!t)return;t.setAttribute("aria-hidden","true"),document.body.style.overflow="";const n=document.getElementById("search-input"),e=document.getElementById("search-results");n&&(n.value="",toggleClearButton()),e&&(e.innerHTML="",e.style.display="none")}function setupSearchInput(){const e=document.getElementById("search-input");if(!e)return;const t=debounce(e=>{performSearch(e)},SEARCH_DEBOUNCE_DELAY);e.addEventListener("input",e=>{const n=e.target.value;toggleClearButton(),t(n)}),toggleClearButton()}function setupClearButton(){const e=document.getElementById("search-input-clear");if(!e)return;e.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation();const t=document.getElementById("search-input"),n=document.getElementById("search-results");t&&(t.value="",t.focus(),toggleClearButton(),n&&(n.innerHTML="",n.style.display="none"),t.dispatchEvent(new Event("input",{bubbles:!0})))})}function setupKeyboardShortcuts(){document.addEventListener("keydown",e=>{const t=document.getElementById("search-modal");e.key==="Escape"&&t?.getAttribute("aria-hidden")==="false"&&closeSearchModal()})}function setupModalClickHandling(){const e=document.getElementById("search-modal"),t=e?.querySelector(".search-modal-container");t?.addEventListener("click",e=>{e.stopPropagation()})}function initSearch(){const e=document.getElementById("search-toggle"),t=document.getElementById("search-modal-backdrop"),n=document.getElementById("search-modal-close");e&&e.addEventListener("click",openSearchModal),t&&t.addEventListener("click",closeSearchModal),n&&n.addEventListener("click",closeSearchModal),setupSearchInput(),setupClearButton(),setupKeyboardShortcuts(),setupModalClickHandling(),loadSearchIndex()}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initSearch):initSearch()})();function toggleScrollButton(){const e=document.getElementById("scroll-to-top");if(!e)return;window.scrollY>SCROLL_THRESHOLD?e.classList.add("visible"):e.classList.remove("visible")}function scrollToTop(){window.scrollTo({top:0,behavior:"smooth"})}function initScrollToTop(){const e=document.getElementById("scroll-to-top");if(!e)return;window.addEventListener("scroll",toggleScrollButton),e.addEventListener("click",scrollToTop)}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initScrollToTop):initScrollToTop()})();function initGlassDockNavigation(){const t=document.querySelector(".glass-dock-toggle"),e=document.querySelector(".glass-dock-list");if(!t||!e)return;t.addEventListener("click",function(){const t=this.getAttribute("aria-expanded")==="true";this.setAttribute("aria-expanded",!t),e.classList.toggle("mobile-open",!t)}),e.querySelectorAll(".glass-dock-link").forEach(n=>{n.addEventListener("click",function(){window.innerWidth<=MOBILE_BREAKPOINT&&(t.setAttribute("aria-expanded","false"),e.classList.remove("mobile-open"))})}),document.addEventListener("click",function(n){window.innerWidth<=MOBILE_BREAKPOINT&&!t.contains(n.target)&&!e.contains(n.target)&&(t.setAttribute("aria-expanded","false"),e.classList.remove("mobile-open"))})}function initSmoothScroll(){document.querySelectorAll('a[href^="#"]').forEach(e=>{e.addEventListener("click",function(e){const t=this.getAttribute("href");if(t==="#"||t.length<=1)return;const n=document.querySelector(t);n&&(e.preventDefault(),n.scrollIntoView({behavior:"smooth",block:"start"}))})})}function initPostCardClick(){document.querySelectorAll(".post-card[data-post-url]").forEach(e=>{e.addEventListener("click",function(e){if(e.target.closest("a"))return;const t=this.getAttribute("data-post-url");t&&(window.location.href=t)})})}function initNavigation(){initGlassDockNavigation(),initSmoothScroll(),initPostCardClick()}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initNavigation):initNavigation()})();function isWideScreen(){return window.innerWidth>WIDE_SCREEN_BREAKPOINT}function expandTOC(e,t){e.setAttribute("aria-expanded","true"),t.classList.add("expanded")}function collapseTOC(e,t){e.setAttribute("aria-expanded","false"),t.classList.remove("expanded")}function toggleTOC(e,t){const n=e.getAttribute("aria-expanded")==="true";n?collapseTOC(e,t):expandTOC(e,t)}function initializeTOCState(e,t){isWideScreen()?expandTOC(e,t):collapseTOC(e,t)}function updateActiveTOCItem(e,t,n){const o=window.scrollY+TOC_SCROLL_OFFSET;let s=null;for(let t=e.length-1;t>=0;t--){const{element:n}=e[t];if(n&&n.offsetTop<=o){s=e[t];break}}if(t.forEach(e=>e.classList.remove("active")),s&&(s.link.classList.add("active"),n.classList.contains("expanded")&&s.link)){const e=s.link.offsetTop,t=s.link.offsetHeight,o=n.offsetHeight,i=n.scrollTop;e<i?n.scrollTo({top:e-20,behavior:"smooth"}):e+t>i+o&&n.scrollTo({top:e-o+t+20,behavior:"smooth"})}}function initTOC(){const i=document.getElementById("post-toc"),t=document.getElementById("toc-toggle"),e=document.getElementById("toc-content");if(!i||!t||!e)return;const n=i.querySelectorAll('a[href^="#"]'),s=Array.from(n).map(e=>{const n=e.getAttribute("href"),t=n.substring(1),s=document.getElementById(t);return{link:e,element:s,id:t}}).filter(e=>e.element);t.addEventListener("click",()=>{toggleTOC(t,e)});let a;if(window.addEventListener("resize",()=>{clearTimeout(a),a=setTimeout(()=>{initializeTOCState(t,e)},TOC_RESIZE_DEBOUNCE)}),initializeTOCState(t,e),s.length===0)return;let o=!1;window.addEventListener("scroll",()=>{o||(window.requestAnimationFrame(()=>{updateActiveTOCItem(s,n,e),o=!1}),o=!0)}),updateActiveTOCItem(s,n,e)}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initTOC):initTOC()})();function initFilters(){const r=document.getElementById("filter-year-month"),j=document.getElementById("clear-filters"),h=document.getElementById("posts-container"),f=document.getElementById("filtered-count"),n=document.getElementById("tag-search-input"),t=document.getElementById("tag-search-results"),l=document.getElementById("selected-tags-container"),b=document.getElementById("all-tags-data");if(!h)return;const m=Array.from(b?.querySelectorAll("[data-tag]")||[]).map(e=>e.getAttribute("data-tag")),o=new Set;let e=-1;function p(e){const t=document.createElement("label");return t.className="filter-tag-checkbox",t.innerHTML=`
<input type="checkbox" value="${e}" class="filter-tag-input" checked>
<span class="filter-tag-label">${e}</span>
`,t}function c(e){if(o.has(e))return;o.add(e);const t=p(e);t.querySelector(".filter-tag-input").addEventListener("change",function(){this.checked||g(e),a()}),l.appendChild(t),a()}function g(e){o.delete(e);const t=l.querySelector(`input[value="${e}"]`)?.closest(".filter-tag-checkbox");t&&t.remove(),a()}function u(s){if(!t)return;const i=s.toLowerCase().trim();if(!i){t.innerHTML="",t.style.display="none",e=-1;return}const a=m.filter(e=>e.toLowerCase().includes(i)&&!o.has(e));if(a.length===0){t.innerHTML='<div class="tag-search-no-results">No tags found</div>',t.style.display="block",e=-1;return}t.innerHTML=a.map((t,n)=>`<div class="tag-search-result-item ${n===e?"selected":""}" data-tag="${t}" data-index="${n}">${t}</div>`).join(""),t.style.display="block",t.querySelectorAll(".tag-search-result-item").forEach(s=>{s.addEventListener("click",()=>{const o=s.getAttribute("data-tag");c(o),n.value="",t.style.display="none",e=-1,n.focus()})}),d()}function d(){const n=t.querySelectorAll(".tag-search-result-item");n.forEach((t,n)=>{n===e?t.classList.add("selected"):t.classList.remove("selected")})}function v(){const s=t.querySelectorAll(".tag-search-result-item");if(s.length===0){const i=n.value.trim(),s=m.find(e=>e.toLowerCase()===i.toLowerCase()&&!o.has(e));if(s){c(s),n.value="",t.style.display="none",e=-1;return}return}if(e>=0&&e<s.length){const o=s[e],i=o.getAttribute("data-tag");c(i),n.value="",t.style.display="none",e=-1}else if(s.length>0){const o=s[0],i=o.getAttribute("data-tag");c(i),n.value="",t.style.display="none",e=-1}}function a(){const e=r?.value||"",t=Array.from(o),s=h.querySelectorAll(".post-card");let n=0;s.forEach(s=>{const o=s.getAttribute("data-year-month")||"",i=s.getAttribute("data-tags")?.split(",")||[],a=!e||o===e,r=t.length===0||t.some(e=>i.includes(e));a&&r?(s.style.display="",n++):s.style.display="none"}),f&&(f.textContent=n)}r?.addEventListener("change",a),n&&(n.addEventListener("input",t=>{e=-1,u(t.target.value)}),n.addEventListener("focus",()=>{n.value.trim()&&u(n.value)}),n.addEventListener("keydown",s=>{const o=t.querySelectorAll(".tag-search-result-item");s.key==="ArrowDown"?(s.preventDefault(),o.length>0&&(e=e<o.length-1?e+1:0,d(),o[e]&&o[e].scrollIntoView({block:"nearest",behavior:"smooth"}))):s.key==="ArrowUp"?(s.preventDefault(),o.length>0&&(e=e>0?e-1:o.length-1,d(),o[e]&&o[e].scrollIntoView({block:"nearest",behavior:"smooth"}))):s.key==="Enter"?(s.preventDefault(),v()):s.key==="Escape"&&(t.style.display="none",e=-1,n.blur())}),document.addEventListener("click",s=>{!n.contains(s.target)&&!t.contains(s.target)&&(t.style.display="none",e=-1)})),j?.addEventListener("click",()=>{r&&(r.value=""),o.clear(),l.innerHTML="",n&&(n.value=""),t&&(t.style.display="none"),a()});const i=document.getElementById("filter-toggle-btn"),s=document.getElementById("posts-filter-content");i&&s&&(s.style.display="flex",i.addEventListener("click",()=>{const e=i.getAttribute("aria-expanded")==="true";if(e)s.style.maxHeight=s.scrollHeight+"px",s.offsetHeight,s.style.maxHeight="0px",s.classList.remove("expanded");else{s.style.maxHeight="none";const e=s.scrollHeight;s.style.maxHeight="0px",s.offsetHeight,s.style.maxHeight=Math.max(e,300)+"px",s.classList.add("expanded")}i.setAttribute("aria-expanded",!e),i.classList.toggle("expanded",!e)}))}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initFilters):initFilters()})();function initCollapsibleCodeBlocks(){const e=document.querySelector(".post-content-main");if(!e)return;const t=e.querySelectorAll(".highlight"),n=Array.from(e.querySelectorAll("pre")).filter(e=>!e.closest(".highlight")),s=[...t,...n];s.forEach(e=>{let n=e.closest(".code-block-wrapper"),s=!1;n||(n=document.createElement("div"),n.className="code-block-wrapper collapsed",s=!0);let t=n.querySelector(".code-block-copy");if(!t){t=document.createElement("button"),t.className="code-block-copy",t.setAttribute("aria-label","Copy code"),t.innerHTML=`
<svg class="copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path>
</svg>
<svg class="checkmark-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24" style="display: none;">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
</svg>
<span class="copy-text">Copy</span>
<span class="copied-text" style="display: none;">Copied!</span>
`;const o=()=>{const t=e.querySelector("code")||e;return t.textContent||t.innerText||""};t.addEventListener("click",async e=>{e.stopPropagation();const s=o(),n=window.innerWidth<=768;try{await navigator.clipboard.writeText(s);const e=t.querySelector(".copy-text"),o=t.querySelector(".copied-text"),i=t.querySelector(".copy-icon"),a=t.querySelector(".checkmark-icon");t.setAttribute("aria-label","Code copied"),i.style.display="none",a.style.display="block",n||(e.style.display="none",o.style.display="inline"),t.classList.add("copied"),t.setAttribute("aria-label","Code copied"),setTimeout(()=>{a.style.display="none",i.style.display="block",n||(o.style.display="none",e.style.display="inline"),t.classList.remove("copied"),t.setAttribute("aria-label","Copy code")},2e3)}catch{const e=document.createElement("textarea");e.value=s,e.style.position="fixed",e.style.opacity="0",document.body.appendChild(e),e.select();try{document.execCommand("copy");const e=t.querySelector(".copy-text"),s=t.querySelector(".copied-text"),o=t.querySelector(".copy-icon"),i=t.querySelector(".checkmark-icon");o.style.display="none",i.style.display="block",n||(e.style.display="none",s.style.display="inline"),t.classList.add("copied"),t.setAttribute("aria-label","Code copied"),setTimeout(()=>{o.style.display="block",i.style.display="none",n||(e.style.display="inline",s.style.display="none"),t.classList.remove("copied"),t.setAttribute("aria-label","Copy code")},2e3)}catch(e){console.error("Failed to copy code:",e)}document.body.removeChild(e)}});const s=n.querySelector(".code-block-toggle");s?n.insertBefore(t,s):n.insertBefore(t,n.firstChild)}if(s){const t=document.createElement("button");t.className="code-block-toggle",t.setAttribute("aria-label","Toggle code block"),t.setAttribute("aria-expanded","false"),t.innerHTML=`
<span>Expand</span>
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"></path>
</svg>
`;const s=document.createElement("div");s.className="code-block-content",e.parentNode.insertBefore(n,e),n.appendChild(t),n.appendChild(s),s.appendChild(e),t.addEventListener("click",()=>{const e=n.classList.contains("collapsed");n.classList.toggle("collapsed"),t.setAttribute("aria-expanded",!e),t.querySelector("span").textContent=e?"Collapse":"Expand"})}})}(function(){document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initCollapsibleCodeBlocks):initCollapsibleCodeBlocks()})(),function(){"use strict";function e(){const e=document.querySelectorAll(".alert-collapsible .alert-header");e.forEach(e=>{if(e.dataset.initialized==="true")return;e.dataset.initialized="true",e.addEventListener("click",function(){const e=this.closest(".alert-collapsible"),t=e.querySelector(".alert-content"),n=e.querySelector(".alert-toggle");if(!t||!n)return;const s=t.style.display==="none"||e.dataset.collapsed==="true";s?(t.style.display="block",n.textContent="",e.dataset.collapsed="false"):(t.style.display="none",n.textContent="+",e.dataset.collapsed="true")})})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",e):e(),typeof window!="undefined"&&(window.initAlertToggles=e)}()