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 = `
