From f6e975808c5cd2af8678dd1bfe23783856f292b7 Mon Sep 17 00:00:00 2001 From: kascit Date: Wed, 13 May 2026 00:31:05 +0530 Subject: [PATCH] logo raw url --- .github/raw-mirror-paths.txt | 2 + static/js/core/trusted-types.js | 9 +- static/js/shell.min.js | 1077 ++++++++++++++++++++++++++++++- templates/shell-chrome.html | 4 +- 4 files changed, 1086 insertions(+), 6 deletions(-) diff --git a/.github/raw-mirror-paths.txt b/.github/raw-mirror-paths.txt index 1789345..68f5409 100644 --- a/.github/raw-mirror-paths.txt +++ b/.github/raw-mirror-paths.txt @@ -2,3 +2,5 @@ # Keep one path per line. rss.xml +images/branding/logo-light.png +images/branding/logo-dark.png diff --git a/static/js/core/trusted-types.js b/static/js/core/trusted-types.js index 5feea9c..503dd8f 100644 --- a/static/js/core/trusted-types.js +++ b/static/js/core/trusted-types.js @@ -8,6 +8,13 @@ * Must run BEFORE any code that touches DOM injection sinks. */ export function ensureDefaultPolicy() { + // Avoid attempting to create the policy if it already exists. Creating + // a TrustedTypes policy with the same name can trigger a CSP violation + // (browsers may block duplicate creations when CSP doesn't allow + // duplicates). The main site sets `window.__defaultPolicy` when it + // bootstraps — check that first to keep this function idempotent. + if (window.__defaultPolicy) return; + if (window.trustedTypes && window.trustedTypes.createPolicy) { try { window.__defaultPolicy = window.trustedTypes.createPolicy("default", { @@ -19,7 +26,7 @@ export function ensureDefaultPolicy() { }, }); } catch { - /* policy already exists — safe to ignore */ + /* policy already exists or creation blocked by CSP — safe to ignore */ } } diff --git a/static/js/shell.min.js b/static/js/shell.min.js index 3ed0453..7127df9 100644 --- a/static/js/shell.min.js +++ b/static/js/shell.min.js @@ -1,4 +1,531 @@ -(()=>{function H(){if(window.__siteConfig)return window.__siteConfig;let e=document.getElementById("site-config");if(e)try{return window.__siteConfig=JSON.parse(e.textContent),window.__siteConfig}catch(t){console.error("[SiteConfig] Failed to parse JSON config",t)}return window.__siteConfig=window.SiteNavConfig||{},window.__siteConfig}var A="https://dhanur.me",O=(()=>{let e=window.location.hostname;if(e==="localhost"||e==="127.0.0.1")return"";let t=e.split(".");return t.length>=2?"."+t.slice(-2).join("."):""})();var ye={MOBILE:0,SM:640,MD:768,LG:1024,XL:1280,XXL:1536},f={isDesktop:!1,isMobile:!1,mediaQueries:{},listeners:new Set},G=!1;function M(){let e=f.isDesktop;f.isDesktop=f.mediaQueries.hoverCapable?.matches&&f.mediaQueries.finePointer?.matches,f.isMobile=!f.isDesktop,e!==f.isDesktop&&ve()}function ve(){f.listeners.forEach(e=>{try{e({isDesktop:f.isDesktop,isMobile:f.isMobile,isLargeScreen:we(),isTouchDevice:be(),prefersReducedMotion:Se()})}catch(t){console.error(t)}})}function j(){G||typeof window.matchMedia=="function"&&(G=!0,f.mediaQueries.hoverCapable=window.matchMedia("(hover: hover)"),f.mediaQueries.finePointer=window.matchMedia("(pointer: fine)"),f.mediaQueries.largeScreen=window.matchMedia(`(min-width: ${ye.LG}px)`),f.mediaQueries.touchDevice=window.matchMedia("(pointer: coarse)"),f.mediaQueries.reducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)"),M(),Object.values(f.mediaQueries).forEach(e=>{e.addListener?e.addListener(M):e.addEventListener&&e.addEventListener("change",M)}))}var we=()=>f.mediaQueries.largeScreen?.matches||!1,be=()=>f.mediaQueries.touchDevice?.matches||!1,Se=()=>f.mediaQueries.reducedMotion?.matches||!1;function z(e){let t=`${e}=`,n=document.cookie?document.cookie.split(";"):[];for(let a of n){let o=a.trim();if(o.startsWith(t))return decodeURIComponent(o.slice(t.length))}return""}function F(e,t,n={}){let{maxAgeSeconds:a,domain:o,path:r="/",sameSite:i="Lax"}=n,c=typeof a=="number"?`; Max-Age=${a}`:"",s=o?`; Domain=${o}`:"";document.cookie=`${e}=${encodeURIComponent(t)}; Path=${r}; SameSite=${i}; Secure${c}${s}`}var Ae={dark:"dark",light:"light"},Le=["auto","light","dark"],Q={dark:"#010409",light:"#f6f8fa"},Ce=240,w="auto",y=window.matchMedia?window.matchMedia("(prefers-color-scheme: dark)"):null,L=null;function C(e,t="auto"){let n=String(e||"").trim().toLowerCase();return Le.includes(n)?n:n.includes("dark")?"dark":n.includes("light")?"light":t}function ke(){let e=window.__getThemeCookie?window.__getThemeCookie():z("theme")||null;return C(e,"auto")}function qe(e){let t=C(e,"auto");if(window.__setThemeCookie){window.__setThemeCookie(t);return}F("theme",t,{maxAgeSeconds:31536e3,domain:O||void 0,path:"/",sameSite:"Lax",secure:window.location.protocol==="https:"})}function T(e){let t=C(e,"auto");return window.__resolveColorset?window.__resolveColorset(t):t==="auto"?y&&y.matches?"dark":"light":t}function D(e){let t=Ae[e]||e;document.documentElement.setAttribute("data-theme",t),document.documentElement.style.backgroundColor=Q[e]||Q.dark,e==="dark"?(document.documentElement.classList.add("dark"),document.documentElement.classList.remove("light"),document.documentElement.style.colorScheme="dark"):(document.documentElement.classList.add("light"),document.documentElement.classList.remove("dark"),document.documentElement.style.colorScheme="light");function n(a,o){document.querySelectorAll(a).forEach(r=>{r.classList.remove("hidden","invisible"),r.style.opacity=o?"1":"0",r.style.visibility=o?"visible":"hidden",r.style.pointerEvents=o?"":"none"})}n(".logo-dark",e==="dark"),n(".logo-light",e==="light"),n(".hero-dark",e==="dark"),n(".hero-light",e==="light")}function W(){let e=document.documentElement;e.classList.add("is-theme-switching"),L&&window.clearTimeout(L),L=window.setTimeout(()=>{e.classList.remove("is-theme-switching"),L=null},Ce)}function I(){document.querySelectorAll(".theme-switcher").forEach(e=>{e.querySelectorAll("[data-theme-mode]").forEach(t=>{let a=t.getAttribute("data-theme-mode")===w;t.style.background=a?"color-mix(in oklab, var(--color-base-content) 20%, transparent)":"",t.style.boxShadow=a?"0 1px 3px rgba(0,0,0,0.12), inset 0 0 0 1px color-mix(in oklab, var(--color-base-content) 8%, transparent)":"",t.style.opacity=a?"1":"0.55"})})}function Ee(e){w=e,qe(e),W();let t=T(e);D(t),I(),document.dispatchEvent(new CustomEvent("themeChanged",{detail:t}))}function J(e=document){w=C(ke(),"auto");let t=T(w);if(D(t),I(),document.dispatchEvent(new CustomEvent("themeChanged",{detail:t})),e.querySelectorAll(".theme-switcher [data-theme-mode]").forEach(n=>{n.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation();let o=n.getAttribute("data-theme-mode");o&&o!==w&&Ee(o)})}),y){let n=()=>{if(w==="auto"){W();let a=T("auto");D(a),I(),document.dispatchEvent(new CustomEvent("themeChanged",{detail:a}))}};y.addEventListener?y.addEventListener("change",n):y.addListener&&y.addListener(n)}}function K({src:e,selector:t,async:n=!0,defer:a=!1,crossOrigin:o,loadedAttribute:r,onLoad:i,onError:c}){if(!e&&!t)return null;let s=t?document.querySelector(t):document.querySelector(`script[src="${e}"]`);if(s)return typeof i=="function"&&((r?s.getAttribute(r)==="1":!1)||s.readyState==="complete"?i():s.addEventListener("load",i,{once:!0})),typeof c=="function"&&s.addEventListener("error",c,{once:!0}),s;let l=document.createElement("script"),u=window.__defaultPolicy;return l.src=u?u.createScriptURL(e):e,l.async=n,l.defer=a,o&&(l.crossOrigin=o),l.addEventListener("load",()=>{r&&l.setAttribute(r,"1"),typeof i=="function"&&i()},{once:!0}),typeof c=="function"&&l.addEventListener("error",c,{once:!0}),document.head.appendChild(l),l}function q(){return!window.AUTH||typeof window.AUTH!="object"?null:window.AUTH}function xe(e){let t=!1;return(...n)=>{t||(t=!0,e(...n))}}function p(...e){return e.find(Boolean)||null}function S(...e){e.forEach(t=>t?.classList.remove("hidden"))}function k(...e){e.forEach(t=>t?.classList.add("hidden"))}function b(e,t){e&&(e.textContent=t)}function R(e,t){if(e){if(t){e.src=t;return}e.removeAttribute("src")}}function V(e,t,n,a,o){e.querySelectorAll(t).forEach(r=>{r.addEventListener(n,a,o)})}function _e(e){let t=xe(e);if(q()){t();return}document.addEventListener("authReady",t,{once:!0}),K({src:"https://auth.dhanur.me/auth-client.js",selector:'script[src*="auth-client.js"]',defer:!0,onLoad:()=>{let n=q();n&&typeof n.onReady=="function"?n.onReady(()=>t()):t()},onError:()=>{console.warn("[Auth] Could not load auth-client.js")}}),window.setTimeout(()=>{q()&&t()},2e3)}function Me(e){if(!e)return"";try{let t=new Date(e);return`resets ${["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][t.getUTCMonth()]} ${t.getUTCDate()}`}catch{return""}}function X(e,t){if(!t)return;let n=t.unlimited||t.balance===-1,a=n?"\u221E":String(t.balance),o=n?"":Me(t.periodEnd),r=e.querySelector('[data-auth="credits-row"]');if(r){r.classList.remove("hidden");let c=r.querySelector('[data-auth="credits-balance"]'),s=r.querySelector('[data-auth="credits-reset"]');c&&(c.textContent=a),s&&(s.textContent=o)}let i=e.querySelector('[data-auth="sidebar-credits-row"]');if(i){i.classList.remove("hidden");let c=i.querySelector('[data-auth="sidebar-credits-balance"]'),s=i.querySelector('[data-auth="sidebar-credits-reset"]');c&&(c.textContent=a),s&&(s.textContent=o)}}function Te(e){e.querySelector('[data-auth="credits-row"]')?.classList.add("hidden"),e.querySelector('[data-auth="sidebar-credits-row"]')?.classList.add("hidden")}function Y(e=document,t=null){e.__authIntegrationBound||(e.__authIntegrationBound=!0,_e(()=>{let n=q();if(!n)return;let a=e.querySelector(".navbar"),o=e.querySelector("[data-sidebar-root]")||e.querySelector("#navigation-drawer"),r=e.querySelector("[data-sidebar-account]"),i={navGuestAvatar:p(e.querySelector('[data-auth="nav-guest-avatar"]'),a?.querySelector('[data-dropdown="account"] .bg-base-300')),navAuthedAvatar:p(e.querySelector('[data-auth="nav-authed-avatar"]'),a?.querySelector('[data-dropdown="account"] .ring-primary')),navAvatarImg:p(e.querySelector('[data-auth="nav-authed-avatar"] img'),a?.querySelector('[data-dropdown="account"] .ring-primary img')),navAuthedHeader:p(e.querySelector('[data-auth="nav-authed-header"]'),a?.querySelector('.dropdown-panel [data-auth="nav-name"]')?.closest(".border-b")),navGuestHeader:p(e.querySelector('[data-auth="nav-guest-header"]'),a?.querySelector(".dropdown-panel .fa-user")?.closest(".border-b")),navAuthedHeaderImg:e.querySelector('[data-auth="nav-authed-header-avatar"]'),navName:p(e.querySelector('[data-auth="nav-name"]'),a?.querySelector('[data-auth="name"]')),navEmail:p(e.querySelector('[data-auth="nav-email"]'),a?.querySelector('[data-auth="email"]')),navRole:p(e.querySelector('[data-auth="nav-role"]'),a?.querySelector('[data-auth="role"]')),navLoginItem:a?.querySelector('[data-auth="login-item"]')||null,navAccountItem:a?.querySelector('[data-auth="account-item"]')||null,navLogoutItem:a?.querySelector('[data-auth="logout-item"]')||null,sidebarGuestAvatar:p(e.querySelector('[data-auth="sidebar-guest-avatar"]'),r?.querySelector(".bg-base-300")),sidebarAuthedAvatar:p(e.querySelector('[data-auth="sidebar-authed-avatar"]'),r?.querySelector(".ring-primary")),sidebarAvatarImg:p(e.querySelector('[data-auth="sidebar-authed-avatar"] img'),r?.querySelector(".ring-primary img")),sidebarName:p(e.querySelector('[data-auth="sidebar-name"]'),r?.querySelector(".font-semibold")),sidebarEmail:p(e.querySelector('[data-auth="sidebar-email"]'),r?.querySelector(".text-xs.opacity-60")),sidebarLoginBtn:o?.querySelector('[data-auth="sidebar-login-btn"]')||null,sidebarLogoutBtn:o?.querySelector('[data-auth="sidebar-logout-btn"]')||null,sidebarAccountBtn:o?.querySelector('[data-auth="sidebar-account-btn"]')||null};function c(s){if(!s)return;let l=s.authenticated,u=s.user,h=u?.avatar_url||"",m=u?.name||"User";if(l&&u){if(k(i.navGuestAvatar,i.navGuestHeader,i.navLoginItem),S(i.navAuthedAvatar,i.navAuthedHeader,i.navAccountItem,i.navLogoutItem),R(i.navAvatarImg,h),R(i.navAuthedHeaderImg,h),b(i.navName,m),b(i.navEmail,u.email||""),i.navRole){let d=s.role||"user";i.navRole.textContent=d.toUpperCase(),i.navRole.className=d==="admin"?"badge badge-sm badge-error":"badge badge-sm badge-success",S(i.navRole)}k(i.sidebarGuestAvatar,i.sidebarLoginBtn),S(i.sidebarAuthedAvatar,i.sidebarLogoutBtn,i.sidebarAccountBtn),R(i.sidebarAvatarImg,h),b(i.sidebarName,m),b(i.sidebarEmail,u.email||""),X(e,s.credits||null)}else S(i.navGuestAvatar,i.navGuestHeader,i.navLoginItem),k(i.navAuthedAvatar,i.navAuthedHeader,i.navRole,i.navAccountItem,i.navLogoutItem),S(i.sidebarGuestAvatar,i.sidebarLoginBtn),k(i.sidebarAuthedAvatar,i.sidebarLogoutBtn,i.sidebarAccountBtn),b(i.sidebarName,"Guest"),b(i.sidebarEmail,"Not signed in"),Te(e);typeof t=="function"&&t(s)}typeof n.onReady=="function"?n.onReady(s=>c(s?.status||s||n.status||null)):n.status&&c(n.status),document.addEventListener("authChanged",s=>c(s.detail)),document.addEventListener("creditsChanged",s=>X(e,s.detail)),V(e,'[data-auth="login-btn"], [data-auth="sidebar-login-btn"]',"click",s=>{s.preventDefault(),typeof n.login=="function"&&n.login()}),V(e,'[data-auth="logout-btn"], [data-auth="sidebar-logout-btn"]',"click",s=>{if(s.preventDefault(),typeof n.logout=="function"){let l=n.logout();l&&typeof l.then=="function"?l.then(()=>window.location.reload()).catch(u=>{console.warn("[Auth] Logout failed:",u),window.location.reload()}):window.location.reload()}})}))}var De=` +(() => { + function H() { + if (window.__siteConfig) return window.__siteConfig; + let e = document.getElementById("site-config"); + if (e) + try { + return ( + (window.__siteConfig = JSON.parse(e.textContent)), + window.__siteConfig + ); + } catch (t) { + console.error("[SiteConfig] Failed to parse JSON config", t); + } + return ( + (window.__siteConfig = window.SiteNavConfig || {}), + window.__siteConfig + ); + } + var A = "https://dhanur.me", + O = (() => { + let e = window.location.hostname; + if (e === "localhost" || e === "127.0.0.1") return ""; + let t = e.split("."); + return t.length >= 2 ? "." + t.slice(-2).join(".") : ""; + })(); + var ye = { MOBILE: 0, SM: 640, MD: 768, LG: 1024, XL: 1280, XXL: 1536 }, + f = { isDesktop: !1, isMobile: !1, mediaQueries: {}, listeners: new Set() }, + G = !1; + function M() { + let e = f.isDesktop; + ((f.isDesktop = + f.mediaQueries.hoverCapable?.matches && + f.mediaQueries.finePointer?.matches), + (f.isMobile = !f.isDesktop), + e !== f.isDesktop && ve()); + } + function ve() { + f.listeners.forEach((e) => { + try { + e({ + isDesktop: f.isDesktop, + isMobile: f.isMobile, + isLargeScreen: we(), + isTouchDevice: be(), + prefersReducedMotion: Se(), + }); + } catch (t) { + console.error(t); + } + }); + } + function j() { + G || + (typeof window.matchMedia == "function" && + ((G = !0), + (f.mediaQueries.hoverCapable = window.matchMedia("(hover: hover)")), + (f.mediaQueries.finePointer = window.matchMedia("(pointer: fine)")), + (f.mediaQueries.largeScreen = window.matchMedia( + `(min-width: ${ye.LG}px)`, + )), + (f.mediaQueries.touchDevice = window.matchMedia("(pointer: coarse)")), + (f.mediaQueries.reducedMotion = window.matchMedia( + "(prefers-reduced-motion: reduce)", + )), + M(), + Object.values(f.mediaQueries).forEach((e) => { + e.addListener + ? e.addListener(M) + : e.addEventListener && e.addEventListener("change", M); + }))); + } + var we = () => f.mediaQueries.largeScreen?.matches || !1, + be = () => f.mediaQueries.touchDevice?.matches || !1, + Se = () => f.mediaQueries.reducedMotion?.matches || !1; + function z(e) { + let t = `${e}=`, + n = document.cookie ? document.cookie.split(";") : []; + for (let a of n) { + let o = a.trim(); + if (o.startsWith(t)) return decodeURIComponent(o.slice(t.length)); + } + return ""; + } + function F(e, t, n = {}) { + let { maxAgeSeconds: a, domain: o, path: r = "/", sameSite: i = "Lax" } = n, + c = typeof a == "number" ? `; Max-Age=${a}` : "", + s = o ? `; Domain=${o}` : ""; + document.cookie = `${e}=${encodeURIComponent(t)}; Path=${r}; SameSite=${i}; Secure${c}${s}`; + } + var Ae = { dark: "dark", light: "light" }, + Le = ["auto", "light", "dark"], + Q = { dark: "#010409", light: "#f6f8fa" }, + Ce = 240, + w = "auto", + y = window.matchMedia + ? window.matchMedia("(prefers-color-scheme: dark)") + : null, + L = null; + function C(e, t = "auto") { + let n = String(e || "") + .trim() + .toLowerCase(); + return Le.includes(n) + ? n + : n.includes("dark") + ? "dark" + : n.includes("light") + ? "light" + : t; + } + function ke() { + let e = window.__getThemeCookie + ? window.__getThemeCookie() + : z("theme") || null; + return C(e, "auto"); + } + function qe(e) { + let t = C(e, "auto"); + if (window.__setThemeCookie) { + window.__setThemeCookie(t); + return; + } + F("theme", t, { + maxAgeSeconds: 31536e3, + domain: O || void 0, + path: "/", + sameSite: "Lax", + secure: window.location.protocol === "https:", + }); + } + function T(e) { + let t = C(e, "auto"); + return window.__resolveColorset + ? window.__resolveColorset(t) + : t === "auto" + ? y && y.matches + ? "dark" + : "light" + : t; + } + function D(e) { + let t = Ae[e] || e; + (document.documentElement.setAttribute("data-theme", t), + (document.documentElement.style.backgroundColor = Q[e] || Q.dark), + e === "dark" + ? (document.documentElement.classList.add("dark"), + document.documentElement.classList.remove("light"), + (document.documentElement.style.colorScheme = "dark")) + : (document.documentElement.classList.add("light"), + document.documentElement.classList.remove("dark"), + (document.documentElement.style.colorScheme = "light"))); + function n(a, o) { + document.querySelectorAll(a).forEach((r) => { + (r.classList.remove("hidden", "invisible"), + (r.style.opacity = o ? "1" : "0"), + (r.style.visibility = o ? "visible" : "hidden"), + (r.style.pointerEvents = o ? "" : "none")); + }); + } + (n(".logo-dark", e === "dark"), + n(".logo-light", e === "light"), + n(".hero-dark", e === "dark"), + n(".hero-light", e === "light")); + } + function W() { + let e = document.documentElement; + (e.classList.add("is-theme-switching"), + L && window.clearTimeout(L), + (L = window.setTimeout(() => { + (e.classList.remove("is-theme-switching"), (L = null)); + }, Ce))); + } + function I() { + document.querySelectorAll(".theme-switcher").forEach((e) => { + e.querySelectorAll("[data-theme-mode]").forEach((t) => { + let a = t.getAttribute("data-theme-mode") === w; + ((t.style.background = a + ? "color-mix(in oklab, var(--color-base-content) 20%, transparent)" + : ""), + (t.style.boxShadow = a + ? "0 1px 3px rgba(0,0,0,0.12), inset 0 0 0 1px color-mix(in oklab, var(--color-base-content) 8%, transparent)" + : ""), + (t.style.opacity = a ? "1" : "0.55")); + }); + }); + } + function Ee(e) { + ((w = e), qe(e), W()); + let t = T(e); + (D(t), + I(), + document.dispatchEvent(new CustomEvent("themeChanged", { detail: t }))); + } + function J(e = document) { + w = C(ke(), "auto"); + let t = T(w); + if ( + (D(t), + I(), + document.dispatchEvent(new CustomEvent("themeChanged", { detail: t })), + e.querySelectorAll(".theme-switcher [data-theme-mode]").forEach((n) => { + n.addEventListener("click", (a) => { + (a.preventDefault(), a.stopPropagation()); + let o = n.getAttribute("data-theme-mode"); + o && o !== w && Ee(o); + }); + }), + y) + ) { + let n = () => { + if (w === "auto") { + W(); + let a = T("auto"); + (D(a), + I(), + document.dispatchEvent( + new CustomEvent("themeChanged", { detail: a }), + )); + } + }; + y.addEventListener + ? y.addEventListener("change", n) + : y.addListener && y.addListener(n); + } + } + function K({ + src: e, + selector: t, + async: n = !0, + defer: a = !1, + crossOrigin: o, + loadedAttribute: r, + onLoad: i, + onError: c, + }) { + if (!e && !t) return null; + let s = t + ? document.querySelector(t) + : document.querySelector(`script[src="${e}"]`); + if (s) + return ( + typeof i == "function" && + ((r ? s.getAttribute(r) === "1" : !1) || s.readyState === "complete" + ? i() + : s.addEventListener("load", i, { once: !0 })), + typeof c == "function" && s.addEventListener("error", c, { once: !0 }), + s + ); + let l = document.createElement("script"), + u = window.__defaultPolicy; + return ( + (l.src = u ? u.createScriptURL(e) : e), + (l.async = n), + (l.defer = a), + o && (l.crossOrigin = o), + l.addEventListener( + "load", + () => { + (r && l.setAttribute(r, "1"), typeof i == "function" && i()); + }, + { once: !0 }, + ), + typeof c == "function" && l.addEventListener("error", c, { once: !0 }), + document.head.appendChild(l), + l + ); + } + function q() { + return !window.AUTH || typeof window.AUTH != "object" ? null : window.AUTH; + } + function xe(e) { + let t = !1; + return (...n) => { + t || ((t = !0), e(...n)); + }; + } + function p(...e) { + return e.find(Boolean) || null; + } + function S(...e) { + e.forEach((t) => t?.classList.remove("hidden")); + } + function k(...e) { + e.forEach((t) => t?.classList.add("hidden")); + } + function b(e, t) { + e && (e.textContent = t); + } + function R(e, t) { + if (e) { + if (t) { + e.src = t; + return; + } + e.removeAttribute("src"); + } + } + function V(e, t, n, a, o) { + e.querySelectorAll(t).forEach((r) => { + r.addEventListener(n, a, o); + }); + } + function _e(e) { + let t = xe(e); + if (q()) { + t(); + return; + } + (document.addEventListener("authReady", t, { once: !0 }), + K({ + src: "https://auth.dhanur.me/auth-client.js", + selector: 'script[src*="auth-client.js"]', + defer: !0, + onLoad: () => { + let n = q(); + n && typeof n.onReady == "function" ? n.onReady(() => t()) : t(); + }, + onError: () => { + console.warn("[Auth] Could not load auth-client.js"); + }, + }), + window.setTimeout(() => { + q() && t(); + }, 2e3)); + } + function Me(e) { + if (!e) return ""; + try { + let t = new Date(e); + return `resets ${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][t.getUTCMonth()]} ${t.getUTCDate()}`; + } catch { + return ""; + } + } + function X(e, t) { + if (!t) return; + let n = t.unlimited || t.balance === -1, + a = n ? "\u221E" : String(t.balance), + o = n ? "" : Me(t.periodEnd), + r = e.querySelector('[data-auth="credits-row"]'); + if (r) { + r.classList.remove("hidden"); + let c = r.querySelector('[data-auth="credits-balance"]'), + s = r.querySelector('[data-auth="credits-reset"]'); + (c && (c.textContent = a), s && (s.textContent = o)); + } + let i = e.querySelector('[data-auth="sidebar-credits-row"]'); + if (i) { + i.classList.remove("hidden"); + let c = i.querySelector('[data-auth="sidebar-credits-balance"]'), + s = i.querySelector('[data-auth="sidebar-credits-reset"]'); + (c && (c.textContent = a), s && (s.textContent = o)); + } + } + function Te(e) { + (e.querySelector('[data-auth="credits-row"]')?.classList.add("hidden"), + e + .querySelector('[data-auth="sidebar-credits-row"]') + ?.classList.add("hidden")); + } + function Y(e = document, t = null) { + e.__authIntegrationBound || + ((e.__authIntegrationBound = !0), + _e(() => { + let n = q(); + if (!n) return; + let a = e.querySelector(".navbar"), + o = + e.querySelector("[data-sidebar-root]") || + e.querySelector("#navigation-drawer"), + r = e.querySelector("[data-sidebar-account]"), + i = { + navGuestAvatar: p( + e.querySelector('[data-auth="nav-guest-avatar"]'), + a?.querySelector('[data-dropdown="account"] .bg-base-300'), + ), + navAuthedAvatar: p( + e.querySelector('[data-auth="nav-authed-avatar"]'), + a?.querySelector('[data-dropdown="account"] .ring-primary'), + ), + navAvatarImg: p( + e.querySelector('[data-auth="nav-authed-avatar"] img'), + a?.querySelector('[data-dropdown="account"] .ring-primary img'), + ), + navAuthedHeader: p( + e.querySelector('[data-auth="nav-authed-header"]'), + a + ?.querySelector('.dropdown-panel [data-auth="nav-name"]') + ?.closest(".border-b"), + ), + navGuestHeader: p( + e.querySelector('[data-auth="nav-guest-header"]'), + a + ?.querySelector(".dropdown-panel .fa-user") + ?.closest(".border-b"), + ), + navAuthedHeaderImg: e.querySelector( + '[data-auth="nav-authed-header-avatar"]', + ), + navName: p( + e.querySelector('[data-auth="nav-name"]'), + a?.querySelector('[data-auth="name"]'), + ), + navEmail: p( + e.querySelector('[data-auth="nav-email"]'), + a?.querySelector('[data-auth="email"]'), + ), + navRole: p( + e.querySelector('[data-auth="nav-role"]'), + a?.querySelector('[data-auth="role"]'), + ), + navLoginItem: a?.querySelector('[data-auth="login-item"]') || null, + navAccountItem: + a?.querySelector('[data-auth="account-item"]') || null, + navLogoutItem: + a?.querySelector('[data-auth="logout-item"]') || null, + sidebarGuestAvatar: p( + e.querySelector('[data-auth="sidebar-guest-avatar"]'), + r?.querySelector(".bg-base-300"), + ), + sidebarAuthedAvatar: p( + e.querySelector('[data-auth="sidebar-authed-avatar"]'), + r?.querySelector(".ring-primary"), + ), + sidebarAvatarImg: p( + e.querySelector('[data-auth="sidebar-authed-avatar"] img'), + r?.querySelector(".ring-primary img"), + ), + sidebarName: p( + e.querySelector('[data-auth="sidebar-name"]'), + r?.querySelector(".font-semibold"), + ), + sidebarEmail: p( + e.querySelector('[data-auth="sidebar-email"]'), + r?.querySelector(".text-xs.opacity-60"), + ), + sidebarLoginBtn: + o?.querySelector('[data-auth="sidebar-login-btn"]') || null, + sidebarLogoutBtn: + o?.querySelector('[data-auth="sidebar-logout-btn"]') || null, + sidebarAccountBtn: + o?.querySelector('[data-auth="sidebar-account-btn"]') || null, + }; + function c(s) { + if (!s) return; + let l = s.authenticated, + u = s.user, + h = u?.avatar_url || "", + m = u?.name || "User"; + if (l && u) { + if ( + (k(i.navGuestAvatar, i.navGuestHeader, i.navLoginItem), + S( + i.navAuthedAvatar, + i.navAuthedHeader, + i.navAccountItem, + i.navLogoutItem, + ), + R(i.navAvatarImg, h), + R(i.navAuthedHeaderImg, h), + b(i.navName, m), + b(i.navEmail, u.email || ""), + i.navRole) + ) { + let d = s.role || "user"; + ((i.navRole.textContent = d.toUpperCase()), + (i.navRole.className = + d === "admin" + ? "badge badge-sm badge-error" + : "badge badge-sm badge-success"), + S(i.navRole)); + } + (k(i.sidebarGuestAvatar, i.sidebarLoginBtn), + S(i.sidebarAuthedAvatar, i.sidebarLogoutBtn, i.sidebarAccountBtn), + R(i.sidebarAvatarImg, h), + b(i.sidebarName, m), + b(i.sidebarEmail, u.email || ""), + X(e, s.credits || null)); + } else + (S(i.navGuestAvatar, i.navGuestHeader, i.navLoginItem), + k( + i.navAuthedAvatar, + i.navAuthedHeader, + i.navRole, + i.navAccountItem, + i.navLogoutItem, + ), + S(i.sidebarGuestAvatar, i.sidebarLoginBtn), + k(i.sidebarAuthedAvatar, i.sidebarLogoutBtn, i.sidebarAccountBtn), + b(i.sidebarName, "Guest"), + b(i.sidebarEmail, "Not signed in"), + Te(e)); + typeof t == "function" && t(s); + } + (typeof n.onReady == "function" + ? n.onReady((s) => c(s?.status || s || n.status || null)) + : n.status && c(n.status), + document.addEventListener("authChanged", (s) => c(s.detail)), + document.addEventListener("creditsChanged", (s) => X(e, s.detail)), + V( + e, + '[data-auth="login-btn"], [data-auth="sidebar-login-btn"]', + "click", + (s) => { + (s.preventDefault(), typeof n.login == "function" && n.login()); + }, + ), + V( + e, + '[data-auth="logout-btn"], [data-auth="sidebar-logout-btn"]', + "click", + (s) => { + if ((s.preventDefault(), typeof n.logout == "function")) { + let l = n.logout(); + l && typeof l.then == "function" + ? l + .then(() => window.location.reload()) + .catch((u) => { + (console.warn("[Auth] Logout failed:", u), + window.location.reload()); + }) + : window.location.reload(); + } + }, + )); + })); + } + var De = ` .access-wall { display: flex; flex-direction: column; @@ -22,7 +549,37 @@ font-size: 0.9rem; opacity: 0.7; } -`;function Ie(){if(document.getElementById("access-wall-styles"))return;let e=document.createElement("style");e.id="access-wall-styles",e.textContent=De,document.head.appendChild(e)}function Z(e={},t=null){let n=e.requireAdmin===!0;if(!(e.requireAuth===!0||n))return{allowed:!0};let o=t?.authenticated===!0,r=t?.role||"guest";return o?n&&r!=="admin"?{allowed:!1,reason:"admin_required"}:{allowed:!0}:{allowed:!1,reason:"auth_required"}}function ee(e,t="auth_required",n="This app"){if(!e)return;Ie();let a=t==="admin_required",o=a?"fa-solid fa-shield-halved":"fa-solid fa-lock",r=a?"Admin access required":"Sign in to continue",i=a?`${n} is restricted to administrator sessions.`:`${n} requires a dhanur.me account to continue.`,c=a?"Verify Admin":"Sign In",s=a?"upgrade-btn":"login-btn";e.innerHTML=` +`; + function Ie() { + if (document.getElementById("access-wall-styles")) return; + let e = document.createElement("style"); + ((e.id = "access-wall-styles"), + (e.textContent = De), + document.head.appendChild(e)); + } + function Z(e = {}, t = null) { + let n = e.requireAdmin === !0; + if (!(e.requireAuth === !0 || n)) return { allowed: !0 }; + let o = t?.authenticated === !0, + r = t?.role || "guest"; + return o + ? n && r !== "admin" + ? { allowed: !1, reason: "admin_required" } + : { allowed: !0 } + : { allowed: !1, reason: "auth_required" }; + } + function ee(e, t = "auth_required", n = "This app") { + if (!e) return; + Ie(); + let a = t === "admin_required", + o = a ? "fa-solid fa-shield-halved" : "fa-solid fa-lock", + r = a ? "Admin access required" : "Sign in to continue", + i = a + ? `${n} is restricted to administrator sessions.` + : `${n} requires a dhanur.me account to continue.`, + c = a ? "Verify Admin" : "Sign In", + s = a ? "upgrade-btn" : "login-btn"; + e.innerHTML = `

${r}

@@ -32,4 +589,518 @@ ${c}
- `;let l=window.AUTH;if(t==="admin_required"){let h=e.querySelector('[data-auth="upgrade-btn"]');h&&l&&typeof l.upgrade=="function"&&h.addEventListener("click",m=>{m.preventDefault(),l.upgrade()});return}let u=e.querySelector('[data-auth="login-btn"]');u&&l&&typeof l.login=="function"&&u.addEventListener("click",h=>{h.preventDefault(),l.login()})}var Re="https://up.dhanur.me/api/manifest",ne="dhanur_manifest_v1";var oe=[{name:"Home",url:"https://dhanur.me",icon:"fa-solid fa-house",minRole:"guest"},{name:"Linkr",url:"https://linkr.dhanur.me",icon:"fa-solid fa-link",minRole:"guest"},{name:"Tasks",url:"https://tasks.dhanur.me",icon:"fa-solid fa-clipboard-list",minRole:"guest"},{name:"Auth",url:"https://auth.dhanur.me",icon:"fa-solid fa-fingerprint",minRole:"guest"},{name:"Status",url:"https://up.dhanur.me",icon:"fa-solid fa-heart-pulse",minRole:"guest",category:"Core"}],v=null,E=new Map;function $e(e){return e==="admin"?"admin":e==="user"?"user":"guest"}function te(e){return e==="admin"?2:e==="user"?1:0}function Ne(){try{let e=localStorage.getItem(ne);if(!e)return null;let t=JSON.parse(e);if(!t||!Array.isArray(t.apps))return null;let n=Number(t._cachedAt||0);return{...t,_stale:Date.now()-n>36e5}}catch{return null}}function Be(e){try{localStorage.setItem(ne,JSON.stringify({version:e.version||"1",apps:Array.isArray(e.apps)?e.apps:oe,_cachedAt:Date.now()}))}catch{}}function $(){if(v&&Array.isArray(v.apps))return v;let e=Ne();return e&&Array.isArray(e.apps)?(v=e,e):{version:"0",apps:oe,_stale:!0}}function N(e,t="guest"){let n=te(t);return(Array.isArray(e)?e:[]).filter(a=>te(a?.minRole||"guest")<=n)}async function ae(e="guest"){let t=$e(e);if(E.has(t))return E.get(t);let n=(async()=>{try{let a=`${Re}?role=${encodeURIComponent(t)}`,o=await fetch(a,{credentials:"omit",mode:"cors",cache:"no-cache"});if(!o.ok)throw new Error(`Manifest request failed with status ${o.status}`);let r=await o.json();if(!r||!Array.isArray(r.apps))throw new Error("Manifest payload is invalid");return v={version:r.version||"1",apps:r.apps},Be(v),v}catch{return $()}})();E.set(t,n);try{return await n}finally{E.delete(t)}}var re=!1;function x(){document.querySelectorAll("[data-dropdown][data-open]").forEach(e=>{e.removeAttribute("data-open")})}function B(){return document.querySelector("[data-dropdown][data-open]")}function ie(e){let t=e.querySelector(".dropdown-panel");if(!t)return;let n=e.getBoundingClientRect(),a=t.offsetWidth||224,o=(n.width-a)/2,r=n.left+o+a-(window.innerWidth-16);r>0&&(o-=r),n.left+o<8&&(o=8-n.left),t.style.left=`${o}px`,t.style.right="auto"}function Pe(e){x(),e.setAttribute("data-open",""),ie(e)}function se(e=document){let t=e.querySelectorAll("[data-dropdown]");t.length&&(t.forEach(n=>{if(n.getAttribute("data-dropdown-init")==="1")return;let a=n.querySelector('[role="button"]');if(!a)return;let o=n.querySelector(".dropdown-panel"),r=a.classList.contains("tooltip")&&(a.hasAttribute("data-tooltip-label")||a.hasAttribute("data-tip")||!!a.querySelector(":scope > .tooltip-content"));n.setAttribute("data-dropdown-tooltip",r?"1":"0"),a.addEventListener("click",i=>{i.stopPropagation(),n.hasAttribute("data-open")?x():Pe(n)}),o&&o.addEventListener("click",i=>i.stopPropagation()),n.setAttribute("data-dropdown-init","1")}),!re&&(re=!0,document.addEventListener("click",()=>{B()&&x()}),document.addEventListener("keydown",n=>{n.key==="Escape"&&B()&&x()}),window.addEventListener("resize",()=>{let n=B();n&&ie(n)})))}var P={shellPath:"/navbar/",favicon:!0,enablePwa:!0,swPath:"/sw.js",requireAuth:!1,requireAdmin:!1,showMobileMenu:!0,showLanguage:!1,showAppsGrid:!0,showAccountButton:!0,showThemeToggle:!1};typeof window<"u"&&(window.SiteNavConfig={...P,...window.SiteNavConfig||{}});window.__componentsJS=!0;var ce=!1,le={...P,noCss:!1,showNavbar:!0};function he(){let e=H()||{},t=e.shell&&typeof e.shell=="object"?e.shell:{},n={...le,...e,...t};return(typeof n.shellPath!="string"||n.shellPath.trim()==="")&&(n.shellPath=le.shellPath),n}function me(){return window.location.origin===A}function Ue(e){if(e.enablePwa===!1||!("serviceWorker"in navigator)||!window.isSecureContext)return;let t=typeof e.swPath=="string"&&e.swPath.trim()!==""?e.swPath:"/sw.js";window.addEventListener("load",()=>{navigator.serviceWorker.register(t).catch(()=>{})},{once:!0})}function pe(e,t){if(t.noCss||document.querySelector('link[data-shell-style="main"]'))return;let n=e?"":A,a=e?`${n}/css/main.css`:`${n}/css/dui.css`,o=document.createElement("link");o.rel="stylesheet",o.href=a,o.setAttribute("data-shell-style","main"),e||(o.crossOrigin="anonymous"),document.head.appendChild(o);let r=document.createElement("link");r.rel="stylesheet",r.href=`${n}/css/font-awesome.min.css`,r.setAttribute("data-shell-style","fa"),r.media="print",r.onload=function(){this.media="all"},e||(r.crossOrigin="anonymous"),document.head.appendChild(r)}function ge(e,t){if(t.favicon===!1)return;let n=e?"/icons/":`${A}/icons/`;document.querySelectorAll('link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]').forEach(o=>o.remove());let a=[{rel:"icon",type:"image/png",sizes:"96x96",href:`${n}favicon-96x96-transparent.png`},{rel:"icon",type:"image/svg+xml",href:`${n}favicon.svg`},{rel:"apple-touch-icon",sizes:"180x180",href:`${n}apple-touch-icon-180x180-transparent.png`}];e&&a.push({rel:"shortcut icon",href:`${n}favicon-transparent.ico`}),e&&(document.querySelectorAll('link[rel="manifest"]').forEach(o=>o.remove()),a.push({rel:"manifest",href:`${n}site.webmanifest`})),a.forEach(o=>{let r=document.createElement("link");r.rel=o.rel,o.type&&(r.type=o.type),o.sizes&&(r.sizes=o.sizes),r.href=o.href,!e&&o.rel==="manifest"&&(r.crossOrigin="anonymous"),document.head.appendChild(r)})}function He(e,t){if(t.showLanguage||e.querySelectorAll('[data-nav-chrome="lang"]').forEach(n=>n.remove()),t.showAppsGrid||e.querySelectorAll('[data-nav-chrome="apps"]').forEach(n=>n.remove()),t.showAccountButton||e.querySelectorAll('[data-nav-chrome="account"]').forEach(n=>n.remove()),t.showThemeToggle||e.querySelectorAll('[data-nav-chrome="theme"]').forEach(n=>n.remove()),!t.showMobileMenu){let n=e.querySelector("#shell-mobile-toggle");if(n){let o=n.closest(".flex-none");o&&o.remove()}let a=e.querySelector("[data-shell-mobile-panel]");a&&a.remove()}}function Oe(e){let t=String(e||"").trim();if(!t)return"#";try{let n=new URL(t,window.location.origin);if(n.protocol==="http:"||n.protocol==="https:")return n.href}catch{}return"#"}function Ge(e){let t=String(e||"").trim();return!t||!/^[a-z0-9\s_-]+$/i.test(t)?"fa-solid fa-link":t}function ue(e,t){let n=e.querySelectorAll("[data-app-menu-grid], [data-apps-grid], [data-apps-grid-mobile]");if(!n.length)return;let a=Array.isArray(t)?t:[];n.forEach(o=>{let r=o.getAttribute("data-app-menu-grid"),c=r==="desktop"||!r&&o.hasAttribute("data-apps-grid")?"p-3":"p-2.5",s=document.createDocumentFragment();for(let l of a){let u=Oe(l?.url),h=Ge(l?.icon),m=String(l?.name||"App").trim()||"App",d=document.createElement("a");d.href=u,d.className=`group flex flex-col items-center gap-1.5 ${c} rounded-md hover:bg-base-200 transition-colors duration-200 no-underline hover:no-underline text-base-content`;let g=document.createElement("div");g.className="w-10 h-10 rounded-md bg-base-300/50 flex items-center justify-center group-hover:bg-primary/10 group-hover:text-primary transition-colors";let U=document.createElement("i");U.className=`${h} text-lg`;let _=document.createElement("span");_.className="text-[10px] font-medium opacity-70 group-hover:opacity-100",_.textContent=m,g.appendChild(U),d.appendChild(g),d.appendChild(_),s.appendChild(d)}o.replaceChildren(s)})}async function de(e,t){let n=$(),a=N(n.apps,t);ue(e,a);let o=await ae(t),r=N(o.apps,t);return ue(e,r),r}function je(e){let t=e.querySelector("[data-shell-mobile-panel]");if(!t)return;let n=e.querySelector("#shell-mobile-toggle"),a=t.querySelector("[data-shell-mobile-backdrop]"),o=t.querySelector("[data-shell-mobile-drawer]"),r=t.querySelector("[data-shell-mobile-close]");function i(){t.classList.remove("hidden"),o.offsetWidth,o.style.transform="translateX(0)",document.body.style.overflow="hidden"}function c(){o.style.transform="translateX(-100%)",document.body.style.overflow="",setTimeout(()=>{t.classList.add("hidden")},300)}n&&n.addEventListener("click",i),a&&a.addEventListener("click",c),r&&r.addEventListener("click",c),document.addEventListener("keydown",s=>{s.key==="Escape"&&!t.classList.contains("hidden")&&c()})}function ze(e,t){let n=e.querySelector("[data-shell-mobile-panel]");if(!n)return;let a=t?.authenticated===!0,o=t?.user,r=n.querySelector('[data-auth="mobile-guest-avatar"]'),i=n.querySelector('[data-auth="mobile-authed-avatar"]'),c=n.querySelector('[data-auth="mobile-name"]'),s=n.querySelector('[data-auth="mobile-email"]'),l=n.querySelector('[data-auth="mobile-login-btn"]'),u=n.querySelector('[data-auth="mobile-logout-btn"]'),h=n.querySelector('[data-auth="mobile-account-btn"]');if(a&&o){if(r&&r.classList.add("hidden"),i){i.classList.remove("hidden");let m=i.querySelector("img");if(m){let d=o.avatar_url;d?m.src=d:m.removeAttribute("src")}}c&&(c.textContent=o.name||"User"),s&&(s.textContent=o.email||""),l&&l.classList.add("hidden"),u&&u.classList.remove("hidden"),h&&h.classList.remove("hidden")}else r&&r.classList.remove("hidden"),i&&i.classList.add("hidden"),c&&(c.textContent="Guest"),s&&(s.textContent="Not signed in"),l&&l.classList.remove("hidden"),u&&u.classList.add("hidden"),h&&h.classList.add("hidden");u&&(u.onclick=m=>{m.preventDefault();let d=window.AUTH;if(d&&typeof d.logout=="function"){let g=d.logout();g&&typeof g.then=="function"?g.then(()=>window.location.reload()).catch(()=>window.location.reload()):window.location.reload()}}),l&&(l.onclick=m=>{m.preventDefault();let d=window.AUTH;d&&typeof d.login=="function"?d.login():window.location.href="https://auth.dhanur.me"})}function Fe(e){let t=he(),n=me(),a=!!document.querySelector('link[rel="stylesheet"][href*="/css/main.css"], link[rel="stylesheet"][href*="/css/dui.css"], link[data-shell-style="main"]'),o=!!document.querySelector('link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]');(!n||!a)&&pe(n,t),(!n||!o)&&ge(n,t),He(e,t),de(e,"guest"),j(),J(e),se(e),je(e),Y(e,r=>{let i=r?.role||"guest",c=Z(t,r),s=e.querySelector(".site-nav-slot")||e.querySelector(".drawer-content");if(!c.allowed){s&&ee(s,c.reason,document.title||"This app");return}de(e,i),ze(e,r)})}async function fe(){if(ce)return;ce=!0;let e=he();if(e.showNavbar===!1)return;Ue(e);let t=me();if(document.querySelector(".navbar")){t||Fe(document.body);return}if(!t){pe(!1,e),ge(!1,e);return}}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",fe):fe();})(); + `; + let l = window.AUTH; + if (t === "admin_required") { + let h = e.querySelector('[data-auth="upgrade-btn"]'); + h && + l && + typeof l.upgrade == "function" && + h.addEventListener("click", (m) => { + (m.preventDefault(), l.upgrade()); + }); + return; + } + let u = e.querySelector('[data-auth="login-btn"]'); + u && + l && + typeof l.login == "function" && + u.addEventListener("click", (h) => { + (h.preventDefault(), l.login()); + }); + } + var Re = "https://up.dhanur.me/api/manifest", + ne = "dhanur_manifest_v1"; + var oe = [ + { + name: "Home", + url: "https://dhanur.me", + icon: "fa-solid fa-house", + minRole: "guest", + }, + { + name: "Linkr", + url: "https://linkr.dhanur.me", + icon: "fa-solid fa-link", + minRole: "guest", + }, + { + name: "Tasks", + url: "https://tasks.dhanur.me", + icon: "fa-solid fa-clipboard-list", + minRole: "guest", + }, + { + name: "Auth", + url: "https://auth.dhanur.me", + icon: "fa-solid fa-fingerprint", + minRole: "guest", + }, + { + name: "Status", + url: "https://up.dhanur.me", + icon: "fa-solid fa-heart-pulse", + minRole: "guest", + category: "Core", + }, + ], + v = null, + E = new Map(); + function $e(e) { + return e === "admin" ? "admin" : e === "user" ? "user" : "guest"; + } + function te(e) { + return e === "admin" ? 2 : e === "user" ? 1 : 0; + } + function Ne() { + try { + let e = localStorage.getItem(ne); + if (!e) return null; + let t = JSON.parse(e); + if (!t || !Array.isArray(t.apps)) return null; + let n = Number(t._cachedAt || 0); + return { ...t, _stale: Date.now() - n > 36e5 }; + } catch { + return null; + } + } + function Be(e) { + try { + localStorage.setItem( + ne, + JSON.stringify({ + version: e.version || "1", + apps: Array.isArray(e.apps) ? e.apps : oe, + _cachedAt: Date.now(), + }), + ); + } catch {} + } + function $() { + if (v && Array.isArray(v.apps)) return v; + let e = Ne(); + return e && Array.isArray(e.apps) + ? ((v = e), e) + : { version: "0", apps: oe, _stale: !0 }; + } + function N(e, t = "guest") { + let n = te(t); + return (Array.isArray(e) ? e : []).filter( + (a) => te(a?.minRole || "guest") <= n, + ); + } + async function ae(e = "guest") { + let t = $e(e); + if (E.has(t)) return E.get(t); + let n = (async () => { + try { + let a = `${Re}?role=${encodeURIComponent(t)}`, + o = await fetch(a, { + credentials: "omit", + mode: "cors", + cache: "no-cache", + }); + if (!o.ok) + throw new Error(`Manifest request failed with status ${o.status}`); + let r = await o.json(); + if (!r || !Array.isArray(r.apps)) + throw new Error("Manifest payload is invalid"); + return ((v = { version: r.version || "1", apps: r.apps }), Be(v), v); + } catch { + return $(); + } + })(); + E.set(t, n); + try { + return await n; + } finally { + E.delete(t); + } + } + var re = !1; + function x() { + document.querySelectorAll("[data-dropdown][data-open]").forEach((e) => { + e.removeAttribute("data-open"); + }); + } + function B() { + return document.querySelector("[data-dropdown][data-open]"); + } + function ie(e) { + let t = e.querySelector(".dropdown-panel"); + if (!t) return; + let n = e.getBoundingClientRect(), + a = t.offsetWidth || 224, + o = (n.width - a) / 2, + r = n.left + o + a - (window.innerWidth - 16); + (r > 0 && (o -= r), + n.left + o < 8 && (o = 8 - n.left), + (t.style.left = `${o}px`), + (t.style.right = "auto")); + } + function Pe(e) { + (x(), e.setAttribute("data-open", ""), ie(e)); + } + function se(e = document) { + let t = e.querySelectorAll("[data-dropdown]"); + t.length && + (t.forEach((n) => { + if (n.getAttribute("data-dropdown-init") === "1") return; + let a = n.querySelector('[role="button"]'); + if (!a) return; + let o = n.querySelector(".dropdown-panel"), + r = + a.classList.contains("tooltip") && + (a.hasAttribute("data-tooltip-label") || + a.hasAttribute("data-tip") || + !!a.querySelector(":scope > .tooltip-content")); + (n.setAttribute("data-dropdown-tooltip", r ? "1" : "0"), + a.addEventListener("click", (i) => { + (i.stopPropagation(), n.hasAttribute("data-open") ? x() : Pe(n)); + }), + o && o.addEventListener("click", (i) => i.stopPropagation()), + n.setAttribute("data-dropdown-init", "1")); + }), + !re && + ((re = !0), + document.addEventListener("click", () => { + B() && x(); + }), + document.addEventListener("keydown", (n) => { + n.key === "Escape" && B() && x(); + }), + window.addEventListener("resize", () => { + let n = B(); + n && ie(n); + }))); + } + var P = { + shellPath: "/navbar/", + favicon: !0, + enablePwa: !0, + swPath: "/sw.js", + requireAuth: !1, + requireAdmin: !1, + showMobileMenu: !0, + showLanguage: !1, + showAppsGrid: !0, + showAccountButton: !0, + showThemeToggle: !1, + }; + typeof window < "u" && + (window.SiteNavConfig = { ...P, ...(window.SiteNavConfig || {}) }); + window.__componentsJS = !0; + var ce = !1, + le = { ...P, noCss: !1, showNavbar: !0 }; + function he() { + let e = H() || {}, + t = e.shell && typeof e.shell == "object" ? e.shell : {}, + n = { ...le, ...e, ...t }; + return ( + (typeof n.shellPath != "string" || n.shellPath.trim() === "") && + (n.shellPath = le.shellPath), + n + ); + } + function me() { + return window.location.origin === A; + } + function Ue(e) { + if ( + e.enablePwa === !1 || + !("serviceWorker" in navigator) || + !window.isSecureContext + ) + return; + let t = + typeof e.swPath == "string" && e.swPath.trim() !== "" + ? e.swPath + : "/sw.js"; + window.addEventListener( + "load", + () => { + navigator.serviceWorker.register(t).catch(() => {}); + }, + { once: !0 }, + ); + } + function pe(e, t) { + if (t.noCss || document.querySelector('link[data-shell-style="main"]')) + return; + let n = e ? "" : A, + a = e ? `${n}/css/main.css` : `${n}/css/dui.css`, + o = document.createElement("link"); + ((o.rel = "stylesheet"), + (o.href = a), + o.setAttribute("data-shell-style", "main"), + e || (o.crossOrigin = "anonymous"), + document.head.appendChild(o)); + let r = document.createElement("link"); + ((r.rel = "stylesheet"), + (r.href = `${n}/css/font-awesome.min.css`), + r.setAttribute("data-shell-style", "fa"), + (r.media = "print"), + (r.onload = function () { + this.media = "all"; + }), + e || (r.crossOrigin = "anonymous"), + document.head.appendChild(r)); + } + function ge(e, t) { + if (t.favicon === !1) return; + let n = e ? "/icons/" : `${A}/icons/`; + document + .querySelectorAll( + 'link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]', + ) + .forEach((o) => o.remove()); + let a = [ + { + rel: "icon", + type: "image/png", + sizes: "96x96", + href: `${n}favicon-96x96-transparent.png`, + }, + { rel: "icon", type: "image/svg+xml", href: `${n}favicon.svg` }, + { + rel: "apple-touch-icon", + sizes: "180x180", + href: `${n}apple-touch-icon-180x180-transparent.png`, + }, + ]; + (e && a.push({ rel: "shortcut icon", href: `${n}favicon-transparent.ico` }), + e && + (document + .querySelectorAll('link[rel="manifest"]') + .forEach((o) => o.remove()), + a.push({ rel: "manifest", href: `${n}site.webmanifest` })), + a.forEach((o) => { + let r = document.createElement("link"); + ((r.rel = o.rel), + o.type && (r.type = o.type), + o.sizes && (r.sizes = o.sizes), + (r.href = o.href), + !e && o.rel === "manifest" && (r.crossOrigin = "anonymous"), + document.head.appendChild(r)); + })); + } + function He(e, t) { + if ( + (t.showLanguage || + e + .querySelectorAll('[data-nav-chrome="lang"]') + .forEach((n) => n.remove()), + t.showAppsGrid || + e + .querySelectorAll('[data-nav-chrome="apps"]') + .forEach((n) => n.remove()), + t.showAccountButton || + e + .querySelectorAll('[data-nav-chrome="account"]') + .forEach((n) => n.remove()), + t.showThemeToggle || + e + .querySelectorAll('[data-nav-chrome="theme"]') + .forEach((n) => n.remove()), + !t.showMobileMenu) + ) { + let n = e.querySelector("#shell-mobile-toggle"); + if (n) { + let o = n.closest(".flex-none"); + o && o.remove(); + } + let a = e.querySelector("[data-shell-mobile-panel]"); + a && a.remove(); + } + } + function Oe(e) { + let t = String(e || "").trim(); + if (!t) return "#"; + try { + let n = new URL(t, window.location.origin); + if (n.protocol === "http:" || n.protocol === "https:") return n.href; + } catch {} + return "#"; + } + function Ge(e) { + let t = String(e || "").trim(); + return !t || !/^[a-z0-9\s_-]+$/i.test(t) ? "fa-solid fa-link" : t; + } + function ue(e, t) { + let n = e.querySelectorAll( + "[data-app-menu-grid], [data-apps-grid], [data-apps-grid-mobile]", + ); + if (!n.length) return; + let a = Array.isArray(t) ? t : []; + n.forEach((o) => { + let r = o.getAttribute("data-app-menu-grid"), + c = + r === "desktop" || (!r && o.hasAttribute("data-apps-grid")) + ? "p-3" + : "p-2.5", + s = document.createDocumentFragment(); + for (let l of a) { + let u = Oe(l?.url), + h = Ge(l?.icon), + m = String(l?.name || "App").trim() || "App", + d = document.createElement("a"); + ((d.href = u), + (d.className = `group flex flex-col items-center gap-1.5 ${c} rounded-md hover:bg-base-200 transition-colors duration-200 no-underline hover:no-underline text-base-content`)); + let g = document.createElement("div"); + g.className = + "w-10 h-10 rounded-md bg-base-300/50 flex items-center justify-center group-hover:bg-primary/10 group-hover:text-primary transition-colors"; + let U = document.createElement("i"); + U.className = `${h} text-lg`; + let _ = document.createElement("span"); + ((_.className = + "text-[10px] font-medium opacity-70 group-hover:opacity-100"), + (_.textContent = m), + g.appendChild(U), + d.appendChild(g), + d.appendChild(_), + s.appendChild(d)); + } + o.replaceChildren(s); + }); + } + async function de(e, t) { + let n = $(), + a = N(n.apps, t); + ue(e, a); + let o = await ae(t), + r = N(o.apps, t); + return (ue(e, r), r); + } + function je(e) { + let t = e.querySelector("[data-shell-mobile-panel]"); + if (!t) return; + let n = e.querySelector("#shell-mobile-toggle"), + a = t.querySelector("[data-shell-mobile-backdrop]"), + o = t.querySelector("[data-shell-mobile-drawer]"), + r = t.querySelector("[data-shell-mobile-close]"); + function i() { + (t.classList.remove("hidden"), + o.offsetWidth, + (o.style.transform = "translateX(0)"), + (document.body.style.overflow = "hidden")); + } + function c() { + ((o.style.transform = "translateX(-100%)"), + (document.body.style.overflow = ""), + setTimeout(() => { + t.classList.add("hidden"); + }, 300)); + } + (n && n.addEventListener("click", i), + a && a.addEventListener("click", c), + r && r.addEventListener("click", c), + document.addEventListener("keydown", (s) => { + s.key === "Escape" && !t.classList.contains("hidden") && c(); + })); + } + function ze(e, t) { + let n = e.querySelector("[data-shell-mobile-panel]"); + if (!n) return; + let a = t?.authenticated === !0, + o = t?.user, + r = n.querySelector('[data-auth="mobile-guest-avatar"]'), + i = n.querySelector('[data-auth="mobile-authed-avatar"]'), + c = n.querySelector('[data-auth="mobile-name"]'), + s = n.querySelector('[data-auth="mobile-email"]'), + l = n.querySelector('[data-auth="mobile-login-btn"]'), + u = n.querySelector('[data-auth="mobile-logout-btn"]'), + h = n.querySelector('[data-auth="mobile-account-btn"]'); + if (a && o) { + if ((r && r.classList.add("hidden"), i)) { + i.classList.remove("hidden"); + let m = i.querySelector("img"); + if (m) { + let d = o.avatar_url; + d ? (m.src = d) : m.removeAttribute("src"); + } + } + (c && (c.textContent = o.name || "User"), + s && (s.textContent = o.email || ""), + l && l.classList.add("hidden"), + u && u.classList.remove("hidden"), + h && h.classList.remove("hidden")); + } else + (r && r.classList.remove("hidden"), + i && i.classList.add("hidden"), + c && (c.textContent = "Guest"), + s && (s.textContent = "Not signed in"), + l && l.classList.remove("hidden"), + u && u.classList.add("hidden"), + h && h.classList.add("hidden")); + (u && + (u.onclick = (m) => { + m.preventDefault(); + let d = window.AUTH; + if (d && typeof d.logout == "function") { + let g = d.logout(); + g && typeof g.then == "function" + ? g + .then(() => window.location.reload()) + .catch(() => window.location.reload()) + : window.location.reload(); + } + }), + l && + (l.onclick = (m) => { + m.preventDefault(); + let d = window.AUTH; + d && typeof d.login == "function" + ? d.login() + : (window.location.href = "https://auth.dhanur.me"); + })); + } + function Fe(e) { + let t = he(), + n = me(), + a = !!document.querySelector( + 'link[rel="stylesheet"][href*="/css/main.css"], link[rel="stylesheet"][href*="/css/dui.css"], link[data-shell-style="main"]', + ), + o = !!document.querySelector( + 'link[rel="icon"], link[rel="shortcut icon"], link[rel="apple-touch-icon"]', + ); + ((!n || !a) && pe(n, t), + (!n || !o) && ge(n, t), + He(e, t), + de(e, "guest"), + j(), + J(e), + se(e), + je(e), + Y(e, (r) => { + let i = r?.role || "guest", + c = Z(t, r), + s = + e.querySelector(".site-nav-slot") || + e.querySelector(".drawer-content"); + if (!c.allowed) { + s && ee(s, c.reason, document.title || "This app"); + return; + } + (de(e, i), ze(e, r)); + })); + } + async function fe() { + if (ce) return; + ce = !0; + let e = he(); + if (e.showNavbar === !1) return; + Ue(e); + let t = me(); + if (document.querySelector(".navbar")) { + t || Fe(document.body); + return; + } + if (!t) { + (pe(!1, e), ge(!1, e)); + return; + } + } + document.readyState === "loading" + ? document.addEventListener("DOMContentLoaded", fe) + : fe(); +})(); diff --git a/templates/shell-chrome.html b/templates/shell-chrome.html index 61c5882..83c79e3 100644 --- a/templates/shell-chrome.html +++ b/templates/shell-chrome.html @@ -20,7 +20,7 @@
~/dhanur