window.workTrackerTheme = (() => { const storageKey = "worktracker.themeMode"; const mediaQuery = window.matchMedia ? window.matchMedia("(prefers-color-scheme: dark)") : null; function normalize(mode) { const normalized = (mode || "system").toString().toLowerCase(); return normalized === "light" || normalized === "dark" || normalized === "system" ? normalized : "system"; } function resolve(mode) { if (mode === "system") { return mediaQuery && mediaQuery.matches ? "dark" : "light"; } return mode; } function apply(mode) { const normalized = normalize(mode); const effectiveMode = resolve(normalized); document.documentElement.setAttribute("data-bs-theme", effectiveMode); document.documentElement.setAttribute("data-theme-mode", normalized); document.documentElement.style.colorScheme = effectiveMode; localStorage.setItem(storageKey, normalized); } function handleSystemThemeChange() { const currentMode = normalize(localStorage.getItem(storageKey) || document.documentElement.getAttribute("data-theme-mode")); if (currentMode === "system") { apply(currentMode); } } if (mediaQuery) { if (typeof mediaQuery.addEventListener === "function") { mediaQuery.addEventListener("change", handleSystemThemeChange); } else if (typeof mediaQuery.addListener === "function") { mediaQuery.addListener(handleSystemThemeChange); } } return { init() { apply(localStorage.getItem(storageKey) || document.documentElement.getAttribute("data-theme-mode")); }, setTheme(mode) { apply(mode); } }; })(); window.workTrackerPreferences = { getBool(key) { try { const value = localStorage.getItem(key); if (value === null) { return null; } if (value === "true") { return true; } if (value === "false") { return false; } return null; } catch { return null; } }, setBool(key, value) { try { localStorage.setItem(key, value ? "true" : "false"); } catch { } } }; window.workTrackerDownloads = { async downloadFromUrl(url) { const response = await fetch(url, { credentials: "same-origin" }); if (!response.ok) { throw new Error(`Download failed with status ${response.status}`); } const blob = await response.blob(); const contentDisposition = response.headers.get("content-disposition") || ""; const fileNameMatch = /filename\*=UTF-8''([^;]+)|filename="?([^";]+)"?/i.exec(contentDisposition); const fileName = decodeURIComponent(fileNameMatch?.[1] || fileNameMatch?.[2] || "worktracker-backup.json"); const objectUrl = URL.createObjectURL(blob); try { const anchor = document.createElement("a"); anchor.href = objectUrl; anchor.download = fileName; anchor.rel = "noopener"; anchor.style.display = "none"; document.body.appendChild(anchor); anchor.click(); anchor.remove(); } finally { URL.revokeObjectURL(objectUrl); } } }; window.workTrackerDateInput = (() => { const listeners = new WeakMap(); function unregisterOutsideClick(root) { const existingListener = listeners.get(root); if (!existingListener) { return; } document.removeEventListener("pointerdown", existingListener, true); listeners.delete(root); } function registerOutsideClick(root, dotNetReference) { if (!root || !dotNetReference) { return; } unregisterOutsideClick(root); const listener = (event) => { if (root.contains(event.target)) { return; } dotNetReference.invokeMethodAsync("ClosePopupFromOutsideClickAsync"); }; listeners.set(root, listener); document.addEventListener("pointerdown", listener, true); } return { registerOutsideClick, unregisterOutsideClick }; })(); window.workTrackerTheme.init();