'):o+='
',o+='
'+a[i]+"
",(l[i]||[]).forEach(function(c){o+='
'+c[1]+'#000000
'}),o+="
"}),o}function w(){return window.THEMES.map(function(a){return'
"}).join("")}var T='
Theme Builder
Sample Card
Secondary text preview
ONOFF
Online Offline
'+L()+'
';injectModal("theme-builder-modal",T);var k=document.getElementById("theme-builder-modal"),B=document.getElementById("theme-builder-start"),I=document.getElementById("theme-builder-name"),C=document.getElementById("theme-builder-edit-select"),j=document.getElementById("theme-builder-existing"),M=document.getElementById("theme-builder-lightbg"),D=k.querySelectorAll(".theme-builder-color"),x=document.getElementById("theme-builder-advanced"),A=document.getElementById("theme-builder-advanced-toggle"),y=document.getElementById("theme-builder-export"),m=!1;A.addEventListener("click",function(){m=!m,x.style.display=m?"":"none",A.innerHTML=m?"Hide advanced colors ▲":"Show advanced colors ▼"});function b(){var a={};return D.forEach(function(l){a[l.dataset.prop]=l.value}),a["card-bg"]=a["card-base"],a}function p(){var a={};return D.forEach(function(l){l.dataset.advanced||(a[l.dataset.prop]=l.value)}),a["card-bg"]=a["card-base"],M.checked&&(a.lightBg=!0),a}function u(){var a=p(),l=window.deriveExtendedColors?window.deriveExtendedColors(a):{};D.forEach(function(o){if(o.dataset.advanced&&!O[o.dataset.prop]){var i=l[o.dataset.prop]||"#333333";o.value=i;var c=k.querySelector('[data-hex="'+o.dataset.prop+'"]');c&&(c.textContent=i.toUpperCase())}})}function s(a){var l=window.THEME_COLORS[a];l&&(O={},D.forEach(function(o){var i=l[o.dataset.prop]||"#000000";(i.startsWith("rgba")||i.startsWith("color-mix"))&&(i="#333333"),o.value=i;var c=k.querySelector('[data-hex="'+o.dataset.prop+'"]');c&&(c.textContent=i.toUpperCase())}),M.checked=!!l.lightBg,r())}function d(a){var l=safeGetJSON(window.USER_THEMES_KEY,{}),o=l[a];o&&(O={},D.forEach(function(i){var c=o[i.dataset.prop]||"#000000";i.value=c;var $=k.querySelector('[data-hex="'+i.dataset.prop+'"]');$&&($.textContent=c.toUpperCase()),i.dataset.advanced&&o[i.dataset.prop]&&(O[i.dataset.prop]=!0)}),I.value=o.name||"",M.checked=!!o.lightBg,u(),r())}function r(){var a=b(),l=document.getElementById("theme-builder-preview"),o=document.getElementById("theme-preview-card"),i=o.querySelector(".preview-title"),c=o.querySelector(".preview-muted"),$=document.getElementById("preview-badge-ok"),H=document.getElementById("preview-badge-bad"),U=document.getElementById("preview-dot-ok"),q=document.getElementById("preview-dot-bad"),F=document.getElementById("preview-accent-btn"),G=o.querySelector(".preview-dots");l.style.background=a.bg,o.style.background=a["card-base"],o.style.borderColor=a.border,i.style.color=a.fg,c.style.color=a.muted,$.style.background=a["ok-bg"],$.style.color=a["ok-fg"],H.style.background=a["bad-bg"],H.style.color=a["bad-fg"],U.style.background=a["dot-ok"],q.style.background=a["dot-bad"],G.style.color=a.fg,F.style.background=a.accent,F.style.color=a.bg}function f(a){var l=window.deriveExtendedColors?window.deriveExtendedColors(a):{};window.THEME_PROPS.forEach(function(o){var i=a[o]||l[o];i&&document.documentElement.style.setProperty("--"+o,i)})}D.forEach(function(a){a.addEventListener("input",function(){var l=k.querySelector('[data-hex="'+a.dataset.prop+'"]');l&&(l.textContent=a.value.toUpperCase()),a.dataset.advanced?O[a.dataset.prop]=!0:u(),r(),f(b())})}),M.addEventListener("change",function(){u(),r(),f(b())}),B.addEventListener("change",function(){O={},s(B.value),f(b())});function v(){var a=safeGetJSON(window.USER_THEMES_KEY,{}),l=Object.keys(a);C.innerHTML='
',l.forEach(function(o){var i=document.createElement("option");i.value=o,i.textContent=a[o].name||o,C.appendChild(i)}),j.style.display=l.length?"":"none"}function t(){B.innerHTML=w()}C.addEventListener("change",function(){var a=this.value;a?(S=a,d(a),f(b())):(S=null,O={},I.value="",B.value=window.getActiveTheme(),s(B.value)),y.style.display=S?"":"none"});function e(){h=window.getActiveTheme(),S=null,O={},m=!1,x.style.display="none",A.innerHTML="Show advanced colors ▼",v(),t();var a=safeGetJSON(window.USER_THEMES_KEY,{});a[h]?(C.value=h,S=h,d(h)):(C.value="",I.value="",B.value=h,s(h)),y.style.display=S?"":"none",k.classList.add("show")}var n=document.getElementById("theme-customize-btn");n&&n.addEventListener("click",function(){e()}),document.getElementById("theme-builder-save").addEventListener("click",function(){var a=b(),l=I.value.trim();if(!l){showNotification("Please enter a theme name","warning",3e3),I.focus();return}var o=safeGetJSON(window.USER_THEMES_KEY,{}),i,c=null;if(S){i=S;var $=window.slugifyThemeName(l,S);if($!==S){c=S,delete o[S];var H=window.THEMES.indexOf(S);H!==-1&&window.THEMES.splice(H,1),delete window.THEME_COLORS[S],i=$}}else i=window.slugifyThemeName(l);var U={name:l};M.checked&&(U.lightBg=!0),window.THEME_PROPS.forEach(function(F){a[F]&&(U[F]=a[F])}),o[i]=U,safeSet(window.USER_THEMES_KEY,JSON.stringify(o)),window.clearCustomProperties(),window.injectUserThemeStyles(),window.applyTheme(i),k.classList.remove("show"),g();var q={};window.THEME_PROPS.forEach(function(F){a[F]&&(q[F]=a[F])}),c&&secureFetch("/api/v1/themes/"+c,{method:"DELETE"}).catch(function(){}),secureFetch("/api/v1/themes/"+i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:l,colors:q,lightBg:M.checked})}).then(function(){showNotification(l+" theme saved","success",3e3)}).catch(function(){showNotification(l+" theme saved locally (server sync failed)","warning",3e3)})}),document.getElementById("theme-builder-cancel").addEventListener("click",function(){k.classList.remove("show"),window.clearCustomProperties(),h&&window.applyTheme(h)}),document.getElementById("theme-builder-delete").addEventListener("click",function(){if(S){var a=safeGetJSON(window.USER_THEMES_KEY,{}),l=a[S]?a[S].name:S;if(confirm('Delete "'+l+'" theme?')){var o=S;delete a[o],safeSet(window.USER_THEMES_KEY,JSON.stringify(a));var i=window.THEMES.indexOf(o);i!==-1&&window.THEMES.splice(i,1),delete window.THEME_COLORS[o],window.clearCustomProperties(),window.injectUserThemeStyles();var c=h&&h!==o?h:"dark";window.applyTheme(c),S=null,k.classList.remove("show"),g(),secureFetch("/api/v1/themes/"+o,{method:"DELETE"}).then(function(){showNotification(l+" theme deleted","success",3e3)}).catch(function(){showNotification(l+" theme deleted locally (server sync failed)","warning",3e3)})}}}),document.getElementById("theme-builder-export").addEventListener("click",function(){if(!S){showNotification("Save the theme first, then export","warning",3e3);return}var a=safeGetJSON(window.USER_THEMES_KEY,{}),l=a[S];if(l){var o={_dashcaddy_theme:!0,version:"1.0",exportDate:new Date().toISOString(),slug:S,name:l.name,lightBg:l.lightBg||!1,colors:{}};window.THEME_PROPS.forEach(function(H){l[H]&&(o.colors[H]=l[H])});var i=new Blob([JSON.stringify(o,null,2)],{type:"application/json"}),c=URL.createObjectURL(i),$=document.createElement("a");$.href=c,$.download=S+"-theme.json",document.body.appendChild($),$.click(),document.body.removeChild($),URL.revokeObjectURL(c),showNotification("Theme exported as "+S+"-theme.json","success",3e3)}}),document.getElementById("theme-builder-import").addEventListener("click",function(){var a=document.createElement("input");a.type="file",a.accept=".json",a.onchange=function(l){var o=l.target.files[0];if(o){var i=new FileReader;i.onload=function(c){try{var $=JSON.parse(c.target.result),H,U,q;if($._dashcaddy_theme&&$.colors)H=$.name||"Imported",U=$.colors,q=$.lightBg||!1;else if($.name&&($.bg||$["card-base"]))H=$.name,U={},window.THEME_PROPS.forEach(function(F){$[F]&&(U[F]=$[F])}),q=$.lightBg||!1;else throw new Error("Not a valid DashCaddy theme file");I.value=H,M.checked=!!q,S=null,C.value="",O={},D.forEach(function(F){var G=U[F.dataset.prop]||"#000000";F.value=G;var J=k.querySelector('[data-hex="'+F.dataset.prop+'"]');J&&(J.textContent=G.toUpperCase()),F.dataset.advanced&&U[F.dataset.prop]&&(O[F.dataset.prop]=!0)}),u(),r(),f(b()),y.style.display="none",showNotification('"'+H+'" loaded into builder. Click Save to keep it.',"success",5e3)}catch(F){showNotification("Import failed: "+F.message,"error",5e3)}},i.readAsText(o)}},a.click()}),wireModal(k),k.addEventListener("click",function(a){a.target===k&&(window.clearCustomProperties(),h&&window.applyTheme(h))})})(),(function(){injectModal("license-modal",`
+
`);const r=document.getElementById("clock-settings-modal"),c=document.getElementById("clock-chimes-toggle"),d=document.getElementById("clock-chime-volume"),b=document.getElementById("clock-volume-section");function y(){const t=safeGet("clock-style")||"default",e=r.querySelector(`input[value="${t}"]`);e&&(e.checked=!0),c.checked=safeGet("clock-chimes")==="true",d.value=safeGet("clock-chime-volume")||"50",b.style.opacity=c.checked?"1":"0.4"}c?.addEventListener("change",()=>{b.style.opacity=c.checked?"1":"0.4"}),document.getElementById("clock-settings")?.addEventListener("click",()=>{y(),r.classList.add("show")}),document.getElementById("clock-chime-test")?.addEventListener("click",()=>{const t=parseInt(d.value,10)/100,e=new Audio("/assets/sounds/church-bell.mp3");e.volume=t,e.play().catch(()=>{})}),document.getElementById("clock-settings-save")?.addEventListener("click",()=>{const t=r.querySelector('input[name="clock-style-radio"]:checked'),e=t?t.value:"default";safeSet("clock-style",e),safeSet("clock-chimes",String(c.checked)),safeSet("clock-chime-volume",d.value),P=e,v="",S(),m(),h(),r.classList.remove("show"),showNotification("Clock settings saved","success",2e3)}),document.getElementById("clock-settings-cancel")?.addEventListener("click",()=>{r.classList.remove("show")}),wireModal(r),r?.querySelectorAll('input[name="clock-style-radio"]').forEach(t=>{t.addEventListener("change",()=>{P=t.value,v="",S(),m()})})})(),(function(){async function f(){try{const D=await(await fetch("/api/v1/health-checks/status")).json();if(!D.success||!D.status)return;for(const[v,B]of Object.entries(D.status)){const x=document.getElementById("uptime-"+v),$=document.getElementById("uptime-bar-"+v);if(!x)continue;const k=B.uptime?.["24h"];if(k!=null){const T=k.toFixed(1);x.textContent=`${T}% uptime`,x.className="uptime-chip",k>=99.9?x.classList.add("excellent"):k>=99?x.classList.add("good"):k>=95?x.classList.add("degraded"):x.classList.add("poor"),$&&($.style.width=T+"%")}}}catch{console.warn("[Card Badges] Health check API unavailable")}}let I;try{I=new Set(JSON.parse(safeSessionGet("dismissed-updates")||"[]"))}catch{I=new Set}let A=[];async function E(z){try{const v=await(await fetch("/api/v1/updates/available")).json();if(!v.success)return;document.querySelectorAll(".update-available-badge").forEach(x=>x.classList.remove("visible"));const B=v.updates||[];if(A=B,z&&B.length>0){const x=window._lastKnownUpdateCount||0;x>0&&B.length>x&&showNotification(`${B.length} container update(s) available \u2014 click Update Management to review.`,"info"),window._lastKnownUpdateCount=B.length}if(!B.length)return;for(const x of B){const $=window.APPS||[];for(const k of $)if(k.containerId===x.containerId||k.id===x.containerName||k.name===x.containerName){if(I.has(k.id))break;const T=document.getElementById("update-badge-"+k.id),S=document.getElementById("update-btn-"+k.id);T&&(T.classList.add("visible"),T.title="Update available \u2014 click to open Update Management.",T.style.cursor="pointer",T.onclick=L=>{L.stopPropagation(),window.openUpdateModal&&window.openUpdateModal(k.id)}),S&&(S.style.background="#f97316",S.style.borderColor="#f97316",S.style.boxShadow="0 0 6px #f9731688",S.title="Update available \u2014 click to open Update Management.");break}}}catch{console.warn("[Card Badges] Updates API unavailable")}}function M(){setTimeout(()=>{f(),E()},5e3),setInterval(()=>{f(),E(!0)},6e4)}const P=window.refreshAll;P&&(window.refreshAll=async function(){try{await P(),setTimeout(f,1e3)}catch(z){console.warn("[Card Badges] Error in refreshAll hook:",z.message)}}),M()})(),(function(){var f=null,I=null,A={},E={dark:"Dark",light:"Light",blue:"Blue",black:"Black",nord:"Nord",dracula:"Dracula","solarized-dark":"Solarized Dark","solarized-light":"Solarized Light",taxi:"Taxi",ocean:"Ocean"},M=[["bg","Background","base"],["card-base","Card","base"],["fg","Text","base"],["muted","Muted Text","base"],["border","Border","base"],["accent","Accent","accent"],["accent-strong","Accent Strong","accent"],["ok-bg","OK Background","status"],["ok-fg","OK Text","status"],["bad-bg","Error Bg","status"],["bad-fg","Error Text","status"],["dot-ok","Dot OK","status"],["dot-bad","Dot Error","status"],["uptime","Uptime Bar","status"],["hover","Hover","advanced"],["card-hover","Card Hover","advanced"],["base","Tags/Badges","advanced"],["fg-muted","Dim Text","advanced"],["success","Success","advanced"],["error","Error","advanced"],["warning","Warning","advanced"]],P=document.getElementById("theme");if(!P)return;var z=document.getElementById("theme-label");function D(o){if(E[o])return E[o];var i=safeGetJSON(window.USER_THEMES_KEY,{});return i[o]&&i[o].name||o}function v(){z&&(z.textContent=D(window.getActiveTheme()))}P.addEventListener("click",function(){var o=window.THEMES.slice(),i=window.getActiveTheme(),n=o.indexOf(i),s=o[(n+1)%o.length];window.applyTheme(s),v()}),v();function B(){var o={base:"Base Colors",accent:"Accent",status:"Status",advanced:"Advanced (auto-derived)"},i={};M.forEach(function(s){i[s[2]]||(i[s[2]]=[]),i[s[2]].push(s)});var n="";return Object.keys(o).forEach(function(s){s==="advanced"?(n+='
Show advanced colors ▼
',n+='
'):n+='
',n+='
'+o[s]+"
",(i[s]||[]).forEach(function(l){n+='
'+l[1]+'#000000
'}),n+="
"}),n}function x(){return window.THEMES.map(function(o){return'
"}).join("")}var $='
Theme Builder
Sample Card
Secondary text preview
ONOFF
Online Offline
'+B()+'
';injectModal("theme-builder-modal",$);var k=document.getElementById("theme-builder-modal"),T=document.getElementById("theme-builder-start"),S=document.getElementById("theme-builder-name"),L=document.getElementById("theme-builder-edit-select"),j=document.getElementById("theme-builder-existing"),C=document.getElementById("theme-builder-lightbg"),N=k.querySelectorAll(".theme-builder-color"),R=document.getElementById("theme-builder-advanced"),U=document.getElementById("theme-builder-advanced-toggle"),u=document.getElementById("theme-builder-export"),m=!1;U.addEventListener("click",function(){m=!m,R.style.display=m?"":"none",U.innerHTML=m?"Hide advanced colors ▲":"Show advanced colors ▼"});function h(){var o={};return N.forEach(function(i){o[i.dataset.prop]=i.value}),o["card-bg"]=o["card-base"],o}function g(){var o={};return N.forEach(function(i){i.dataset.advanced||(o[i.dataset.prop]=i.value)}),o["card-bg"]=o["card-base"],C.checked&&(o.lightBg=!0),o}function H(){var o=g(),i=window.deriveExtendedColors?window.deriveExtendedColors(o):{};N.forEach(function(n){if(n.dataset.advanced&&!A[n.dataset.prop]){var s=i[n.dataset.prop]||"#333333";n.value=s;var l=k.querySelector('[data-hex="'+n.dataset.prop+'"]');l&&(l.textContent=s.toUpperCase())}})}function r(o){var i=window.THEME_COLORS[o];i&&(A={},N.forEach(function(n){var s=i[n.dataset.prop]||"#000000";(s.startsWith("rgba")||s.startsWith("color-mix"))&&(s="#333333"),n.value=s;var l=k.querySelector('[data-hex="'+n.dataset.prop+'"]');l&&(l.textContent=s.toUpperCase())}),C.checked=!!i.lightBg,d())}function c(o){var i=safeGetJSON(window.USER_THEMES_KEY,{}),n=i[o];n&&(A={},N.forEach(function(s){var l=n[s.dataset.prop]||"#000000";s.value=l;var p=k.querySelector('[data-hex="'+s.dataset.prop+'"]');p&&(p.textContent=l.toUpperCase()),s.dataset.advanced&&n[s.dataset.prop]&&(A[s.dataset.prop]=!0)}),S.value=n.name||"",C.checked=!!n.lightBg,H(),d())}function d(){var o=h(),i=document.getElementById("theme-builder-preview"),n=document.getElementById("theme-preview-card"),s=n.querySelector(".preview-title"),l=n.querySelector(".preview-muted"),p=document.getElementById("preview-badge-ok"),w=document.getElementById("preview-badge-bad"),O=document.getElementById("preview-dot-ok"),_=document.getElementById("preview-dot-bad"),F=document.getElementById("preview-accent-btn"),q=n.querySelector(".preview-dots");i.style.background=o.bg,n.style.background=o["card-base"],n.style.borderColor=o.border,s.style.color=o.fg,l.style.color=o.muted,p.style.background=o["ok-bg"],p.style.color=o["ok-fg"],w.style.background=o["bad-bg"],w.style.color=o["bad-fg"],O.style.background=o["dot-ok"],_.style.background=o["dot-bad"],q.style.color=o.fg,F.style.background=o.accent,F.style.color=o.bg}function b(o){var i=window.deriveExtendedColors?window.deriveExtendedColors(o):{};window.THEME_PROPS.forEach(function(n){var s=o[n]||i[n];s&&document.documentElement.style.setProperty("--"+n,s)})}N.forEach(function(o){o.addEventListener("input",function(){var i=k.querySelector('[data-hex="'+o.dataset.prop+'"]');i&&(i.textContent=o.value.toUpperCase()),o.dataset.advanced?A[o.dataset.prop]=!0:H(),d(),b(h())})}),C.addEventListener("change",function(){H(),d(),b(h())}),T.addEventListener("change",function(){A={},r(T.value),b(h())});function y(){var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=Object.keys(o);L.innerHTML='
',i.forEach(function(n){var s=document.createElement("option");s.value=n,s.textContent=o[n].name||n,L.appendChild(s)}),j.style.display=i.length?"":"none"}function t(){T.innerHTML=x()}L.addEventListener("change",function(){var o=this.value;o?(I=o,c(o),b(h())):(I=null,A={},S.value="",T.value=window.getActiveTheme(),r(T.value)),u.style.display=I?"":"none"});function e(){f=window.getActiveTheme(),I=null,A={},m=!1,R.style.display="none",U.innerHTML="Show advanced colors ▼",y(),t();var o=safeGetJSON(window.USER_THEMES_KEY,{});o[f]?(L.value=f,I=f,c(f)):(L.value="",S.value="",T.value=f,r(f)),u.style.display=I?"":"none",k.classList.add("show")}var a=document.getElementById("theme-customize-btn");a&&a.addEventListener("click",function(){e()}),document.getElementById("theme-builder-save").addEventListener("click",function(){var o=h(),i=S.value.trim();if(!i){showNotification("Please enter a theme name","warning",3e3),S.focus();return}var n=safeGetJSON(window.USER_THEMES_KEY,{}),s,l=null;if(I){s=I;var p=window.slugifyThemeName(i,I);if(p!==I){l=I,delete n[I];var w=window.THEMES.indexOf(I);w!==-1&&window.THEMES.splice(w,1),delete window.THEME_COLORS[I],s=p}}else s=window.slugifyThemeName(i);var O={name:i};C.checked&&(O.lightBg=!0),window.THEME_PROPS.forEach(function(F){o[F]&&(O[F]=o[F])}),n[s]=O,safeSet(window.USER_THEMES_KEY,JSON.stringify(n)),window.clearCustomProperties(),window.injectUserThemeStyles(),window.applyTheme(s),k.classList.remove("show"),v();var _={};window.THEME_PROPS.forEach(function(F){o[F]&&(_[F]=o[F])}),l&&secureFetch("/api/v1/themes/"+l,{method:"DELETE"}).catch(function(){}),secureFetch("/api/v1/themes/"+s,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:i,colors:_,lightBg:C.checked})}).then(function(){showNotification(i+" theme saved","success",3e3)}).catch(function(){showNotification(i+" theme saved locally (server sync failed)","warning",3e3)})}),document.getElementById("theme-builder-cancel").addEventListener("click",function(){k.classList.remove("show"),window.clearCustomProperties(),f&&window.applyTheme(f)}),document.getElementById("theme-builder-delete").addEventListener("click",function(){if(I){var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=o[I]?o[I].name:I;if(confirm('Delete "'+i+'" theme?')){var n=I;delete o[n],safeSet(window.USER_THEMES_KEY,JSON.stringify(o));var s=window.THEMES.indexOf(n);s!==-1&&window.THEMES.splice(s,1),delete window.THEME_COLORS[n],window.clearCustomProperties(),window.injectUserThemeStyles();var l=f&&f!==n?f:"dark";window.applyTheme(l),I=null,k.classList.remove("show"),v(),secureFetch("/api/v1/themes/"+n,{method:"DELETE"}).then(function(){showNotification(i+" theme deleted","success",3e3)}).catch(function(){showNotification(i+" theme deleted locally (server sync failed)","warning",3e3)})}}}),document.getElementById("theme-builder-export").addEventListener("click",function(){if(!I){showNotification("Save the theme first, then export","warning",3e3);return}var o=safeGetJSON(window.USER_THEMES_KEY,{}),i=o[I];if(i){var n={_dashcaddy_theme:!0,version:"1.0",exportDate:new Date().toISOString(),slug:I,name:i.name,lightBg:i.lightBg||!1,colors:{}};window.THEME_PROPS.forEach(function(w){i[w]&&(n.colors[w]=i[w])});var s=new Blob([JSON.stringify(n,null,2)],{type:"application/json"}),l=URL.createObjectURL(s),p=document.createElement("a");p.href=l,p.download=I+"-theme.json",document.body.appendChild(p),p.click(),document.body.removeChild(p),URL.revokeObjectURL(l),showNotification("Theme exported as "+I+"-theme.json","success",3e3)}}),document.getElementById("theme-builder-import").addEventListener("click",function(){var o=document.createElement("input");o.type="file",o.accept=".json",o.onchange=function(i){var n=i.target.files[0];if(n){var s=new FileReader;s.onload=function(l){try{var p=JSON.parse(l.target.result),w,O,_;if(p._dashcaddy_theme&&p.colors)w=p.name||"Imported",O=p.colors,_=p.lightBg||!1;else if(p.name&&(p.bg||p["card-base"]))w=p.name,O={},window.THEME_PROPS.forEach(function(F){p[F]&&(O[F]=p[F])}),_=p.lightBg||!1;else throw new Error("Not a valid DashCaddy theme file");S.value=w,C.checked=!!_,I=null,L.value="",A={},N.forEach(function(F){var q=O[F.dataset.prop]||"#000000";F.value=q;var J=k.querySelector('[data-hex="'+F.dataset.prop+'"]');J&&(J.textContent=q.toUpperCase()),F.dataset.advanced&&O[F.dataset.prop]&&(A[F.dataset.prop]=!0)}),H(),d(),b(h()),u.style.display="none",showNotification('"'+w+'" loaded into builder. Click Save to keep it.',"success",5e3)}catch(F){showNotification("Import failed: "+F.message,"error",5e3)}},s.readAsText(n)}},o.click()}),wireModal(k),k.addEventListener("click",function(o){o.target===k&&(window.clearCustomProperties(),f&&window.applyTheme(f))})})(),(function(){injectModal("license-modal",`
DashCaddy License
@@ -1853,16 +1891,16 @@ To endpoint: POST /api/v1/security/events/ingest or /events/batch`),m()}catch(f)
-
`);const h=document.getElementById("license-modal"),S=document.getElementById("license-code-input"),O=document.getElementById("license-activate"),E=document.getElementById("license-deactivate"),N=document.getElementById("license-error"),R=document.getElementById("license-success"),z=document.getElementById("license-badge-icon"),P=document.getElementById("license-badge-text"),g=document.getElementById("license-badge"),L=document.getElementById("license-details"),w=document.getElementById("license-feature-list"),T=document.getElementById("license-activate-section");let k=null;function B(){N.style.display="none",R.style.display="none"}function I(b){B(),N.textContent=b,N.style.display="block"}function C(b){B(),R.textContent=b,R.style.display="block"}function j(b){if(k=b,b.active){g.style.background="rgba(46,204,113,0.15)",g.style.color="var(--ok-fg)",z.textContent="\u2605",P.textContent="Premium Active";const s=b.lifetime?"
License: LIFETIME
":`
Expires: ${new Date(b.expiresAt).toLocaleDateString()} (${b.daysRemaining} days remaining)
`;L.innerHTML=`
-
Code: ${b.code||"***"}
- ${s}
- `,T.style.display="none",O.style.display="none",E.style.display=""}else g.style.background="rgba(149,165,166,0.15)",g.style.color="var(--muted)",z.textContent="\u2606",P.textContent=b.expired?"License Expired":"Free Tier",L.innerHTML=b.expired?"
Your license has expired. Enter a new code to renew.
":"
Enter a license code to unlock premium features.
",T.style.display="",O.style.display="",E.style.display="none";const p=b.premiumFeatures||{},u=new Set(b.features||[]);w.innerHTML=Object.entries(p).map(([s,d])=>`
- ${u.has(s)?"\u2705":"\u{1F512}"}
+
`);const f=document.getElementById("license-modal"),I=document.getElementById("license-code-input"),A=document.getElementById("license-activate"),E=document.getElementById("license-deactivate"),M=document.getElementById("license-error"),P=document.getElementById("license-success"),z=document.getElementById("license-badge-icon"),D=document.getElementById("license-badge-text"),v=document.getElementById("license-badge"),B=document.getElementById("license-details"),x=document.getElementById("license-feature-list"),$=document.getElementById("license-activate-section");let k=null;function T(){M.style.display="none",P.style.display="none"}function S(h){T(),M.textContent=h,M.style.display="block"}function L(h){T(),P.textContent=h,P.style.display="block"}function j(h){if(k=h,h.active){v.style.background="rgba(46,204,113,0.15)",v.style.color="var(--ok-fg)",z.textContent="\u2605",D.textContent="Premium Active";const r=h.lifetime?"
License: LIFETIME
":`
Expires: ${new Date(h.expiresAt).toLocaleDateString()} (${h.daysRemaining} days remaining)
`;B.innerHTML=`
+
Code: ${h.code||"***"}
+ ${r}
+ `,$.style.display="none",A.style.display="none",E.style.display=""}else v.style.background="rgba(149,165,166,0.15)",v.style.color="var(--muted)",z.textContent="\u2606",D.textContent=h.expired?"License Expired":"Free Tier",B.innerHTML=h.expired?"
Your license has expired. Enter a new code to renew.
":"
Enter a license code to unlock premium features.
",$.style.display="",A.style.display="",E.style.display="none";const g=h.premiumFeatures||{},H=new Set(h.features||[]);x.innerHTML=Object.entries(g).map(([r,c])=>`
+
${H.has(r)?"\u2705":"\u{1F512}"}
-
${d.name}
-
${d.description}
+
${c.name}
+
${c.description}
-
`).join("")}async function M(){try{const p=await(await fetch("/api/v1/license/status")).json();p.success&&(j(p.license),A(p.license))}catch(b){console.warn("Failed to load license status:",b.message)}}async function D(){const b=S.value.trim();if(!b){I("Please enter a license code.");return}B(),O.disabled=!0,O.textContent="Activating...";try{const u=await(await secureFetch("/api/v1/license/activate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:b})})).json();u.success?(C(u.message),S.value="",j(u.license),showNotification("License activated! Premium features unlocked.","success",5e3),A(u.license)):I(u.error||"Activation failed")}catch(p){I("Network error: "+p.message)}finally{O.disabled=!1,O.textContent="Activate"}}async function x(){if(confirm("Deactivate your license? You can reuse the code on another machine.")){E.disabled=!0,E.textContent="Deactivating...";try{const p=await(await secureFetch("/api/v1/license/deactivate",{method:"POST"})).json();p.success?(C(p.message),await M(),showNotification("License deactivated.","info",3e3),A({active:!1})):I(p.error||"Deactivation failed")}catch(b){I("Network error: "+b.message)}finally{E.disabled=!1,E.textContent="Deactivate"}}}function A(b){const p=document.getElementById("license-status-topbar"),u=document.getElementById("license-topbar-icon"),s=document.getElementById("license-topbar-text"),d=document.getElementById("license-topbar-time");if(p)if(p.className="license-status-topbar "+(b.active?"premium":"free"),b.active)if(u.textContent="\u2605",s.textContent="PREMIUM",b.lifetime)d.textContent="\xB7 LIFETIME";else{const r=b.daysRemaining;d.textContent=r!=null?"\xB7 "+r+"d remaining":""}else u.textContent="\u2606",s.textContent=b.expired?"EXPIRED":"FREE TIER",d.textContent=""}function y(){B(),M(),h.classList.add("show")}S.addEventListener("input",function(){let b=this.value.toUpperCase().replace(/[^A-Z0-9-]/g,"");if(b.length>this._prevLength&&(b=b.replace(/-/g,""),b.length>2&&!b.startsWith("DC")&&(b="DC"+b),b.startsWith("DC")&&b.length>2)){const p=["DC"],u=b.substring(2);for(let s=0;s
{b.key==="Enter"&&D()}),wireModal(h,document.getElementById("license-cancel"));const m=document.getElementById("license-status-topbar");m&&m.addEventListener("click",()=>window.openLicenseModal&&window.openLicenseModal()),window.openLicenseModal=y,window.checkPremiumFeature=async function(b){try{return(await(await fetch(`/api/v1/license/feature/${b}`)).json()).available}catch{return!1}},M().then(b=>{k&&A(k)})})(),(function(){"use strict";if(window.__dc_058_share_modal_loaded)return;window.__dc_058_share_modal_loaded=!0;const h=[{ms:3600*1e3,label:"1 hour"},{ms:1440*60*1e3,label:"24 hours"},{ms:10080*60*1e3,label:"7 days"}];injectModal("share-modal",`
+ `).join("")}async function C(){try{const g=await(await fetch("/api/v1/license/status")).json();g.success&&(j(g.license),U(g.license))}catch(h){console.warn("Failed to load license status:",h.message)}}async function N(){const h=I.value.trim();if(!h){S("Please enter a license code.");return}T(),A.disabled=!0,A.textContent="Activating...";try{const H=await(await secureFetch("/api/v1/license/activate",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:h})})).json();H.success?(L(H.message),I.value="",j(H.license),showNotification("License activated! Premium features unlocked.","success",5e3),U(H.license)):S(H.error||"Activation failed")}catch(g){S("Network error: "+g.message)}finally{A.disabled=!1,A.textContent="Activate"}}async function R(){if(confirm("Deactivate your license? You can reuse the code on another machine.")){E.disabled=!0,E.textContent="Deactivating...";try{const g=await(await secureFetch("/api/v1/license/deactivate",{method:"POST"})).json();g.success?(L(g.message),await C(),showNotification("License deactivated.","info",3e3),U({active:!1})):S(g.error||"Deactivation failed")}catch(h){S("Network error: "+h.message)}finally{E.disabled=!1,E.textContent="Deactivate"}}}function U(h){const g=document.getElementById("license-status-topbar"),H=document.getElementById("license-topbar-icon"),r=document.getElementById("license-topbar-text"),c=document.getElementById("license-topbar-time");if(g)if(g.className="license-status-topbar "+(h.active?"premium":"free"),h.active)if(H.textContent="\u2605",r.textContent="PREMIUM",h.lifetime)c.textContent="\xB7 LIFETIME";else{const d=h.daysRemaining;c.textContent=d!=null?"\xB7 "+d+"d remaining":""}else H.textContent="\u2606",r.textContent=h.expired?"EXPIRED":"FREE TIER",c.textContent=""}function u(){T(),C(),f.classList.add("show")}I.addEventListener("input",function(){let h=this.value.toUpperCase().replace(/[^A-Z0-9-]/g,"");if(h.length>this._prevLength&&(h=h.replace(/-/g,""),h.length>2&&!h.startsWith("DC")&&(h="DC"+h),h.startsWith("DC")&&h.length>2)){const g=["DC"],H=h.substring(2);for(let r=0;r