@shellui/core 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/features/config/ConfigProvider.ts","../src/features/config/useConfig.ts","../src/components/HomeView.tsx","../src/lib/utils.ts","../src/components/ui/breadcrumb.tsx","../src/lib/z-index.ts","../src/components/ui/sidebar.tsx","../src/features/settings/SettingsIcons.tsx","../src/features/settings/SettingsContext.tsx","../src/features/settings/hooks/useSettings.tsx","../src/components/ui/button.tsx","../src/components/ui/button-group.tsx","../src/features/theme/themes.ts","../src/features/settings/components/Appearance.tsx","../src/i18n/config.ts","../src/components/ui/select.tsx","../src/features/settings/components/LanguageAndRegion.tsx","../src/service-worker/register.ts","../src/features/settings/components/UpdateApp.tsx","../src/components/ui/switch.tsx","../src/features/cookieConsent/cookieConsent.ts","../src/features/sentry/initSentry.ts","../src/features/settings/components/Advanced.tsx","../src/features/layouts/utils.ts","../src/features/settings/components/develop/ToastTestButtons.tsx","../src/features/settings/components/develop/DialogTestButtons.tsx","../src/features/settings/components/develop/ModalTestButtons.tsx","../src/features/settings/components/develop/DrawerTestButtons.tsx","../src/features/settings/components/Develop.tsx","../src/features/settings/components/DataPrivacy.tsx","../src/features/settings/components/ServiceWorker.tsx","../src/features/settings/SettingsRoutes.tsx","../src/features/settings/SettingsView.tsx","../src/features/cookieConsent/CookiePreferencesView.tsx","../src/components/LoadingOverlay.tsx","../src/components/ContentView.tsx","../src/components/ViewRoute.tsx","../src/components/NotFoundView.tsx","../src/components/RouteErrorBoundary.tsx","../src/features/modal/ModalContext.tsx","../src/features/drawer/DrawerContext.tsx","../src/features/sonner/SonnerContext.tsx","../src/features/layouts/LayoutProviders.tsx","../src/components/ui/dialog.tsx","../src/components/ui/drawer.tsx","../src/components/ui/sonner.tsx","../src/features/layouts/OverlayShell.tsx","../src/features/layouts/DefaultLayout.tsx","../src/features/layouts/FullscreenLayout.tsx","../src/features/layouts/WindowsLayout.tsx","../src/features/layouts/AppLayout.tsx","../src/router/routes.tsx","../src/router/router.tsx","../src/features/settings/SettingsProvider.tsx","../src/features/theme/useTheme.tsx","../src/features/theme/ThemeProvider.tsx","../src/i18n/I18nProvider.tsx","../src/components/ui/alert-dialog.tsx","../src/features/alertDialog/DialogContext.tsx","../src/features/cookieConsent/CookieConsentModal.tsx","../src/app.tsx","../src/features/cookieConsent/useCookieConsent.ts"],"sourcesContent":["import { createContext, useState, createElement, type ReactNode } from 'react';\nimport { getLogger } from '@shellui/sdk';\nimport type { ShellUIConfig } from './types';\n\nconst logger = getLogger('shellcore');\n\nexport interface ConfigContextValue {\n config: ShellUIConfig;\n}\n\nexport const ConfigContext = createContext<ConfigContextValue | null>(null);\n\nexport interface ConfigProviderProps {\n children: ReactNode;\n}\n\n// Track if config has been logged to prevent duplicate logs in dev mode\n// (can happen with React StrictMode or when app renders in multiple contexts)\nlet configLogged = false;\n\n/**\n * Loads ShellUI config from __SHELLUI_CONFIG__ (injected by Vite at build time)\n * and provides it via context. Children can use useConfig() to read config.\n */\n\nexport function ConfigProvider(props: ConfigProviderProps): ReturnType<typeof createElement> {\n const [config] = useState<ShellUIConfig>(() => {\n try {\n // __SHELLUI_CONFIG__ is replaced by Vite at build time via define\n // After replacement, it will be a JSON string like: \"{\\\"title\\\":\\\"shellui\\\",...}\"\n // Vite's define inserts the string value directly, so we only need to parse once\n // Access it directly (no typeof check) so Vite can statically analyze and replace it\n // @ts-expect-error - __SHELLUI_CONFIG__ is injected by Vite at build time\n const configValue: unknown = __SHELLUI_CONFIG__;\n\n // After Vite replacement, configValue will be a JSON string\n // Example: \"{\\\"title\\\":\\\"shellui\\\"}\" -> parse -> {title: \"shellui\"}\n if (configValue !== undefined && configValue !== null && typeof configValue === 'string') {\n try {\n // Parse the JSON string to get the config object\n const parsedConfig: ShellUIConfig = JSON.parse(configValue);\n if (typeof window !== 'undefined' && parsedConfig.runtime === 'tauri') {\n (window as Window & { __SHELLUI_TAURI__?: boolean }).__SHELLUI_TAURI__ = true;\n }\n\n // Log in dev mode to help debug (only once per page load)\n if (process.env.NODE_ENV === 'development' && !configLogged) {\n configLogged = true;\n logger.info('Config loaded from __SHELLUI_CONFIG__', {\n hasNavigation: !!parsedConfig.navigation,\n navigationItems: parsedConfig.navigation?.length || 0,\n });\n }\n\n return parsedConfig;\n } catch (parseError) {\n logger.error('Failed to parse config JSON:', { error: parseError });\n logger.error('Config value (first 200 chars):', { value: configValue.substring(0, 200) });\n // Fall through to return empty config\n }\n }\n\n // Fallback: try to read from globalThis (for edge cases or if define didn't work)\n const g = globalThis as unknown as { __SHELLUI_CONFIG__?: unknown };\n if (typeof g.__SHELLUI_CONFIG__ !== 'undefined') {\n const fallbackValue = g.__SHELLUI_CONFIG__;\n const parsedConfig: ShellUIConfig =\n typeof fallbackValue === 'string'\n ? JSON.parse(fallbackValue)\n : (fallbackValue as ShellUIConfig);\n if (typeof window !== 'undefined' && parsedConfig.runtime === 'tauri') {\n (window as Window & { __SHELLUI_TAURI__?: boolean }).__SHELLUI_TAURI__ = true;\n }\n\n if (process.env.NODE_ENV === 'development') {\n logger.warn('Config loaded from globalThis fallback (define may not have worked)');\n }\n\n return parsedConfig;\n }\n\n // Return empty config if __SHELLUI_CONFIG__ is undefined (fallback for edge cases)\n logger.warn(\n 'Config not found. Using empty config. Make sure shellui.config.ts is properly loaded during build.',\n );\n return {} as ShellUIConfig;\n } catch (err) {\n logger.error('Failed to load ShellUI config:', { error: err });\n // Don't throw - return empty config instead to prevent app crash\n return {} as ShellUIConfig;\n }\n });\n\n const value: ConfigContextValue = { config };\n return createElement(ConfigContext.Provider, { value }, props.children);\n}\n","import { useContext } from 'react';\nimport { ConfigContext, type ConfigContextValue } from './ConfigProvider';\n\n/**\n * Hook to access ShellUI configuration from ConfigProvider context.\n * Must be used within a ConfigProvider.\n * @returns {ConfigContextValue} Configuration object and loading state\n */\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (context === null) {\n throw new Error('useConfig must be used within a ConfigProvider');\n }\n return context;\n}\n","import { useTranslation } from 'react-i18next';\nimport { useConfig } from '../features/config/useConfig';\n\nexport const HomeView = () => {\n const { t } = useTranslation('common');\n const { config } = useConfig();\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-8 md:p-10\">\n <h1\n className=\"m-0 text-3xl font-light text-foreground\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('welcome', { title: config.title })}\n </h1>\n <p className=\"mt-4 text-lg text-muted-foreground\">{t('getStarted')}</p>\n </div>\n );\n};\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ComponentProps,\n type ReactNode,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '@/lib/utils';\n\nconst Breadcrumb = forwardRef<\n HTMLElement,\n ComponentPropsWithoutRef<'nav'> & {\n separator?: ReactNode;\n }\n>(({ ...props }, ref) => (\n <nav\n ref={ref}\n aria-label=\"breadcrumb\"\n {...props}\n />\n));\nBreadcrumb.displayName = 'Breadcrumb';\n\nconst BreadcrumbList = forwardRef<HTMLOListElement, ComponentPropsWithoutRef<'ol'>>(\n ({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n 'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5',\n className,\n )}\n {...props}\n />\n ),\n);\nBreadcrumbList.displayName = 'BreadcrumbList';\n\nconst BreadcrumbItem = forwardRef<HTMLLIElement, ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n ),\n);\nBreadcrumbItem.displayName = 'BreadcrumbItem';\n\nconst BreadcrumbLink = forwardRef<\n HTMLAnchorElement,\n ComponentPropsWithoutRef<'a'> & {\n asChild?: boolean;\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n ref={ref}\n className={cn('transition-colors hover:text-foreground', className)}\n {...props}\n />\n );\n});\nBreadcrumbLink.displayName = 'BreadcrumbLink';\n\nconst BreadcrumbPage = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('font-normal text-foreground', className)}\n {...props}\n />\n ),\n);\nBreadcrumbPage.displayName = 'BreadcrumbPage';\n\nconst BreadcrumbSeparator = ({ children, className, ...props }: ComponentProps<'li'>) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('[&>svg]:size-3.5', className)}\n {...props}\n >\n {children ?? (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n )}\n </li>\n);\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\n\nconst BreadcrumbEllipsis = ({ className, ...props }: ComponentProps<'span'>) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex h-9 w-9 items-center justify-center', className)}\n {...props}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"1\"\n />\n <circle\n cx=\"19\"\n cy=\"12\"\n r=\"1\"\n />\n <circle\n cx=\"5\"\n cy=\"12\"\n r=\"1\"\n />\n </svg>\n <span className=\"sr-only\">More</span>\n </span>\n);\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n","/**\n * Central z-index scale for overlay layers.\n * Order (bottom to top): modal/drawer → toast → alert-dialog.\n * Use these constants everywhere so stacking stays consistent.\n */\nexport const Z_INDEX = {\n /** Sidebar trigger (above main content, below modals) */\n SIDEBAR_TRIGGER: 9999,\n /** Modal overlay and content (settings panel, etc.) */\n MODAL_OVERLAY: 10000,\n MODAL_CONTENT: 10001,\n /** Drawer overlay and content (slide-out panels; same level as modal) */\n DRAWER_OVERLAY: 10000,\n DRAWER_CONTENT: 10001,\n /** Toasts (above modals so they stay clickable when modal is open) */\n TOAST: 10100,\n /** Alert dialog overlay and content (confirmations; above toasts) */\n ALERT_DIALOG_OVERLAY: 10200,\n ALERT_DIALOG_CONTENT: 10201,\n /** Cookie consent (above everything to ensure visibility) */\n COOKIE_CONSENT_OVERLAY: 10300,\n COOKIE_CONSENT_CONTENT: 10301,\n /** Windows layout: taskbar (below windows), windows use dynamic z-index above this */\n WINDOWS_TASKBAR: 9000,\n /** Base z-index for windows; each window gets base + order */\n WINDOWS_WINDOW_BASE: 9001,\n} as const;\n\nexport type ZIndexLayer = keyof typeof Z_INDEX;\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n forwardRef,\n type ReactNode,\n type HTMLAttributes,\n type ButtonHTMLAttributes,\n type AnchorHTMLAttributes,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ntype SidebarContextValue = {\n isCollapsed: boolean;\n toggle: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextValue | undefined>(undefined);\n\nconst useSidebar = () => {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider');\n }\n return context;\n};\n\nconst SidebarProvider = ({ children }: { children: ReactNode }) => {\n const [isCollapsed, setIsCollapsed] = useState(false);\n\n const toggle = useCallback(() => {\n setIsCollapsed((prev) => !prev);\n }, []);\n\n return (\n <SidebarContext.Provider value={{ isCollapsed, toggle }}>{children}</SidebarContext.Provider>\n );\n};\n\nconst Sidebar = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n const { isCollapsed } = useSidebar();\n\n return (\n <div\n ref={ref}\n data-sidebar=\"sidebar\"\n data-collapsed={isCollapsed}\n className={cn(\n 'flex h-full flex-col gap-2 border-r bg-sidebar-background p-2 text-sidebar-foreground transition-all duration-300 ease-in-out overflow-hidden',\n isCollapsed ? 'w-0 border-r-0 p-0' : 'w-64',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebar.displayName = 'Sidebar';\n\n/** Inline SVG: panel-left-open (expand sidebar) */\nconst PanelLeftOpenIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-5 w-5 transition-transform duration-300\"\n aria-hidden\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </svg>\n);\n\n/** Inline SVG: panel-left-close (collapse sidebar) */\nconst PanelLeftCloseIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-5 w-5 transition-transform duration-300\"\n aria-hidden\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m16 15-3-3 3-3\" />\n </svg>\n);\n\nconst SidebarTrigger = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(\n ({ className, ...props }, ref) => {\n const { toggle, isCollapsed } = useSidebar();\n\n return (\n <button\n ref={ref}\n onClick={toggle}\n className={cn(\n 'relative flex items-center justify-center rounded-md p-2 text-foreground transition-colors hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring shadow-lg backdrop-blur-md cursor-pointer bg-background/95 border border-border',\n className,\n )}\n aria-label={isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n style={{ zIndex: Z_INDEX.SIDEBAR_TRIGGER }}\n {...props}\n >\n {isCollapsed ? <PanelLeftOpenIcon /> : <PanelLeftCloseIcon />}\n </button>\n );\n },\n);\nSidebarTrigger.displayName = 'SidebarTrigger';\n\nconst SidebarHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n },\n);\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-1 flex-col gap-2 overflow-auto', className)}\n {...props}\n />\n );\n },\n);\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n },\n);\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarGroup = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('group/sidebar-group', className)}\n {...props}\n />\n );\n },\n);\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n className,\n )}\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n {...props}\n />\n );\n },\n);\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nconst SidebarGroupAction = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n asChild?: boolean;\n }\n>(({ className, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1.5 text-sidebar-foreground outline-none ring-sidebar-ring transition-opacity hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:opacity-100 focus-visible:ring-2 group-hover/sidebar-group:opacity-100 peer-data-[size=sm]/sidebar-group-action:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarGroupAction.displayName = 'SidebarGroupAction';\n\nconst SidebarGroupContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full text-sm', className)}\n {...props}\n />\n );\n },\n);\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst sidebarMenuButtonVariants = cva(\n 'flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:bg-sidebar-accent focus-visible:text-sidebar-accent-foreground focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-ring))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-base',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nconst SidebarMenuButton = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof sidebarMenuButtonVariants> & {\n asChild?: boolean;\n isActive?: boolean;\n }\n>(({ className, variant, size, asChild = false, isActive, children, ...props }, ref) => {\n const { isCollapsed } = useSidebar();\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={ref}\n data-active={isActive}\n data-collapsed={isCollapsed}\n className={cn(\n sidebarMenuButtonVariants({ variant, size }),\n isCollapsed && 'justify-center',\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n});\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nconst SidebarMenu = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(\n ({ className, ...props }, ref) => {\n return (\n <ul\n ref={ref}\n className={cn('flex w-full min-w-0 flex-col gap-1', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, ...props }, ref) => {\n return (\n <li\n ref={ref}\n className={cn('group/menu-item relative', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst SidebarMenuAction = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n asChild?: boolean;\n }\n>(({ className, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 flex -translate-y-1/2 items-center justify-center rounded-md p-1 text-sidebar-foreground opacity-0 transition-opacity group-hover/menu-item:opacity-100 group-focus/menu-item:opacity-100 [&:has(~:hover)]:opacity-100 [&:has(~:focus)]:opacity-100',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarMenuAction.displayName = 'SidebarMenuAction';\n\nconst SidebarMenuBadge = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 flex -translate-y-1/2 items-center justify-center rounded-md px-1.5 py-0.5 text-xs font-medium tabular-nums text-sidebar-foreground',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebarMenuBadge.displayName = 'SidebarMenuBadge';\n\nconst SidebarMenuSkeleton = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n showIcon?: boolean;\n }\n>(({ className, showIcon = false, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex items-center gap-2 px-2 py-1.5', className)}\n {...props}\n >\n {showIcon && <div className=\"flex h-4 w-4 rounded-md bg-sidebar-primary/10\" />}\n <div className=\"flex flex-1 flex-col gap-1.5\">\n <div className=\"h-2.5 w-16 rounded-md bg-sidebar-primary/10\" />\n <div className=\"h-2.5 w-24 rounded-md bg-sidebar-primary/10\" />\n </div>\n </div>\n );\n});\nSidebarMenuSkeleton.displayName = 'SidebarMenuSkeleton';\n\nconst SidebarMenuSub = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(\n ({ className, ...props }, ref) => {\n return (\n <ul\n ref={ref}\n className={cn(\n 'ml-4 mt-1 flex min-w-0 flex-col gap-0.5 border-l border-sidebar-border pl-2.5',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebarMenuSub.displayName = 'SidebarMenuSub';\n\nconst SidebarMenuSubButton = forwardRef<\n HTMLAnchorElement,\n AnchorHTMLAttributes<HTMLAnchorElement> & {\n asChild?: boolean;\n size?: 'sm' | 'md' | 'lg';\n isActive?: boolean;\n }\n>(({ className, asChild = false, size = 'md', isActive, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md p-2 text-sidebar-foreground outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarMenuSubButton.displayName = 'SidebarMenuSubButton';\n\nconst SidebarMenuSubItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, ...props }, ref) => {\n return (\n <li\n ref={ref}\n className={cn('group/menu-sub-item relative', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenuSubItem.displayName = 'SidebarMenuSubItem';\n\nexport {\n Sidebar,\n SidebarProvider,\n SidebarTrigger,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n useSidebar,\n};\n","// Simple icon components (since we don't have lucide-react)\nexport const MenuIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n);\n\nexport const HomeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <polyline points=\"9 22 9 12 15 12 15 22\" />\n </svg>\n);\n\nexport const PaintbrushIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path\n fill=\"none\"\n d=\"m14.622 17.897l-10.68-2.913M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0zM9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15\"\n />\n </svg>\n);\n\nexport const MessageCircleIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\" />\n </svg>\n);\n\nexport const GlobeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <line\n x1=\"2\"\n x2=\"22\"\n y1=\"12\"\n y2=\"12\"\n />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n);\n\nexport const KeyboardIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"16\"\n x=\"2\"\n y=\"4\"\n rx=\"2\"\n />\n <path d=\"M6 8h.01\" />\n <path d=\"M10 8h.01\" />\n <path d=\"M14 8h.01\" />\n <path d=\"M18 8h.01\" />\n <path d=\"M8 12h.01\" />\n <path d=\"M12 12h.01\" />\n <path d=\"M16 12h.01\" />\n <path d=\"M7 16h10\" />\n </svg>\n);\n\nexport const CheckIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\nexport const VideoIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect\n x=\"2\"\n y=\"6\"\n width=\"14\"\n height=\"12\"\n rx=\"2\"\n />\n </svg>\n);\n\nexport const LinkIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n);\n\nexport const LockIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"18\"\n height=\"11\"\n x=\"3\"\n y=\"11\"\n rx=\"2\"\n ry=\"2\"\n />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n);\n\nexport const SettingsIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"3\"\n />\n </svg>\n);\n\nexport const CodeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </svg>\n);\n\nexport const ChevronRightIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\nexport const ChevronLeftIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n);\n\nexport const ShieldIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n);\n\nexport const HardDriveIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line\n x1=\"22\"\n y1=\"12\"\n x2=\"2\"\n y2=\"12\"\n />\n <path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n <line\n x1=\"6\"\n y1=\"16\"\n x2=\"6.01\"\n y2=\"16\"\n />\n <line\n x1=\"10\"\n y1=\"16\"\n x2=\"10.01\"\n y2=\"16\"\n />\n </svg>\n);\n\nexport const RefreshCwIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n);\n\n/** Double-arrow refresh / sync icon (two curved arrows in a circle). */\nexport const RefreshDoubleIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 0 0-9-9a9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5m-5 4a9 9 0 0 0 9 9a9.75 9.75 0 0 0 6.74-2.74L21 16\" />\n <path d=\"M16 16h5v5\" />\n </svg>\n);\n\nexport const ServerIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"8\"\n x=\"2\"\n y=\"2\"\n rx=\"2\"\n ry=\"2\"\n />\n <rect\n width=\"20\"\n height=\"8\"\n x=\"2\"\n y=\"14\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"6.01\"\n y2=\"6\"\n />\n <line\n x1=\"6\"\n y1=\"18\"\n x2=\"6.01\"\n y2=\"18\"\n />\n <line\n x1=\"10\"\n y1=\"6\"\n x2=\"10.01\"\n y2=\"6\"\n />\n <line\n x1=\"10\"\n y1=\"18\"\n x2=\"10.01\"\n y2=\"18\"\n />\n </svg>\n);\n\nexport const PackageIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m7.5 4.27 9 5.15\" />\n <path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\" />\n <path d=\"m3.3 7 8.7 5 8.7-5\" />\n <path d=\"M12 22V12\" />\n </svg>\n);\n","import { useContext, createContext } from 'react';\nimport type { Settings } from '@shellui/sdk';\n\nexport interface SettingsContextValue {\n settings: Settings;\n updateSettings: (updates: Partial<Settings>) => void;\n updateSetting: <K extends keyof Settings>(key: K, updates: Partial<Settings[K]>) => void;\n resetAllData: () => void;\n}\n\nexport const SettingsContext = createContext<SettingsContextValue | undefined>(undefined);\n\nexport function useSettings() {\n const context = useContext(SettingsContext);\n if (context === undefined) {\n throw new Error('useSettings must be used within a SettingsProvider');\n }\n return context;\n}\n","import { useContext } from 'react';\nimport { SettingsContext } from '../SettingsContext';\n\nexport function useSettings() {\n const context = useContext(SettingsContext);\n if (context === undefined) {\n throw new Error('useSettings must be used within a SettingsProvider');\n }\n return context;\n}\n","import { forwardRef, type ButtonHTMLAttributes } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n","import {\n forwardRef,\n Children,\n isValidElement,\n cloneElement,\n type HTMLAttributes,\n type ReactNode,\n type ReactElement,\n} from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('inline-flex rounded-md', className)}\n role=\"group\"\n {...props}\n >\n {Children.map(children, (child, index) => {\n if (isValidElement(child)) {\n const isFirst = index === 0;\n const isLast = index === Children.count(children) - 1;\n\n return cloneElement(child as ReactElement<Record<string, unknown>>, {\n className: cn(\n // Remove rounded corners from all buttons\n 'rounded-none',\n // First button: rounded left only (uses theme radius)\n isFirst && 'rounded-l-md',\n // Last button: rounded right only (uses theme radius)\n isLast && 'rounded-r-md',\n // Remove left border from all except first, using theme border color\n !isFirst && 'border-l-0 -ml-px',\n (child as ReactElement<{ className?: string }>).props.className,\n ),\n });\n }\n return child;\n })}\n </div>\n );\n },\n);\nButtonGroup.displayName = 'ButtonGroup';\n\nexport { ButtonGroup };\n","/* eslint-disable no-console */\n/**\n * Theme color definitions following shadcn/ui CSS variable structure\n * Each theme has light and dark mode variants\n * Colors are stored in hex format (e.g., \"#4CAF50\" or \"4CAF50\")\n * and converted to HSL when applied to CSS variables\n */\n\n/**\n * Convert hex color (format: \"#RRGGBB\" or \"RRGGBB\") to HSL string (format: \"H S% L%\")\n */\nfunction hexToHsl(hexString: string): string {\n // Handle non-color values like radius\n if (!hexString || typeof hexString !== 'string') {\n return hexString;\n }\n\n // Check if it's a hex color\n if (!hexString.match(/^#?[0-9A-Fa-f]{6}$/)) {\n // If it's not a hex color, return as-is (might be radius or other value)\n return hexString;\n }\n\n // Remove # if present\n const hex = hexString.replace('#', '');\n\n // Parse RGB values\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n // Validate parsed values\n if (isNaN(r) || isNaN(g) || isNaN(b)) {\n console.warn(`[Theme] Invalid hex color: ${hexString}`);\n return hexString;\n }\n\n // Normalize RGB values to 0-1\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const max = Math.max(rNorm, gNorm, bNorm);\n const min = Math.min(rNorm, gNorm, bNorm);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case rNorm:\n h = ((gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0)) / 6;\n break;\n case gNorm:\n h = ((bNorm - rNorm) / d + 2) / 6;\n break;\n case bNorm:\n h = ((rNorm - gNorm) / d + 4) / 6;\n break;\n }\n }\n\n // Convert to degrees and percentages\n const hDeg = Math.round(h * 360 * 10) / 10; // Keep one decimal for precision\n const sPercent = Math.round(s * 100 * 10) / 10;\n const lPercent = Math.round(l * 100 * 10) / 10;\n\n const result = `${hDeg} ${sPercent}% ${lPercent}%`;\n\n // Validate result\n if (!result.match(/^\\d+(\\.\\d+)?\\s+\\d+(\\.\\d+)?%\\s+\\d+(\\.\\d+)?%$/)) {\n console.warn(`[Theme] Invalid HSL conversion result for ${hexString}: ${result}`);\n return hexString;\n }\n\n return result;\n}\n\nexport interface ThemeColors {\n light: {\n background: string;\n foreground: string;\n card: string;\n cardForeground: string;\n popover: string;\n popoverForeground: string;\n primary: string;\n primaryForeground: string;\n secondary: string;\n secondaryForeground: string;\n muted: string;\n mutedForeground: string;\n accent: string;\n accentForeground: string;\n destructive: string;\n destructiveForeground: string;\n border: string;\n input: string;\n ring: string;\n radius: string;\n sidebarBackground: string;\n sidebarForeground: string;\n sidebarPrimary: string;\n sidebarPrimaryForeground: string;\n sidebarAccent: string;\n sidebarAccentForeground: string;\n sidebarBorder: string;\n sidebarRing: string;\n };\n dark: {\n background: string;\n foreground: string;\n card: string;\n cardForeground: string;\n popover: string;\n popoverForeground: string;\n primary: string;\n primaryForeground: string;\n secondary: string;\n secondaryForeground: string;\n muted: string;\n mutedForeground: string;\n accent: string;\n accentForeground: string;\n destructive: string;\n destructiveForeground: string;\n border: string;\n input: string;\n ring: string;\n radius: string;\n sidebarBackground: string;\n sidebarForeground: string;\n sidebarPrimary: string;\n sidebarPrimaryForeground: string;\n sidebarAccent: string;\n sidebarAccentForeground: string;\n sidebarBorder: string;\n sidebarRing: string;\n };\n}\n\nexport interface ThemeDefinition {\n name: string;\n displayName: string;\n colors: ThemeColors;\n fontFamily?: string; // Optional custom font family (backward compatible)\n headingFontFamily?: string; // Optional font family for headings (h1-h6)\n bodyFontFamily?: string; // Optional font family for body text\n fontFiles?: string[]; // Optional array of font file URLs or paths to load (e.g., Google Fonts links or local paths)\n letterSpacing?: string; // Optional custom letter spacing (e.g., \"0.02em\")\n textShadow?: string; // Optional custom text shadow (e.g., \"1px 1px 2px rgba(0, 0, 0, 0.1)\")\n lineHeight?: string; // Optional custom line height (e.g., \"1.6\")\n}\n\n/**\n * Default theme - Green (current ShellUI theme)\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const defaultTheme: ThemeDefinition = {\n name: 'default',\n displayName: 'Default',\n colors: {\n light: {\n background: '#FFFFFF', // White\n foreground: '#020617', // Very dark blue-gray\n card: '#FFFFFF', // White\n cardForeground: '#020617', // Very dark blue-gray\n popover: '#FFFFFF', // White\n popoverForeground: '#020617', // Very dark blue-gray\n primary: '#22C55E', // Green\n primaryForeground: '#FFFFFF', // White\n secondary: '#F1F5F9', // Light gray-blue\n secondaryForeground: '#0F172A', // Dark blue-gray\n muted: '#F1F5F9', // Light gray-blue\n mutedForeground: '#64748B', // Medium gray-blue\n accent: '#F1F5F9', // Light gray-blue\n accentForeground: '#0F172A', // Dark blue-gray\n destructive: '#EF4444', // Red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#E2E8F0', // Light gray\n input: '#E2E8F0', // Light gray\n ring: '#020617', // Very dark blue-gray\n radius: '0.5rem',\n sidebarBackground: '#FAFAFA', // Off-white\n sidebarForeground: '#334155', // Dark gray-blue\n sidebarPrimary: '#0F172A', // Very dark blue-gray\n sidebarPrimaryForeground: '#FAFAFA', // Off-white\n sidebarAccent: '#F4F4F5', // Light gray\n sidebarAccentForeground: '#0F172A', // Very dark blue-gray\n sidebarBorder: '#E2E8F0', // Light gray\n sidebarRing: '#3B82F6', // Blue\n },\n dark: {\n background: '#020617', // Very dark blue-gray\n foreground: '#F8FAFC', // Off-white\n card: '#020617', // Very dark blue-gray\n cardForeground: '#F8FAFC', // Off-white\n popover: '#020617', // Very dark blue-gray\n popoverForeground: '#F8FAFC', // Off-white\n primary: '#4ADE80', // Bright green\n primaryForeground: '#FFFFFF', // White\n secondary: '#1E293B', // Dark blue-gray\n secondaryForeground: '#F8FAFC', // Off-white\n muted: '#1E293B', // Dark blue-gray\n mutedForeground: '#94A3B8', // Medium gray-blue\n accent: '#1E293B', // Dark blue-gray\n accentForeground: '#F8FAFC', // Off-white\n destructive: '#991B1B', // Dark red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#1E293B', // Dark blue-gray\n input: '#1E293B', // Dark blue-gray\n ring: '#CBD5E1', // Light gray-blue\n radius: '0.5rem',\n sidebarBackground: '#0F172A', // Very dark blue-gray\n sidebarForeground: '#F1F5F9', // Light gray-blue\n sidebarPrimary: '#E0E7FF', // Very light blue\n sidebarPrimaryForeground: '#0F172A', // Very dark blue-gray\n sidebarAccent: '#18181B', // Very dark gray\n sidebarAccentForeground: '#F1F5F9', // Light gray-blue\n sidebarBorder: '#18181B', // Very dark gray\n sidebarRing: '#3B82F6', // Blue\n },\n },\n};\n\n/**\n * Blue theme\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const blueTheme: ThemeDefinition = {\n name: 'blue',\n displayName: 'Blue',\n colors: {\n light: {\n background: '#FFFFFF', // White\n foreground: '#020617', // Very dark blue-gray\n card: '#FFFFFF', // White\n cardForeground: '#020617', // Very dark blue-gray\n popover: '#FFFFFF', // White\n popoverForeground: '#020617', // Very dark blue-gray\n primary: '#3B82F6', // Blue\n primaryForeground: '#FFFFFF', // White\n secondary: '#F1F5F9', // Light gray-blue\n secondaryForeground: '#0F172A', // Dark blue-gray\n muted: '#F1F5F9', // Light gray-blue\n mutedForeground: '#64748B', // Medium gray-blue\n accent: '#F1F5F9', // Light gray-blue\n accentForeground: '#0F172A', // Dark blue-gray\n destructive: '#EF4444', // Red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#E2E8F0', // Light gray\n input: '#E2E8F0', // Light gray\n ring: '#3B82F6', // Blue\n radius: '0.5rem',\n sidebarBackground: '#FAFAFA', // Off-white\n sidebarForeground: '#334155', // Dark gray-blue\n sidebarPrimary: '#3B82F6', // Blue\n sidebarPrimaryForeground: '#FFFFFF', // White\n sidebarAccent: '#F4F4F5', // Light gray\n sidebarAccentForeground: '#0F172A', // Very dark blue-gray\n sidebarBorder: '#E2E8F0', // Light gray\n sidebarRing: '#3B82F6', // Blue\n },\n dark: {\n background: '#020617', // Very dark blue-gray\n foreground: '#F8FAFC', // Off-white\n card: '#020617', // Very dark blue-gray\n cardForeground: '#F8FAFC', // Off-white\n popover: '#020617', // Very dark blue-gray\n popoverForeground: '#F8FAFC', // Off-white\n primary: '#3B82F6', // Blue\n primaryForeground: '#FFFFFF', // White\n secondary: '#1E293B', // Dark blue-gray\n secondaryForeground: '#F8FAFC', // Off-white\n muted: '#1E293B', // Dark blue-gray\n mutedForeground: '#94A3B8', // Medium gray-blue\n accent: '#1E293B', // Dark blue-gray\n accentForeground: '#F8FAFC', // Off-white\n destructive: '#991B1B', // Dark red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#1E293B', // Dark blue-gray\n input: '#1E293B', // Dark blue-gray\n ring: '#3B82F6', // Blue\n radius: '0.5rem',\n sidebarBackground: '#0F172A', // Very dark blue-gray\n sidebarForeground: '#F1F5F9', // Light gray-blue\n sidebarPrimary: '#3B82F6', // Blue\n sidebarPrimaryForeground: '#0F172A', // Dark blue-gray\n sidebarAccent: '#18181B', // Very dark gray\n sidebarAccentForeground: '#F1F5F9', // Light gray-blue\n sidebarBorder: '#18181B', // Very dark gray\n sidebarRing: '#3B82F6', // Blue\n },\n },\n};\n\n/**\n * Warm Yellow theme - Custom yellowish theme with warm tones\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const warmYellowTheme: ThemeDefinition = {\n name: 'warm-yellow',\n displayName: 'Warm Yellow',\n fontFamily: '\"Comic Sans MS\", \"Comic Sans\", \"Chalkboard SE\", \"Comic Neue\", cursive, sans-serif',\n letterSpacing: '0.02em',\n textShadow: '1px 1px 2px rgba(0, 0, 0, 0.1)',\n lineHeight: '1.6',\n colors: {\n light: {\n background: '#FFF8E7', // Warm cream/yellowish\n foreground: '#3E2723', // Warm dark brown\n card: '#FFFEF5', // Slightly off-white cream\n cardForeground: '#3E2723', // Warm dark brown\n popover: '#FFFEF5', // Slightly off-white cream\n popoverForeground: '#3E2723', // Warm dark brown\n primary: '#F59E0B', // Warm golden amber (complements yellow)\n primaryForeground: '#FFFFFF', // White\n secondary: '#F5E6D3', // Warm beige\n secondaryForeground: '#3E2723', // Warm dark brown\n muted: '#F5E6D3', // Warm beige\n mutedForeground: '#6D4C41', // Medium warm brown\n accent: '#FFE082', // Light warm yellow\n accentForeground: '#3E2723', // Warm dark brown\n destructive: '#E57373', // Soft red (works with warm tones)\n destructiveForeground: '#FFFFFF', // White\n border: '#E8D5B7', // Warm tan border\n input: '#E8D5B7', // Warm tan input border\n ring: '#F59E0B', // Warm golden amber ring\n radius: '0.5rem',\n sidebarBackground: '#FFF5E1', // Slightly warmer cream (subtle contrast with main background)\n sidebarForeground: '#5D4037', // Medium warm brown\n sidebarPrimary: '#F59E0B', // Warm golden amber\n sidebarPrimaryForeground: '#FFFFFF', // White\n sidebarAccent: '#F5E6D3', // Warm beige\n sidebarAccentForeground: '#3E2723', // Warm dark brown\n sidebarBorder: '#E8D5B7', // Warm tan\n sidebarRing: '#F59E0B', // Warm golden amber\n },\n dark: {\n background: '#2E2419', // Dark warm brown\n foreground: '#FFF8E7', // Warm cream (inverted)\n card: '#3E2723', // Dark warm brown\n cardForeground: '#FFF8E7', // Warm cream\n popover: '#3E2723', // Dark warm brown\n popoverForeground: '#FFF8E7', // Warm cream\n primary: '#FBBF24', // Bright golden amber (lighter for dark mode)\n primaryForeground: '#FFFFFF', // White for better contrast\n secondary: '#4E342E', // Medium dark warm brown\n secondaryForeground: '#FFF8E7', // Warm cream\n muted: '#4E342E', // Medium dark warm brown\n mutedForeground: '#D7CCC8', // Light warm gray\n accent: '#FFB74D', // Warm orange accent\n accentForeground: '#2E2419', // Dark warm brown for better contrast\n destructive: '#EF5350', // Softer red for dark mode\n destructiveForeground: '#FFF8E7', // Warm cream\n border: '#5D4037', // Medium warm brown border\n input: '#5D4037', // Medium warm brown input border\n ring: '#FBBF24', // Bright golden amber ring\n radius: '0.5rem',\n sidebarBackground: '#35281F', // Slightly warmer dark brown (subtle contrast with main background)\n sidebarForeground: '#D7CCC8', // Light warm gray\n sidebarPrimary: '#FBBF24', // Bright golden amber\n sidebarPrimaryForeground: '#2E2419', // Dark warm brown for better contrast\n sidebarAccent: '#4E342E', // Medium dark warm brown\n sidebarAccentForeground: '#FFF8E7', // Warm cream\n sidebarBorder: '#5D4037', // Medium warm brown\n sidebarRing: '#FBBF24', // Bright golden amber\n },\n },\n};\n\n/**\n * Registry of all available themes\n */\nconst themeRegistry = new Map<string, ThemeDefinition>([\n ['default', defaultTheme],\n ['blue', blueTheme],\n ['warm-yellow', warmYellowTheme],\n]);\n\n/**\n * Register a custom theme\n */\nexport function registerTheme(theme: ThemeDefinition): void {\n themeRegistry.set(theme.name, theme);\n}\n\n/**\n * Get a theme by name\n */\nexport function getTheme(name: string): ThemeDefinition | undefined {\n return themeRegistry.get(name);\n}\n\n/**\n * Get all available themes\n */\nexport function getAllThemes(): ThemeDefinition[] {\n return Array.from(themeRegistry.values());\n}\n\n/**\n * Apply theme colors to the document\n * Converts hex format colors to HSL format for CSS variables\n * Sets variables directly on :root to ensure they override CSS defaults\n */\nexport function applyTheme(theme: ThemeDefinition, isDark: boolean): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n const colors = isDark ? theme.colors.dark : theme.colors.light;\n\n // Convert hex to HSL for all colors\n const primaryHsl = hexToHsl(colors.primary);\n\n // Apply CSS variables directly on :root element\n // Inline styles have the highest specificity and will override CSS defaults\n // Format: HSL values without hsl() wrapper (e.g., \"142 71% 45%\")\n root.style.setProperty('--background', hexToHsl(colors.background));\n root.style.setProperty('--foreground', hexToHsl(colors.foreground));\n root.style.setProperty('--card', hexToHsl(colors.card));\n root.style.setProperty('--card-foreground', hexToHsl(colors.cardForeground));\n root.style.setProperty('--popover', hexToHsl(colors.popover));\n root.style.setProperty('--popover-foreground', hexToHsl(colors.popoverForeground));\n root.style.setProperty('--primary', primaryHsl);\n root.style.setProperty('--primary-foreground', hexToHsl(colors.primaryForeground));\n root.style.setProperty('--secondary', hexToHsl(colors.secondary));\n root.style.setProperty('--secondary-foreground', hexToHsl(colors.secondaryForeground));\n root.style.setProperty('--muted', hexToHsl(colors.muted));\n root.style.setProperty('--muted-foreground', hexToHsl(colors.mutedForeground));\n root.style.setProperty('--accent', hexToHsl(colors.accent));\n root.style.setProperty('--accent-foreground', hexToHsl(colors.accentForeground));\n root.style.setProperty('--destructive', hexToHsl(colors.destructive));\n root.style.setProperty('--destructive-foreground', hexToHsl(colors.destructiveForeground));\n root.style.setProperty('--border', hexToHsl(colors.border));\n root.style.setProperty('--input', hexToHsl(colors.input));\n root.style.setProperty('--ring', hexToHsl(colors.ring));\n root.style.setProperty('--radius', colors.radius); // radius is not a color\n root.style.setProperty('--sidebar-background', hexToHsl(colors.sidebarBackground));\n root.style.setProperty('--sidebar-foreground', hexToHsl(colors.sidebarForeground));\n root.style.setProperty('--sidebar-primary', hexToHsl(colors.sidebarPrimary));\n root.style.setProperty('--sidebar-primary-foreground', hexToHsl(colors.sidebarPrimaryForeground));\n root.style.setProperty('--sidebar-accent', hexToHsl(colors.sidebarAccent));\n root.style.setProperty('--sidebar-accent-foreground', hexToHsl(colors.sidebarAccentForeground));\n root.style.setProperty('--sidebar-border', hexToHsl(colors.sidebarBorder));\n root.style.setProperty('--sidebar-ring', hexToHsl(colors.sidebarRing));\n\n // Load custom font files if provided\n // Always clean up existing theme fonts first (for theme switching)\n const head = document.head || document.getElementsByTagName('head')[0];\n const existingFontLinks = head.querySelectorAll('link[data-theme-font], style[data-theme-font]');\n existingFontLinks.forEach((link) => link.remove());\n\n if (theme.fontFiles && theme.fontFiles.length > 0) {\n theme.fontFiles.forEach((fontFile, index) => {\n // Check if it's a Google Fonts link or a regular stylesheet\n if (fontFile.includes('fonts.googleapis.com') || fontFile.endsWith('.css')) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = fontFile;\n link.setAttribute('data-theme-font', theme.name);\n head.appendChild(link);\n } else {\n // Assume it's a font file URL - create @font-face rule\n const style = document.createElement('style');\n style.setAttribute('data-theme-font', theme.name);\n // Extract font name from URL or use a generic name\n const fontName = `ThemeFont-${theme.name}-${index}`;\n style.textContent = `\n @font-face {\n font-family: '${fontName}';\n src: url('${fontFile}') format('woff2');\n }\n `;\n head.appendChild(style);\n }\n });\n }\n\n // Apply custom font families\n // Priority: headingFontFamily/bodyFontFamily > fontFamily (backward compatible)\n const bodyFont = theme.bodyFontFamily || theme.fontFamily;\n const headingFont = theme.headingFontFamily || theme.fontFamily || bodyFont;\n\n if (bodyFont) {\n root.style.setProperty('--body-font-family', bodyFont);\n root.style.setProperty('--font-family', bodyFont); // Backward compatibility\n document.body.style.fontFamily = bodyFont;\n } else {\n root.style.removeProperty('--body-font-family');\n root.style.removeProperty('--font-family');\n document.body.style.fontFamily = '';\n }\n\n if (headingFont) {\n root.style.setProperty('--heading-font-family', headingFont);\n // Apply to headings via CSS variable (will be used in CSS)\n } else {\n root.style.removeProperty('--heading-font-family');\n }\n\n // Apply optional font styling properties generically\n if (theme.letterSpacing) {\n root.style.setProperty('--letter-spacing', theme.letterSpacing);\n root.style.letterSpacing = theme.letterSpacing;\n } else {\n root.style.removeProperty('--letter-spacing');\n root.style.letterSpacing = '';\n }\n\n if (theme.textShadow) {\n root.style.setProperty('--text-shadow', theme.textShadow);\n // Apply slightly lighter shadow to body for better readability\n const bodyShadow = theme.textShadow.replace(/rgba\\(([^)]+)\\)/, (match, rgba) => {\n // Reduce opacity by ~20% for body text\n const values = rgba.split(',').map((v: string) => v.trim());\n if (values.length === 4) {\n const opacity = parseFloat(values[3]);\n return `rgba(${values[0]}, ${values[1]}, ${values[2]}, ${Math.max(0, opacity * 0.8)})`;\n }\n return match;\n });\n document.body.style.textShadow = bodyShadow;\n } else {\n root.style.removeProperty('--text-shadow');\n document.body.style.textShadow = '';\n }\n\n if (theme.lineHeight) {\n root.style.setProperty('--line-height', theme.lineHeight);\n document.body.style.lineHeight = theme.lineHeight;\n } else {\n root.style.removeProperty('--line-height');\n document.body.style.lineHeight = '';\n }\n\n // Verify primary color is set (for debugging)\n const actualPrimary = root.style.getPropertyValue('--primary');\n\n // Validate HSL format (should be \"H S% L%\" like \"142 71% 45%\")\n const hslFormat = /^\\d+(\\.\\d+)?\\s+\\d+(\\.\\d+)?%\\s+\\d+(\\.\\d+)?%$/;\n\n if (!actualPrimary || actualPrimary.trim() === '') {\n console.error(\n `[Theme] Failed to set --primary CSS variable. Expected HSL from ${colors.primary}, got: \"${actualPrimary}\"`,\n );\n } else if (!hslFormat.test(actualPrimary.trim())) {\n console.error(\n `[Theme] Invalid HSL format for --primary: \"${actualPrimary}\". Expected format: \"H S% L%\"`,\n );\n }\n\n // Force a reflow to ensure Tailwind picks up the changes\n // This is sometimes needed for Tailwind v4 to recognize CSS variable changes\n void root.offsetHeight;\n}\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { cn } from '@/lib/utils';\nimport { useEffect, useState } from 'react';\nimport { getAllThemes, registerTheme, type ThemeDefinition } from '@/features/theme/themes';\n\nconst SunIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"4\"\n />\n <path d=\"M12 2v2\" />\n <path d=\"M12 20v2\" />\n <path d=\"m4.93 4.93 1.41 1.41\" />\n <path d=\"m17.66 17.66 1.41 1.41\" />\n <path d=\"M2 12h2\" />\n <path d=\"M20 12h2\" />\n <path d=\"m6.34 17.66-1.41 1.41\" />\n <path d=\"m19.07 4.93-1.41 1.41\" />\n </svg>\n);\n\nconst MoonIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\" />\n </svg>\n);\n\nconst MonitorIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"14\"\n x=\"2\"\n y=\"3\"\n rx=\"2\"\n />\n <line\n x1=\"8\"\n x2=\"16\"\n y1=\"21\"\n y2=\"21\"\n />\n <line\n x1=\"12\"\n x2=\"12\"\n y1=\"17\"\n y2=\"21\"\n />\n </svg>\n);\n\n// Theme color preview component\nconst ThemePreview = ({\n theme,\n isSelected,\n isDark,\n}: {\n theme: ThemeDefinition;\n isSelected: boolean;\n isDark: boolean;\n}) => {\n const colors = isDark ? theme.colors.dark : theme.colors.light;\n\n return (\n <div\n className={cn(\n 'relative overflow-hidden rounded-lg border-2 transition-all',\n isSelected ? 'border-primary shadow-lg' : 'border-border',\n )}\n style={{ backgroundColor: colors.background }}\n >\n <div className=\"p-3 space-y-2\">\n {/* Primary color */}\n <div\n className=\"h-8 rounded-md\"\n style={{ backgroundColor: colors.primary }}\n />\n {/* Secondary colors */}\n <div className=\"flex gap-1\">\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.background }}\n />\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.secondary }}\n />\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.accent }}\n />\n </div>\n {/* Accent colors */}\n <div className=\"flex gap-1\">\n <div\n className=\"h-4 flex-1 rounded\"\n style={{ backgroundColor: colors.muted }}\n />\n <div\n className=\"h-4 flex-1 rounded\"\n style={{ backgroundColor: colors.border }}\n />\n </div>\n </div>\n {/* Theme name overlay */}\n <div\n className=\"absolute bottom-0 left-0 right-0 bg-background/90 backdrop-blur-sm px-2 py-1\"\n style={{ backgroundColor: colors.background }}\n >\n <p\n className=\"text-xs font-medium text-center\"\n style={\n theme.fontFamily\n ? {\n fontFamily: theme.fontFamily,\n letterSpacing: theme.letterSpacing || 'normal',\n textShadow: theme.textShadow || 'none',\n }\n : {}\n }\n >\n {theme.displayName}\n </p>\n </div>\n </div>\n );\n};\n\nexport const Appearance = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentTheme = settings.appearance?.theme || 'system';\n const currentThemeName = settings.appearance?.themeName || 'default';\n\n const [availableThemes, setAvailableThemes] = useState<ThemeDefinition[]>([]);\n\n // Register custom themes from config and get all themes\n useEffect(() => {\n if (config?.themes) {\n config.themes.forEach((themeDef: ThemeDefinition) => {\n registerTheme(themeDef);\n });\n }\n setAvailableThemes(getAllThemes());\n }, [config]);\n\n // Determine if we're in dark mode for preview\n const [isDarkForPreview, setIsDarkForPreview] = useState(() => {\n if (typeof window === 'undefined') return false;\n return (\n currentTheme === 'dark' ||\n (currentTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)\n );\n });\n\n // Update preview mode when theme changes\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const updatePreview = () => {\n setIsDarkForPreview(\n currentTheme === 'dark' ||\n (currentTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches),\n );\n };\n\n updatePreview();\n\n if (currentTheme === 'system') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => updatePreview();\n\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n } else if (mediaQuery.addListener) {\n mediaQuery.addListener(handleChange);\n return () => mediaQuery.removeListener(handleChange);\n }\n }\n }, [currentTheme]);\n\n const modeThemes = [\n { value: 'light' as const, label: t('appearance.themes.light'), icon: SunIcon },\n { value: 'dark' as const, label: t('appearance.themes.dark'), icon: MoonIcon },\n { value: 'system' as const, label: t('appearance.themes.system'), icon: MonitorIcon },\n ];\n\n return (\n <div className=\"space-y-6\">\n {/* Theme Mode Selection (Light/Dark/System) */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('appearance.mode')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('appearance.modeDescription')}</p>\n </div>\n <div className=\"mt-2\">\n <ButtonGroup>\n {modeThemes.map((theme) => {\n const Icon = theme.icon;\n const isSelected = currentTheme === theme.value;\n return (\n <Button\n key={theme.value}\n variant={isSelected ? 'default' : 'outline'}\n onClick={() => {\n updateSetting('appearance', { theme: theme.value });\n }}\n className={cn(\n 'h-10 px-4 transition-all flex items-center gap-2 cursor-pointer',\n isSelected && ['font-semibold'],\n !isSelected && ['bg-background hover:bg-accent/50', 'text-muted-foreground'],\n )}\n aria-label={theme.label}\n title={theme.label}\n >\n <Icon />\n <span className=\"text-sm font-medium\">{theme.label}</span>\n </Button>\n );\n })}\n </ButtonGroup>\n </div>\n </div>\n\n {/* Theme Selection (Color Scheme) */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('appearance.colorTheme')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('appearance.colorThemeDescription')}</p>\n </div>\n <div className=\"mt-2 grid grid-cols-2 md:grid-cols-3 gap-4\">\n {availableThemes.map((theme) => {\n const isSelected = currentThemeName === theme.name;\n return (\n <button\n key={theme.name}\n onClick={() => {\n updateSetting('appearance', { themeName: theme.name });\n }}\n className={cn(\n 'text-left transition-all cursor-pointer',\n isSelected && 'ring-2 ring-primary ring-offset-2 rounded-lg',\n )}\n aria-label={theme.displayName}\n >\n <ThemePreview\n theme={theme}\n isSelected={isSelected}\n isDark={isDarkForPreview}\n />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n};\n","import i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport enCommon from './translations/en/common.json';\nimport enSettings from './translations/en/settings.json';\nimport enCookieConsent from './translations/en/cookieConsent.json';\nimport frCommon from './translations/fr/common.json';\nimport frSettings from './translations/fr/settings.json';\nimport frCookieConsent from './translations/fr/cookieConsent.json';\n\nexport const allSupportedLanguages = [\n { code: 'en', name: 'English', nativeName: 'English' },\n { code: 'fr', name: 'French', nativeName: 'Français' },\n] as const;\n\nexport type SupportedLanguage = (typeof allSupportedLanguages)[number]['code'];\n\nconst resources = {\n en: {\n common: enCommon,\n settings: enSettings,\n cookieConsent: enCookieConsent,\n },\n fr: {\n common: frCommon,\n settings: frSettings,\n cookieConsent: frCookieConsent,\n },\n};\n\n// Get initial language from localStorage if available\nconst getInitialLanguage = (enabledLanguages: string[]): SupportedLanguage => {\n if (typeof window !== 'undefined') {\n try {\n const stored = localStorage.getItem('shellui:settings');\n if (stored) {\n const parsed = JSON.parse(stored);\n const languageCode = parsed.language?.code;\n // Only use stored language if it's in the enabled languages list\n if (languageCode && enabledLanguages.includes(languageCode)) {\n return languageCode as SupportedLanguage;\n }\n }\n } catch (_error) {\n // Ignore errors, fall back to default\n }\n }\n // Fallback to first enabled language or 'en'\n return (enabledLanguages[0] || 'en') as SupportedLanguage;\n};\n\n// Initialize i18n with default settings (will be updated when config loads)\nlet isInitialized = false;\n\nexport const initializeI18n = (enabledLanguages?: string | string[]) => {\n // Normalize to array\n const enabledLangs = enabledLanguages\n ? Array.isArray(enabledLanguages)\n ? enabledLanguages\n : [enabledLanguages]\n : allSupportedLanguages.map((lang) => lang.code);\n\n // Filter to only include languages we have translations for\n const validLangs = enabledLangs.filter((lang) =>\n allSupportedLanguages.some((supported) => supported.code === lang),\n );\n\n // Ensure at least 'en' is available\n const finalLangs = validLangs.length > 0 ? validLangs : ['en'];\n const initialLang = getInitialLanguage(finalLangs);\n\n if (!isInitialized) {\n i18n.use(initReactI18next).init({\n resources,\n defaultNS: 'common',\n lng: initialLang,\n fallbackLng: 'en',\n supportedLngs: finalLangs,\n interpolation: {\n escapeValue: false, // React already escapes values\n },\n react: {\n useSuspense: false, // Disable suspense for better PWA compatibility\n },\n });\n isInitialized = true;\n } else {\n // Update supported languages if config changes\n i18n.changeLanguage(initialLang);\n }\n\n return finalLangs;\n};\n\n// Initialize with all languages by default (will be filtered when config loads)\ninitializeI18n();\n\nexport const getSupportedLanguages = (enabledLanguages?: string | string[]) => {\n const enabledLangs = enabledLanguages\n ? Array.isArray(enabledLanguages)\n ? enabledLanguages\n : [enabledLanguages]\n : allSupportedLanguages.map((lang) => lang.code);\n\n return allSupportedLanguages.filter((lang) => enabledLangs.includes(lang.code));\n};\n\nexport default i18n;\n","import { forwardRef, type SelectHTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport type SelectProps = SelectHTMLAttributes<HTMLSelectElement>;\n\nconst Select = forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <select\n className={cn(\n 'select-field flex h-10 w-full rounded-md border border-input bg-background pl-3 pr-10 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n >\n {children}\n </select>\n );\n },\n);\nSelect.displayName = 'Select';\n\nexport { Select };\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { getSupportedLanguages } from '@/i18n/config';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { Select } from '@/components/ui/select';\nimport { cn } from '@/lib/utils';\nimport { useState, useEffect } from 'react';\n\nconst GlobeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <line\n x1=\"2\"\n x2=\"22\"\n y1=\"12\"\n y2=\"12\"\n />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n);\n\nconst ClockIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n);\n\n// Timezones organized by region\nconst TIMEZONE_GROUPS = [\n {\n label: 'UTC',\n timezones: [{ value: 'UTC', label: 'UTC (Coordinated Universal Time)' }],\n },\n {\n label: 'North America',\n timezones: [\n { value: 'America/New_York', label: 'Eastern Time (US & Canada)' },\n { value: 'America/Chicago', label: 'Central Time (US & Canada)' },\n { value: 'America/Denver', label: 'Mountain Time (US & Canada)' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (US & Canada)' },\n { value: 'America/Toronto', label: 'Toronto' },\n { value: 'America/Vancouver', label: 'Vancouver' },\n { value: 'America/Mexico_City', label: 'Mexico City' },\n ],\n },\n {\n label: 'South America',\n timezones: [\n { value: 'America/Sao_Paulo', label: 'São Paulo' },\n { value: 'America/Buenos_Aires', label: 'Buenos Aires' },\n ],\n },\n {\n label: 'Europe',\n timezones: [\n { value: 'Europe/London', label: 'London' },\n { value: 'Europe/Paris', label: 'Paris' },\n { value: 'Europe/Berlin', label: 'Berlin' },\n { value: 'Europe/Rome', label: 'Rome' },\n { value: 'Europe/Madrid', label: 'Madrid' },\n { value: 'Europe/Amsterdam', label: 'Amsterdam' },\n { value: 'Europe/Stockholm', label: 'Stockholm' },\n { value: 'Europe/Zurich', label: 'Zurich' },\n ],\n },\n {\n label: 'Asia',\n timezones: [\n { value: 'Asia/Tokyo', label: 'Tokyo' },\n { value: 'Asia/Shanghai', label: 'Shanghai' },\n { value: 'Asia/Hong_Kong', label: 'Hong Kong' },\n { value: 'Asia/Singapore', label: 'Singapore' },\n { value: 'Asia/Dubai', label: 'Dubai' },\n { value: 'Asia/Kolkata', label: 'Mumbai, New Delhi' },\n { value: 'Asia/Bangkok', label: 'Bangkok' },\n ],\n },\n {\n label: 'Australia & Pacific',\n timezones: [\n { value: 'Australia/Sydney', label: 'Sydney' },\n { value: 'Australia/Melbourne', label: 'Melbourne' },\n { value: 'Pacific/Auckland', label: 'Auckland' },\n ],\n },\n];\n\n// Format date based on timezone and language\nconst formatDate = (date: Date, timezone: string, lang: string): string => {\n try {\n return new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n }).format(date);\n } catch {\n return date.toLocaleDateString(lang);\n }\n};\n\n// Format time based on timezone and language\nconst formatTime = (date: Date, timezone: string, lang: string): string => {\n try {\n return new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n }).format(date);\n } catch {\n return date.toLocaleTimeString(lang);\n }\n};\n\n// Get browser's current timezone\nconst getBrowserTimezone = (): string => {\n if (typeof Intl !== 'undefined') {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n};\n\n// Get human-readable timezone name\nconst getTimezoneDisplayName = (timezone: string, lang = 'en'): string => {\n try {\n // Try to get a friendly name from Intl\n const formatter = new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n timeZoneName: 'long',\n });\n const parts = formatter.formatToParts(new Date());\n const timeZoneName = parts.find((part) => part.type === 'timeZoneName')?.value;\n\n if (timeZoneName) {\n return timeZoneName;\n }\n\n // Fallback: try to get city name from timezone string\n const cityName = timezone.split('/').pop()?.replace(/_/g, ' ') || timezone;\n return cityName;\n } catch {\n // Final fallback: use the timezone code\n return timezone;\n }\n};\n\nexport const LanguageAndRegion = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n const browserTimezone = getBrowserTimezone();\n const currentTimezone = settings.region?.timezone || browserTimezone;\n const isUsingBrowserTimezone = currentTimezone === browserTimezone;\n\n // Get supported languages based on config\n const supportedLanguages = getSupportedLanguages(config?.language);\n\n const handleResetRegion = () => {\n updateSetting('region', { timezone: browserTimezone });\n };\n\n // State for current date/time\n const [currentDateTime, setCurrentDateTime] = useState<{ date: string; time: string }>(() => {\n const now = new Date();\n return {\n date: formatDate(now, currentTimezone, currentLanguage),\n time: formatTime(now, currentTimezone, currentLanguage),\n };\n });\n\n // Update date/time every second and when timezone/language changes\n useEffect(() => {\n const updateDateTime = () => {\n const now = new Date();\n setCurrentDateTime({\n date: formatDate(now, currentTimezone, currentLanguage),\n time: formatTime(now, currentTimezone, currentLanguage),\n });\n };\n\n // Update immediately when timezone or language changes\n updateDateTime();\n\n // Then update every second\n const interval = setInterval(updateDateTime, 1000);\n\n return () => clearInterval(interval);\n }, [currentTimezone, currentLanguage]);\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('languageAndRegion.language')}\n </label>\n <div className=\"mt-2\">\n <ButtonGroup>\n {supportedLanguages.map((lang) => {\n const isSelected = currentLanguage === lang.code;\n return (\n <Button\n key={lang.code}\n variant={isSelected ? 'default' : 'outline'}\n onClick={() => {\n updateSetting('language', { code: lang.code });\n }}\n className={cn(\n 'h-10 px-4 transition-all flex items-center gap-2',\n isSelected && ['shadow-md', 'font-semibold'],\n !isSelected && ['bg-background hover:bg-accent/50', 'text-muted-foreground'],\n )}\n aria-label={lang.nativeName}\n title={lang.nativeName}\n >\n <GlobeIcon />\n <span className=\"text-sm font-medium\">{lang.nativeName}</span>\n </Button>\n );\n })}\n </ButtonGroup>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('languageAndRegion.region')}\n </label>\n {!isUsingBrowserTimezone && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleResetRegion}\n className=\"h-8 text-xs\"\n >\n {t('languageAndRegion.resetToBrowser')}\n </Button>\n )}\n </div>\n <div className=\"mt-2 space-y-3\">\n <Select\n value={currentTimezone}\n onChange={(e) => {\n updateSetting('region', { timezone: e.target.value });\n }}\n className=\"w-full\"\n >\n {TIMEZONE_GROUPS.map((group) => (\n <optgroup\n key={group.label}\n label={group.label}\n >\n {group.timezones.map((tz) => {\n const isBrowserTimezone = tz.value === browserTimezone;\n return (\n <option\n key={tz.value}\n value={tz.value}\n >\n {tz.label}\n {isBrowserTimezone ? ` (${t('languageAndRegion.defaultBrowser')})` : ''}\n </option>\n );\n })}\n </optgroup>\n ))}\n </Select>\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-md bg-muted/60 border border-border/50\">\n <ClockIcon />\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-lg font-semibold tabular-nums\">{currentDateTime.time}</span>\n <span className=\"text-xs text-muted-foreground\">{currentDateTime.date}</span>\n </div>\n </div>\n <div className=\"text-xs text-muted-foreground flex items-center gap-1\">\n <span>{t('languageAndRegion.timezoneLabel')}:</span>\n <span className=\"font-medium\">\n {getTimezoneDisplayName(currentTimezone, currentLanguage)}\n </span>\n {isUsingBrowserTimezone && (\n <span className=\"ml-1\">({t('languageAndRegion.defaultBrowser')})</span>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","/* eslint-disable no-console */\nimport { Workbox } from 'workbox-window';\nimport { shellui, getLogger } from '@shellui/sdk';\n\nconst logger = getLogger('shellcore');\n\nlet wb: Workbox | null = null;\nlet updateAvailable = false;\nlet waitingServiceWorker: ServiceWorker | null = null;\nlet registrationPromise: Promise<void> | null = null;\nlet statusListeners: Array<(status: { registered: boolean; updateAvailable: boolean }) => void> =\n [];\nlet isInitialRegistration = false; // Track if this is the first registration (no reload needed)\nlet eventListenersAdded = false; // Track if event listeners have been added to prevent duplicates\nlet toastShownForServiceWorkerId: string | null = null; // Track which service worker we've shown toast for (prevents duplicates within same page load)\nlet isIntentionalUpdate = false; // Track if we're performing an intentional update (user clicked Install Now)\n// CRITICAL: Track registration state to prevent disabling during registration or immediately after page load\n// Initialize start time to page load time to provide grace period immediately after refresh\n// This prevents race conditions where error handlers fire before registration completes\nlet isRegistering = false; // Track if registration is currently in progress\nlet registrationStartTime = typeof window !== 'undefined' ? Date.now() : 0; // Track when registration started (initialize to page load time)\nconst REGISTRATION_GRACE_PERIOD = 5000; // Don't auto-disable within 5 seconds of page load/registration start\n\n// Store event handler references so we can remove them if needed\ntype EventHandler = (event?: unknown) => void;\nlet waitingHandler: EventHandler | null = null;\nlet activatedHandler: EventHandler | null = null;\nlet controllingHandler: EventHandler | null = null;\nlet registeredHandler: EventHandler | null = null;\nlet redundantHandler: EventHandler | null = null;\nlet serviceWorkerErrorHandler: EventHandler | null = null;\nlet messageErrorHandler: EventHandler | null = null;\n\n/** Global set by host or by us from config so Tauri can be forced (e.g. when __TAURI__ is not yet injected in dev). */\ndeclare global {\n interface Window {\n __SHELLUI_TAURI__?: boolean;\n }\n}\n\nfunction hasTauriOnWindow(w: Window | null): boolean {\n if (!w) return false;\n const o = w as Window & {\n __TAURI__?: unknown;\n __TAURI_INTERNALS__?: unknown;\n __SHELLUI_TAURI__?: boolean;\n };\n if (o.__SHELLUI_TAURI__ === true) return true;\n return !!(o.__TAURI__ ?? o.__TAURI_INTERNALS__);\n}\n\n/** True when the app is running inside Tauri (desktop). Service worker is disabled there; a different caching system is used. */\nexport function isTauri(): boolean {\n if (typeof window === 'undefined') return false;\n if (hasTauriOnWindow(window)) return true;\n try {\n if (window !== window.top && hasTauriOnWindow(window.top)) return true;\n if (window.parent && window.parent !== window && hasTauriOnWindow(window.parent)) return true;\n } catch {\n // Cross-origin: can't access top/parent\n }\n return false;\n}\n\n// Cache for service worker file existence check to avoid duplicate fetches\nlet swFileExistsCache: Promise<boolean> | null = null;\nlet swFileExistsCacheTime = 0;\nconst SW_FILE_EXISTS_CACHE_TTL = 5000; // Cache for 5 seconds\n\n// Notify all listeners of status changes\nasync function notifyStatusListeners() {\n const registered = await isServiceWorkerRegistered();\n const status = {\n registered,\n updateAvailable,\n };\n statusListeners.forEach((listener) => listener(status));\n}\n\nexport interface ServiceWorkerRegistrationOptions {\n enabled: boolean;\n onUpdateAvailable?: () => void;\n}\n\n/**\n * Disable caching automatically when errors occur\n * This helps prevent hard-to-debug issues\n */\nasync function disableCachingAutomatically(reason: string): Promise<void> {\n // CRITICAL: Don't disable if registration is in progress or just started\n // This prevents race conditions where errors fire during registration\n const timeSinceRegistrationStart = Date.now() - registrationStartTime;\n if (isRegistering || timeSinceRegistrationStart < REGISTRATION_GRACE_PERIOD) {\n console.warn(\n `[Service Worker] NOT disabling - registration in progress or within grace period. Reason: ${reason}, isRegistering: ${isRegistering}, timeSinceStart: ${timeSinceRegistrationStart}ms`,\n );\n logger.warn(\n `Not disabling service worker - registration in progress or within grace period: ${reason}`,\n );\n return;\n }\n\n logger.error(`Auto-disabling caching due to error: ${reason}`);\n\n try {\n // Unregister service worker first\n await unregisterServiceWorker();\n\n // Disable service worker in settings\n // We need to access settings through localStorage since we're in a module\n if (typeof window !== 'undefined') {\n const STORAGE_KEY = 'shellui:settings';\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const settings = JSON.parse(stored);\n // Only update if service worker is currently enabled to avoid unnecessary updates\n if (settings.serviceWorker?.enabled !== false) {\n settings.serviceWorker = { enabled: false };\n // Migrate legacy key so old cached shape is updated\n if (settings.caching !== undefined) {\n delete settings.caching;\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));\n\n // Notify the app to reload settings via message system\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings },\n });\n\n // Also dispatch event for local listeners\n window.dispatchEvent(\n new CustomEvent('shellui:settings-updated', {\n detail: { settings },\n }),\n );\n\n // Show a toast notification\n shellui.toast({\n title: 'Service Worker Disabled',\n description: `The service worker has been automatically disabled due to an error: ${reason}`,\n type: 'error',\n duration: 10000,\n });\n }\n } else {\n // No settings stored, create default with service worker disabled\n const defaultSettings = {\n serviceWorker: { enabled: false },\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(defaultSettings));\n\n shellui.toast({\n title: 'Service Worker Disabled',\n description: `The service worker has been automatically disabled due to an error: ${reason}`,\n type: 'error',\n duration: 10000,\n });\n }\n } catch (error) {\n logger.error('Failed to disable service worker in settings:', { error });\n // Still show toast even if settings update fails\n shellui.toast({\n title: 'Service Worker Error',\n description: `Service worker error: ${reason}. Please disable it manually in settings.`,\n type: 'error',\n duration: 10000,\n });\n }\n }\n } catch (error) {\n logger.error('Failed to disable caching automatically:', { error });\n }\n}\n\n/**\n * Check if service worker file exists\n * Uses caching to prevent duplicate fetches when called concurrently\n */\nexport async function serviceWorkerFileExists(): Promise<boolean> {\n const now = Date.now();\n\n // Return cached promise if it's still valid and in progress\n if (swFileExistsCache && now - swFileExistsCacheTime < SW_FILE_EXISTS_CACHE_TTL) {\n return swFileExistsCache;\n }\n\n // Create a new fetch promise and cache it\n swFileExistsCache = (async () => {\n try {\n // Use a timestamp to prevent caching\n const response = await fetch(`/sw.js?t=${Date.now()}`, {\n method: 'GET',\n cache: 'no-store',\n headers: {\n 'Cache-Control': 'no-cache',\n Pragma: 'no-cache',\n },\n });\n\n // Handle 500 errors - server error, but don't disable caching immediately\n // This might be a transient server issue, just return false\n if (response.status >= 500) {\n console.warn(\n `[Service Worker] Server error (${response.status}) when fetching service worker - not disabling`,\n );\n logger.warn(\n `Server error (${response.status}) when fetching service worker - not disabling to avoid false positives`,\n );\n return false;\n }\n\n // If not ok or 404, file doesn't exist\n if (!response.ok || response.status === 404) {\n return false;\n }\n\n // Check content type - should be JavaScript\n const contentType = response.headers.get('content-type') || '';\n const isJavaScript =\n contentType.includes('javascript') ||\n contentType.includes('application/javascript') ||\n contentType.includes('text/javascript');\n\n // If content type is HTML, it's likely Vite's dev server returning index.html\n // which means the file doesn't exist\n if (contentType.includes('text/html')) {\n return false;\n }\n\n // Try to read a bit of the content to verify it's actually a service worker\n const text = await response.text();\n // Service worker files typically start with imports or have workbox/precache references\n const looksLikeServiceWorker =\n text.includes('workbox') ||\n text.includes('precache') ||\n text.includes('serviceWorker') ||\n text.includes('self.addEventListener');\n\n // If we got a response but it doesn't look like a service worker, log warning but don't disable\n // This could be a dev server issue or temporary problem\n if (!isJavaScript && !looksLikeServiceWorker) {\n console.warn('[Service Worker] File does not look like a service worker - not disabling');\n logger.warn(\n 'Service worker file appears to be invalid or corrupted - not disabling to avoid false positives',\n );\n return false;\n }\n\n return isJavaScript || looksLikeServiceWorker;\n } catch (error) {\n // Network errors - don't disable caching, might be offline or transient issue\n if (error instanceof TypeError && error.message.includes('Failed to fetch')) {\n // Don't disable on network errors - might be offline\n console.warn('[Service Worker] Network error when checking file existence - not disabling');\n return false;\n }\n // Other errors - log but don't disable, could be transient\n console.warn('[Service Worker] Error checking file existence - not disabling:', error);\n logger.warn(\n 'Network error checking service worker file - not disabling to avoid false positives',\n { error },\n );\n return false;\n }\n })();\n\n swFileExistsCacheTime = now;\n return swFileExistsCache;\n}\n\n/**\n * Register the service worker and handle updates\n */\nexport async function registerServiceWorker(\n options: ServiceWorkerRegistrationOptions = { enabled: true },\n): Promise<void> {\n if (!('serviceWorker' in navigator)) {\n return;\n }\n\n if (isTauri()) {\n await unregisterServiceWorker();\n wb = null;\n return;\n }\n\n if (!options.enabled) {\n // If disabled, unregister existing service worker\n await unregisterServiceWorker();\n wb = null;\n return;\n }\n\n // Check if service worker file exists (works in both dev and production)\n const swExists = await serviceWorkerFileExists();\n if (!swExists) {\n // In dev mode, the service worker might not be ready yet, try again after a short delay\n // Only retry once to avoid infinite loops\n if (!registrationPromise) {\n setTimeout(async () => {\n const retryExists = await serviceWorkerFileExists();\n if (retryExists && !registrationPromise) {\n // Retry registration if file becomes available\n registerServiceWorker(options);\n } else if (!retryExists) {\n logger.warn('Service worker file not found. Service workers may not be available.');\n }\n }, 1000);\n }\n return;\n }\n\n // If already registering, wait for that to complete\n if (registrationPromise) {\n return registrationPromise;\n }\n\n registrationPromise = (async () => {\n // CRITICAL: Mark that registration is starting to prevent auto-disable during registration\n isRegistering = true;\n registrationStartTime = Date.now();\n\n try {\n // Check if service worker is already registered\n const existingRegistration = await navigator.serviceWorker.getRegistration();\n\n // CRITICAL: If there's a waiting service worker on page load, automatically activate it\n // The user refreshed the page, so they want the new version - activate it automatically\n // This ensures the new version is used without requiring manual \"Install Now\" click\n if (existingRegistration?.waiting && !existingRegistration.installing) {\n // There's a waiting service worker from before the refresh\n // Since the user refreshed, they want the new version - activate it automatically\n console.info(\n '[Service Worker] Waiting service worker found on page load - automatically activating',\n );\n logger.info(\n 'Waiting service worker found on page load - automatically activating since user refreshed',\n );\n\n // Store reference to waiting service worker\n const waitingSW = existingRegistration.waiting;\n waitingServiceWorker = waitingSW;\n\n // CRITICAL: Mark that we're auto-activating so the controlling handler knows to reload\n // Store in sessionStorage so it survives if there's a reload\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('shellui:service-worker:auto-activated', 'true');\n }\n\n // Automatically activate the waiting service worker\n // This is safe because the user already refreshed, so they want the new version\n // The controlling event handler will detect the auto-activation and reload the page\n try {\n waitingSW.postMessage({ type: 'SKIP_WAITING' });\n console.info(\n '[Service Worker] Sent SKIP_WAITING to waiting service worker - will reload when it takes control',\n );\n } catch (error) {\n logger.error('Failed to activate waiting service worker:', { error });\n // Clear the flag on error\n if (typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:auto-activated');\n }\n }\n }\n\n if (existingRegistration && wb) {\n // Already registered, just update\n isInitialRegistration = false; // This is an update check\n wb.update();\n return;\n }\n\n // Check if there's already a service worker controlling the page\n // If not, this is an initial registration (don't reload)\n isInitialRegistration = !navigator.serviceWorker.controller;\n\n // Register the service worker\n // Only create new Workbox instance if one doesn't exist\n const isNewWorkbox = !wb;\n if (!wb) {\n // Use updateViaCache: 'none' to ensure service worker file changes are always detected\n // This bypasses the browser cache when checking for updates to sw.js/sw-dev.js\n wb = new Workbox('/sw.js', {\n type: 'classic',\n updateViaCache: 'none', // Always check network for service worker updates\n });\n }\n\n // Remove old listeners if they exist (handles React Strict Mode double-mounting)\n // Always remove listeners if wb exists and we have handler references, regardless of flag\n // This ensures we clean up properly even if the flag was reset\n if (wb) {\n if (waitingHandler) {\n wb.removeEventListener('waiting', waitingHandler);\n waitingHandler = null;\n }\n if (activatedHandler) {\n wb.removeEventListener('activated', activatedHandler);\n activatedHandler = null;\n }\n if (controllingHandler) {\n wb.removeEventListener('controlling', controllingHandler);\n controllingHandler = null;\n }\n if (registeredHandler) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (wb as any).removeEventListener('registered', registeredHandler);\n registeredHandler = null;\n }\n if (redundantHandler) {\n wb.removeEventListener('redundant', redundantHandler);\n redundantHandler = null;\n }\n if (serviceWorkerErrorHandler) {\n navigator.serviceWorker.removeEventListener('error', serviceWorkerErrorHandler);\n serviceWorkerErrorHandler = null;\n }\n if (messageErrorHandler) {\n navigator.serviceWorker.removeEventListener('messageerror', messageErrorHandler);\n messageErrorHandler = null;\n }\n // Reset flag so we can add listeners again\n eventListenersAdded = false;\n }\n\n // Only add event listeners once (when creating a new Workbox instance or if they were removed)\n if (isNewWorkbox && !eventListenersAdded) {\n // Set flag IMMEDIATELY to prevent duplicate listener registration\n eventListenersAdded = true;\n\n // Handle service worker updates\n // CRITICAL: Use a consistent toast ID to prevent duplicate toasts\n // If the handler is called multiple times (event listener + manual call),\n // using the same ID will update the existing toast instead of creating a new one\n const UPDATE_AVAILABLE_TOAST_ID = 'shellui:update-available';\n\n waitingHandler = async () => {\n try {\n // CRITICAL: If we're auto-activating (user refreshed), don't show toast\n // The service worker will activate automatically and page will reload\n const isAutoActivating =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:auto-activated') === 'true';\n\n // Get the waiting service worker\n const registration = await navigator.serviceWorker.getRegistration();\n if (!registration || !registration.waiting) {\n return;\n }\n\n const currentWaitingSW = registration.waiting;\n const currentWaitingSWId = currentWaitingSW.scriptURL;\n\n // CRITICAL: If auto-activating, update state but skip toast\n if (isAutoActivating) {\n console.info(\n '[Service Worker] Waiting event fired during auto-activation - skipping toast',\n );\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n return;\n }\n\n // CRITICAL: Check flag BEFORE updating state to prevent race conditions\n // If we've already shown toast for this service worker in this page load, don't show again\n // This prevents duplicate toasts within the same page load, but allows showing after refresh\n if (toastShownForServiceWorkerId === currentWaitingSWId) {\n // Already shown, but ensure state is correct\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n return;\n }\n\n // CRITICAL: Mark that we've shown toast for this service worker IMMEDIATELY\n // This must happen BEFORE showing the toast to prevent race conditions\n // If the handler is called twice quickly, both might pass the check before the flag is set\n toastShownForServiceWorkerId = currentWaitingSWId;\n\n // Update state\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n\n // Show toast notification about update\n if (options.onUpdateAvailable) {\n options.onUpdateAvailable();\n } else {\n // CRITICAL: Use consistent toast ID so duplicate calls update the same toast\n // This prevents multiple toasts from appearing if the handler is called multiple times\n // CRITICAL: Always create fresh action handlers that reference the current waitingServiceWorker\n // This ensures the action handler always has the correct service worker reference\n // even if the toast is updated later\n const actionHandler = () => {\n logger.info('Install Now clicked, updating service worker...');\n // CRITICAL: Get the current waitingServiceWorker at click time, not at toast creation time\n // This ensures it works even if the toast was created earlier and then updated\n if (waitingServiceWorker) {\n updateServiceWorker().catch((error) => {\n logger.error('Failed to update service worker:', { error });\n });\n } else {\n logger.warn('Install Now clicked but no waiting service worker found');\n // Try to get it from registration as fallback\n navigator.serviceWorker.getRegistration().then((swRegistration) => {\n if (swRegistration?.waiting) {\n waitingServiceWorker = swRegistration.waiting;\n updateServiceWorker().catch((error) => {\n logger.error('Failed to update service worker:', { error });\n });\n }\n });\n }\n };\n\n shellui.toast({\n id: UPDATE_AVAILABLE_TOAST_ID, // Use consistent ID to prevent duplicates\n title: 'New version available',\n description: 'A new version of the app is available. Install now or later?',\n type: 'info',\n duration: 0, // Don't auto-dismiss\n position: 'bottom-left',\n action: {\n label: 'Install Now',\n onClick: actionHandler, // Use the handler function\n },\n cancel: {\n label: 'Later',\n onClick: () => {\n // User chose to install later, toast will be dismissed\n },\n },\n });\n }\n } catch (error) {\n logger.error('Error in waiting handler:', { error });\n // On error, reset the flag so we can try again for this service worker\n toastShownForServiceWorkerId = null;\n }\n };\n wb.addEventListener('waiting', waitingHandler);\n\n // Handle service worker activated\n activatedHandler = (event?: unknown) => {\n const evt = (event ?? {}) as Record<string, unknown>;\n console.info('[Service Worker] Service worker activated:', {\n isUpdate: evt.isUpdate,\n isInitialRegistration,\n });\n notifyStatusListeners();\n // Reset flags when service worker is activated (update installed or new registration)\n updateAvailable = false;\n waitingServiceWorker = null;\n toastShownForServiceWorkerId = null; // Reset so we can show toast for the next update\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\")\n // Check both in-memory flag and sessionStorage to ensure we only reload when user explicitly requested it\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const shouldReload = isIntentionalUpdate || isIntentionalUpdatePersisted;\n\n // Clear intentional update flag after activation (update is complete)\n if (typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:intentional-update');\n }\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\")\n // Do NOT reload automatically when a new service worker is installed - wait for user action\n // Exception: If we auto-activated on page load, the new version is already active, no reload needed\n if (evt.isUpdate && !isInitialRegistration && shouldReload) {\n // User explicitly clicked \"Install Now\", so reload to use the new version\n console.info('[Service Worker] Reloading page after intentional update');\n window.location.reload();\n } else if (evt.isUpdate && !isInitialRegistration && !shouldReload) {\n // Auto-activated on page load - new version is now active, UI will update via notifyStatusListeners\n console.info(\n '[Service Worker] Service worker auto-activated on page load - new version is now active',\n );\n }\n // Reset flag after activation\n isInitialRegistration = false;\n };\n wb.addEventListener('activated', activatedHandler as (event: unknown) => void);\n\n // Handle service worker controlling\n controllingHandler = () => {\n notifyStatusListeners();\n\n // CRITICAL: Check if this is an auto-activation from page load refresh\n // If user refreshed and we auto-activated, we need to reload to get the new JavaScript\n const wasAutoActivated =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:auto-activated') === 'true';\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\") OR auto-activation\n // The controlling event fires when a service worker takes control\n // Check both in-memory flag and sessionStorage to ensure we only reload when appropriate\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const shouldReload =\n isIntentionalUpdate || isIntentionalUpdatePersisted || wasAutoActivated;\n\n // Clear auto-activation flag if it was set\n if (wasAutoActivated && typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:auto-activated');\n }\n\n // CRITICAL: Reload if this is an intentional update OR auto-activation from page refresh\n // After reload, the new version will be active and UI will show correct state\n if (!isInitialRegistration && shouldReload) {\n if (wasAutoActivated) {\n console.info(\n '[Service Worker] Auto-activated service worker took control - reloading to use new version',\n );\n } else {\n console.info(\n '[Service Worker] User clicked Install Now - reloading to use new version',\n );\n }\n // Reload to ensure new JavaScript is loaded\n window.location.reload();\n }\n // Reset flag after controlling\n isInitialRegistration = false;\n };\n wb.addEventListener('controlling', controllingHandler);\n\n // Handle service worker registered\n registeredHandler = () => {\n notifyStatusListeners();\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (wb as any).addEventListener('registered', registeredHandler);\n\n // CRITICAL: Handle service worker 'redundant' event\n // This event fires when a service worker is replaced, which is NORMAL during updates\n // The 'redundant' event fires for the OLD service worker when a NEW one takes control\n // During intentional updates (user clicked \"Install Now\"), this is EXPECTED behavior\n // We MUST check for intentional updates BEFORE disabling, otherwise we'll disable the\n // service worker right after the user explicitly asked to install an update!\n redundantHandler = (event?: unknown) => {\n logger.info('Service worker became redundant:', event as Record<string, unknown>);\n\n // CRITICAL CHECK: Verify this is an intentional update BEFORE doing anything\n // Check sessionStorage FIRST (survives page reloads) - this is set BEFORE skip waiting\n // Then check in-memory flag as backup\n // This prevents race conditions where the flag might not be set yet\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n\n // CRITICAL: Also check if there's a waiting service worker - if there is, we're in update flow\n // This provides an additional safety check in case sessionStorage check fails\n // A waiting service worker means an update is in progress, so redundant is expected\n // We check synchronously first (waitingServiceWorker variable), then async if needed\n const hasWaitingServiceWorkerSync = !!waitingServiceWorker;\n\n // CRITICAL: If ANY of these indicate an intentional update, DO NOT disable\n // The combination of checks prevents false positives from disabling during updates\n // This is the KEY fix - we check multiple signals to be absolutely sure it's an update\n const isUpdateFlow =\n isIntentionalUpdate || isIntentionalUpdatePersisted || hasWaitingServiceWorkerSync;\n\n // CRITICAL: Only disable if this is NOT part of a normal update flow\n // Disabling during an update would break the user's explicit \"Install Now\" action\n // This bug has been seen many times - the redundant event fires during normal updates\n // and without these checks, it would disable the service worker right after install\n if (!isUpdateFlow) {\n // Double-check asynchronously in case the sync check missed it\n // CRITICAL: Be very defensive here - only disable if we're absolutely sure it's an error\n navigator.serviceWorker\n .getRegistration()\n .then((registration) => {\n const hasWaitingAsync = !!registration?.waiting;\n const hasInstallingAsync = !!registration?.installing;\n const hasActiveAsync = !!registration?.active;\n\n // CRITICAL: Only disable if there's NO waiting, NO installing, and NO active service worker\n // If any of these exist, it means an update is in progress and redundant is expected\n if (!hasWaitingAsync && !hasInstallingAsync && !hasActiveAsync) {\n // No service worker at all - this is truly unexpected and likely an error\n console.warn(\n '[Service Worker] Redundant event: No service workers found, disabling',\n );\n logger.warn(\n 'Service worker became redundant unexpectedly (no service workers found)',\n );\n disableCachingAutomatically(\n 'Service worker became redundant (no service workers found)',\n );\n } else {\n // Service workers exist - this is likely part of an update flow, don't disable\n console.info(\n '[Service Worker] Redundant event: Service workers exist, likely update in progress - ignoring',\n );\n logger.info(\n 'Service worker became redundant but other service workers exist - likely update in progress, ignoring',\n );\n }\n })\n .catch((error) => {\n // CRITICAL: If async check fails, DON'T disable - this could be a transient error\n // Log the error but don't disable the service worker\n console.warn(\n '[Service Worker] Redundant event: Async check failed, but NOT disabling:',\n error,\n );\n logger.warn(\n 'Service worker redundant event: Async check failed, but NOT disabling to avoid false positives',\n { error },\n );\n });\n } else {\n console.info(\n '[Service Worker] Redundant event: Intentional update detected - ignoring',\n );\n logger.info(\n 'Service worker became redundant as part of normal update - this is expected and safe',\n );\n // CRITICAL: Don't clear the sessionStorage flag immediately - wait until activation\n // Clearing it too early could cause issues if redundant fires multiple times\n // The activated handler will clear it when the update is complete\n }\n };\n wb.addEventListener('redundant', redundantHandler);\n\n // Handle external service worker errors\n // Only disable caching on critical errors, not during normal update operations\n serviceWorkerErrorHandler = (event?: unknown) => {\n logger.error('Service worker error event:', event as Record<string, unknown>);\n\n // Check if this is an intentional update (check both in-memory flag and sessionStorage)\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const isUpdateFlow = isIntentionalUpdate || isIntentionalUpdatePersisted;\n\n // CRITICAL: Be very defensive - only disable on truly critical errors\n // Many service worker errors are non-fatal and don't require disabling\n if (!isUpdateFlow) {\n // Only disable on actual errors, not warnings or non-critical issues\n const evt = (event ?? {}) as Record<string, unknown>;\n const evtError = evt.error as Record<string, unknown> | undefined;\n const errorMessage = (evt.message as string) || (evtError?.message as string) || 'Unknown error';\n const errorName = (evtError?.name as string) || '';\n\n // CRITICAL: Only disable on critical errors, ignore common non-fatal errors\n // Many errors during service worker lifecycle are expected and don't require disabling\n const isCriticalError =\n !errorMessage.includes('update') &&\n !errorMessage.includes('activate') &&\n !errorMessage.includes('install') &&\n !errorName.includes('AbortError') &&\n !errorName.includes('NetworkError');\n\n if (isCriticalError) {\n disableCachingAutomatically(`Service worker error: ${errorMessage}`);\n } else {\n console.warn('[Service Worker] Non-critical error, ignoring:', errorMessage);\n logger.warn('Service worker non-critical error, not disabling:', {\n errorMessage,\n errorName,\n });\n }\n } else {\n console.info('[Service Worker] Error during update flow, ignoring');\n logger.info('Service worker error during update flow, ignoring');\n }\n };\n navigator.serviceWorker.addEventListener('error', serviceWorkerErrorHandler);\n\n // Handle message errors from service worker\n messageErrorHandler = (event?: unknown) => {\n logger.error('Service worker message error:', event as Record<string, unknown>);\n // Don't disable on message errors - they're usually not critical\n };\n navigator.serviceWorker.addEventListener('messageerror', messageErrorHandler);\n } // End of event listeners block\n\n // Register the service worker\n await wb.register();\n\n // Get the underlying registration to set updateViaCache\n // This ensures changes to sw.js/sw-dev.js are always detected (bypasses cache)\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration) {\n // Set updateViaCache to 'none' to ensure service worker file changes are always detected\n // This tells the browser to always check the network for sw.js/sw-dev.js updates\n // Note: This property is read-only in some browsers, but setting it helps where supported\n try {\n // Access the registration's update method to ensure cache-busting\n // The browser will check the service worker file with cache: 'reload' when update() is called\n } catch (_e) {\n // Ignore if updateViaCache can't be set (some browsers don't support it)\n }\n\n // Check if there's a waiting service worker after registration\n // If we already handled it above (auto-activation on page load), skip showing toast\n // Otherwise, show toast to let user know an update is available\n if (registration.waiting && waitingHandler) {\n const waitingSWId = registration.waiting.scriptURL;\n\n // Check if we already auto-activated this waiting service worker above\n // If so, don't show toast - it will activate automatically\n const wasAutoActivated =\n waitingServiceWorker === registration.waiting && updateAvailable === true;\n\n if (!wasAutoActivated) {\n // This is a new waiting service worker that appeared after registration\n // Show toast to notify user\n // CRITICAL: Check flag BEFORE calling handler to prevent duplicate toasts\n // The waiting event might have already fired and shown the toast\n if (toastShownForServiceWorkerId !== waitingSWId) {\n // Update state first\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n // Trigger the waiting handler to show toast\n // The handler will check the flag again and show toast if needed\n waitingHandler();\n } else {\n // Toast already shown, just update state\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n notifyStatusListeners();\n }\n } else {\n // Already auto-activated, just ensure state is correct\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n notifyStatusListeners();\n }\n }\n }\n\n notifyStatusListeners();\n\n // Check for updates periodically (including service worker file changes)\n // This ensures changes to sw.js/sw-dev.js are detected\n /* const _updateInterval = */ setInterval(\n () => {\n if (wb && options.enabled) {\n // wb.update() checks for updates to the service worker file itself\n // The browser will compare the byte-by-byte content of sw.js/sw-dev.js\n wb.update();\n }\n },\n 60 * 60 * 1000,\n ); // Check every hour\n\n // Also check for updates when the page becomes visible (user returns to tab)\n // This helps detect service worker file changes more quickly\n let visibilityHandler: (() => void) | null = null;\n if (typeof document !== 'undefined') {\n visibilityHandler = () => {\n if (!document.hidden && wb && options.enabled) {\n wb.update();\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n\n // CRITICAL: Mark registration as complete only after everything is set up\n // This prevents error handlers from disabling during the registration process\n isRegistering = false;\n\n // Store interval and handler for cleanup (though cleanup is best-effort)\n // The interval will continue until page reload, which is acceptable\n } catch (error) {\n // Handle registration errors - be very selective about disabling\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : '';\n logger.error('Registration failed:', { error });\n\n // CRITICAL: Only disable on truly critical errors that indicate the service worker is broken\n // Many registration errors are transient or non-fatal\n const isCriticalError =\n (errorMessage.includes('Failed to register') &&\n !errorMessage.includes('already registered')) ||\n (errorMessage.includes('script error') && !errorMessage.includes('network')) ||\n errorMessage.includes('SyntaxError') ||\n (errorMessage.includes('TypeError') && !errorMessage.includes('fetch')) ||\n (error instanceof DOMException &&\n error.name !== 'SecurityError' &&\n error.name !== 'AbortError');\n\n if (isCriticalError) {\n await disableCachingAutomatically(`Registration failed: ${errorMessage}`);\n } else {\n console.warn(\n '[Service Worker] Non-critical registration error, NOT disabling:',\n errorMessage,\n );\n logger.warn('Non-critical registration error, not disabling:', { errorMessage, errorName });\n }\n } finally {\n // CRITICAL: Reset registration flag in finally block to ensure it's always reset\n // But keep a grace period to prevent immediate disable after registration completes\n // The grace period is handled in disableCachingAutomatically\n isRegistering = false;\n registrationPromise = null;\n }\n })();\n\n return registrationPromise;\n}\n\n/**\n * Update the service worker immediately\n * This will reload the page when the update is installed\n */\nexport async function updateServiceWorker(): Promise<void> {\n if (!wb || !waitingServiceWorker) {\n return;\n }\n\n try {\n // CRITICAL: Set intentional update flag FIRST, before any other operations\n // This flag MUST be set in sessionStorage BEFORE skip waiting is called\n // The 'redundant' event can fire very quickly after skip waiting, and if this flag\n // isn't set yet, the redundant handler will think it's an error and disable the SW\n // This is the ROOT CAUSE of the bug where service worker gets disabled on \"Install Now\"\n const INTENTIONAL_UPDATE_KEY = 'shellui:service-worker:intentional-update';\n if (typeof window !== 'undefined') {\n // CRITICAL: Set this IMMEDIATELY - don't wait for anything else\n sessionStorage.setItem(INTENTIONAL_UPDATE_KEY, 'true');\n }\n\n // CRITICAL: Also set in-memory flag immediately\n // This provides backup protection in case sessionStorage has issues\n isIntentionalUpdate = true;\n\n // CRITICAL: Ensure service worker setting is preserved and enabled before reload\n // This prevents the service worker from being disabled after refresh\n // The user explicitly clicked \"Install Now\", so we must keep the service worker enabled\n if (typeof window !== 'undefined') {\n const STORAGE_KEY = 'shellui:settings';\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const settings = JSON.parse(stored);\n // CRITICAL: Always ensure service worker is enabled when user clicks Install Now\n // This ensures it stays enabled after the page reloads\n // Without this, the service worker could be disabled after the reload\n settings.serviceWorker = { enabled: true };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));\n\n // Notify the app about the settings update (in case it's listening)\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings },\n });\n } else {\n // No settings stored, create default with service worker enabled\n const defaultSettings = {\n serviceWorker: { enabled: true },\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(defaultSettings));\n }\n } catch (error) {\n logger.warn('Failed to preserve settings before update:', { error });\n // CRITICAL: Even if settings update fails, the intentional update flag is already set\n // This prevents the redundant handler from disabling the service worker\n // The app.tsx will default to enabled anyway, so continue with the update\n }\n }\n\n // Mark that this is an update (not initial registration)\n isInitialRegistration = false;\n\n // Set up reload handler before sending skip waiting\n const reloadApp = () => {\n // Use shellUI refresh message if available, otherwise fallback to window.location.reload\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) {\n window.location.reload();\n }\n };\n\n // Add one-time listener for controlling event\n const updateControllingHandler = () => {\n reloadApp();\n wb?.removeEventListener('controlling', updateControllingHandler);\n // Reset flag after reload is triggered\n setTimeout(() => {\n isIntentionalUpdate = false;\n }, 1000);\n };\n wb.addEventListener('controlling', updateControllingHandler);\n\n // Send skip waiting message to the waiting service worker\n waitingServiceWorker.postMessage({ type: 'SKIP_WAITING' });\n\n // Fallback: if controlling event doesn't fire within 2 seconds, reload anyway\n setTimeout(() => {\n if (controllingHandler) wb?.removeEventListener('controlling', controllingHandler);\n // Check if service worker is now controlling\n if (navigator.serviceWorker.controller) {\n reloadApp();\n }\n // Reset flag if fallback is used\n setTimeout(() => {\n isIntentionalUpdate = false;\n }, 1000);\n }, 2000);\n } catch (error) {\n logger.error('Failed to update service worker:', { error });\n // Reset flag on error\n isIntentionalUpdate = false;\n }\n}\n\n/**\n * Unregister the service worker silently (no page reload)\n */\nexport async function unregisterServiceWorker(): Promise<void> {\n if (!('serviceWorker' in navigator)) {\n return;\n }\n\n try {\n // Set flag to prevent any reloads during unregistration\n isInitialRegistration = true;\n\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration) {\n await registration.unregister();\n\n // Clear all caches silently\n if ('caches' in window) {\n const cacheNames = await caches.keys();\n await Promise.all(cacheNames.map((name) => caches.delete(name)));\n }\n }\n\n // Clean up workbox instance and remove all event listeners\n if (wb) {\n // Remove all event listeners before cleaning up\n if (waitingHandler) wb.removeEventListener('waiting', waitingHandler);\n if (activatedHandler) wb.removeEventListener('activated', activatedHandler);\n if (controllingHandler) wb.removeEventListener('controlling', controllingHandler);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (registeredHandler) (wb as any).removeEventListener('registered', registeredHandler);\n if (redundantHandler) wb.removeEventListener('redundant', redundantHandler);\n if (serviceWorkerErrorHandler) {\n navigator.serviceWorker.removeEventListener('error', serviceWorkerErrorHandler);\n }\n if (messageErrorHandler) {\n navigator.serviceWorker.removeEventListener('messageerror', messageErrorHandler);\n }\n // Clear handler references\n waitingHandler = null;\n activatedHandler = null;\n controllingHandler = null;\n registeredHandler = null;\n redundantHandler = null;\n serviceWorkerErrorHandler = null;\n messageErrorHandler = null;\n // Remove workbox instance\n wb = null;\n }\n\n updateAvailable = false;\n waitingServiceWorker = null;\n isInitialRegistration = false;\n toastShownForServiceWorkerId = null; // Reset toast flag on unregister\n eventListenersAdded = false; // Reset event listeners flag on unregister\n isIntentionalUpdate = false; // Reset intentional update flag on unregister\n notifyStatusListeners();\n } catch (error) {\n logger.error('Failed to unregister service worker:', { error });\n isInitialRegistration = false;\n }\n}\n\n/**\n * Check if service worker is registered and active\n */\nexport async function isServiceWorkerRegistered(): Promise<boolean> {\n if (!('serviceWorker' in navigator)) {\n return false;\n }\n if (isTauri()) {\n return false;\n }\n\n // First check if service worker file exists (only in production)\n const swExists = await serviceWorkerFileExists();\n if (!swExists) {\n return false;\n }\n\n try {\n const registration = await navigator.serviceWorker.getRegistration();\n if (!registration) {\n return false;\n }\n\n // Check if service worker is active (either controlling or installed)\n // A service worker can be registered but not yet active\n if (registration.active) {\n return true;\n }\n\n // Also check if there's a waiting or installing service worker\n // This means registration is in progress or update is available\n if (registration.waiting || registration.installing) {\n return true;\n }\n\n // If navigator.serviceWorker.controller exists, the SW is controlling the page\n if (navigator.serviceWorker.controller) {\n return true;\n }\n\n return false;\n } catch (_error) {\n // Silently return false if there's an error checking registration\n return false;\n }\n}\n\n/**\n * Get service worker status\n */\nexport async function getServiceWorkerStatus(): Promise<{\n registered: boolean;\n updateAvailable: boolean;\n}> {\n const registered = await isServiceWorkerRegistered();\n\n // Actually check if there's a waiting service worker (more reliable than in-memory flag)\n // This ensures we get the correct state even after page reloads\n let actuallyUpdateAvailable = false;\n if (registered && !isTauri()) {\n try {\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration?.waiting) {\n // There's a waiting service worker, so an update is available\n actuallyUpdateAvailable = true;\n // Sync the in-memory flag with the actual state\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n } else {\n // No waiting service worker, so no update is available\n actuallyUpdateAvailable = false;\n // Sync the in-memory flag with the actual state\n updateAvailable = false;\n waitingServiceWorker = null;\n }\n } catch (error) {\n logger.error('Failed to check service worker registration:', { error });\n // Fall back to in-memory flag if check fails\n actuallyUpdateAvailable = updateAvailable;\n }\n } else {\n // Not registered or Tauri, so no update available\n actuallyUpdateAvailable = false;\n updateAvailable = false;\n waitingServiceWorker = null;\n }\n\n return {\n registered,\n updateAvailable: actuallyUpdateAvailable,\n };\n}\n\n/**\n * Manually trigger a check for service worker updates (browser only).\n * Resolves when the check is complete. Listen to addStatusListener for updateAvailable changes.\n */\nexport async function checkForServiceWorkerUpdate(): Promise<void> {\n if (isTauri() || !wb) return;\n await wb.update();\n}\n\n/**\n * Add a listener for service worker status changes\n */\nexport function addStatusListener(\n listener: (status: { registered: boolean; updateAvailable: boolean }) => void,\n): () => void {\n statusListeners.push(listener);\n // Don't call immediately - let the component do the initial check to avoid duplicate fetches\n\n // Return unsubscribe function\n return () => {\n statusListeners = statusListeners.filter((l) => l !== listener);\n };\n}\n","import { useTranslation } from 'react-i18next';\nimport { useConfig } from '@/features/config/useConfig';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport {\n isTauri,\n getServiceWorkerStatus,\n addStatusListener,\n checkForServiceWorkerUpdate,\n updateServiceWorker,\n} from '@/service-worker/register';\nimport { shellui, getLogger } from '@shellui/sdk';\nimport { CheckIcon } from '../SettingsIcons';\nimport { useState, useEffect } from 'react';\n\nconst logger = getLogger('shellcore');\n\nexport const UpdateApp = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings } = useSettings();\n const [updateAvailable, setUpdateAvailable] = useState(false);\n const [checking, setChecking] = useState(false);\n const [showUpToDateInButton, setShowUpToDateInButton] = useState(false);\n const [checkError, setCheckError] = useState(false);\n\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true;\n\n useEffect(() => {\n if (isTauri()) return;\n const load = async () => {\n const status = await getServiceWorkerStatus();\n setUpdateAvailable(status.updateAvailable);\n };\n load();\n const unsubscribe = addStatusListener((status) => {\n setUpdateAvailable(status.updateAvailable);\n // If an update becomes available, hide the \"You are up to date\" message and clear any errors\n if (status.updateAvailable) {\n setShowUpToDateInButton(false);\n setCheckError(false);\n }\n });\n return unsubscribe;\n }, []);\n\n const handleCheckForUpdate = async () => {\n if (isTauri()) return;\n setShowUpToDateInButton(false);\n setCheckError(false);\n setChecking(true);\n try {\n // Check current status before triggering update check\n const initialStatus = await getServiceWorkerStatus();\n\n // If update is already available, don't show \"You are up to date\"\n if (initialStatus.updateAvailable) {\n return;\n }\n\n // Trigger update check\n await checkForServiceWorkerUpdate();\n\n // Wait a bit for the update check to complete and status to update\n // The status listener will update updateAvailable if an update is found\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // Check status again after update check\n // Use the state value which may have been updated by the status listener\n // If updateAvailable is true, don't show \"You are up to date\"\n if (!updateAvailable) {\n // Double-check with API to be sure\n const finalStatus = await getServiceWorkerStatus();\n if (!finalStatus.updateAvailable) {\n setShowUpToDateInButton(true);\n window.setTimeout(() => setShowUpToDateInButton(false), 3000);\n }\n }\n } catch (error) {\n // Error occurred during update check - show error message in button\n setCheckError(true);\n logger.error('Failed to check for service worker update:', { error });\n } finally {\n setChecking(false);\n }\n };\n\n const version = config?.version ?? t('updateApp.versionUnknown');\n\n if (isTauri()) {\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.currentVersion')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{version}</p>\n </div>\n <div className=\"rounded-lg border border-border bg-muted/30 p-4\">\n <p className=\"text-sm text-muted-foreground\">{t('updateApp.tauriComingSoon')}</p>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-4\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.currentVersion')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{version}</p>\n </div>\n {!serviceWorkerEnabled ? (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">{t('updateApp.swDisabledMessage')}</p>\n <Button\n variant=\"outline\"\n onClick={() => {\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) window.location.reload();\n }}\n className=\"w-full sm:w-auto\"\n >\n {t('updateApp.refreshApp')}\n </Button>\n </div>\n ) : (\n <>\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.status')}\n </label>\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n {updateAvailable ? (\n <span className=\"text-blue-600 dark:text-blue-400\">\n ● {t('updateApp.statusUpdateAvailable')}\n </span>\n ) : (\n <span className=\"text-green-600 dark:text-green-400\">\n ● {t('updateApp.statusUpToDate')}\n </span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n {updateAvailable && (\n <Button\n variant=\"default\"\n onClick={async () => {\n await updateServiceWorker();\n }}\n className=\"w-full sm:w-auto\"\n >\n {t('updateApp.installNow')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n onClick={handleCheckForUpdate}\n disabled={checking || updateAvailable}\n className=\"w-full sm:w-auto\"\n >\n {checking ? (\n <>\n <span\n className=\"inline-block h-4 w-4 shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent mr-2\"\n aria-hidden\n />\n {t('updateApp.checking')}\n </>\n ) : checkError ? (\n <span className=\"inline-flex items-center gap-2 text-red-600 dark:text-red-400\">\n {t('updateApp.checkError')}\n </span>\n ) : showUpToDateInButton && !updateAvailable ? (\n <span className=\"inline-flex items-center gap-2 text-green-600 dark:text-green-400\">\n <CheckIcon />\n {t('updateApp.youAreUpToDate')}\n </span>\n ) : (\n t('updateApp.checkForUpdate')\n )}\n </Button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n};\n","import { forwardRef, type InputHTMLAttributes, type ChangeEvent } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nconst Switch = forwardRef<HTMLInputElement, SwitchProps>(\n ({ className, checked, onCheckedChange, ...props }, ref) => {\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n onCheckedChange?.(e.target.checked);\n };\n\n return (\n <label className=\"inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n ref={ref}\n checked={checked}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n <div\n className={cn(\n 'relative w-11 h-6 rounded-full border border-border transition-colors focus-within:outline-none focus-within:ring-2 focus-within:ring-ring',\n checked ? 'bg-primary' : 'bg-muted',\n className,\n )}\n >\n <div\n className={cn(\n 'absolute top-[1px] left-[1px] h-5 w-5 bg-background border border-border rounded-full transition-transform',\n checked ? 'translate-x-5' : 'translate-x-0',\n )}\n />\n </div>\n </label>\n );\n },\n);\nSwitch.displayName = 'Switch';\n\nexport { Switch };\n","import type { ShellUIConfig } from '../config/types';\n\nconst STORAGE_KEY = 'shellui:settings';\n\nfunction getConfig(): ShellUIConfig | undefined {\n if (typeof globalThis === 'undefined') return undefined;\n const g = globalThis as unknown as { __SHELLUI_CONFIG__?: string | ShellUIConfig };\n const raw = g.__SHELLUI_CONFIG__;\n if (raw === null || raw === undefined) return undefined;\n return typeof raw === 'string' ? (JSON.parse(raw) as ShellUIConfig) : raw;\n}\n\nfunction getStoredCookieConsent(): {\n acceptedHosts: string[];\n consentedCookieHosts: string[];\n} {\n if (typeof window === 'undefined') {\n return { acceptedHosts: [], consentedCookieHosts: [] };\n }\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return { acceptedHosts: [], consentedCookieHosts: [] };\n const parsed = JSON.parse(stored) as {\n cookieConsent?: { acceptedHosts?: string[]; consentedCookieHosts?: string[] };\n };\n return {\n acceptedHosts: Array.isArray(parsed?.cookieConsent?.acceptedHosts)\n ? parsed.cookieConsent.acceptedHosts\n : [],\n consentedCookieHosts: Array.isArray(parsed?.cookieConsent?.consentedCookieHosts)\n ? parsed.cookieConsent.consentedCookieHosts\n : [],\n };\n } catch {\n return { acceptedHosts: [], consentedCookieHosts: [] };\n }\n}\n\n/**\n * Returns whether the given cookie host is accepted by the user.\n * Use this outside React (e.g. in initSentry) to gate features by cookie consent.\n * - If there is no cookieConsent config, returns true (no consent required).\n * - If the host is not in the config list, returns true (unknown cookie, don't block).\n * - Otherwise returns whether the host is in settings.cookieConsent.acceptedHosts.\n */\nexport function getCookieConsentAccepted(host: string): boolean {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return true;\n const knownHosts = new Set(config.cookieConsent.cookies.map((c) => c.host));\n if (!knownHosts.has(host)) return true;\n const { acceptedHosts } = getStoredCookieConsent();\n return acceptedHosts.includes(host);\n}\n\n/**\n * Returns whether the app should ask for consent again because new cookies were added to config.\n * True when current config has at least one host that is not in consentedCookieHosts (the list\n * stored when the user last gave consent). When re-prompting, pre-fill with acceptedHosts so\n * existing approvals are kept.\n */\nexport function getCookieConsentNeedsRenewal(): boolean {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return false;\n const { consentedCookieHosts } = getStoredCookieConsent();\n if (consentedCookieHosts.length === 0) return true; // Never consented\n const currentHosts = new Set(config.cookieConsent.cookies.map((c) => c.host));\n for (const host of currentHosts) {\n if (!consentedCookieHosts.includes(host)) return true;\n }\n return false;\n}\n\n/**\n * Returns the list of cookie hosts that are in the current config but were not in the list\n * when the user last gave consent. Use to show \"new\" badges or to know which cookies need\n * fresh approval while keeping existing acceptedHosts as pre-checked.\n */\nexport function getCookieConsentNewHosts(): string[] {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return [];\n const { consentedCookieHosts } = getStoredCookieConsent();\n const consentedSet = new Set(consentedCookieHosts);\n return config.cookieConsent.cookies.map((c) => c.host).filter((host) => !consentedSet.has(host));\n}\n","import { getCookieConsentAccepted } from '../cookieConsent/cookieConsent';\n\nconst SETTINGS_KEY = 'shellui:settings';\n\n/** True after @sentry/react has been lazy-loaded and init() was called. */\nlet sentryLoaded = false;\n\nfunction isErrorReportingEnabled(): boolean {\n if (typeof window === 'undefined') return true;\n // If cookie consent is configured with a cookie for sentry.io, only enable when user accepted it\n if (!getCookieConsentAccepted('sentry.io')) return false;\n try {\n const stored = localStorage.getItem(SETTINGS_KEY);\n if (!stored) return true;\n const parsed = JSON.parse(stored) as { errorReporting?: { enabled?: boolean } };\n return parsed?.errorReporting?.enabled !== false;\n } catch {\n return true;\n }\n}\n\ntype SentryGlobals = {\n __SHELLUI_SENTRY_DSN__?: string;\n __SHELLUI_SENTRY_ENVIRONMENT__?: string;\n __SHELLUI_SENTRY_RELEASE__?: string;\n};\n\n/**\n * Initialize error reporting only in production when configured and user has not disabled it.\n * Lazy-loads @sentry/react only when needed so the bundle is not loaded when Sentry is unused.\n * Reads DSN, environment, and release from __SHELLUI_SENTRY_DSN__, __SHELLUI_SENTRY_ENVIRONMENT__,\n * and __SHELLUI_SENTRY_RELEASE__ (injected at build time) and user preference from settings.\n * Exported so the settings UI can re-initialize when the user re-enables reporting.\n */\nexport function initSentry(): void {\n const isDev = (import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV;\n if (isDev) {\n return;\n }\n if (!isErrorReportingEnabled()) {\n return;\n }\n const g = globalThis as unknown as SentryGlobals;\n const dsn = g.__SHELLUI_SENTRY_DSN__;\n if (!dsn || typeof dsn !== 'string') {\n return;\n }\n void import('@sentry/react').then((Sentry) => {\n Sentry.init({\n dsn,\n environment: g.__SHELLUI_SENTRY_ENVIRONMENT__ ?? 'production',\n release: g.__SHELLUI_SENTRY_RELEASE__,\n });\n sentryLoaded = true;\n });\n}\n\n/**\n * Close Sentry when the user disables error reporting in settings.\n * Only loads @sentry/react if it was already initialized (avoids loading the chunk just to close).\n */\nexport function closeSentry(): void {\n if (!sentryLoaded) {\n return;\n }\n void import('@sentry/react').then((Sentry) => {\n Sentry.close();\n sentryLoaded = false;\n });\n}\n\ninitSentry();\n","import { useTranslation } from 'react-i18next';\nimport { Switch } from '@/components/ui/switch';\nimport { useConfig } from '@/features/config/useConfig';\nimport { closeSentry, initSentry } from '@/features/sentry/initSentry';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const Advanced = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings, updateSetting, resetAllData } = useSettings();\n const errorReportingConfigured = Boolean(config?.sentry?.dsn);\n\n const handleErrorReportingChange = (checked: boolean) => {\n updateSetting('errorReporting', { enabled: checked });\n if (checked) {\n initSentry();\n } else {\n closeSentry();\n }\n };\n\n const handleResetClick = () => {\n shellui.dialog({\n title: t('advanced.dangerZone.reset.toast.title'),\n description: t('advanced.dangerZone.reset.toast.description'),\n mode: 'delete',\n size: 'sm',\n okLabel: t('advanced.dangerZone.reset.toast.confirm'),\n cancelLabel: t('advanced.dangerZone.reset.toast.cancel'),\n onOk: () => {\n resetAllData();\n shellui.toast({\n title: t('advanced.dangerZone.reset.toast.success.title'),\n description: t('advanced.dangerZone.reset.toast.success.description'),\n type: 'success',\n });\n shellui.navigate('/');\n },\n onCancel: () => {\n // User cancelled, no action needed\n },\n });\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <span\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.errorReporting.label')}\n </span>\n <p className=\"text-sm text-muted-foreground\">\n {errorReportingConfigured\n ? t('advanced.errorReporting.statusConfigured')\n : t('advanced.errorReporting.statusNotConfigured')}\n </p>\n </div>\n {errorReportingConfigured && (\n <Switch\n id=\"error-reporting\"\n checked={settings.errorReporting.enabled}\n onCheckedChange={handleErrorReportingChange}\n />\n )}\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"developer-features\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.developerFeatures.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('advanced.developerFeatures.description')}\n </p>\n </div>\n <Switch\n id=\"developer-features\"\n checked={settings.developerFeatures.enabled}\n onCheckedChange={(checked) => updateSetting('developerFeatures', { enabled: checked })}\n />\n </div>\n\n <div className=\"border-t pt-6 mt-6\">\n <div className=\"space-y-4\">\n <div className=\"space-y-0.5\">\n <h3\n className=\"text-sm font-semibold leading-none text-destructive\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.dangerZone.title')}\n </h3>\n <p className=\"text-sm text-muted-foreground\">{t('advanced.dangerZone.description')}</p>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.dangerZone.reset.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('advanced.dangerZone.reset.warning')}\n </p>\n </div>\n <Button\n variant=\"destructive\"\n onClick={handleResetClick}\n className=\"w-full sm:w-auto\"\n >\n {t('advanced.dangerZone.reset.button')}\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import type { NavigationItem, NavigationGroup, LocalizedString } from '../config/types';\n\n/** Resolve a localized string to a single string for the given language. */\nexport function resolveLocalizedString(value: LocalizedString | undefined, lang: string): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Flatten navigation items from groups or flat array. */\nexport function flattenNavigationItems(\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] {\n if (navigation.length === 0) {\n return [];\n }\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) {\n return (item as NavigationGroup).items;\n }\n return item as NavigationItem;\n });\n}\n\nexport type Viewport = 'mobile' | 'desktop';\n\n/** Filter navigation by viewport: remove hidden and viewport-specific hidden items (and empty groups). */\nexport function filterNavigationByViewport(\n navigation: (NavigationItem | NavigationGroup)[],\n viewport: Viewport,\n): (NavigationItem | NavigationGroup)[] {\n if (navigation.length === 0) return [];\n const hideOnMobile = viewport === 'mobile';\n const hideOnDesktop = viewport === 'desktop';\n return navigation\n .map((item) => {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n const visibleItems = group.items.filter((navItem) => {\n if (navItem.hidden) return false;\n if (hideOnMobile && navItem.hiddenOnMobile) return false;\n if (hideOnDesktop && navItem.hiddenOnDesktop) return false;\n return true;\n });\n if (visibleItems.length === 0) return null;\n return { ...group, items: visibleItems };\n }\n const navItem = item as NavigationItem;\n if (navItem.hidden) return null;\n if (hideOnMobile && navItem.hiddenOnMobile) return null;\n if (hideOnDesktop && navItem.hiddenOnDesktop) return null;\n return item;\n })\n .filter((item): item is NavigationItem | NavigationGroup => item !== null);\n}\n\n/** Filter navigation for sidebar: remove hidden items and groups that become empty. */\nexport function filterNavigationForSidebar(\n navigation: (NavigationItem | NavigationGroup)[],\n): (NavigationItem | NavigationGroup)[] {\n if (navigation.length === 0) return [];\n return navigation\n .map((item) => {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n const visibleItems = group.items.filter((navItem) => !navItem.hidden);\n if (visibleItems.length === 0) return null;\n return { ...group, items: visibleItems };\n }\n const navItem = item as NavigationItem;\n if (navItem.hidden) return null;\n return item;\n })\n .filter((item): item is NavigationItem | NavigationGroup => item !== null);\n}\n\n/** Split navigation by position: start (main content) and end (footer). */\nexport function splitNavigationByPosition(navigation: (NavigationItem | NavigationGroup)[]): {\n start: (NavigationItem | NavigationGroup)[];\n end: NavigationItem[];\n} {\n const start: (NavigationItem | NavigationGroup)[] = [];\n const end: NavigationItem[] = [];\n for (const item of navigation) {\n const position = 'position' in item ? (item.position ?? 'start') : 'start';\n if (position === 'end') {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n end.push(...group.items.filter((navItem) => !navItem.hidden));\n } else {\n const navItem = item as NavigationItem;\n if (!navItem.hidden) end.push(navItem);\n }\n } else {\n start.push(item);\n }\n }\n return { start, end };\n}\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const ToastTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.toastNotifications.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.success.title'),\n description: t('develop.testing.toastNotifications.messages.success.description'),\n type: 'success',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.success')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.error.title'),\n description: t('develop.testing.toastNotifications.messages.error.description'),\n type: 'error',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.error')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.warning.title'),\n description: t('develop.testing.toastNotifications.messages.warning.description'),\n type: 'warning',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.warning')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.info.title'),\n description: t('develop.testing.toastNotifications.messages.info.description'),\n type: 'info',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.info')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.default.title'),\n description: t('develop.testing.toastNotifications.messages.default.description'),\n type: 'default',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.default')}\n </Button>\n <Button\n onClick={() => {\n const toastId = shellui.toast({\n title: t('develop.testing.toastNotifications.messages.processing.title'),\n description: t('develop.testing.toastNotifications.messages.processing.description'),\n type: 'loading',\n });\n\n // Simulate async operation and update toast\n if (typeof toastId === 'string') {\n setTimeout(() => {\n shellui.toast({\n id: toastId,\n type: 'success',\n title: t('develop.testing.toastNotifications.messages.uploadComplete.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.uploadComplete.description',\n ),\n });\n }, 2000);\n }\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.loadingSuccess')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.withAction.title'),\n description: t('develop.testing.toastNotifications.messages.withAction.description'),\n type: 'success',\n action: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.undo'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.undone.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.undone.description',\n ),\n type: 'info',\n });\n },\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.withAction')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.withAction.title'),\n description: t('develop.testing.toastNotifications.messages.withAction.description'),\n type: 'success',\n action: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.undo'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.undone.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.undone.description',\n ),\n type: 'info',\n });\n },\n },\n cancel: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.cancel'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.cancelled.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.cancelled.description',\n ),\n type: 'info',\n });\n },\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.withActionAndCancel')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.persistent.title'),\n description: t('develop.testing.toastNotifications.messages.persistent.description'),\n type: 'info',\n duration: 10000,\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.longDuration')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const DialogTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.dialogTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.ok.title'),\n description: t('develop.testing.dialogTesting.dialogs.ok.description'),\n mode: 'ok',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.okClicked'),\n type: 'success',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.okDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.okCancel.title'),\n description: t('develop.testing.dialogTesting.dialogs.okCancel.description'),\n mode: 'okCancel',\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.okClicked'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.cancelClicked'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.okCancelDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.delete.title'),\n description: t('develop.testing.dialogTesting.dialogs.delete.description'),\n mode: 'delete',\n okLabel: t('develop.testing.dialogTesting.dialogs.delete.okLabel'),\n cancelLabel: t('develop.testing.dialogTesting.dialogs.delete.cancelLabel'),\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.itemDeleted'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.deletionCancelled'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.deleteDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.confirm.title'),\n description: t('develop.testing.dialogTesting.dialogs.confirm.description'),\n mode: 'confirm',\n okLabel: t('develop.testing.dialogTesting.dialogs.confirm.okLabel'),\n cancelLabel: t('develop.testing.dialogTesting.dialogs.confirm.cancelLabel'),\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.actionConfirmed'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.actionCancelled'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.confirmDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.onlyCancel.title'),\n description: t('develop.testing.dialogTesting.dialogs.onlyCancel.description'),\n mode: 'onlyCancel',\n cancelLabel: t('develop.testing.dialogTesting.dialogs.onlyCancel.cancelLabel'),\n size: 'sm',\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.dialogClosed'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.onlyCancelDialog')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\nimport urls from '@/constants/urls';\n\nexport const ModalTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.modalTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => shellui.openModal(urls.settings)}\n variant=\"outline\"\n >\n {t('develop.testing.modalTesting.buttons.openModal')}\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground mt-2\">\n {t('develop.testing.modalTesting.description')}\n </p>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui, type OpenDrawerOptions } from '@shellui/sdk';\nimport urls from '@/constants/urls';\n\nexport const DrawerTestButtons = () => {\n const { t } = useTranslation('settings');\n\n const openDrawer = (options: OpenDrawerOptions) => {\n shellui.openDrawer({ url: urls.settings, ...options });\n };\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.drawerTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => openDrawer({ position: 'right' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerRight')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'left' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerLeft')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'top' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerTop')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'bottom' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerBottom')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'right', size: '400px' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerRightNarrow')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'bottom', size: '60vh' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerBottomHalf')}\n </Button>\n <Button\n onClick={() => shellui.closeDrawer()}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.closeDrawer')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '../../config/useConfig';\nimport { flattenNavigationItems, resolveLocalizedString } from '../../layouts/utils';\nimport { Switch } from '@/components/ui/switch';\nimport { Select } from '@/components/ui/select';\nimport { Button } from '@/components/ui/button';\nimport { ToastTestButtons } from './develop/ToastTestButtons';\nimport { DialogTestButtons } from './develop/DialogTestButtons';\nimport { ModalTestButtons } from './develop/ModalTestButtons';\nimport { DrawerTestButtons } from './develop/DrawerTestButtons';\nimport type { LayoutType } from '../../config/types';\n\nexport const Develop = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n const effectiveLayout: LayoutType = settings.layout ?? config?.layout ?? 'sidebar';\n const navItems = config?.navigation?.length\n ? flattenNavigationItems(config?.navigation ?? []).filter(\n (item, index, self) => index === self.findIndex((i) => i.path === item.path),\n )\n : [];\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.title')}\n </h3>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"log-shellsdk\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.shellsdk.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('develop.logging.shellsdk.description')}\n </p>\n </div>\n <Switch\n id=\"log-shellsdk\"\n checked={settings.logging?.namespaces?.shellsdk || false}\n onCheckedChange={(checked) =>\n updateSetting('logging', {\n namespaces: {\n ...settings.logging?.namespaces,\n shellsdk: checked,\n },\n })\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"log-shellcore\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.shellcore.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('develop.logging.shellcore.description')}\n </p>\n </div>\n <Switch\n id=\"log-shellcore\"\n checked={settings.logging?.namespaces?.shellcore || false}\n onCheckedChange={(checked) =>\n updateSetting('logging', {\n namespaces: {\n ...settings.logging?.namespaces,\n shellcore: checked,\n },\n })\n }\n />\n </div>\n </div>\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.navigation.title')}\n </h3>\n {navItems.length ? (\n <div className=\"space-y-2\">\n <label\n htmlFor=\"develop-nav-select\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.navigation.selectLabel')}\n </label>\n <div className=\"mt-2\">\n <Select\n id=\"develop-nav-select\"\n defaultValue=\"\"\n onChange={(e) => {\n const path = e.target.value;\n if (path) {\n shellui.navigate(path.startsWith('/') ? path : `/${path}`);\n }\n }}\n >\n <option value=\"\">{t('develop.navigation.placeholder')}</option>\n {navItems.map((item) => (\n <option\n key={item.path}\n value={`/${item.path}`}\n >\n {resolveLocalizedString(item.label, currentLanguage) || item.path}\n </option>\n ))}\n </Select>\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('develop.navigation.empty')}</p>\n )}\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.layout.title')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {(['sidebar', 'windows'] as const).map((layoutMode) => (\n <Button\n key={layoutMode}\n variant={effectiveLayout === layoutMode ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updateSetting('layout', layoutMode as LayoutType)}\n >\n {t(`develop.layout.${layoutMode}`)}\n </Button>\n ))}\n </div>\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.title')}\n </h3>\n <div className=\"space-y-4\">\n <ToastTestButtons />\n <DialogTestButtons />\n <ModalTestButtons />\n <DrawerTestButtons />\n </div>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\nimport urls from '@/constants/urls';\nimport { cn } from '@/lib/utils';\n\nexport const DataPrivacy = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n\n const cookies = config?.cookieConsent?.cookies ?? [];\n const hasCookieConsent = cookies.length > 0;\n const hasConsented = Boolean(settings?.cookieConsent?.consentedCookieHosts?.length);\n\n // Determine consent status\n const acceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n const allHosts = cookies.map((c) => c.host);\n const strictNecessaryHosts = cookies\n .filter((c) => c.category === 'strict_necessary')\n .map((c) => c.host);\n\n const acceptedAll =\n hasConsented &&\n acceptedHosts.length === allHosts.length &&\n allHosts.every((h) => acceptedHosts.includes(h));\n // \"Rejected all\" means only strictly necessary cookies are accepted\n const rejectedAll =\n hasConsented &&\n acceptedHosts.length === strictNecessaryHosts.length &&\n strictNecessaryHosts.every((h) => acceptedHosts.includes(h)) &&\n !acceptedHosts.some((h) => !strictNecessaryHosts.includes(h));\n const isCustom = hasConsented && !acceptedAll && !rejectedAll;\n\n const handleResetCookieConsent = () => {\n updateSetting('cookieConsent', {\n acceptedHosts: [],\n consentedCookieHosts: [],\n });\n };\n\n return (\n <div className=\"space-y-6\">\n {!hasCookieConsent ? (\n <div className=\"rounded-lg border bg-card p-4 space-y-3\">\n <div className=\"space-y-1\">\n <h3\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('dataPrivacy.noCookiesConfigured.title')}\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n {t('dataPrivacy.noCookiesConfigured.description')}\n </p>\n </div>\n <div className=\"flex items-start gap-2 text-sm\">\n <span className=\"text-green-600 dark:text-green-400 mt-0.5\">✓</span>\n <span className=\"text-muted-foreground\">\n {t('dataPrivacy.noCookiesConfigured.info')}\n </span>\n </div>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('dataPrivacy.cookieConsent.title')}\n </label>\n <div className=\"mt-2 space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {!hasConsented\n ? t('dataPrivacy.cookieConsent.descriptionNotConsented')\n : acceptedAll\n ? t('dataPrivacy.cookieConsent.statusAcceptedAll')\n : rejectedAll\n ? t('dataPrivacy.cookieConsent.statusRejectedAll')\n : t('dataPrivacy.cookieConsent.statusCustom')}\n </p>\n {hasConsented && (\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n acceptedAll\n ? 'bg-primary/10 text-primary border border-primary/20'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelAcceptedAll')}\n </span>\n <span className=\"text-muted-foreground/30\">|</span>\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n isCustom\n ? 'bg-muted text-muted-foreground border border-border'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelCustom')}\n </span>\n <span className=\"text-muted-foreground/30\">|</span>\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n rejectedAll\n ? 'bg-muted text-muted-foreground border border-border'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelRejectedAll')}\n </span>\n </div>\n )}\n <div className=\"flex flex-wrap gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => shellui.openDrawer({ url: urls.cookiePreferences, size: '420px' })}\n className=\"w-full sm:w-auto\"\n >\n {t('dataPrivacy.cookieConsent.manageButton')}\n </Button>\n <Button\n variant=\"ghost\"\n onClick={handleResetCookieConsent}\n disabled={!hasConsented}\n className=\"w-full sm:w-auto\"\n >\n {t('dataPrivacy.cookieConsent.button')}\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport { Switch } from '@/components/ui/switch';\nimport {\n isServiceWorkerRegistered,\n updateServiceWorker,\n getServiceWorkerStatus,\n addStatusListener,\n serviceWorkerFileExists,\n} from '@/service-worker/register';\nimport { shellui } from '@shellui/sdk';\nimport { useState, useEffect } from 'react';\n\nexport const ServiceWorker = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const [isRegistered, setIsRegistered] = useState(false);\n const [updateAvailable, setUpdateAvailable] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [swFileExists, setSwFileExists] = useState(true); // Track if service worker file exists\n\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true;\n\n useEffect(() => {\n // Don't check service worker status if disabled\n if (!serviceWorkerEnabled) {\n // Immediately clear all state and hide error messages\n setIsRegistered(false);\n setUpdateAvailable(false);\n setIsLoading(false);\n setSwFileExists(true); // Set to true to prevent error messages from showing\n return;\n }\n\n // Initial check with loading state\n const initialCheck = async () => {\n // Double-check service worker is still enabled before proceeding\n const stillEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!stillEnabled) {\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n\n // First check if service worker file exists\n const exists = await serviceWorkerFileExists();\n\n // Check again if service worker was disabled during the async operation\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabled) {\n setIsLoading(false);\n return;\n }\n\n setSwFileExists(exists);\n\n if (exists) {\n // Check service worker status only if file exists\n const status = await getServiceWorkerStatus();\n\n // Final check before updating state\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n }\n } else {\n // File doesn't exist, so service worker can't be registered\n // Only update if service worker is still enabled\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n }\n }\n\n setIsLoading(false);\n };\n\n // Background refresh without affecting loading state\n const refreshStatus = async () => {\n // Skip if service worker was disabled (check current setting value)\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabled) {\n return;\n }\n\n // Check if file exists first\n const exists = await serviceWorkerFileExists();\n\n // Check again if service worker was disabled during the async operation\n const currentEnabledAfter = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabledAfter) {\n return;\n }\n\n setSwFileExists(exists);\n\n if (exists) {\n // Check service worker status only if file exists\n const status = await getServiceWorkerStatus();\n\n // Final check before updating state\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n }\n } else {\n // File doesn't exist, so service worker can't be registered\n // Only update if service worker is still enabled\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n }\n }\n };\n\n // Initial check immediately\n initialCheck();\n\n // Listen for status changes\n const unsubscribe = addStatusListener((status) => {\n // Only update if service worker is still enabled (check current setting value)\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (currentEnabled) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n setIsLoading(false);\n }\n });\n\n // Also check periodically as fallback (background refresh) - less frequent to avoid excessive fetches\n const interval = setInterval(refreshStatus, 30000); // Check every 30 seconds instead of 5\n\n return () => {\n unsubscribe();\n clearInterval(interval);\n };\n }, [serviceWorkerEnabled]);\n\n const handleToggleServiceWorker = async (enabled: boolean) => {\n // Immediately clear all state before updating setting to prevent error flashes\n if (!enabled) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n setSwFileExists(true); // Set to true to hide error messages immediately\n setIsLoading(false);\n }\n\n updateSetting('serviceWorker', { enabled });\n\n if (!enabled) {\n // Already cleared above, just return\n return;\n }\n\n // Give it a moment to register/unregister\n setTimeout(async () => {\n // Double-check service worker is still enabled before updating state\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (enabled && currentEnabled) {\n const registered = await isServiceWorkerRegistered();\n setIsRegistered(registered);\n }\n }, 1000);\n };\n\n const handleUpdateNow = async () => {\n try {\n await updateServiceWorker();\n // Don't show toast here - updateServiceWorker() will handle the reload\n // and the update process already provides feedback through the UI\n } catch (_error) {\n shellui.toast({\n title: t('caching.updateError.title'),\n description: t('caching.updateError.description'),\n type: 'error',\n });\n }\n };\n\n const handleResetToLatest = async () => {\n try {\n // Clear all caches and reload\n if ('caches' in window) {\n const cacheNames = await caches.keys();\n await Promise.all(cacheNames.map((name) => caches.delete(name)));\n }\n\n shellui.toast({\n title: t('caching.resetSuccess.title'),\n description: t('caching.resetSuccess.description'),\n type: 'success',\n });\n\n // Reload the app using shellUI refresh message (refreshes entire app, not just iframe)\n setTimeout(() => {\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) {\n // Fallback to window.location.reload if message can't be sent\n window.location.reload();\n }\n }, 1000);\n } catch (_error) {\n shellui.toast({\n title: t('caching.resetError.title'),\n description: t('caching.resetError.description'),\n type: 'error',\n });\n }\n };\n\n return (\n <div className=\"space-y-6\">\n {isLoading ? (\n <div className=\"text-sm text-muted-foreground\">{t('caching.loading')}</div>\n ) : null}\n\n {!isLoading && (\n <div className=\"space-y-6\">\n {/* Enable/Disable service worker */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.enabled.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {serviceWorkerEnabled\n ? t('caching.enabled.descriptionEnabled')\n : t('caching.enabled.descriptionDisabled')}\n </p>\n </div>\n <Switch\n checked={serviceWorkerEnabled}\n onCheckedChange={handleToggleServiceWorker}\n />\n </div>\n </div>\n\n {/* Status – always visible; shows Disabled when off */}\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.status.title')}\n </label>\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n {!serviceWorkerEnabled ? (\n <span className=\"text-muted-foreground\">○ {t('caching.status.disabled')}</span>\n ) : !swFileExists ? (\n <span className=\"text-red-600 dark:text-red-400\">\n ✗ {t('caching.status.fileNotFound')}\n </span>\n ) : (\n <>\n <span\n className={\n isRegistered\n ? 'text-green-600 dark:text-green-400'\n : 'text-orange-600 dark:text-orange-400'\n }\n >\n {isRegistered ? '●' : '○'}{' '}\n {isRegistered ? t('caching.status.registered') : t('caching.status.notRunning')}\n </span>\n {updateAvailable && (\n <>\n <span className=\"text-muted-foreground/50\">|</span>\n <span className=\"text-blue-600 dark:text-blue-400\">\n ● {t('caching.status.updateAvailable')}\n </span>\n </>\n )}\n </>\n )}\n </div>\n </div>\n\n {serviceWorkerEnabled && (\n <>\n {/* Error Message when file missing */}\n {!swFileExists && (\n <div className=\"rounded-lg border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-950/30 p-4 space-y-3\">\n <div className=\"space-y-1\">\n <h3\n className=\"text-sm font-medium leading-none text-red-600 dark:text-red-400\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.status.fileNotFound')}\n </h3>\n <p className=\"text-sm text-red-700 dark:text-red-300\">\n {t('caching.status.fileNotFoundDescription')}\n </p>\n </div>\n </div>\n )}\n\n {/* Update Available */}\n {updateAvailable && (\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.update.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('caching.update.description')}\n </p>\n </div>\n <div className=\"mt-2\">\n <Button\n variant=\"outline\"\n onClick={handleUpdateNow}\n className=\"w-full sm:w-auto\"\n >\n {t('caching.update.button')}\n </Button>\n </div>\n </div>\n )}\n\n {/* Reset Cache */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.reset.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('caching.reset.description')}</p>\n </div>\n <div className=\"mt-2\">\n <Button\n variant=\"outline\"\n onClick={handleResetToLatest}\n className=\"w-full sm:w-auto\"\n >\n {t('caching.reset.button')}\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n","import {\n PaintbrushIcon,\n GlobeIcon,\n SettingsIcon,\n CodeIcon,\n ShieldIcon,\n PackageIcon,\n RefreshDoubleIcon,\n} from './SettingsIcons';\nimport { Appearance } from './components/Appearance';\nimport { LanguageAndRegion } from './components/LanguageAndRegion';\nimport { UpdateApp } from './components/UpdateApp';\nimport { Advanced } from './components/Advanced';\nimport { Develop } from './components/Develop';\nimport { DataPrivacy } from './components/DataPrivacy';\nimport { ServiceWorker } from './components/ServiceWorker';\nimport { isTauri } from '../../service-worker/register';\n\nexport const createSettingsRoutes = (t: (key: string) => string) => [\n {\n name: t('routes.appearance'),\n icon: PaintbrushIcon,\n path: 'appearance',\n element: <Appearance />,\n },\n {\n name: t('routes.languageAndRegion'),\n icon: GlobeIcon,\n path: 'language-and-region',\n element: <LanguageAndRegion />,\n },\n {\n name: t('routes.updateApp'),\n icon: RefreshDoubleIcon,\n path: 'update-app',\n element: <UpdateApp />,\n },\n {\n name: t('routes.advanced'),\n icon: SettingsIcon,\n path: 'advanced',\n element: <Advanced />,\n },\n {\n name: t('routes.dataPrivacy'),\n icon: ShieldIcon,\n path: 'data-privacy',\n element: <DataPrivacy />,\n },\n {\n name: t('routes.develop'),\n icon: CodeIcon,\n path: 'developpers',\n element: <Develop />,\n },\n ...(isTauri()\n ? []\n : [\n {\n name: t('routes.serviceWorker'),\n icon: PackageIcon,\n path: 'service-worker',\n element: <ServiceWorker />,\n },\n ]),\n];\n","import { useState, useEffect, useMemo, useCallback } from 'react';\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/components/ui/breadcrumb';\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/components/ui/sidebar';\nimport { Route, Routes, useLocation, useNavigate, Navigate } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport urls from '@/constants/urls';\nimport { createSettingsRoutes } from './SettingsRoutes';\nimport { useSettings } from './hooks/useSettings';\nimport { useConfig } from '../config/useConfig';\nimport { isTauri } from '@/service-worker/register';\nimport { Button } from '@/components/ui/button';\nimport { ChevronRightIcon, ChevronLeftIcon } from './SettingsIcons';\n\nexport const SettingsView = () => {\n const location = useLocation();\n const navigate = useNavigate();\n const { settings } = useSettings();\n const { config } = useConfig();\n const { t } = useTranslation('settings');\n // Re-check isTauri after mount and after a short delay so we catch late-injected __TAURI__ in dev\n const [isTauriEnv, setIsTauriEnv] = useState(() => isTauri());\n\n useEffect(() => {\n setIsTauriEnv(isTauri());\n const tid = window.setTimeout(() => setIsTauriEnv(isTauri()), 200);\n return () => window.clearTimeout(tid);\n }, []);\n\n useEffect(() => {\n if (config?.title) {\n const settingsLabel = t('settings', { ns: 'common' });\n document.title = `${settingsLabel} | ${config.title}`;\n }\n }, [config?.title, t]);\n\n // Create routes with translations (service-worker route is already omitted in Tauri by createSettingsRoutes)\n const settingsRoutes = useMemo(() => createSettingsRoutes(t), [t]);\n\n // In Tauri, hide service worker route; use reactive isTauriEnv so we catch late injection (e.g. dev)\n const routesWithoutTauriSw = useMemo(() => {\n if (isTauriEnv) {\n return settingsRoutes.filter((route) => route.path !== 'service-worker');\n }\n return settingsRoutes;\n }, [settingsRoutes, isTauriEnv]);\n\n // Filter routes based on developer features setting\n const filteredRoutes = useMemo(() => {\n if (settings.developerFeatures.enabled) {\n return routesWithoutTauriSw;\n }\n return routesWithoutTauriSw.filter(\n (route) => route.path !== 'developpers' && route.path !== 'service-worker',\n );\n }, [settings.developerFeatures.enabled, routesWithoutTauriSw]);\n\n // Group routes by category\n const groupedRoutes = useMemo(() => {\n const developerOnlyPaths = ['developpers', 'service-worker'];\n const groups = [\n {\n title: t('categories.preferences'),\n routes: filteredRoutes.filter((route) =>\n ['appearance', 'language-and-region', 'data-privacy'].includes(route.path),\n ),\n },\n {\n title: t('categories.system'),\n routes: filteredRoutes.filter((route) => ['update-app', 'advanced'].includes(route.path)),\n },\n {\n title: t('categories.developer'),\n routes: filteredRoutes.filter((route) => developerOnlyPaths.includes(route.path)),\n },\n ];\n return groups.filter((group) => group.routes.length > 0);\n }, [filteredRoutes, t]);\n\n // Find matching nav item by checking if URL contains or ends with the item path\n const getSelectedItemFromUrl = useCallback(() => {\n const pathname = location.pathname;\n\n // Find matching nav item by checking if pathname contains the item path\n // This works regardless of the URL structure/prefix\n const matchedItem = filteredRoutes.find((item) => {\n // Normalize paths for comparison (remove leading/trailing slashes)\n const normalizedPathname = pathname.replace(/^\\/+|\\/+$/g, '');\n const normalizedItemPath = item.path.replace(/^\\/+|\\/+$/g, '');\n\n // Check if pathname ends with the item path, or contains it as a path segment\n return (\n normalizedPathname === normalizedItemPath ||\n normalizedPathname.endsWith(`/${normalizedItemPath}`) ||\n normalizedPathname.includes(`/${normalizedItemPath}/`)\n );\n });\n\n return matchedItem;\n }, [location.pathname, filteredRoutes]);\n\n const selectedItem = useMemo(() => getSelectedItemFromUrl(), [getSelectedItemFromUrl]);\n\n // Check if we're at the settings root (no specific route selected)\n const isSettingsRoot = useMemo(() => {\n const pathname = location.pathname;\n // Normalize the settings URL (remove leading/trailing slashes)\n const normalizedSettingsPath = urls.settings.replace(/^\\/+|\\/+$/g, '');\n // Normalize the current pathname (remove leading/trailing slashes)\n const normalizedPathname = pathname.replace(/^\\/+|\\/+$/g, '');\n\n // Check if we're exactly at the settings root\n // This handles both \"/__settings\" and \"/__settings/\" cases\n if (normalizedPathname === normalizedSettingsPath) {\n return true;\n }\n\n // If pathname starts with settings path followed by a slash, we're at a subpage\n // e.g., \"__settings/appearance\" means we're NOT at root\n const settingsPathWithSlash = `${normalizedSettingsPath}/`;\n if (normalizedPathname.startsWith(settingsPathWithSlash)) {\n return false;\n }\n\n // Pathname doesn't match settings path structure - not in settings\n return false;\n }, [location.pathname, filteredRoutes]);\n\n // Navigate back to settings root\n const handleBackToSettings = useCallback(() => {\n // Navigate to settings root, replacing current history entry\n navigate(urls.settings, { replace: true });\n }, [navigate]);\n\n return (\n <SidebarProvider>\n <div className=\"flex h-full w-full overflow-hidden items-start\">\n {/* Desktop Sidebar */}\n <Sidebar className=\"hidden md:flex\">\n <SidebarContent>\n {groupedRoutes.map((group) => (\n <SidebarGroup key={group.title}>\n <SidebarGroupLabel>{group.title}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n {group.routes.map((item) => (\n <SidebarMenuItem key={item.name}>\n <SidebarMenuButton\n asChild\n isActive={item.name === selectedItem?.name}\n >\n <button\n onClick={() => navigate(`${urls.settings}/${item.path}`)}\n className=\"cursor-pointer\"\n >\n <item.icon />\n <span>{item.name}</span>\n </button>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n ))}\n </SidebarContent>\n </Sidebar>\n\n {/* Mobile List View */}\n <div className=\"md:hidden flex h-full w-full flex-col overflow-hidden\">\n {isSettingsRoot ? (\n // Show list of settings pages\n <div className=\"flex flex-1 flex-col overflow-y-auto bg-background\">\n <header className=\"flex h-16 shrink-0 items-center justify-center px-4 border-b\">\n <h1 className=\"text-lg font-semibold\">{t('title')}</h1>\n </header>\n <div className=\"flex flex-1 flex-col p-4 gap-6\">\n {groupedRoutes.map((group) => (\n <div\n key={group.title}\n className=\"flex flex-col gap-2\"\n >\n <h2\n className=\"text-xs font-semibold text-foreground/60 uppercase tracking-wider px-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {group.title}\n </h2>\n <div className=\"flex flex-col bg-card rounded-lg overflow-hidden border border-border\">\n {group.routes.map((item, itemIndex) => {\n const Icon = item.icon;\n const isLast = itemIndex === group.routes.length - 1;\n return (\n <div\n key={item.name}\n className=\"relative\"\n >\n {!isLast && (\n <div className=\"absolute left-0 right-0 bottom-0 h-[1px] bg-border\" />\n )}\n <button\n onClick={() => navigate(`${urls.settings}/${item.path}`)}\n className=\"w-full flex items-center justify-between px-4 py-3 bg-transparent hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground transition-colors cursor-pointer rounded-none\"\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <div className=\"flex-shrink-0 text-foreground/70\">\n <Icon />\n </div>\n <span className=\"text-sm font-normal text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"flex-shrink-0 ml-2 text-foreground/40\">\n <ChevronRightIcon />\n </div>\n </button>\n </div>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n ) : (\n // Show selected settings page with back button\n <div className=\"flex h-full flex-1 flex-col overflow-hidden\">\n <header className=\"flex h-16 shrink-0 items-center gap-2 px-4 border-b\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleBackToSettings}\n className=\"mr-2\"\n >\n <ChevronLeftIcon />\n </Button>\n <h1 className=\"text-lg font-semibold\">{selectedItem?.name}</h1>\n </header>\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-4\">\n <Routes>\n <Route\n index\n element={\n filteredRoutes.length > 0 ? (\n <Navigate\n to={`${urls.settings}/${filteredRoutes[0].path}`}\n replace\n />\n ) : null\n }\n />\n {filteredRoutes.map((item) => (\n <Route\n key={item.path}\n path={item.path}\n element={item.element}\n />\n ))}\n </Routes>\n </div>\n </div>\n )}\n </div>\n\n {/* Desktop Main Content */}\n <main className=\"hidden md:flex h-full flex-1 flex-col overflow-hidden\">\n {selectedItem && (\n <header className=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear\">\n <div className=\"flex items-center gap-2 px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>{t('title')}</BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>{selectedItem.name}</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n )}\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0\">\n <Routes>\n <Route\n index\n element={\n <div className=\"flex flex-1 flex-col items-center justify-center p-8 text-center\">\n <div className=\"max-w-md\">\n <h2 className=\"text-lg font-semibold mb-2\">{t('title')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('selectCategory', {\n defaultValue: 'Select a category from the sidebar to get started.',\n })}\n </p>\n </div>\n </div>\n }\n />\n {filteredRoutes.map((item) => (\n <Route\n key={item.path}\n path={item.path}\n element={item.element}\n />\n ))}\n </Routes>\n </div>\n </main>\n </div>\n </SidebarProvider>\n );\n};\n","import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation } from 'react-router';\nimport { shellui } from '@shellui/sdk';\nimport { Button } from '@/components/ui/button';\nimport { Switch } from '@/components/ui/switch';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { resolveLocalizedString } from '../layouts/utils';\nimport type { CookieConsentCategory, CookieDefinition } from '../config/types';\n\n/** Category display order and labels */\nconst CATEGORY_ORDER: CookieConsentCategory[] = [\n 'strict_necessary',\n 'functional_performance',\n 'targeting',\n 'social_media_embedded',\n];\n\n/** Format duration in human-readable format */\nfunction formatDuration(\n seconds: number,\n t: (key: string, options?: Record<string, unknown>) => string,\n): string {\n if (seconds < 60) return t('preferences.duration.seconds', { count: seconds });\n if (seconds < 3600) return t('preferences.duration.minutes', { count: Math.floor(seconds / 60) });\n if (seconds < 86400)\n return t('preferences.duration.hours', { count: Math.floor(seconds / 3600) });\n if (seconds < 31536000)\n return t('preferences.duration.days', { count: Math.floor(seconds / 86400) });\n return t('preferences.duration.years', { count: Math.floor(seconds / 31536000) });\n}\n\nexport function CookiePreferencesView() {\n const { t, i18n } = useTranslation('cookieConsent');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n const location = useLocation();\n const searchParams = new URLSearchParams(location.search);\n const isInitialConsent = searchParams.get('initial') === 'true';\n const currentLanguage = i18n.language || 'en';\n\n const cookies = config?.cookieConsent?.cookies ?? [];\n const allHosts = useMemo(() => cookies.map((c) => c.host), [cookies]);\n\n // Strictly necessary hosts are always enabled\n const strictNecessaryHosts = useMemo(\n () => cookies.filter((c) => c.category === 'strict_necessary').map((c) => c.host),\n [cookies],\n );\n\n const currentAcceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n\n // Local state for unsaved changes (always include strict necessary)\n const [localAcceptedHosts, setLocalAcceptedHosts] = useState<string[]>(() => [\n ...new Set([...currentAcceptedHosts, ...strictNecessaryHosts]),\n ]);\n\n // Track if save/accept/reject was clicked to avoid rejecting on intentional close\n const actionClickedRef = useRef(false);\n\n // Reset local state when drawer opens (when URL changes to include initial param)\n useEffect(() => {\n if (isInitialConsent) {\n // Always include strict necessary hosts\n setLocalAcceptedHosts([...new Set([...currentAcceptedHosts, ...strictNecessaryHosts])]);\n }\n }, [isInitialConsent, currentAcceptedHosts, strictNecessaryHosts]);\n\n // Handle drawer close without saving during initial consent\n useEffect(() => {\n if (!isInitialConsent) return;\n\n const handleDrawerClose = () => {\n // If closing without saving during initial consent, reject all except strict necessary\n // Check if user has never consented and no action was clicked\n const neverConsented = (settings?.cookieConsent?.consentedCookieHosts ?? []).length === 0;\n if (neverConsented && !actionClickedRef.current) {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }\n };\n\n const cleanup = shellui.addMessageListener('SHELLUI_CLOSE_DRAWER', handleDrawerClose);\n return cleanup;\n }, [isInitialConsent, strictNecessaryHosts, allHosts, updateSetting, settings]);\n\n // Cleanup on unmount: if initial consent and drawer closes without save, reject all\n useEffect(() => {\n return () => {\n if (isInitialConsent && !actionClickedRef.current) {\n // Check if user has never consented\n const neverConsented = (settings?.cookieConsent?.consentedCookieHosts ?? []).length === 0;\n if (neverConsented) {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }\n }\n };\n }, [isInitialConsent, strictNecessaryHosts, allHosts, updateSetting, settings]);\n\n // Group cookies by category\n const cookiesByCategory = useMemo(() => {\n const grouped = new Map<CookieConsentCategory, CookieDefinition[]>();\n for (const cookie of cookies) {\n const existing = grouped.get(cookie.category) ?? [];\n grouped.set(cookie.category, [...existing, cookie]);\n }\n return grouped;\n }, [cookies]);\n\n // Toggle individual cookie\n const toggleCookie = useCallback((host: string, enabled: boolean) => {\n setLocalAcceptedHosts((prev) => (enabled ? [...prev, host] : prev.filter((h) => h !== host)));\n }, []);\n\n // Toggle entire category\n const toggleCategory = useCallback(\n (category: CookieConsentCategory, enabled: boolean) => {\n const categoryHosts = cookiesByCategory.get(category)?.map((c) => c.host) ?? [];\n setLocalAcceptedHosts((prev) => {\n if (enabled) {\n return [...new Set([...prev, ...categoryHosts])];\n } else {\n const hostsSet = new Set(categoryHosts);\n return prev.filter((h) => !hostsSet.has(h));\n }\n });\n },\n [cookiesByCategory],\n );\n\n // Check if category is fully or partially enabled\n const getCategoryState = useCallback(\n (category: CookieConsentCategory): 'all' | 'some' | 'none' => {\n const categoryHosts = cookiesByCategory.get(category)?.map((c) => c.host) ?? [];\n if (categoryHosts.length === 0) return 'none';\n const enabledCount = categoryHosts.filter((h) => localAcceptedHosts.includes(h)).length;\n if (enabledCount === categoryHosts.length) return 'all';\n if (enabledCount > 0) return 'some';\n return 'none';\n },\n [cookiesByCategory, localAcceptedHosts],\n );\n\n // Accept all\n const handleAcceptAll = useCallback(() => {\n actionClickedRef.current = true;\n updateSetting('cookieConsent', {\n acceptedHosts: allHosts,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [allHosts, updateSetting]);\n\n // Reject all except strict necessary (which are always enabled)\n const handleRejectAll = useCallback(() => {\n actionClickedRef.current = true;\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [strictNecessaryHosts, allHosts, updateSetting]);\n\n // Save custom preferences (always include strict necessary)\n const handleSave = useCallback(() => {\n actionClickedRef.current = true;\n const hostsToSave = [...new Set([...localAcceptedHosts, ...strictNecessaryHosts])];\n updateSetting('cookieConsent', {\n acceptedHosts: hostsToSave,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [localAcceptedHosts, strictNecessaryHosts, allHosts, updateSetting]);\n\n // Check if preferences have changed\n const hasChanges = useMemo(() => {\n if (localAcceptedHosts.length !== currentAcceptedHosts.length) return true;\n const sortedLocal = [...localAcceptedHosts].sort();\n const sortedCurrent = [...currentAcceptedHosts].sort();\n return sortedLocal.some((h, i) => h !== sortedCurrent[i]);\n }, [localAcceptedHosts, currentAcceptedHosts]);\n\n if (cookies.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full p-6\">\n <p className=\"text-muted-foreground\">{t('preferences.noCookies')}</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full bg-background\">\n {/* Header */}\n <div className=\"flex flex-col space-y-2 border-b border-border/60 px-6 pt-5 pb-4\">\n <h2\n className=\"text-lg font-semibold leading-none tracking-tight\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('preferences.title')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">{t('preferences.description')}</p>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {CATEGORY_ORDER.map((category) => {\n const categoryCookies = cookiesByCategory.get(category);\n if (!categoryCookies || categoryCookies.length === 0) return null;\n\n const categoryState = getCategoryState(category);\n const isStrictNecessary = category === 'strict_necessary';\n\n return (\n <div\n key={category}\n className=\"mb-6 last:mb-0\"\n >\n {/* Category header with toggle */}\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"flex-1 min-w-0\">\n <h3\n className=\"text-sm font-semibold\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t(`preferences.categories.${category}.title`)}\n </h3>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {t(`preferences.categories.${category}.description`)}\n </p>\n </div>\n <div className=\"ml-4 flex items-center gap-2\">\n {!isStrictNecessary && categoryState === 'some' && (\n <span className=\"text-xs text-muted-foreground\">\n {t('preferences.partial')}\n </span>\n )}\n {isStrictNecessary ? (\n <span className=\"text-xs text-muted-foreground\">\n {t('preferences.alwaysOn')}\n </span>\n ) : (\n <Switch\n checked={categoryState === 'all'}\n onCheckedChange={(checked) => toggleCategory(category, checked)}\n aria-label={t(`preferences.categories.${category}.title`)}\n />\n )}\n </div>\n </div>\n\n {/* Individual cookies - only show for non-strictly-necessary categories */}\n {!isStrictNecessary && (\n <div className=\"space-y-2 pl-2 border-l-2 border-border ml-1\">\n {categoryCookies.map((cookie) => {\n const isEnabled = localAcceptedHosts.includes(cookie.host);\n return (\n <div\n key={cookie.host}\n className=\"flex items-start justify-between gap-3 py-2 px-3 rounded-md bg-muted/30\"\n >\n <div className=\"flex-1 min-w-0\">\n <span className=\"text-sm font-medium truncate\">{cookie.name}</span>\n {cookie.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {resolveLocalizedString(cookie.description, currentLanguage)}\n </p>\n )}\n <div className=\"flex items-center gap-3 mt-1 text-[10px] text-muted-foreground/70\">\n <span>{cookie.host}</span>\n <span>•</span>\n <span>{formatDuration(cookie.durationSeconds, t)}</span>\n <span>•</span>\n <span className=\"capitalize\">{cookie.type.replace('_', ' ')}</span>\n </div>\n </div>\n <Switch\n checked={isEnabled}\n onCheckedChange={(checked) => toggleCookie(cookie.host, checked)}\n aria-label={cookie.name}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Footer */}\n <div className=\"mt-auto flex flex-col gap-2 border-t border-border px-6 py-4\">\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRejectAll}\n className=\"flex-1\"\n >\n {t('preferences.rejectAll')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAcceptAll}\n className=\"flex-1\"\n >\n {t('preferences.acceptAll')}\n </Button>\n </div>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={!hasChanges && !isInitialConsent}\n className=\"w-full\"\n >\n {t('preferences.save')}\n </Button>\n </div>\n </div>\n );\n}\n","export function LoadingOverlay() {\n return (\n <div className=\"absolute inset-0 z-10 flex flex-col bg-background\">\n <div className=\"h-1 w-full overflow-hidden bg-muted/30\">\n <div\n className=\"h-full w-0 bg-muted-foreground/50\"\n style={{ animation: 'loading-bar-slide 400ms linear infinite' }}\n />\n </div>\n </div>\n );\n}\n","/* eslint-disable no-console */\nimport type { NavigationItem } from '@/features/config/types';\nimport {\n addIframe,\n removeIframe,\n shellui,\n getLogger,\n type ShellUIUrlPayload,\n type ShellUIMessage,\n} from '@shellui/sdk';\nimport { useEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { LoadingOverlay } from './LoadingOverlay';\n\nconst logger = getLogger('shellcore');\n\ninterface ContentViewProps {\n url: string;\n pathPrefix: string;\n ignoreMessages?: boolean;\n navItem: NavigationItem;\n}\n\nexport const ContentView = ({\n url,\n pathPrefix,\n ignoreMessages = false,\n navItem,\n}: ContentViewProps) => {\n const navigate = useNavigate();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const isInternalNavigation = useRef(false);\n const [initialUrl] = useState(url);\n const [isLoading, setIsLoading] = useState(true);\n\n useEffect(() => {\n if (!iframeRef.current) {\n return;\n }\n const iframeId = addIframe(iframeRef.current);\n return () => {\n removeIframe(iframeId);\n };\n }, []);\n\n // Sync parent URL when iframe notifies us of a change\n useEffect(() => {\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_URL_CHANGED',\n (data: ShellUIMessage, event: MessageEvent) => {\n if (ignoreMessages) {\n return;\n }\n\n // Ignore URL CHANGE from other than ContentView iframe\n if (event.source !== iframeRef.current?.contentWindow) {\n return;\n }\n\n const { pathname, search, hash } = data.payload as ShellUIUrlPayload;\n // Remove leading slash and trailing slashes from iframe pathname\n let cleanPathname = pathname.startsWith(navItem.url)\n ? pathname.slice(navItem.url.length)\n : pathname;\n cleanPathname = cleanPathname.startsWith('/') ? cleanPathname.slice(1) : cleanPathname;\n cleanPathname = cleanPathname.replace(/\\/+$/, ''); // Remove trailing slashes\n // Construct the new path without trailing slashes\n let newShellPath = cleanPathname\n ? `/${pathPrefix}/${cleanPathname}${search}${hash}`\n : `/${pathPrefix}${search}${hash}`;\n\n // Normalize: remove trailing slashes from pathname part only (preserve query/hash)\n const urlParts = newShellPath.match(/^([^?#]*)([?#].*)?$/);\n if (urlParts) {\n const pathnamePart = urlParts[1].replace(/\\/+$/, '') || '/';\n const queryHashPart = urlParts[2] || '';\n newShellPath = pathnamePart + queryHashPart;\n }\n\n // Normalize current path for comparison (remove trailing slashes from pathname)\n const currentPathname = window.location.pathname.replace(/\\/+$/, '') || '/';\n const currentPath = currentPathname + window.location.search + window.location.hash;\n\n // Normalize new path for comparison\n const newPathParts = newShellPath.match(/^([^?#]*)([?#].*)?$/);\n const normalizedNewPathname = newPathParts?.[1]?.replace(/\\/+$/, '') || '/';\n const normalizedNewPath = normalizedNewPathname + (newPathParts?.[2] || '');\n\n if (currentPath !== normalizedNewPath) {\n // Mark this navigation as internal so we don't try to \"push\" it back to the iframe\n isInternalNavigation.current = true;\n navigate(newShellPath, { replace: true });\n\n // Reset the flag after a short delay to allow the render cycle to complete\n setTimeout(() => {\n isInternalNavigation.current = false;\n }, 100);\n }\n },\n );\n\n return () => {\n cleanup();\n };\n }, [pathPrefix, navigate]);\n\n // Hide loading overlay when iframe sends SHELLUI_INITIALIZED\n useEffect(() => {\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_INITIALIZED',\n (_data: ShellUIMessage, event: MessageEvent) => {\n if (event.source === iframeRef.current?.contentWindow) {\n setIsLoading(false);\n }\n },\n );\n return () => cleanup();\n }, []);\n\n // Fallback: hide overlay after 400ms if SHELLUI_INITIALIZED was not received\n useEffect(() => {\n if (!isLoading) return;\n const timeoutId = setTimeout(() => {\n logger.info('ContentView: Timeout expired, hiding loading overlay');\n setIsLoading(false);\n }, 400);\n return () => clearTimeout(timeoutId);\n }, [isLoading]);\n\n // Handle external URL changes (e.g. from Sidebar)\n useEffect(() => {\n if (iframeRef.current && !isInternalNavigation.current) {\n // Only update iframe src if it's actually different from its current src\n // to avoid unnecessary reloads\n if (iframeRef.current.src !== url) {\n iframeRef.current.src = url;\n setIsLoading(true);\n }\n }\n }, [url]);\n\n // Inject script to prevent \"Layout was forced\" warning by deferring layout until stylesheets load\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n const handleLoad = () => {\n try {\n const iframeWindow = iframe.contentWindow;\n const iframeDoc = iframe.contentDocument || iframeWindow?.document;\n if (!iframeDoc || !iframeWindow) return;\n\n // Inject a script that waits for stylesheets before allowing layout calculations\n const script = iframeDoc.createElement('script');\n script.textContent = `\n (function() {\n // Wait for all stylesheets to load\n function waitForStylesheets() {\n const styleSheets = Array.from(document.styleSheets);\n const pendingSheets = styleSheets.filter(function(sheet) {\n try {\n return sheet.cssRules === null;\n } catch (e) {\n return false; // Cross-origin stylesheets, assume loaded\n }\n });\n \n if (pendingSheets.length === 0) {\n // All stylesheets loaded\n return;\n }\n \n // Check again after a short delay\n setTimeout(waitForStylesheets, 10);\n }\n \n // Start checking after DOM is ready\n if (document.readyState === 'complete') {\n waitForStylesheets();\n } else {\n window.addEventListener('load', waitForStylesheets);\n }\n })();\n `;\n iframeDoc.head.appendChild(script);\n } catch (error) {\n // Cross-origin or other errors - ignore (this is expected for some iframes)\n logger.debug('Could not inject stylesheet wait script:', { error });\n }\n };\n\n // Wait for iframe to load before injecting script\n iframe.addEventListener('load', handleLoad);\n\n // Also try immediately if already loaded\n if (iframe.contentDocument?.readyState === 'complete') {\n handleLoad();\n }\n\n return () => {\n iframe.removeEventListener('load', handleLoad);\n };\n }, [initialUrl]);\n\n // Suppress browser warnings that are expected and acceptable\n useEffect(() => {\n if (process.env.NODE_ENV === 'development') {\n const originalWarn = console.warn;\n console.warn = (...args: unknown[]) => {\n const message = String(args[0] ?? '');\n // Suppress the specific sandbox warning\n if (\n message.includes('allow-scripts') &&\n message.includes('allow-same-origin') &&\n message.includes('sandbox')\n ) {\n return;\n }\n // Suppress \"Layout was forced\" warning from iframe content\n // This is a performance warning that occurs when iframe content calculates layout before stylesheets load\n // It's harmless and common in iframe scenarios, especially with React apps\n if (\n message.includes('Layout was forced') &&\n message.includes('before the page was fully loaded')\n ) {\n return;\n }\n originalWarn.apply(console, args);\n };\n return () => {\n console.warn = originalWarn;\n };\n }\n }, []);\n\n return (\n <div style={{ width: '100%', height: '100%', display: 'flex', position: 'relative' }}>\n {/* Note: allow-same-origin is required for same-origin iframe content (e.g., Vite dev server, cookies, localStorage).\n While this allows the iframe to remove its own sandboxing, it's acceptable here because the iframe content\n is trusted microfrontend content from the same application origin.\n Browser security warnings about this combination cannot be suppressed programmatically. */}\n <iframe\n ref={iframeRef}\n src={initialUrl}\n style={{\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n }}\n title=\"Content Frame\"\n sandbox=\"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox\"\n referrerPolicy=\"no-referrer-when-downgrade\"\n />\n {isLoading && <LoadingOverlay />}\n </div>\n );\n};\n","import { useMemo } from 'react';\nimport { Navigate, useLocation } from 'react-router';\nimport { ContentView } from './ContentView';\nimport type { NavigationItem } from '../features/config/types';\n\ninterface ViewRouteProps {\n navigation: NavigationItem[];\n}\n\nexport const ViewRoute = ({ navigation }: ViewRouteProps) => {\n const location = useLocation();\n const pathname = location.pathname;\n\n const navItem = useMemo(() => {\n return navigation.find((item) => {\n const pathPrefix = `/${item.path}`;\n return pathname === pathPrefix || pathname.startsWith(`${pathPrefix}/`);\n });\n }, [navigation, pathname]);\n\n if (!navItem) {\n return (\n <Navigate\n to=\"/\"\n replace\n />\n );\n }\n // Calculate the relative path from the navItem.path\n // e.g. if item.path is \"docs\" and pathname is \"/docs/intro\", subPath is \"intro\"\n const pathPrefix = `/${navItem.path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n\n // Construct the final URL for the iframe\n let finalUrl = navItem.url;\n if (subPath) {\n const baseUrl = navItem.url.endsWith('/') ? navItem.url : `${navItem.url}/`;\n finalUrl = `${baseUrl}${subPath}`;\n }\n return (\n <ContentView\n url={finalUrl}\n pathPrefix={navItem.path}\n navItem={navItem}\n />\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useConfig } from '@/features/config/useConfig';\nimport type { NavigationItem, NavigationGroup } from '@/features/config/types';\n\nconst flattenNavigationItems = (\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] => {\n if (navigation.length === 0) return [];\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) {\n return (item as NavigationGroup).items;\n }\n return item as NavigationItem;\n });\n};\n\nexport const NotFoundView = () => {\n const { config } = useConfig();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n const navItems =\n config?.navigation && config.navigation.length > 0\n ? flattenNavigationItems(config.navigation)\n .filter((item) => !item.hidden)\n .filter((item, index, self) => index === self.findIndex((i) => i.path === item.path))\n : [];\n\n const handleNavigate = (path: string) => {\n shellui.navigate(path.startsWith('/') ? path : `/${path}`);\n };\n\n return (\n <div className=\"flex flex-col min-h-full\">\n <div className=\"flex-1 flex flex-col items-center justify-center px-6 py-12 text-muted-foreground\">\n <span className=\"text-6xl font-light tracking-tighter text-foreground/80 select-none\">\n 404\n </span>\n <p className=\"mt-3 text-lg text-muted-foreground\">Page not found</p>\n </div>\n\n {navItems.length > 0 && (\n <footer className=\"border-t border-border py-4 px-6 mt-auto bg-muted/30\">\n <nav\n className=\"flex flex-row flex-wrap justify-center items-center gap-x-2 gap-y-1 text-sm text-muted-foreground\"\n aria-label=\"Available pages\"\n >\n {navItems.map((item, index) => (\n <span\n key={item.path}\n className=\"inline-flex items-center gap-x-2\"\n >\n {index > 0 && (\n <span\n className=\"text-border select-none\"\n aria-hidden\n >\n ·\n </span>\n )}\n <button\n type=\"button\"\n onClick={() => handleNavigate(`/${item.path}`)}\n className=\"text-muted-foreground hover:text-foreground hover:underline underline-offset-2 cursor-pointer bg-transparent border-0 p-0 font-normal\"\n >\n {resolveLocalizedString(item.label, currentLanguage)}\n </button>\n </span>\n ))}\n </nav>\n </footer>\n )}\n </div>\n );\n};\n","import { useRouteError, isRouteErrorResponse } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { Button } from '@/components/ui/button';\n\nfunction isChunkLoadError(error: unknown): boolean {\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return (\n msg.includes('loading dynamically imported module') ||\n msg.includes('chunk') ||\n msg.includes('failed to fetch dynamically imported module')\n );\n }\n return false;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (isRouteErrorResponse(error)) {\n return error.data?.message ?? error.statusText ?? 'Something went wrong';\n }\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction getErrorStack(error: unknown): string | null {\n if (error instanceof Error && error.stack) {\n return error.stack;\n }\n return null;\n}\n\nfunction getErrorDetailsText(error: unknown): string {\n const message = getErrorMessage(error);\n const stack = getErrorStack(error);\n if (stack) {\n return `Message:\\n${message}\\n\\nStack:\\n${stack}`;\n }\n return message;\n}\n\nexport function RouteErrorBoundary() {\n const error = useRouteError();\n const { t } = useTranslation('common');\n const isChunkError = isChunkLoadError(error);\n const detailsText = getErrorDetailsText(error);\n\n return (\n <div\n className=\"flex min-h-screen flex-col items-center justify-center bg-background px-4 py-12\"\n style={{ fontFamily: 'var(--heading-font-family, system-ui, sans-serif)' }}\n >\n <div className=\"w-full max-w-md space-y-6 text-center\">\n <div className=\"space-y-2\">\n <h1 className=\"text-xl font-semibold text-foreground\">\n {isChunkError ? t('errorBoundary.titleChunk') : t('errorBoundary.titleGeneric')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {isChunkError\n ? t('errorBoundary.descriptionChunk')\n : t('errorBoundary.descriptionGeneric')}\n </p>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:justify-center\">\n <Button\n variant=\"default\"\n onClick={() => window.location.reload()}\n className=\"shrink-0\"\n >\n {t('errorBoundary.tryAgain')}\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => shellui.navigate('/')}\n className=\"shrink-0\"\n >\n {t('errorBoundary.goToHome')}\n </Button>\n </div>\n\n <details className=\"rounded-lg border border-border bg-muted/30 text-left\">\n <summary className=\"cursor-pointer px-4 py-3 text-xs font-medium text-muted-foreground hover:text-foreground\">\n {t('errorBoundary.errorDetails')}\n </summary>\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-all px-4 pb-3 pt-1 text-xs text-muted-foreground font-mono\">\n {detailsText}\n </pre>\n </details>\n </div>\n </div>\n );\n}\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';\n\n/**\n * Validates and normalizes a URL to ensure it's from the same domain or localhost\n * @param url - The URL or path to validate\n * @returns The normalized absolute URL or null if invalid\n */\nexport const validateAndNormalizeUrl = (url: string | undefined | null): string | null => {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n try {\n // If it's already an absolute URL, check if it's same origin or localhost\n if (url.startsWith('http://') || url.startsWith('https://')) {\n const urlObj = new URL(url);\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n\n // Allow same origin\n if (urlObj.origin === currentOrigin) {\n return url;\n }\n\n // Allow localhost URLs (for development)\n if (urlObj.hostname === 'localhost' || urlObj.hostname === '127.0.0.1') {\n return url;\n }\n\n return null; // Different origin, reject for security\n }\n\n // If it's a relative URL, make it absolute using current origin\n if (url.startsWith('/') || url.startsWith('./') || !url.startsWith('//')) {\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n // Ensure relative paths start with /\n const normalizedPath = url.startsWith('/') ? url : `/${url}`;\n return `${currentOrigin}${normalizedPath}`;\n }\n\n // Reject protocol-relative URLs (//example.com) for security\n return null;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Invalid URL:', url, error);\n return null;\n }\n};\n\ninterface ModalContextValue {\n isOpen: boolean;\n modalUrl: string | null;\n openModal: (url?: string) => void;\n closeModal: () => void;\n}\n\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\n\nexport const useModal = () => {\n const context = useContext(ModalContext);\n if (!context) {\n throw new Error('useModal must be used within a ModalProvider');\n }\n return context;\n};\n\ninterface ModalProviderProps {\n children: ReactNode;\n}\n\nexport const ModalProvider = ({ children }: ModalProviderProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [modalUrl, setModalUrl] = useState<string | null>(null);\n\n const openModal = useCallback((url?: string) => {\n const validatedUrl = url ? validateAndNormalizeUrl(url) : null;\n setModalUrl(validatedUrl);\n setIsOpen(true);\n }, []);\n\n const closeModal = useCallback(() => {\n setIsOpen(false);\n // Clear URL after a short delay to allow animation to complete\n setTimeout(() => setModalUrl(null), 200);\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n const cleanupOpenModal = shellui.addMessageListener(\n 'SHELLUI_OPEN_MODAL',\n (data: ShellUIMessage) => {\n const payload = data.payload as { url?: string };\n openModal(payload.url);\n },\n );\n\n const cleanupCloseModal = shellui.addMessageListener('SHELLUI_CLOSE_MODAL', () => {\n closeModal();\n });\n\n return () => {\n cleanupOpenModal();\n cleanupCloseModal();\n };\n }, [openModal, closeModal]);\n\n return (\n <ModalContext.Provider value={{ isOpen, modalUrl, openModal, closeModal }}>\n {children}\n </ModalContext.Provider>\n );\n};\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';\nimport type { DrawerDirection } from '@/components/ui/drawer';\nimport { useModal } from '../modal/ModalContext';\n\n/**\n * Validates and normalizes a URL for the drawer iframe.\n * Allows same-origin, localhost, and external http(s) URLs (e.g. from nav config).\n */\nconst validateAndNormalizeUrl = (url: string | undefined | null): string | null => {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n try {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n new URL(url); // validate\n return url;\n }\n\n if (url.startsWith('/') || url.startsWith('./') || !url.startsWith('//')) {\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n const normalizedPath = url.startsWith('/') ? url : `/${url}`;\n return `${currentOrigin}${normalizedPath}`;\n }\n\n return null;\n } catch {\n return null;\n }\n};\n\nexport const DEFAULT_DRAWER_POSITION: DrawerDirection = 'right';\n\ninterface OpenDrawerOptions {\n url?: string;\n position?: DrawerDirection;\n /** CSS length: height for top/bottom (e.g. \"80vh\", \"400px\"), width for left/right (e.g. \"50vw\", \"320px\") */\n size?: string;\n}\n\ninterface DrawerContextValue {\n isOpen: boolean;\n drawerUrl: string | null;\n position: DrawerDirection;\n size: string | null;\n openDrawer: (options?: OpenDrawerOptions) => void;\n closeDrawer: () => void;\n}\n\nconst DrawerContext = createContext<DrawerContextValue | undefined>(undefined);\n\nexport const useDrawer = () => {\n const context = useContext(DrawerContext);\n if (!context) {\n throw new Error('useDrawer must be used within a DrawerProvider');\n }\n return context;\n};\n\ninterface DrawerProviderProps {\n children: ReactNode;\n}\n\nexport const DrawerProvider = ({ children }: DrawerProviderProps) => {\n const { closeModal } = useModal();\n const [isOpen, setIsOpen] = useState(false);\n const [drawerUrl, setDrawerUrl] = useState<string | null>(null);\n const [position, setPosition] = useState<DrawerDirection>(DEFAULT_DRAWER_POSITION);\n const [size, setSize] = useState<string | null>(null);\n\n const openDrawer = useCallback(\n (options?: OpenDrawerOptions) => {\n closeModal();\n const url = options?.url;\n const validatedUrl = url ? validateAndNormalizeUrl(url) : null;\n setDrawerUrl(validatedUrl);\n setPosition(options?.position ?? DEFAULT_DRAWER_POSITION);\n setSize(options?.size ?? null);\n setIsOpen(true);\n },\n [closeModal],\n );\n\n const closeDrawer = useCallback(() => {\n setIsOpen(false);\n // Do not reset drawerUrl/position here — Vaul's close animation uses the current\n // direction. Resetting position (e.g. to 'right') mid-animation would make\n // non-right drawers jump. State is set on next openDrawer().\n }, []);\n\n useEffect(() => {\n const cleanupOpen = shellui.addMessageListener(\n 'SHELLUI_OPEN_DRAWER',\n (data: ShellUIMessage) => {\n const payload = data.payload as { url?: string; position?: DrawerDirection; size?: string };\n openDrawer({ url: payload.url, position: payload.position, size: payload.size });\n },\n );\n\n const cleanupClose = shellui.addMessageListener('SHELLUI_CLOSE_DRAWER', () => {\n closeDrawer();\n });\n\n return () => {\n cleanupOpen();\n cleanupClose();\n };\n }, [openDrawer, closeDrawer]);\n\n return (\n <DrawerContext.Provider value={{ isOpen, drawerUrl, position, size, openDrawer, closeDrawer }}>\n {children}\n </DrawerContext.Provider>\n );\n};\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useCallback, useEffect, type ReactNode } from 'react';\nimport { toast as sonnerToast } from 'sonner';\n\ninterface ToastOptions {\n id?: string;\n title?: string;\n description?: string;\n type?: 'default' | 'success' | 'error' | 'warning' | 'info' | 'loading';\n duration?: number;\n position?:\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n action?: {\n label: string;\n onClick: () => void;\n };\n cancel?: {\n label: string;\n onClick: () => void;\n };\n onDismiss?: () => void;\n onAutoClose?: () => void;\n}\n\ninterface SonnerContextValue {\n toast: (options: ToastOptions) => void;\n}\n\nconst SonnerContext = createContext<SonnerContextValue | undefined>(undefined);\n\nexport function useSonner() {\n const context = useContext(SonnerContext);\n if (!context) {\n throw new Error('useSonner must be used within a SonnerProvider');\n }\n return context;\n}\n\ninterface SonnerProviderProps {\n children: ReactNode;\n}\n\nexport const SonnerProvider = ({ children }: SonnerProviderProps) => {\n const toast = useCallback((options: ToastOptions) => {\n const {\n id,\n title,\n description,\n type = 'default',\n duration,\n position,\n action,\n cancel,\n onDismiss,\n onAutoClose,\n } = options;\n\n const toastOptions: Parameters<typeof sonnerToast>[1] = {\n id,\n duration,\n position,\n action: action\n ? {\n label: action.label,\n onClick: action.onClick,\n }\n : undefined,\n cancel: cancel\n ? {\n label: cancel.label,\n onClick: cancel.onClick,\n }\n : undefined,\n onDismiss: onDismiss,\n onAutoClose: onAutoClose,\n };\n\n // If ID is provided, this is an update operation\n if (id) {\n switch (type) {\n case 'success':\n sonnerToast.success(title || 'Success', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'error':\n sonnerToast.error(title || 'Error', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'warning':\n sonnerToast.warning(title || 'Warning', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'info':\n sonnerToast.info(title || 'Info', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'loading':\n sonnerToast.loading(title || 'Loading...', {\n id,\n description,\n ...toastOptions,\n });\n break;\n default:\n sonnerToast(title || 'Notification', {\n id,\n description,\n ...toastOptions,\n });\n break;\n }\n return;\n }\n\n // Create new toast\n switch (type) {\n case 'success':\n sonnerToast.success(title || 'Success', {\n description,\n ...toastOptions,\n });\n break;\n case 'error':\n sonnerToast.error(title || 'Error', {\n description,\n ...toastOptions,\n });\n break;\n case 'warning':\n sonnerToast.warning(title || 'Warning', {\n description,\n ...toastOptions,\n });\n break;\n case 'info':\n sonnerToast.info(title || 'Info', {\n description,\n ...toastOptions,\n });\n break;\n case 'loading':\n sonnerToast.loading(title || 'Loading...', {\n description,\n ...toastOptions,\n });\n break;\n default:\n sonnerToast(title || 'Notification', {\n description,\n ...toastOptions,\n });\n break;\n }\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n const cleanupToast = shellui.addMessageListener('SHELLUI_TOAST', (data: ShellUIMessage) => {\n const payload = data.payload as ToastOptions;\n toast({\n ...payload,\n onDismiss: () => {\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CLEAR',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n onAutoClose: () => {\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CLEAR',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n action:\n payload.action &&\n (() => {\n let actionSent = false;\n return {\n label: payload.action?.label ?? undefined,\n onClick: () => {\n if (actionSent) return;\n actionSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_ACTION',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n cancel:\n payload.cancel &&\n (() => {\n let cancelSent = false;\n return {\n label: payload.cancel?.label ?? undefined,\n onClick: () => {\n if (cancelSent) return;\n cancelSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CANCEL',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n });\n });\n\n const cleanupToastUpdate = shellui.addMessageListener(\n 'SHELLUI_TOAST_UPDATE',\n (data: ShellUIMessage) => {\n const payload = data.payload as ToastOptions;\n // CRITICAL: When updating a toast, we MUST re-register action handlers\n // The callbackRegistry still has the callbacks, but the toast button needs onClick handlers\n // that trigger the callbackRegistry via SHELLUI_TOAST_ACTION messages\n toast({\n ...payload,\n // Re-register action handlers so the button works after update\n // These handlers send messages that trigger the callbackRegistry\n action:\n payload.action &&\n (() => {\n let actionSent = false;\n return {\n label: payload.action?.label ?? undefined,\n onClick: () => {\n if (actionSent) return;\n actionSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_ACTION',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n cancel:\n payload.cancel &&\n (() => {\n let cancelSent = false;\n return {\n label: payload.cancel?.label ?? undefined,\n onClick: () => {\n if (cancelSent) return;\n cancelSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CANCEL',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n });\n },\n );\n\n return () => {\n cleanupToast();\n cleanupToastUpdate();\n };\n }, [toast]);\n\n return <SonnerContext.Provider value={{ toast }}>{children}</SonnerContext.Provider>;\n};\n","import type { ReactNode } from 'react';\nimport { ModalProvider } from '../modal/ModalContext';\nimport { DrawerProvider } from '../drawer/DrawerContext';\nimport { SonnerProvider } from '../sonner/SonnerContext';\n\ninterface LayoutProvidersProps {\n children: ReactNode;\n}\n\n/** Wraps layout content with Modal, Drawer and Sonner providers.\n * Note: DialogProvider is now at the app level in app.tsx */\nexport function LayoutProviders({ children }: LayoutProvidersProps) {\n return (\n <ModalProvider>\n <DrawerProvider>\n <SonnerProvider>{children}</SonnerProvider>\n </DrawerProvider>\n </ModalProvider>\n );\n}\n","import {\n forwardRef,\n useCallback,\n Children,\n type ElementRef,\n type ComponentPropsWithoutRef,\n type ComponentProps,\n type HTMLAttributes,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n data-dialog-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.MODAL_OVERLAY }}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\ninterface DialogContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n /** When true, the default close (X) button is not rendered. Escape and overlay still close. */\n hideCloseButton?: boolean;\n}\n\nconst DialogContent = forwardRef<ElementRef<typeof DialogPrimitive.Content>, DialogContentProps>(\n ({ className, children, onPointerDownOutside, hideCloseButton, ...props }, ref) => {\n const hasContent = Children.count(children) > 2;\n\n const handlePointerDownOutside = useCallback(\n (\n event: Parameters<NonNullable<ComponentProps<typeof DialogPrimitive.Content>['onPointerDownOutside']>>[0],\n ) => {\n const target = event?.target as Element | null;\n if (target?.closest?.('[data-sonner-toaster]')) {\n event.preventDefault();\n }\n onPointerDownOutside?.(event);\n },\n [onPointerDownOutside],\n );\n\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n data-dialog-content\n data-has-content={hasContent}\n className={cn(\n 'fixed left-[50%] top-[50%] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-6 border bg-background px-6 pt-0 pb-0 shadow-lg sm:rounded-lg',\n 'data-[has-content=false]:gap-0 data-[has-content=false]:[&>[data-dialog-header]]:border-b-0 data-[has-content=false]:[&>[data-dialog-header]]:pb-0',\n className,\n )}\n style={{ backgroundColor: 'hsl(var(--background))', zIndex: Z_INDEX.MODAL_CONTENT }}\n onPointerDownOutside={handlePointerDownOutside}\n {...props}\n >\n {children}\n {!hideCloseButton && (\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground cursor-pointer\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n },\n);\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-dialog-header\n className={cn(\n '-mx-6 flex flex-col space-y-2.5 border-b border-border/60 px-6 pt-5 pb-4 text-left',\n className,\n )}\n {...props}\n />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n '-mx-6 mt-4 flex flex-col-reverse gap-2 rounded-b-lg border-t border-border bg-sidebar-background px-6 py-2 text-sidebar-foreground sm:flex-row sm:justify-end sm:space-x-2 [&_button]:h-8 [&_button]:px-3 [&_button]:text-xs',\n className,\n )}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n","'use client';\n\nimport {\n forwardRef,\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ReactNode,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react';\nimport { Drawer as VaulDrawer } from 'vaul';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\nexport type DrawerDirection = 'top' | 'bottom' | 'left' | 'right';\n\nconst Drawer = ({\n open,\n onOpenChange,\n direction = 'right',\n ...props\n}: ComponentProps<typeof VaulDrawer.Root> & {\n direction?: DrawerDirection;\n}) => (\n <VaulDrawer.Root\n open={open}\n onOpenChange={onOpenChange}\n direction={direction}\n {...props}\n />\n);\nDrawer.displayName = 'Drawer';\n\nconst DrawerTrigger = VaulDrawer.Trigger;\nDrawerTrigger.displayName = 'DrawerTrigger';\n\nconst DrawerPortal = VaulDrawer.Portal;\n(DrawerPortal as unknown as { displayName: string }).displayName = 'DrawerPortal';\n\nconst DrawerOverlay = forwardRef<\n ComponentRef<typeof VaulDrawer.Overlay>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Overlay>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Overlay\n ref={ref}\n data-drawer-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.DRAWER_OVERLAY }}\n {...props}\n />\n));\nDrawerOverlay.displayName = VaulDrawer.Overlay.displayName;\n\n/** Base layout classes per direction — max dimension is applied via style so size prop can override. */\nconst drawerContentByDirection: Record<DrawerDirection, string> = {\n bottom: 'fixed inset-x-0 bottom-0 mt-24 flex h-auto flex-col border border-border bg-background',\n top: 'fixed inset-x-0 top-0 mb-24 flex h-auto flex-col border border-border bg-background',\n left: 'fixed inset-y-0 left-0 mr-24 flex h-full w-auto flex-col border border-border bg-background',\n right:\n 'fixed inset-y-0 right-0 ml-24 flex h-full w-auto flex-col border border-border bg-background',\n};\n\ninterface DrawerContentProps extends Omit<\n ComponentPropsWithoutRef<typeof VaulDrawer.Content>,\n 'direction'\n> {\n direction?: DrawerDirection;\n /** CSS length: height for top/bottom (e.g. \"80vh\", \"400px\"), width for left/right (e.g. \"50vw\", \"320px\") */\n size?: string | null;\n className?: string;\n children?: ReactNode;\n style?: CSSProperties;\n}\n\nconst DrawerContent = forwardRef<ComponentRef<typeof VaulDrawer.Content>, DrawerContentProps>(\n ({ className, direction = 'right', size, children, style, ...props }, ref) => {\n const pos: DrawerDirection = direction;\n const isVertical = pos === 'top' || pos === 'bottom';\n // Set dimension via inline style; use both width/height and max so Vaul/defaults don't override.\n const effectiveSize = size?.trim() || (isVertical ? '80vh' : '80vw');\n const sizeStyle = isVertical\n ? { height: effectiveSize, maxHeight: effectiveSize }\n : { width: effectiveSize, maxWidth: effectiveSize };\n return (\n <DrawerPortal>\n <DrawerOverlay />\n <VaulDrawer.Content\n ref={ref}\n data-drawer-content\n className={cn('outline-none', drawerContentByDirection[pos], className)}\n style={{\n backgroundColor: 'hsl(var(--background))',\n zIndex: Z_INDEX.DRAWER_CONTENT,\n ...sizeStyle,\n ...style,\n }}\n {...props}\n >\n {children}\n <VaulDrawer.Close\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground cursor-pointer\"\n aria-label=\"Close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n <span className=\"sr-only\">Close</span>\n </VaulDrawer.Close>\n </VaulDrawer.Content>\n </DrawerPortal>\n );\n },\n);\nDrawerContent.displayName = 'DrawerContent';\n\nconst DrawerClose = VaulDrawer.Close;\nDrawerClose.displayName = 'DrawerClose';\n\nconst DrawerHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-drawer-header\n className={cn(\n 'flex flex-col space-y-2 border-b border-border/60 px-6 pt-5 pb-4 text-left',\n className,\n )}\n {...props}\n />\n);\nDrawerHeader.displayName = 'DrawerHeader';\n\nconst DrawerFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 border-t border-border px-6 py-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n);\nDrawerFooter.displayName = 'DrawerFooter';\n\nconst DrawerTitle = forwardRef<\n ComponentRef<typeof VaulDrawer.Title>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Title>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDrawerTitle.displayName = VaulDrawer.Title.displayName;\n\nconst DrawerDescription = forwardRef<\n ComponentRef<typeof VaulDrawer.Description>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Description>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nDrawerDescription.displayName = VaulDrawer.Description.displayName;\n\nconst DrawerHandle = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-drawer-handle\n className={cn('mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted', className)}\n {...props}\n />\n);\nDrawerHandle.displayName = 'DrawerHandle';\n\nexport {\n Drawer,\n DrawerTrigger,\n DrawerPortal,\n DrawerOverlay,\n DrawerContent,\n DrawerClose,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n DrawerHandle,\n};\n","import type { ComponentProps } from 'react';\nimport { useSettings } from '@/features/settings/hooks/useSettings';\nimport { Toaster as Sonner } from 'sonner';\nimport { Z_INDEX } from '@/lib/z-index';\n\ntype ToasterProps = ComponentProps<typeof Sonner>;\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n const { settings } = useSettings();\n\n return (\n <Sonner\n position=\"top-center\"\n theme={settings.appearance.theme as 'light' | 'dark' | 'system'}\n className=\"toaster group\"\n style={{\n zIndex: Z_INDEX.TOAST,\n // Re-enable pointer events so toasts stay clickable when a Radix modal is open\n // (Radix sets body.style.pointerEvents = 'none' and only the dialog content gets 'auto')\n pointerEvents: 'auto',\n }}\n toastOptions={{\n classNames: {\n toast:\n 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n },\n }}\n {...props}\n />\n );\n};\n\nexport { Toaster };\n","import { useEffect, type ReactNode } from 'react';\nimport { useNavigate } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem } from '../config/types';\nimport { Dialog, DialogContent, DialogTitle, DialogDescription } from '@/components/ui/dialog';\nimport { Drawer, DrawerContent } from '@/components/ui/drawer';\nimport { Toaster } from '@/components/ui/sonner';\nimport { ContentView } from '@/components/ContentView';\nimport { useModal } from '../modal/ModalContext';\nimport { useDrawer } from '../drawer/DrawerContext';\nimport { resolveLocalizedString } from './utils';\n\ninterface OverlayShellProps {\n navigationItems: NavigationItem[];\n children: ReactNode;\n}\n\n/** Renders modal, drawer and toaster overlays and handles SHELLUI_OPEN_MODAL / SHELLUI_NAVIGATE. */\nexport function OverlayShell({ navigationItems, children }: OverlayShellProps) {\n const navigate = useNavigate();\n const { isOpen, modalUrl, closeModal } = useModal();\n const {\n isOpen: isDrawerOpen,\n drawerUrl,\n position: drawerPosition,\n size: drawerSize,\n closeDrawer,\n } = useDrawer();\n const { t, i18n } = useTranslation('common');\n const currentLanguage = i18n.language || 'en';\n\n useEffect(() => {\n const cleanup = shellui.addMessageListener('SHELLUI_OPEN_MODAL', () => {\n closeDrawer();\n });\n return () => cleanup();\n }, [closeDrawer]);\n\n useEffect(() => {\n const cleanup = shellui.addMessageListener('SHELLUI_NAVIGATE', (data) => {\n const payload = data.payload as { url?: string };\n const rawUrl = payload?.url;\n if (typeof rawUrl !== 'string' || !rawUrl.trim()) return;\n\n let pathname: string;\n if (rawUrl.startsWith('http://') || rawUrl.startsWith('https://')) {\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n pathname = rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`;\n }\n } else {\n pathname = rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`;\n }\n\n closeModal();\n closeDrawer();\n\n const isHomepage = pathname === '/' || pathname === '';\n const isAllowed =\n isHomepage ||\n navigationItems.some(\n (item) => pathname === `/${item.path}` || pathname.startsWith(`/${item.path}/`),\n );\n if (isAllowed) {\n navigate(pathname || '/');\n } else {\n shellui.toast({\n type: 'error',\n title: t('navigationError') ?? 'Navigation error',\n description:\n t('navigationNotAllowed') ?? 'This URL is not configured in the app navigation.',\n });\n }\n });\n return () => cleanup();\n }, [navigate, closeModal, closeDrawer, navigationItems, t]);\n\n return (\n <>\n {children}\n <Dialog\n open={isOpen}\n onOpenChange={closeModal}\n >\n <DialogContent className=\"max-w-4xl w-full h-[80vh] max-h-[680px] flex flex-col p-0 overflow-hidden\">\n {modalUrl ? (\n <>\n <DialogTitle className=\"sr-only\">\n {resolveLocalizedString(\n navigationItems.find((item) => item.url === modalUrl)?.label,\n currentLanguage,\n )}\n </DialogTitle>\n <DialogDescription className=\"sr-only\">\n {t('modalContent') ?? 'Modal content'}\n </DialogDescription>\n <div\n className=\"flex-1\"\n style={{ minHeight: 0 }}\n >\n <ContentView\n url={modalUrl}\n pathPrefix=\"settings\"\n ignoreMessages={true}\n navItem={navigationItems.find((item) => item.url === modalUrl) as NavigationItem}\n />\n </div>\n </>\n ) : (\n <>\n <DialogTitle className=\"sr-only\">Error: Modal URL is undefined</DialogTitle>\n <DialogDescription className=\"sr-only\">\n The openModal function was called without a valid URL parameter.\n </DialogDescription>\n <div className=\"flex-1 p-4\">\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-4\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n Error: Modal URL is undefined\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n The <code className=\"text-xs bg-background px-1 py-0.5 rounded\">openModal</code>{' '}\n function was called without a valid URL parameter. Please ensure you provide a\n URL when opening the modal.\n </p>\n </div>\n </div>\n </>\n )}\n </DialogContent>\n </Dialog>\n <Drawer\n open={isDrawerOpen}\n onOpenChange={(open) => !open && closeDrawer()}\n direction={drawerPosition}\n >\n <DrawerContent\n direction={drawerPosition}\n size={drawerSize}\n className=\"p-0 overflow-hidden flex flex-col\"\n >\n {drawerUrl ? (\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <ContentView\n url={drawerUrl}\n pathPrefix=\"settings\"\n ignoreMessages={true}\n navItem={navigationItems.find((item) => item.url === drawerUrl) as NavigationItem}\n />\n </div>\n ) : (\n <div className=\"flex-1 p-4\">\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-4\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n Error: Drawer URL is undefined\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n The <code className=\"text-xs bg-background px-1 py-0.5 rounded\">openDrawer</code>{' '}\n function was called without a valid URL parameter. Please ensure you provide a URL\n when opening the drawer.\n </p>\n </div>\n </div>\n )}\n </DrawerContent>\n </Drawer>\n <Toaster />\n </>\n );\n}\n","import { Link, useLocation, Outlet } from 'react-router';\nimport { useMemo, useEffect, useState, useRef, useLayoutEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n Sidebar,\n SidebarProvider,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\nimport {\n filterNavigationByViewport,\n filterNavigationForSidebar,\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface DefaultLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\n// DuckDuckGo favicon URL for a given page URL (used when openIn === 'external' and no icon is set)\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\nconst NavigationContent = ({\n navigation,\n}: {\n navigation: (NavigationItem | NavigationGroup)[];\n}) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n // Helper function to resolve localized strings\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') {\n return value;\n }\n // Try current language first, then English as fallback\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n // Check if at least one navigation item has an icon\n const hasAnyIcons = useMemo(() => {\n return navigation.some((item) => {\n if ('title' in item && 'items' in item) {\n // It's a group\n return (item as NavigationGroup).items.some((navItem) => !!navItem.icon);\n }\n // It's a standalone item\n return !!(item as NavigationItem).icon;\n });\n }, [navigation]);\n\n // Helper to check if an item is a group\n const isGroup = (item: NavigationItem | NavigationGroup): item is NavigationGroup => {\n return 'title' in item && 'items' in item;\n };\n\n // Render a single nav item link or modal/drawer trigger\n const renderNavItem = (navItem: NavigationItem) => {\n const pathPrefix = `/${navItem.path}`;\n const isOverlay = navItem.openIn === 'modal' || navItem.openIn === 'drawer';\n const isExternal = navItem.openIn === 'external';\n const isActive =\n !isOverlay &&\n !isExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const itemLabel = resolveLocalizedString(navItem.label, currentLanguage);\n const faviconUrl = isExternal && !navItem.icon ? getExternalFaviconUrl(navItem.url) : null;\n const iconSrc = navItem.icon ?? faviconUrl ?? null;\n const iconEl = iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn('h-4 w-4', 'shrink-0')}\n />\n ) : hasAnyIcons ? (\n <span className=\"h-4 w-4 shrink-0\" />\n ) : null;\n const externalIcon = isExternal ? (\n <ExternalLinkIcon className=\"ml-auto h-4 w-4 shrink-0 opacity-70\" />\n ) : null;\n const content = (\n <>\n {iconEl}\n <span className=\"truncate\">{itemLabel}</span>\n {externalIcon}\n </>\n );\n const linkOrTrigger =\n navItem.openIn === 'modal' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(navItem.url)}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'drawer' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: navItem.url, position: navItem.drawerPosition })}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'external' ? (\n <a\n href={navItem.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </a>\n ) : (\n <Link\n to={`/${navItem.path}`}\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </Link>\n );\n return (\n <SidebarMenuButton\n asChild\n isActive={isActive}\n className={cn('w-full', isActive && 'bg-sidebar-accent text-sidebar-accent-foreground')}\n >\n {linkOrTrigger}\n </SidebarMenuButton>\n );\n };\n\n // Render navigation items - handle both groups and standalone items\n return (\n <>\n {navigation.map((item) => {\n if (isGroup(item)) {\n // Render as a group\n const groupTitle = resolveLocalizedString(item.title, currentLanguage);\n return (\n <SidebarGroup\n key={groupTitle}\n className=\"mt-0\"\n >\n <SidebarGroupLabel className=\"mb-1\">{groupTitle}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu className=\"gap-0.5\">\n {item.items.map((navItem) => (\n <SidebarMenuItem key={navItem.path}>{renderNavItem(navItem)}</SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n );\n } else {\n // Render as a standalone item\n return (\n <SidebarMenu\n key={item.path}\n className=\"gap-0.5\"\n >\n <SidebarMenuItem>{renderNavItem(item)}</SidebarMenuItem>\n </SidebarMenu>\n );\n }\n })}\n </>\n );\n};\n\n/** Reusable sidebar inner: header, main nav, footer. Used in desktop Sidebar and mobile Drawer. */\nconst SidebarInner = ({\n title,\n logo,\n startNav,\n endItems,\n}: {\n title?: string;\n logo?: string;\n startNav: (NavigationItem | NavigationGroup)[];\n endItems: (NavigationItem | NavigationGroup)[];\n}) => (\n <>\n <SidebarHeader className=\"border-b border-sidebar-border pb-4\">\n {(title || logo) && (\n <Link\n to=\"/\"\n className=\"flex items-center pl-1 pr-3 py-2 text-lg font-semibold text-sidebar-foreground hover:text-sidebar-foreground/80 transition-colors\"\n >\n {logo && logo.trim() ? (\n <img\n src={logo}\n alt={title || 'Logo'}\n className=\"h-5 w-auto shrink-0 object-contain sidebar-logo\"\n />\n ) : title ? (\n <span className=\"leading-none\">{title}</span>\n ) : null}\n </Link>\n )}\n </SidebarHeader>\n <SidebarContent className=\"gap-1\">\n <NavigationContent navigation={startNav} />\n </SidebarContent>\n {endItems.length > 0 && (\n <SidebarFooter>\n <NavigationContent navigation={endItems} />\n </SidebarFooter>\n )}\n </>\n);\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Approximate width per slot (icon + label + padding) and gap for dynamic slot count. */\nconst BOTTOM_NAV_SLOT_WIDTH = 64;\nconst BOTTOM_NAV_GAP = 4;\nconst BOTTOM_NAV_PX = 12;\n/** Max slots in the row (Home + nav + optional More) to avoid overflow/duplicated wrap. */\nconst BOTTOM_NAV_MAX_SLOTS = 6;\n\n/** True when the icon is a local app icon (/icons/); external images (avatars, favicons) are shown as-is. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\n/** Single nav item for bottom bar: icon + label, link or action. */\nconst BottomNavItem = ({\n item,\n label,\n isActive,\n iconSrc,\n applyIconTheme,\n}: {\n item: NavigationItem;\n label: string;\n isActive: boolean;\n iconSrc: string | null;\n applyIconTheme: boolean;\n}) => {\n const pathPrefix = `/${item.path}`;\n const content = (\n <span className=\"flex flex-col items-center justify-center gap-1 w-full min-w-0 max-w-full overflow-hidden\">\n {iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn(\n 'size-4 shrink-0 rounded-sm object-cover',\n applyIconTheme && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"size-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-[11px] leading-tight truncate w-full min-w-0 text-center block\">\n {label}\n </span>\n </span>\n );\n const baseClass = cn(\n 'flex flex-col items-center justify-center rounded-md py-1.5 px-2 min-w-0 max-w-full transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isActive\n ? 'bg-accent text-accent-foreground [&_span]:text-accent-foreground'\n : 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground [&_span]:inherit',\n );\n if (item.openIn === 'modal') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(item.url)}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'drawer') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: item.url, position: item.drawerPosition })}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'external') {\n return (\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={baseClass}\n >\n {content}\n </a>\n );\n }\n return (\n <Link\n to={pathPrefix}\n className={baseClass}\n >\n {content}\n </Link>\n );\n};\n\n/** Inline SVG: external-link icon. Bundled so consumers don't need to serve static SVGs. */\nconst ExternalLinkIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n);\n\n/** Caret up: expand (show second line). */\nconst CaretUpIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\n/** Caret down: collapse (hide second line). */\nconst CaretDownIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\n/** Home icon for mobile bottom bar (same as sidebar logo action). */\nconst HomeIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <polyline points=\"9 22 9 12 15 12 15 22\" />\n </svg>\n);\n\n/** Mobile bottom nav: Home + nav items; More only when not all fit. Dynamic from width. */\nconst MobileBottomNav = ({\n items,\n currentLanguage,\n}: {\n items: NavigationItem[];\n currentLanguage: string;\n}) => {\n const location = useLocation();\n const [expanded, setExpanded] = useState(false);\n const navRef = useRef<HTMLElement>(null);\n const [rowWidth, setRowWidth] = useState(0);\n\n useLayoutEffect(() => {\n const el = navRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const w = entries[0]?.contentRect.width ?? 0;\n setRowWidth(w);\n });\n ro.observe(el);\n setRowWidth(el.getBoundingClientRect().width);\n return () => ro.disconnect();\n }, []);\n\n const { rowItems, overflowItems, hasMore } = useMemo(() => {\n const list = items.slice();\n const contentWidth = Math.max(0, rowWidth - BOTTOM_NAV_PX * 2);\n const slotTotal = BOTTOM_NAV_SLOT_WIDTH + BOTTOM_NAV_GAP;\n const computedSlots =\n rowWidth > 0 ? Math.floor((contentWidth + BOTTOM_NAV_GAP) / slotTotal) : 5;\n const totalSlots = Math.min(Math.max(0, computedSlots), BOTTOM_NAV_MAX_SLOTS);\n const slotsForNav = totalSlots - 1;\n const allFit = list.length <= slotsForNav;\n const maxInRow = allFit ? list.length : Math.max(0, totalSlots - 2);\n const row = list.slice(0, maxInRow);\n const rowPaths = new Set(row.map((i) => i.path));\n const overflow = list.filter((item) => !rowPaths.has(item.path));\n return {\n rowItems: row,\n overflowItems: overflow,\n hasMore: overflow.length > 0,\n };\n }, [items, rowWidth]);\n\n useEffect(() => {\n setExpanded(false);\n }, [location.pathname]);\n\n const renderItem = (item: NavigationItem, index: number) => {\n const pathPrefix = `/${item.path}`;\n const isOverlayOrExternal =\n item.openIn === 'modal' || item.openIn === 'drawer' || item.openIn === 'external';\n const isActive =\n !isOverlayOrExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const label = resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const iconSrc = item.icon ?? faviconUrl ?? null;\n const applyIconTheme = iconSrc ? isAppIcon(iconSrc) : false;\n return (\n <BottomNavItem\n key={`${item.path}-${item.url}-${index}`}\n item={item}\n label={label}\n isActive={isActive}\n iconSrc={iconSrc}\n applyIconTheme={applyIconTheme}\n />\n );\n };\n\n return (\n <nav\n ref={navRef}\n className=\"fixed bottom-0 left-0 right-0 z-[9999] md:hidden border-t border-sidebar-border bg-sidebar-background overflow-hidden pt-2\"\n style={{\n zIndex: Z_INDEX.SIDEBAR_TRIGGER,\n paddingBottom: 'calc(0.5rem + env(safe-area-inset-bottom, 0px))',\n }}\n >\n {/* Top row: Home + nav items + More/Less — single row, no wrap */}\n <div className=\"flex flex-row flex-nowrap items-center justify-center gap-1 px-3 overflow-x-hidden\">\n <Link\n to=\"/\"\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n location.pathname === '/' || location.pathname === ''\n ? 'bg-sidebar-accent text-sidebar-accent-foreground [&_span]:text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground [&_span]:inherit',\n )}\n aria-label=\"Home\"\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center [&_svg]:text-current\">\n <HomeIcon className=\"size-4\" />\n </span>\n <span className=\"text-[11px] leading-tight\">Home</span>\n </Link>\n {rowItems.map((item, i) => renderItem(item, i))}\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((e) => !e)}\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer',\n 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n )}\n aria-expanded={expanded}\n aria-label={expanded ? 'Show less' : 'Show more'}\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center\">\n {expanded ? <CaretDownIcon className=\"size-4\" /> : <CaretUpIcon className=\"size-4\" />}\n </span>\n <span className=\"text-[11px] leading-tight\">{expanded ? 'Less' : 'More'}</span>\n </button>\n )}\n </div>\n\n {/* Expanded: only overflow items — render list only when expanded so it clears when collapsed */}\n <div\n className={cn(\n 'grid transition-[grid-template-rows] duration-300 ease-out',\n expanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',\n )}\n >\n <div className=\"min-h-0 overflow-hidden\">\n <div className=\"px-4 pt-3 pb-2 border-t border-sidebar-border/50 mt-1\">\n <div className=\"grid grid-cols-5 gap-2 justify-items-center max-w-xs mx-auto\">\n {expanded ? overflowItems.map((item, i) => renderItem(item, i)) : null}\n </div>\n </div>\n </div>\n </div>\n </nav>\n );\n};\n\nconst DefaultLayoutContent = ({ title, logo, navigation }: DefaultLayoutProps) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const { startNav, endItems, navigationItems, mobileNavItems } = useMemo(() => {\n const desktopNav = filterNavigationByViewport(navigation, 'desktop');\n const mobileNav = filterNavigationByViewport(navigation, 'mobile');\n const { start, end } = splitNavigationByPosition(desktopNav);\n const flat = flattenNavigationItems(desktopNav);\n const mobileFlat = flattenNavigationItems(mobileNav);\n return {\n startNav: filterNavigationForSidebar(start),\n endItems: end,\n navigationItems: flat,\n mobileNavItems: mobileFlat,\n };\n }, [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <SidebarProvider>\n <OverlayShell navigationItems={navigationItems}>\n <div className=\"flex h-screen overflow-hidden\">\n {/* Desktop sidebar: visible from md up */}\n <Sidebar className={cn('hidden md:flex shrink-0')}>\n <SidebarInner\n title={title}\n logo={logo}\n startNav={startNav}\n endItems={endItems}\n />\n </Sidebar>\n\n <main className=\"flex-1 flex flex-col overflow-hidden bg-background relative min-w-0\">\n <div className=\"flex-1 flex flex-col overflow-auto pb-16 md:pb-0\">\n <Outlet />\n </div>\n </main>\n </div>\n\n {/* Mobile bottom nav: visible only below md */}\n <MobileBottomNav\n items={mobileNavItems}\n currentLanguage={currentLanguage}\n />\n </OverlayShell>\n </SidebarProvider>\n </LayoutProviders>\n );\n};\n\nexport const DefaultLayout = ({ title, appIcon, logo, navigation }: DefaultLayoutProps) => {\n return (\n <DefaultLayoutContent\n title={title}\n appIcon={appIcon}\n logo={logo}\n navigation={navigation}\n />\n );\n};\n","import { useMemo, useEffect } from 'react';\nimport { Outlet, useLocation } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport { flattenNavigationItems } from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface FullscreenLayoutProps {\n title?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Full-width layout with no sidebar or navigation; only content area. Modal, drawer and providers are still active. */\nexport function FullscreenLayout({ title, navigation }: FullscreenLayoutProps) {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n const navigationItems = useMemo(() => flattenNavigationItems(navigation), [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <main className=\"flex flex-col w-full h-screen overflow-hidden bg-background\">\n <Outlet />\n </main>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n","import {\n useMemo,\n useState,\n useCallback,\n useRef,\n useEffect,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\nimport { ContentView } from '@/components/ContentView';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ninterface WindowsLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\n/** True when the icon is a local app icon (/icons/); apply theme (dark invert) so it matches foreground. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\nconst genId = () => `win-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\nexport interface WindowState {\n id: string;\n path: string;\n pathname: string;\n baseUrl: string;\n label: string;\n icon: string | null;\n bounds: { x: number; y: number; w: number; h: number };\n}\n\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 200;\nconst DEFAULT_WIDTH = 720;\nconst DEFAULT_HEIGHT = 480;\nconst TASKBAR_HEIGHT = 48;\n\nfunction getMaximizedBounds(): WindowState['bounds'] {\n return {\n x: 0,\n y: 0,\n w: typeof window !== 'undefined' ? window.innerWidth : 800,\n h: typeof window !== 'undefined' ? window.innerHeight - TASKBAR_HEIGHT : 600,\n };\n}\n\nfunction buildFinalUrl(baseUrl: string, path: string, pathname: string): string {\n const pathPrefix = `/${path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n if (!subPath) return baseUrl;\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${subPath}`;\n}\n\n/** Single draggable/resizable window */\nfunction AppWindow({\n win,\n navItem,\n currentLanguage,\n isFocused,\n onFocus,\n onClose,\n onBoundsChange,\n maxZIndex,\n zIndex,\n}: {\n win: WindowState;\n navItem: NavigationItem;\n currentLanguage: string;\n isFocused: boolean;\n onFocus: () => void;\n onClose: () => void;\n onBoundsChange: (bounds: WindowState['bounds']) => void;\n maxZIndex: number;\n zIndex: number;\n}) {\n const windowLabel = resolveNavLabel(navItem.label, currentLanguage);\n const [bounds, setBounds] = useState(win.bounds);\n const [isMaximized, setIsMaximized] = useState(false);\n const boundsBeforeMaximizeRef = useRef<WindowState['bounds']>(bounds);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n lastDx: number;\n lastDy: number;\n } | null>(null);\n const resizeRef = useRef<{\n edge: string;\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n } | null>(null);\n const resizeRafRef = useRef<number | null>(null);\n const pendingResizeBoundsRef = useRef<WindowState['bounds'] | null>(null);\n\n useEffect(() => {\n setBounds(win.bounds);\n }, [win.bounds]);\n\n useEffect(() => {\n onBoundsChange(bounds);\n }, [bounds, onBoundsChange]);\n\n // When maximized, keep filling the viewport on window resize\n useEffect(() => {\n if (!isMaximized) return;\n const onResize = () => setBounds(getMaximizedBounds());\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isMaximized]);\n\n const onPointerMove = useCallback((e: PointerEvent) => {\n if (!dragRef.current) return;\n const d = dragRef.current;\n const dx = e.clientX - d.startX;\n const dy = e.clientY - d.startY;\n d.lastDx = dx;\n d.lastDy = dy;\n const el = containerRef.current;\n if (el) {\n el.style.willChange = 'transform';\n el.style.transform = `translate(${dx}px, ${dy}px)`;\n }\n }, []);\n\n const onPointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n if (dragRef.current) {\n const d = dragRef.current;\n if (el) {\n el.style.transform = '';\n el.style.willChange = '';\n }\n const finalBounds: WindowState['bounds'] = {\n ...d.startBounds,\n x: Math.max(0, d.startBounds.x + d.lastDx),\n y: Math.max(0, d.startBounds.y + d.lastDy),\n };\n setBounds(finalBounds);\n dragRef.current = null;\n }\n },\n [onPointerMove],\n );\n\n const handleTitlePointerDown = useCallback(\n (e: ReactPointerEvent) => {\n if (e.button !== 0 || isMaximized) return;\n // Don't start drag when clicking a button (close, maximize) so their click handlers run\n if ((e.target as Element).closest('button')) return;\n e.preventDefault();\n onFocus();\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n lastDx: 0,\n lastDy: 0,\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onPointerMove, { passive: true });\n el.addEventListener('pointerup', onPointerUp as (e: Event) => void);\n }\n },\n [bounds, isMaximized, onFocus, onPointerMove, onPointerUp],\n );\n\n const handleMaximizeToggle = useCallback(() => {\n if (isMaximized) {\n setBounds(boundsBeforeMaximizeRef.current);\n setIsMaximized(false);\n } else {\n boundsBeforeMaximizeRef.current = { ...bounds };\n setBounds(getMaximizedBounds());\n setIsMaximized(true);\n }\n }, [isMaximized, bounds]);\n\n const onResizePointerMove = useCallback((e: PointerEvent) => {\n if (!resizeRef.current) return;\n const { edge, startX, startY, startBounds } = resizeRef.current;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n const next: WindowState['bounds'] = { ...startBounds };\n if (edge.includes('e')) next.w = Math.max(MIN_WIDTH, startBounds.w + dx);\n if (edge.includes('w')) {\n const newW = Math.max(MIN_WIDTH, startBounds.w - dx);\n next.x = startBounds.x + startBounds.w - newW;\n next.w = newW;\n }\n if (edge.includes('s')) next.h = Math.max(MIN_HEIGHT, startBounds.h + dy);\n if (edge.includes('n')) {\n const newH = Math.max(MIN_HEIGHT, startBounds.h - dy);\n next.y = startBounds.y + startBounds.h - newH;\n next.h = newH;\n }\n pendingResizeBoundsRef.current = next;\n if (resizeRafRef.current === null) {\n resizeRafRef.current = requestAnimationFrame(() => {\n const pending = pendingResizeBoundsRef.current;\n resizeRafRef.current = null;\n pendingResizeBoundsRef.current = null;\n if (pending) setBounds(pending);\n });\n }\n }, []);\n\n const onResizePointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onResizePointerMove as (e: Event) => void);\n el.removeEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n resizeRef.current = null;\n },\n [onResizePointerMove],\n );\n\n const handleResizePointerDown = useCallback(\n (e: ReactPointerEvent, edge: string) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n onFocus();\n resizeRef.current = {\n edge,\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onResizePointerMove as (e: Event) => void, {\n passive: true,\n });\n el.addEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n }\n },\n [bounds, onFocus, onResizePointerMove, onResizePointerUp],\n );\n\n const finalUrl = useMemo(\n () => buildFinalUrl(win.baseUrl, win.path, win.pathname),\n [win.baseUrl, win.path, win.pathname],\n );\n\n const z = isFocused ? maxZIndex : zIndex;\n\n return (\n <div\n ref={containerRef}\n className=\"absolute flex flex-col rounded-lg border border-border bg-card shadow-lg overflow-hidden\"\n style={{\n left: bounds.x,\n top: bounds.y,\n width: bounds.w,\n height: bounds.h,\n zIndex: z,\n }}\n onClick={onFocus}\n onMouseDown={onFocus}\n >\n {/* Title bar: pointer capture so drag continues when cursor is over iframe or outside window */}\n <div\n className=\"flex items-center gap-2 pl-2 pr-1 py-1 bg-muted/80 border-b border-border cursor-move select-none shrink-0\"\n onPointerDown={handleTitlePointerDown}\n >\n {win.icon && (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n )}\n <span className=\"flex-1 text-sm font-medium truncate min-w-0\">{windowLabel}</span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleMaximizeToggle();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label={isMaximized ? 'Restore' : 'Maximize'}\n >\n {isMaximized ? <RestoreIcon className=\"h-4 w-4\" /> : <MaximizeIcon className=\"h-4 w-4\" />}\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-destructive/20 hover:text-destructive transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label=\"Close\"\n >\n <CloseIcon className=\"h-4 w-4\" />\n </button>\n </div>\n {/* Content */}\n <div className=\"flex-1 min-h-0 relative bg-background\">\n {/* When not focused, overlay captures clicks to bring window to front */}\n {!isFocused && (\n <div\n className=\"absolute inset-0 z-10 cursor-pointer\"\n onClick={onFocus}\n onMouseDown={(e) => {\n e.stopPropagation();\n onFocus();\n }}\n aria-hidden\n />\n )}\n <ContentView\n url={finalUrl}\n pathPrefix={win.path}\n ignoreMessages={true}\n navItem={navItem}\n />\n </div>\n {/* Resize handles (hidden when maximized) */}\n {!isMaximized &&\n (['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as const).map((edge) => (\n <div\n key={edge}\n className={cn(\n 'absolute bg-transparent',\n edge.includes('n') && 'top-0 h-2 cursor-n-resize',\n edge.includes('s') && 'bottom-0 h-2 cursor-s-resize',\n edge.includes('e') && 'right-0 w-2 cursor-e-resize',\n edge.includes('w') && 'left-0 w-2 cursor-w-resize',\n edge === 'n' && 'left-2 right-2',\n edge === 's' && 'left-2 right-2',\n edge === 'e' && 'top-2 bottom-2',\n edge === 'w' && 'top-2 bottom-2',\n edge === 'ne' && 'top-0 right-0 w-2 h-2 cursor-ne-resize',\n edge === 'nw' && 'top-0 left-0 w-2 h-2 cursor-nw-resize',\n edge === 'se' && 'bottom-0 right-0 w-2 h-2 cursor-se-resize',\n edge === 'sw' && 'bottom-0 left-0 w-2 h-2 cursor-sw-resize',\n )}\n style={\n edge === 'n'\n ? { left: 8, right: 8 }\n : edge === 's'\n ? { left: 8, right: 8 }\n : edge === 'e'\n ? { top: 8, bottom: 8 }\n : edge === 'w'\n ? { top: 8, bottom: 8 }\n : undefined\n }\n onPointerDown={(e) => handleResizePointerDown(e, edge)}\n />\n ))}\n </div>\n );\n}\n\nfunction MaximizeIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nfunction RestoreIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n <rect\n x=\"11\"\n y=\"11\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n </svg>\n );\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/** Start menu icon (Windows-style) */\nfunction StartIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className={className}\n aria-hidden\n >\n <path d=\"M3 3h8v8H3V3zm10 0h8v8h-8V3zM3 13h8v8H3v-8zm10 0h8v8h-8v-8z\" />\n </svg>\n );\n}\n\nfunction getBrowserTimezone(): string {\n if (typeof window !== 'undefined' && Intl.DateTimeFormat) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n}\n\nexport function WindowsLayout({\n title,\n appIcon: _appIcon,\n logo: _logo,\n navigation,\n}: WindowsLayoutProps) {\n const { i18n } = useTranslation();\n const { settings } = useSettings();\n const currentLanguage = i18n.language || 'en';\n const timeZone = settings.region?.timezone ?? getBrowserTimezone();\n const { startNavItems, endNavItems, navigationItems } = useMemo(() => {\n const { start, end } = splitNavigationByPosition(navigation);\n return {\n startNavItems: flattenNavigationItems(start),\n endNavItems: end,\n navigationItems: flattenNavigationItems(navigation),\n };\n }, [navigation]);\n\n const [windows, setWindows] = useState<WindowState[]>([]);\n /** Id of the window that is on top (first plan). Clicking a window or its taskbar button sets this. */\n const [frontWindowId, setFrontWindowId] = useState<string | null>(null);\n const [startMenuOpen, setStartMenuOpen] = useState(false);\n const [now, setNow] = useState(() => new Date());\n const startPanelRef = useRef<HTMLDivElement>(null);\n\n // Update date/time every second for taskbar clock\n useEffect(() => {\n const interval = setInterval(() => setNow(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n /** Highest z-index: front window always gets this so it stays on top. */\n const maxZIndex = useMemo(\n () => Z_INDEX.WINDOWS_WINDOW_BASE + Math.max(windows.length, 1),\n [windows.length],\n );\n\n const openWindow = useCallback(\n (item: NavigationItem) => {\n const label =\n typeof item.label === 'string' ? item.label : resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const icon = item.icon ?? faviconUrl ?? null;\n const id = genId();\n const bounds = {\n x: 60 + windows.length * 24,\n y: 60 + windows.length * 24,\n w: DEFAULT_WIDTH,\n h: DEFAULT_HEIGHT,\n };\n setWindows((prev) => [\n ...prev,\n {\n id,\n path: item.path,\n pathname: `/${item.path}`,\n baseUrl: item.url,\n label,\n icon,\n bounds,\n },\n ]);\n setFrontWindowId(id);\n setStartMenuOpen(false);\n },\n [currentLanguage, windows.length],\n );\n\n const closeWindow = useCallback((id: string) => {\n setWindows((prev) => prev.filter((w) => w.id !== id));\n setFrontWindowId((current) => (current === id ? null : current));\n }, []);\n\n // When front window is closed or missing, bring first window to front\n useEffect(() => {\n if (windows.length === 0) {\n setFrontWindowId(null);\n return;\n }\n const frontStillExists = frontWindowId !== null && windows.some((w) => w.id === frontWindowId);\n if (!frontStillExists) {\n setFrontWindowId(windows[0].id);\n }\n }, [windows, frontWindowId]);\n\n /** Bring the window to front (first plan). Used when clicking the window or its taskbar button. */\n const focusWindow = useCallback((id: string) => {\n setFrontWindowId(id);\n }, []);\n\n const updateWindowBounds = useCallback((id: string, bounds: WindowState['bounds']) => {\n setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, bounds } : w)));\n }, []);\n\n // Close start menu on click outside\n useEffect(() => {\n if (!startMenuOpen) return;\n const onDocClick = (e: MouseEvent) => {\n if (startPanelRef.current && !startPanelRef.current.contains(e.target as Node)) {\n setStartMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDocClick);\n return () => document.removeEventListener('mousedown', onDocClick);\n }, [startMenuOpen]);\n\n const handleNavClick = useCallback(\n (item: NavigationItem) => {\n if (item.openIn === 'modal') {\n shellui.openModal(item.url);\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'drawer') {\n shellui.openDrawer({ url: item.url, position: item.drawerPosition });\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'external') {\n window.open(item.url, '_blank', 'noopener,noreferrer');\n setStartMenuOpen(false);\n return;\n }\n openWindow(item);\n },\n [openWindow],\n );\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <div\n className=\"fixed inset-0 bg-muted/30\"\n style={{ paddingBottom: TASKBAR_HEIGHT }}\n >\n {/* Desktop area: windows */}\n {windows.map((win, index) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n if (!navItem) return null;\n const isFocused = win.id === frontWindowId;\n const zIndex = Z_INDEX.WINDOWS_WINDOW_BASE + index;\n return (\n <AppWindow\n key={win.id}\n win={win}\n navItem={navItem}\n currentLanguage={currentLanguage}\n isFocused={isFocused}\n onFocus={() => focusWindow(win.id)}\n onClose={() => closeWindow(win.id)}\n onBoundsChange={(bounds) => updateWindowBounds(win.id, bounds)}\n maxZIndex={maxZIndex}\n zIndex={zIndex}\n />\n );\n })}\n </div>\n\n {/* Taskbar */}\n <div\n className=\"fixed left-0 right-0 bottom-0 flex items-center gap-1 px-2 border-t border-border bg-sidebar-background\"\n style={{\n height: TASKBAR_HEIGHT,\n zIndex: Z_INDEX.WINDOWS_TASKBAR,\n paddingBottom: 'env(safe-area-inset-bottom, 0px)',\n }}\n >\n {/* Start button */}\n <div\n className=\"relative shrink-0\"\n ref={startPanelRef}\n >\n <button\n type=\"button\"\n onClick={() => setStartMenuOpen((o) => !o)}\n className={cn(\n 'flex items-center gap-2 h-9 px-3 rounded cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n startMenuOpen\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n aria-expanded={startMenuOpen}\n aria-haspopup=\"true\"\n aria-label=\"Start\"\n >\n <StartIcon className=\"h-5 w-5\" />\n <span className=\"font-semibold text-sm hidden sm:inline\">{title || 'Start'}</span>\n </button>\n {/* Start menu panel */}\n {startMenuOpen && (\n <div\n className=\"absolute bottom-full left-0 mb-1 w-64 max-h-[70vh] overflow-y-auto rounded-lg border border-border bg-popover shadow-lg py-2 z-[10001]\"\n style={{ zIndex: Z_INDEX.MODAL_CONTENT }}\n >\n <div className=\"px-2 pb-2 border-b border-border mb-2\">\n <span className=\"text-sm font-semibold text-popover-foreground\">\n {title || 'Applications'}\n </span>\n </div>\n <div className=\"grid gap-0.5\">\n {startNavItems\n .filter((item) => !item.hidden)\n .map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-3 w-full px-3 py-2 text-left text-sm cursor-pointer text-popover-foreground hover:bg-accent hover:text-accent-foreground rounded-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-5 w-5 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-5 w-5 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"truncate\">{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n\n {/* Window list */}\n <div className=\"flex-1 flex items-center gap-1 min-w-0 overflow-x-auto\">\n {windows.map((win) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n const windowLabel = navItem\n ? resolveNavLabel(navItem.label, currentLanguage)\n : win.label;\n const isFocused = win.id === frontWindowId;\n return (\n <button\n key={win.id}\n type=\"button\"\n onClick={() => focusWindow(win.id)}\n onContextMenu={(e) => {\n e.preventDefault();\n closeWindow(win.id);\n }}\n className={cn(\n 'flex items-center gap-2 h-8 px-2 rounded min-w-0 max-w-[140px] shrink-0 cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isFocused\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n title={windowLabel}\n >\n {win.icon ? (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate\">{windowLabel}</span>\n </button>\n );\n })}\n </div>\n\n {/* End navigation items (right side of taskbar) */}\n {endNavItems.length > 0 && (\n <div className=\"flex items-center gap-0.5 shrink-0 border-l border-sidebar-border pl-2 ml-1\">\n {endNavItems.map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-2 h-8 px-2 rounded cursor-pointer text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n title={label}\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate max-w-[100px]\">{label}</span>\n </button>\n );\n })}\n </div>\n )}\n\n {/* Date and time (extreme bottom right, OS-style); uses region timezone from settings */}\n <div\n className=\"flex flex-col items-end justify-center shrink-0 px-3 py-1 text-sidebar-foreground border-l border-sidebar-border ml-1 min-w-0\"\n style={{ paddingRight: 'max(0.75rem, env(safe-area-inset-right))' }}\n role=\"timer\"\n aria-live=\"off\"\n aria-label={new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n dateStyle: 'full',\n timeStyle: 'medium',\n }).format(now)}\n >\n <time\n dateTime={now.toISOString()}\n className=\"text-xs leading-tight tabular-nums whitespace-nowrap\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n }).format(now)}\n </time>\n <time\n dateTime={now.toISOString()}\n className=\"text-[10px] leading-tight whitespace-nowrap text-sidebar-foreground/90\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n }).format(now)}\n </time>\n </div>\n </div>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n","import { lazy, Suspense, type LazyExoticComponent, type ComponentType } from 'react';\nimport type { LayoutType, NavigationItem, NavigationGroup } from '../config/types';\nimport { useSettings } from '../settings/SettingsContext';\n\nconst DefaultLayout = lazy(() =>\n import('./DefaultLayout').then((m) => ({ default: m.DefaultLayout })),\n);\nconst FullscreenLayout = lazy(() =>\n import('./FullscreenLayout').then((m) => ({ default: m.FullscreenLayout })),\n);\nconst WindowsLayout = lazy(() =>\n import('./WindowsLayout').then((m) => ({ default: m.WindowsLayout })),\n);\n\ninterface AppLayoutProps {\n layout?: LayoutType;\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nfunction LayoutFallback() {\n return (\n <div\n className=\"min-h-screen bg-background\"\n aria-hidden\n />\n );\n}\n\n/** Renders the layout based on settings.layout (override) or config.layout: 'sidebar' (default), 'fullscreen', or 'windows'. Lazy-loads only the active layout. */\nexport function AppLayout({\n layout = 'sidebar',\n title,\n appIcon,\n logo,\n navigation,\n}: AppLayoutProps) {\n const { settings } = useSettings();\n const effectiveLayout: LayoutType = settings.layout ?? layout;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LayoutComponent: LazyExoticComponent<ComponentType<any>>;\n let layoutProps: Record<string, unknown>;\n\n if (effectiveLayout === 'fullscreen') {\n LayoutComponent = FullscreenLayout;\n layoutProps = { title, navigation };\n } else if (effectiveLayout === 'windows') {\n LayoutComponent = WindowsLayout;\n layoutProps = { title, appIcon, logo, navigation };\n } else {\n LayoutComponent = DefaultLayout;\n layoutProps = { title, appIcon, logo, navigation };\n }\n\n return (\n <Suspense fallback={<LayoutFallback />}>\n <LayoutComponent {...layoutProps} />\n </Suspense>\n );\n}\n","import { lazy, Suspense } from 'react';\nimport { Outlet, type RouteObject } from 'react-router';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { RouteErrorBoundary } from '../components/RouteErrorBoundary';\nimport { AppLayout } from '../features/layouts/AppLayout';\nimport { flattenNavigationItems } from '../features/layouts/utils';\nimport urls from '../constants/urls';\n\n// Lazy load route components\nconst HomeView = lazy(() =>\n import('../components/HomeView').then((m) => ({ default: m.HomeView })),\n);\nconst SettingsView = lazy(() =>\n import('../features/settings/SettingsView').then((m) => ({ default: m.SettingsView })),\n);\nconst CookiePreferencesView = lazy(() =>\n import('../features/cookieConsent/CookiePreferencesView').then((m) => ({\n default: m.CookiePreferencesView,\n })),\n);\nconst ViewRoute = lazy(() =>\n import('../components/ViewRoute').then((m) => ({ default: m.ViewRoute })),\n);\nconst NotFoundView = lazy(() =>\n import('../components/NotFoundView').then((m) => ({ default: m.NotFoundView })),\n);\n\nfunction RouteFallback() {\n return (\n <div\n className=\"min-h-screen bg-background\"\n aria-hidden\n />\n );\n}\n\nexport const createRoutes = (config: ShellUIConfig): RouteObject[] => {\n const routes: RouteObject[] = [\n {\n path: '/',\n element: <Outlet />,\n errorElement: <RouteErrorBoundary />,\n children: [\n {\n // Settings route (if configured)\n path: `${urls.settings.replace(/^\\//, '')}/*`,\n element: (\n <Suspense fallback={<RouteFallback />}>\n <SettingsView />\n </Suspense>\n ),\n },\n {\n // Cookie preferences route\n path: urls.cookiePreferences.replace(/^\\//, ''),\n element: (\n <Suspense fallback={<RouteFallback />}>\n <CookiePreferencesView />\n </Suspense>\n ),\n },\n {\n // Catch-all route\n path: '*',\n element: (\n <Suspense fallback={<RouteFallback />}>\n <NotFoundView />\n </Suspense>\n ),\n },\n ],\n },\n ];\n\n // Main layout route with nested routes\n const layoutRoute: RouteObject = {\n element: (\n <AppLayout\n layout={config.layout}\n title={config.title}\n appIcon={config.appIcon}\n logo={config.logo}\n navigation={config.navigation || []}\n />\n ),\n children: [\n {\n path: '/',\n element: (\n <Suspense fallback={<RouteFallback />}>\n <HomeView />\n </Suspense>\n ),\n },\n ],\n };\n\n // Add navigation routes\n if (config.navigation && config.navigation.length > 0) {\n const navigationItems = flattenNavigationItems(config.navigation);\n navigationItems.forEach((item) => {\n (layoutRoute.children as RouteObject[]).push({\n path: `/${item.path}/*`,\n element: (\n <Suspense fallback={<RouteFallback />}>\n <ViewRoute navigation={navigationItems} />\n </Suspense>\n ),\n });\n });\n }\n (routes[0].children as RouteObject[]).push(layoutRoute);\n\n return routes;\n};\n","import { createBrowserRouter } from 'react-router';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { createRoutes } from './routes';\n\nexport const createAppRouter = (config: ShellUIConfig) => {\n const routes = createRoutes(config);\n return createBrowserRouter(routes);\n};\n","import { useRef, useState, useEffect, useCallback, useMemo, type ReactNode } from 'react';\nimport {\n getLogger,\n shellui,\n type ShellUIMessage,\n type Settings,\n type SettingsNavigationItem,\n} from '@shellui/sdk';\nimport { SettingsContext } from './SettingsContext';\nimport { useConfig } from '../config/useConfig';\nimport { useTranslation } from 'react-i18next';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\n\nconst logger = getLogger('shellcore');\n\nfunction flattenNavigationItems(\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] {\n if (navigation.length === 0) return [];\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) return (item as NavigationGroup).items;\n return [item as NavigationItem];\n });\n}\n\nfunction resolveLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\nfunction buildSettingsWithNavigation(\n settings: Settings,\n navigation: (NavigationItem | NavigationGroup)[] | undefined,\n lang: string,\n): Settings {\n if (!navigation?.length) return settings;\n const items: SettingsNavigationItem[] = flattenNavigationItems(navigation).map((item) => ({\n path: item.path,\n url: item.url,\n label: resolveLabel(item.label, lang),\n }));\n return { ...settings, navigation: { items } };\n}\n\nconst STORAGE_KEY = 'shellui:settings';\n\n// Get browser's timezone as default\nconst getBrowserTimezone = (): string => {\n if (typeof window !== 'undefined' && Intl) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n};\n\nconst defaultSettings: Settings = {\n developerFeatures: {\n enabled: false,\n },\n errorReporting: {\n enabled: true,\n },\n logging: {\n namespaces: {\n shellsdk: false,\n shellcore: false,\n },\n },\n appearance: {\n theme: 'system',\n themeName: 'default',\n },\n language: {\n code: 'en',\n },\n region: {\n timezone: getBrowserTimezone(),\n },\n cookieConsent: {\n acceptedHosts: [],\n consentedCookieHosts: [],\n },\n serviceWorker: {\n enabled: true,\n },\n};\n\nexport function SettingsProvider({ children }: { children: ReactNode }) {\n const { config } = useConfig();\n const { i18n } = useTranslation();\n // Use a ref to always have current settings for message listeners (avoids closure issues)\n const settingsRef = useRef<Settings | null>(null);\n const [settings, setSettings] = useState<Settings>(() => {\n let initialSettings: Settings;\n\n if (shellui.initialSettings) {\n initialSettings = shellui.initialSettings;\n settingsRef.current = initialSettings;\n return initialSettings;\n }\n\n // Initialize from localStorage\n if (typeof window !== 'undefined') {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const parsed = JSON.parse(stored);\n // Deep merge with defaults to handle new settings\n initialSettings = {\n ...defaultSettings,\n ...parsed,\n errorReporting: {\n enabled: parsed.errorReporting?.enabled ?? defaultSettings.errorReporting.enabled,\n },\n logging: {\n namespaces: {\n ...defaultSettings.logging.namespaces,\n ...parsed.logging?.namespaces,\n },\n },\n appearance: {\n theme: parsed.appearance?.theme || defaultSettings.appearance.theme,\n themeName: parsed.appearance?.themeName || defaultSettings.appearance.themeName,\n },\n language: {\n code: parsed.language?.code || defaultSettings.language.code,\n },\n region: {\n // Only use stored timezone if it exists, otherwise use browser's current timezone\n timezone: parsed.region?.timezone || getBrowserTimezone(),\n },\n cookieConsent: {\n acceptedHosts: Array.isArray(parsed.cookieConsent?.acceptedHosts)\n ? parsed.cookieConsent.acceptedHosts\n : (defaultSettings.cookieConsent?.acceptedHosts ?? []),\n consentedCookieHosts: Array.isArray(parsed.cookieConsent?.consentedCookieHosts)\n ? parsed.cookieConsent.consentedCookieHosts\n : (defaultSettings.cookieConsent?.consentedCookieHosts ?? []),\n },\n serviceWorker: {\n // Migrate from legacy \"caching\" key if present\n enabled: parsed.serviceWorker?.enabled ?? parsed.caching?.enabled ?? true,\n },\n };\n settingsRef.current = initialSettings;\n return initialSettings;\n }\n } catch (error) {\n logger.error('Failed to load settings from localStorage:', { error });\n }\n }\n settingsRef.current = defaultSettings;\n return defaultSettings;\n });\n\n // Keep ref in sync with state for message listeners\n useEffect(() => {\n settingsRef.current = settings;\n }, [settings]);\n\n // Listen for settings updates from parent/other nodes\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_SETTINGS_UPDATED',\n (message: ShellUIMessage) => {\n const payload = message.payload as { settings: Settings };\n const newSettings = payload.settings;\n if (newSettings) {\n // Update localStorage with new settings value\n setSettings(newSettings);\n if (window.parent === window) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n // Confirm: root updated localStorage; re-inject navigation when propagating\n const settingsToPropagate = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n logger.info('Root Parent received settings update', { message });\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsToPropagate },\n });\n } catch (error) {\n logger.error('Failed to update settings from message:', { error });\n }\n }\n }\n },\n );\n\n const cleanupSettingsRequested = shellui.addMessageListener(\n 'SHELLUI_SETTINGS_REQUESTED',\n () => {\n // Use ref to always get current settings (avoids stale closure)\n const currentSettings = settingsRef.current ?? defaultSettings;\n const settingsWithNav = buildSettingsWithNavigation(\n currentSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsWithNav },\n });\n },\n );\n\n const cleanupSettings = shellui.addMessageListener(\n 'SHELLUI_SETTINGS',\n (data: ShellUIMessage) => {\n const message = data as ShellUIMessage;\n const payload = message.payload as { settings: Settings };\n const newSettings = payload.settings;\n if (newSettings) {\n setSettings(newSettings);\n }\n },\n );\n\n return () => {\n cleanup();\n cleanupSettings();\n cleanupSettingsRequested();\n };\n }, [settings, config?.navigation, i18n.language]);\n\n // ACTIONS\n const updateSettings = useCallback(\n (updates: Partial<Settings>) => {\n const newSettings = { ...settings, ...updates };\n\n // Update localStorage and propagate to children if we're in the root window\n if (typeof window !== 'undefined' && window.parent === window) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n setSettings(newSettings);\n // Propagate to child iframes (sendMessageToParent does nothing in root)\n const settingsWithNav = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsWithNav },\n });\n } catch (error) {\n logger.error('Failed to update settings in localStorage:', { error });\n }\n }\n\n // For child iframes, send to parent (parent will propagate to siblings)\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings: newSettings },\n });\n },\n [settings, config?.navigation, i18n.language],\n );\n\n const updateSetting = useCallback(\n <K extends keyof Settings>(key: K, updates: Partial<Settings[K]>) => {\n // Deep merge: preserve existing nested properties\n const currentValue = settings[key];\n const mergedValue =\n typeof currentValue === 'object' && currentValue !== null && !Array.isArray(currentValue)\n ? { ...currentValue, ...updates }\n : updates;\n updateSettings({ [key]: mergedValue } as Partial<Settings>);\n },\n [settings, updateSettings],\n );\n\n const resetAllData = useCallback(() => {\n // Clear all localStorage data\n if (typeof window !== 'undefined') {\n try {\n // Clear settings\n localStorage.removeItem(STORAGE_KEY);\n\n // Clear all other localStorage items that start with shellui:\n const keysToRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith('shellui:')) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach((key) => localStorage.removeItem(key));\n\n // Reset settings to defaults\n const newSettings = defaultSettings;\n setSettings(newSettings);\n\n // If we're in the root window, update localStorage with defaults\n if (window.parent === window) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n const settingsToPropagate = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsToPropagate },\n });\n }\n\n // Notify parent about reset\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings: newSettings },\n });\n\n logger.info('All app data has been reset');\n } catch (error) {\n logger.error('Failed to reset all data:', { error });\n }\n }\n }, [config?.navigation, i18n.language]);\n\n const value = useMemo(\n () => ({\n settings,\n updateSettings,\n updateSetting,\n resetAllData,\n }),\n [settings, updateSettings, updateSetting, resetAllData],\n );\n\n return <SettingsContext.Provider value={value}>{children}</SettingsContext.Provider>;\n}\n","/* eslint-disable no-console */\nimport { useLayoutEffect } from 'react';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { useConfig } from '../config/useConfig';\nimport { getTheme, registerTheme, applyTheme, type ThemeDefinition } from './themes';\n\n/**\n * Apply theme to document element\n */\nfunction applyThemeToDocument(isDark: boolean) {\n const root = document.documentElement;\n if (isDark) {\n root.classList.add('dark');\n } else {\n root.classList.remove('dark');\n }\n}\n\n/**\n * Hook to apply theme based on settings\n * Applies 'dark' class to document.documentElement based on:\n * - 'light': removes dark class\n * - 'dark': adds dark class\n * - 'system': follows prefers-color-scheme media query\n * Also applies theme colors based on themeName setting\n */\nexport function useTheme() {\n const { settings } = useSettings();\n const { config } = useConfig();\n const theme = settings.appearance?.theme || 'system';\n const themeName = settings.appearance?.themeName || 'default';\n\n // Apply theme immediately on mount (synchronously) to prevent empty colors\n // This ensures CSS variables are set before first render\n useLayoutEffect(() => {\n // Get the effective theme name (from settings or config)\n // Use themeName from settings first, then config defaultTheme, then 'default'\n const effectiveThemeName = themeName || config?.defaultTheme || 'default';\n\n if (config?.themes) {\n config.themes.forEach((themeDef: ThemeDefinition) => {\n registerTheme(themeDef);\n });\n }\n\n const themeDefinition = getTheme(effectiveThemeName) || getTheme('default');\n\n if (themeDefinition) {\n const determineIsDark = () => {\n if (theme === 'system') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n return mediaQuery.matches;\n }\n return theme === 'dark';\n };\n const isDark = determineIsDark();\n applyThemeToDocument(isDark);\n applyTheme(themeDefinition, isDark);\n } else {\n console.error('[Theme] No theme definition found, using fallback');\n // Fallback: at least set primary color from default theme\n const defaultTheme = getTheme('default');\n if (defaultTheme) {\n const isDark =\n theme === 'dark' ||\n (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);\n applyTheme(defaultTheme, isDark);\n }\n }\n }, [theme, themeName, config]); // Run when theme, themeName, or config changes\n}\n","import type { ReactNode } from 'react';\nimport { useTheme } from './useTheme';\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n}\n\n/**\n * Provider that applies theme (light/dark/system and theme colors) from settings.\n * Must be rendered inside SettingsProvider so useTheme can read appearance settings.\n * Applies theme to document.documentElement and listens to system preference changes.\n */\nexport function ThemeProvider({ children }: ThemeProviderProps) {\n useTheme();\n return <>{children}</>;\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useSettings } from '../features/settings/hooks/useSettings';\nimport i18n, { initializeI18n } from './config';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { useConfig } from '../features/config/useConfig';\n\ninterface I18nProviderProps {\n children: ReactNode;\n config?: ShellUIConfig;\n}\n\nexport function I18nProvider({ children }: I18nProviderProps) {\n const { settings } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n\n // Initialize i18n with enabled languages from config\n useEffect(() => {\n if (config?.language) {\n initializeI18n(config.language);\n }\n }, [config?.language]);\n\n // Sync i18n language with settings changes\n useEffect(() => {\n if (i18n.language !== currentLanguage) {\n i18n.changeLanguage(currentLanguage);\n }\n }, [currentLanguage]);\n\n return <>{children}</>;\n}\n","import {\n forwardRef,\n type ElementRef,\n type ComponentPropsWithoutRef,\n type HTMLAttributes,\n} from 'react';\nimport * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\nimport { Button, type ButtonProps } from '@/components/ui/button';\n\nconst AlertDialog = AlertDialogPrimitive.Root;\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n ref={ref}\n data-dialog-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.ALERT_DIALOG_OVERLAY }}\n {...props}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst alertDialogContentVariants = cva(\n 'fixed left-[50%] top-[50%] grid w-full min-w-0 max-w-[calc(100vw-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background py-6 shadow-lg box-border overflow-hidden sm:rounded-lg',\n {\n variants: {\n size: {\n default: 'max-w-lg',\n sm: 'max-w-sm',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n },\n);\n\ninterface AlertDialogContentProps\n extends\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>,\n VariantProps<typeof alertDialogContentVariants> {}\n\nconst AlertDialogContent = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Content>,\n AlertDialogContentProps\n>(({ className, size = 'default', children, style, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n data-dialog-content\n className={cn(alertDialogContentVariants({ size }), 'group', className)}\n data-size={size}\n style={{ zIndex: Z_INDEX.ALERT_DIALOG_CONTENT, ...style }}\n {...props}\n >\n {children}\n </AlertDialogPrimitive.Content>\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex flex-col px-6 space-y-2 text-left group-data-[size=sm]:items-center group-data-[size=sm]:text-center',\n className,\n )}\n {...props}\n />\n);\nAlertDialogHeader.displayName = 'AlertDialogHeader';\n\nconst AlertDialogMedia = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-lg mb-4 [&>svg]:size-5',\n className,\n )}\n {...props}\n />\n);\nAlertDialogMedia.displayName = 'AlertDialogMedia';\n\nconst AlertDialogFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex w-full min-w-full flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n '-mb-6 mt-2 border-t border-border bg-muted/50 px-6 py-3 sm:rounded-b-lg',\n '[&_button]:h-8 [&_button]:text-xs [&_button]:px-3',\n 'group-data-[size=sm]:flex-row group-data-[size=sm]:gap-2',\n 'group-data-[size=sm]:[&>*:not(:only-child)]:min-w-0 group-data-[size=sm]:[&>*:not(:only-child)]:flex-1',\n className,\n )}\n {...props}\n />\n);\nAlertDialogFooter.displayName = 'AlertDialogFooter';\n\nconst AlertDialogTitle = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nAlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Action>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action> &\n Pick<ButtonProps, 'variant' | 'size'>\n>(({ className, variant, size, ...props }, ref) => (\n <AlertDialogPrimitive.Action asChild>\n <Button\n ref={ref}\n variant={variant}\n size={size}\n className={className}\n {...props}\n />\n </AlertDialogPrimitive.Action>\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Cancel>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel> &\n Pick<ButtonProps, 'variant' | 'size'>\n>(({ className, variant, size, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel asChild>\n <Button\n ref={ref}\n variant={variant}\n size={size}\n className={className}\n {...props}\n />\n </AlertDialogPrimitive.Cancel>\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n","import { shellui, type ShellUIMessage, type DialogOptions } from '@shellui/sdk';\nimport {\n createContext,\n useContext,\n useCallback,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { Button } from '@/components/ui/button';\nimport { Z_INDEX } from '@/lib/z-index';\n\n/** Match exit animation duration in index.css (overlay + content ~0.1s + buffer) */\nconst DIALOG_EXIT_ANIMATION_MS = 200;\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogOverlay,\n AlertDialogPortal,\n} from '@/components/ui/alert-dialog';\nimport * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';\n\n/** Trash icon (matches lucide trash-2) */\nconst TrashIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n <line\n x1=\"10\"\n x2=\"10\"\n y1=\"11\"\n y2=\"17\"\n />\n <line\n x1=\"14\"\n x2=\"14\"\n y1=\"11\"\n y2=\"17\"\n />\n </svg>\n);\n\n/** Cookie icon for cookie consent */\nconst CookieIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n className={className}\n >\n <path d=\"M164.49 163.51a12 12 0 1 1-17 0a12 12 0 0 1 17 0m-81-8a12 12 0 1 0 17 0a12 12 0 0 0-16.98 0Zm9-39a12 12 0 1 0-17 0a12 12 0 0 0 17-.02Zm48-1a12 12 0 1 0 0 17a12 12 0 0 0 0-17M232 128A104 104 0 1 1 128 24a8 8 0 0 1 8 8a40 40 0 0 0 40 40a8 8 0 0 1 8 8a40 40 0 0 0 40 40a8 8 0 0 1 8 8m-16.31 7.39A56.13 56.13 0 0 1 168.5 87.5a56.13 56.13 0 0 1-47.89-47.19a88 88 0 1 0 95.08 95.08\" />\n </svg>\n);\n\ninterface DialogContextValue {\n dialog: (options: DialogOptions) => void;\n}\n\nconst DialogContext = createContext<DialogContextValue | undefined>(undefined);\n\nexport function useDialog() {\n const context = useContext(DialogContext);\n if (!context) {\n throw new Error('useDialog must be used within a DialogProvider');\n }\n return context;\n}\n\ninterface DialogProviderProps {\n children: ReactNode;\n}\n\ninterface DialogState extends Omit<DialogOptions, 'onOk' | 'onCancel' | 'icon'> {\n id: string;\n mode: DialogOptions['mode'];\n from?: string[];\n iconType?: 'cookie';\n}\n\nexport const DialogProvider = ({ children }: DialogProviderProps) => {\n const [dialogState, setDialogState] = useState<DialogState | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const unmountTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const scheduleUnmount = useCallback(() => {\n if (unmountTimeoutRef.current) clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = setTimeout(() => {\n unmountTimeoutRef.current = null;\n setDialogState(null);\n }, DIALOG_EXIT_ANIMATION_MS);\n }, []);\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n setIsOpen(open);\n if (!open && dialogState) {\n // If dialog was closed without clicking a button (X button or outside click),\n // trigger cancel callback if it exists\n if (dialogState.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_CANCEL',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerCancel(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n // Unmount after exit animation finishes\n scheduleUnmount();\n }\n },\n [dialogState, scheduleUnmount],\n );\n\n const handleOk = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_OK',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerAction(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const handleCancel = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_CANCEL',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerCancel(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const handleSecondary = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_SECONDARY',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerSecondary(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const dialog = useCallback((options: DialogOptions) => {\n // Only show dialog if window is root\n if (typeof window === 'undefined' || window.parent !== window) {\n return;\n }\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n\n const dialogId = options.id || `dialog-${Date.now()}-${Math.random()}`;\n\n // Register callbacks for direct calls (not from iframe)\n if (options.onOk || options.onCancel || options.secondaryButton?.onClick) {\n shellui.callbackRegistry.register(dialogId, {\n action: options.onOk,\n cancel: options.onCancel,\n secondary: options.secondaryButton?.onClick,\n });\n }\n\n setDialogState({\n id: dialogId,\n title: options.title,\n description: options.description,\n mode: options.mode || 'ok',\n okLabel: options.okLabel,\n cancelLabel: options.cancelLabel,\n size: options.size,\n position: options.position,\n secondaryButton: options.secondaryButton,\n iconType: options.icon === 'cookie' ? 'cookie' : undefined,\n });\n setIsOpen(true);\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n // Only listen if window is root\n if (typeof window === 'undefined' || window.parent !== window) {\n return;\n }\n\n const cleanupDialog = shellui.addMessageListener('SHELLUI_DIALOG', (data: ShellUIMessage) => {\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n const payload = data.payload as DialogOptions & { id: string };\n setDialogState({\n id: payload.id,\n title: payload.title,\n description: payload.description,\n mode: payload.mode || 'ok',\n okLabel: payload.okLabel,\n cancelLabel: payload.cancelLabel,\n size: payload.size,\n position: payload.position,\n secondaryButton: payload.secondaryButton,\n iconType: payload.icon === 'cookie' ? 'cookie' : undefined,\n from: data.from,\n });\n setIsOpen(true);\n });\n\n const cleanupDialogUpdate = shellui.addMessageListener(\n 'SHELLUI_DIALOG_UPDATE',\n (data: ShellUIMessage) => {\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n const payload = data.payload as DialogOptions & { id: string };\n setDialogState({\n id: payload.id,\n title: payload.title,\n description: payload.description,\n mode: payload.mode || 'ok',\n okLabel: payload.okLabel,\n cancelLabel: payload.cancelLabel,\n size: payload.size,\n position: payload.position,\n secondaryButton: payload.secondaryButton,\n iconType: payload.icon === 'cookie' ? 'cookie' : undefined,\n from: data.from,\n });\n setIsOpen(true);\n },\n );\n\n return () => {\n cleanupDialog();\n cleanupDialogUpdate();\n if (unmountTimeoutRef.current) clearTimeout(unmountTimeoutRef.current);\n };\n }, []);\n\n const renderButtons = () => {\n if (!dialogState) return null;\n\n const { mode, okLabel, cancelLabel, secondaryButton } = dialogState;\n\n // Cookie consent layout: secondary button on left, primary buttons on right\n if (secondaryButton && dialogState.position === 'bottom-left') {\n return (\n <>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={handleSecondary}\n >\n {secondaryButton.label}\n </Button>\n <div className=\"flex gap-2\">\n {mode === 'okCancel' && (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </Button>\n )}\n <Button\n size=\"sm\"\n onClick={handleOk}\n >\n {okLabel || 'OK'}\n </Button>\n </div>\n </>\n );\n }\n\n switch (mode) {\n case 'ok':\n return <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>;\n\n case 'okCancel':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>\n </>\n );\n\n case 'delete':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={handleOk}\n >\n {okLabel || 'Delete'}\n </AlertDialogAction>\n </>\n );\n\n case 'confirm':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleOk}>{okLabel || 'Confirm'}</AlertDialogAction>\n </>\n );\n\n case 'onlyCancel':\n return (\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n );\n\n default:\n return <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>;\n }\n };\n\n // Render cookie consent dialog with custom layout\n const renderCookieConsentDialog = () => {\n if (!dialogState || dialogState.position !== 'bottom-left') return null;\n\n return (\n <AlertDialog\n open={isOpen}\n onOpenChange={handleOpenChange}\n >\n <AlertDialogPortal>\n <AlertDialogOverlay style={{ zIndex: Z_INDEX.COOKIE_CONSENT_OVERLAY }} />\n <AlertDialogPrimitive.Content\n className=\"fixed w-[calc(100%-32px)] max-w-[520px] rounded-xl border border-border bg-background text-foreground shadow-lg sm:w-full\"\n style={{\n bottom: 16,\n left: 16,\n zIndex: Z_INDEX.COOKIE_CONSENT_CONTENT,\n backgroundColor: 'hsl(var(--background))',\n top: 'auto',\n right: 'auto',\n transform: 'none',\n }}\n data-dialog-content\n data-cookie-consent\n >\n <div className=\"flex items-start gap-4 p-6 sm:gap-5 sm:p-7\">\n {dialogState.iconType === 'cookie' && (\n <div\n className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10\"\n aria-hidden\n >\n <CookieIcon className=\"h-5 w-5 text-primary\" />\n </div>\n )}\n <div className=\"flex-1 space-y-2\">\n <AlertDialogTitle className=\"text-base font-semibold leading-tight\">\n {dialogState.title}\n </AlertDialogTitle>\n {dialogState.description && (\n <AlertDialogDescription className=\"text-sm leading-relaxed\">\n {dialogState.description}\n </AlertDialogDescription>\n )}\n </div>\n </div>\n <div className=\"flex items-center justify-between rounded-b-xl border-t border-border bg-muted/50 px-6 py-4 sm:px-7\">\n {renderButtons()}\n </div>\n </AlertDialogPrimitive.Content>\n </AlertDialogPortal>\n </AlertDialog>\n );\n };\n\n return (\n <DialogContext.Provider value={{ dialog }}>\n {children}\n {dialogState && (\n <>\n {dialogState.position === 'bottom-left' ? (\n renderCookieConsentDialog()\n ) : (\n <AlertDialog\n open={isOpen}\n onOpenChange={handleOpenChange}\n >\n <AlertDialogContent size={dialogState.size ?? 'default'}>\n <AlertDialogHeader>\n {dialogState.mode === 'delete' && (\n <AlertDialogMedia className=\"bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive\">\n <TrashIcon />\n </AlertDialogMedia>\n )}\n <AlertDialogTitle>{dialogState.title}</AlertDialogTitle>\n {dialogState.description && (\n <AlertDialogDescription>{dialogState.description}</AlertDialogDescription>\n )}\n </AlertDialogHeader>\n <AlertDialogFooter>{renderButtons()}</AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </>\n )}\n </DialogContext.Provider>\n );\n};\n","import { useRef, useCallback, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useDialog } from '../alertDialog/DialogContext';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport urls from '@/constants/urls';\n\n/**\n * Shows a friendly cookie consent modal on first visit (when user has not yet consented).\n * Accept all / Reject all only. Closing via Escape or overlay counts as Reject.\n */\nexport function CookieConsentModal() {\n const { t } = useTranslation('cookieConsent');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n const { dialog: showDialog } = useDialog();\n const closedByChoiceRef = useRef(false);\n const dialogShownRef = useRef(false);\n\n const cookieConsent = config?.cookieConsent;\n const cookies = cookieConsent?.cookies ?? [];\n const consentedHosts = settings?.cookieConsent?.consentedCookieHosts ?? [];\n const allHosts = cookies.map((c) => c.host);\n const strictNecessaryHosts = cookies\n .filter((c) => c.category === 'strict_necessary')\n .map((c) => c.host);\n\n // Check if there are new cookies that weren't in the list when user last consented\n const hasNewCookies = allHosts.some((host) => !consentedHosts.includes(host));\n const neverConsented = consentedHosts.length === 0;\n const isRenewal = !neverConsented && hasNewCookies;\n\n // Only show in root window, not in sub-apps (iframes)\n const isRootWindow = typeof window !== 'undefined' && window.parent === window;\n // Show if: has cookies AND (never consented OR new cookies added)\n const shouldShow = isRootWindow && cookies.length > 0 && (neverConsented || hasNewCookies);\n\n // Use renewal text if showing due to cookie policy update\n const title = isRenewal ? t('titleRenewal') : t('title');\n const description = isRenewal ? t('descriptionRenewal') : t('description');\n\n const saveAccept = useCallback(() => {\n updateSetting('cookieConsent', {\n acceptedHosts: allHosts,\n consentedCookieHosts: allHosts,\n });\n }, [allHosts, updateSetting]);\n\n const saveReject = useCallback(() => {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }, [strictNecessaryHosts, allHosts, updateSetting]);\n\n const handleAccept = useCallback(() => {\n closedByChoiceRef.current = true;\n saveAccept();\n }, [saveAccept]);\n\n const handleReject = useCallback(() => {\n closedByChoiceRef.current = true;\n saveReject();\n }, [saveReject]);\n\n const handleSetPreferences = useCallback(() => {\n closedByChoiceRef.current = true;\n shellui.openDrawer({ url: `${urls.cookiePreferences}?initial=true`, size: '420px' });\n }, []);\n\n // Show/hide dialog based on shouldShow\n useEffect(() => {\n if (!shouldShow) {\n dialogShownRef.current = false;\n return;\n }\n\n // Prevent showing dialog multiple times\n if (dialogShownRef.current) {\n return;\n }\n\n // Mark as shown to prevent duplicate calls\n dialogShownRef.current = true;\n\n // Close any open modals/drawers when cookie consent is shown\n shellui.propagateMessage({ type: 'SHELLUI_CLOSE_MODAL', payload: {} });\n shellui.propagateMessage({ type: 'SHELLUI_CLOSE_DRAWER', payload: {} });\n\n // Reset choice ref when showing dialog\n closedByChoiceRef.current = false;\n\n // Show dialog using DialogContext directly (for root window)\n showDialog({\n title,\n description,\n mode: 'okCancel',\n okLabel: t('accept'),\n cancelLabel: t('reject'),\n position: 'bottom-left',\n icon: 'cookie',\n secondaryButton: {\n label: t('setPreferences'),\n onClick: handleSetPreferences,\n },\n onOk: handleAccept,\n onCancel: handleReject,\n });\n }, [\n shouldShow,\n title,\n description,\n t,\n handleAccept,\n handleReject,\n handleSetPreferences,\n showDialog,\n ]);\n\n return null;\n}\n","import { useMemo, useLayoutEffect, useState, useEffect } from 'react';\nimport { RouterProvider } from 'react-router';\nimport { shellui } from '@shellui/sdk';\nimport { useConfig } from './features/config/useConfig';\nimport { ConfigProvider } from './features/config/ConfigProvider';\nimport { createAppRouter } from './router/router';\nimport { SettingsProvider } from './features/settings/SettingsProvider';\nimport { ThemeProvider } from './features/theme/ThemeProvider';\nimport { I18nProvider } from './i18n/I18nProvider';\nimport { DialogProvider } from './features/alertDialog/DialogContext';\nimport { CookieConsentModal } from './features/cookieConsent/CookieConsentModal';\nimport './features/sentry/initSentry';\nimport './i18n/config'; // Initialize i18n\nimport './index.css';\nimport { registerServiceWorker, unregisterServiceWorker, isTauri } from './service-worker/register';\nimport { useSettings } from './features/settings/hooks/useSettings';\n\nconst AppContent = () => {\n const { config } = useConfig();\n const { settings } = useSettings();\n\n // Apply favicon from config when available (allows projects to override default)\n useEffect(() => {\n if (config?.favicon) {\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]');\n if (link) link.href = config.favicon;\n }\n }, [config?.favicon]);\n\n // Register or unregister service worker based on setting\n useEffect(() => {\n if (isTauri()) {\n unregisterServiceWorker();\n return;\n }\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true; // Default to enabled\n\n // Don't register service worker if navigation is empty or undefined\n // This helps prevent issues in development or misconfigured apps\n if (!config?.navigation || config.navigation.length === 0) {\n if (serviceWorkerEnabled) {\n // eslint-disable-next-line no-console\n console.warn('[Service Worker] Disabled: No navigation items configured');\n unregisterServiceWorker();\n }\n return;\n }\n\n if (serviceWorkerEnabled) {\n registerServiceWorker({\n enabled: true,\n });\n } else {\n unregisterServiceWorker();\n }\n }, [settings?.serviceWorker?.enabled, config?.navigation]);\n\n // Create router from config using data mode\n const router = useMemo(() => {\n if (!config) {\n return null;\n }\n return createAppRouter(config);\n }, [config]);\n\n // If no navigation, show simple layout\n if (!config.navigation || config.navigation.length === 0) {\n return (\n <>\n <CookieConsentModal />\n <div style={{ fontFamily: 'system-ui, sans-serif', padding: '2rem' }}>\n <h1>{config.title || 'ShellUI'}</h1>\n <p>No navigation items configured.</p>\n </div>\n </>\n );\n }\n\n if (!router) {\n return null;\n }\n\n return (\n <>\n <CookieConsentModal />\n <RouterProvider router={router} />\n </>\n );\n};\n\nconst App = () => {\n const [isLoading, setIsLoading] = useState(true);\n // Initialize ShellUI SDK to support recursive nesting\n useLayoutEffect(() => {\n shellui.init().then(() => {\n setIsLoading(false);\n });\n }, []);\n\n if (isLoading) {\n return null;\n }\n\n return (\n <ConfigProvider>\n <SettingsProvider>\n <ThemeProvider>\n <I18nProvider>\n <DialogProvider>\n <AppContent />\n </DialogProvider>\n </I18nProvider>\n </ThemeProvider>\n </SettingsProvider>\n </ConfigProvider>\n );\n};\n\nexport default App;\n","import { useMemo } from 'react';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { getCookieConsentNeedsRenewal } from './cookieConsent';\n\n/**\n * Returns whether the given cookie host is accepted (feature may run) and whether\n * consent should be re-collected. Use to gate features in React components.\n *\n * - isAccepted: true if cookie consent is not configured, or the host is not in the config list,\n * or the user has accepted this host.\n * - needsConsent: true if cookie consent is configured and the user has not yet consented,\n * or new cookies were added since last consent (renewal); when showing the UI again, pre-fill\n * with settings.cookieConsent.acceptedHosts to keep existing approvals.\n */\nexport function useCookieConsent(host: string): { isAccepted: boolean; needsConsent: boolean } {\n const { config } = useConfig();\n const { settings } = useSettings();\n\n return useMemo(() => {\n const cookieConsent = config?.cookieConsent;\n const list = cookieConsent?.cookies ?? [];\n const acceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n\n if (!list.length) {\n return { isAccepted: true, needsConsent: false };\n }\n\n const knownHosts = new Set(list.map((c) => c.host));\n if (!knownHosts.has(host)) {\n return { isAccepted: true, needsConsent: false };\n }\n\n const isAccepted = acceptedHosts.includes(host);\n const needsConsent = acceptedHosts.length === 0 || getCookieConsentNeedsRenewal();\n\n return { isAccepted, needsConsent };\n }, [config?.cookieConsent, settings?.cookieConsent?.acceptedHosts, host]);\n}\n"],"names":["logger","getLogger","ConfigContext","createContext","configLogged","ConfigProvider","props","config","useState","configValue","parsedConfig","parseError","g","fallbackValue","err","value","createElement","useConfig","context","useContext","HomeView","t","useTranslation","jsxs","jsx","cn","inputs","twMerge","clsx","Breadcrumb","forwardRef","ref","BreadcrumbList","className","BreadcrumbItem","BreadcrumbLink","asChild","Slot","BreadcrumbPage","BreadcrumbSeparator","children","Z_INDEX","SidebarContext","useSidebar","SidebarProvider","isCollapsed","setIsCollapsed","toggle","useCallback","prev","Sidebar","PanelLeftOpenIcon","PanelLeftCloseIcon","SidebarTrigger","SidebarHeader","SidebarContent","SidebarFooter","SidebarGroup","SidebarGroupLabel","SidebarGroupAction","SidebarGroupContent","sidebarMenuButtonVariants","cva","SidebarMenuButton","variant","size","isActive","SidebarMenu","SidebarMenuItem","SidebarMenuAction","SidebarMenuBadge","SidebarMenuSkeleton","showIcon","SidebarMenuSub","SidebarMenuSubButton","SidebarMenuSubItem","PaintbrushIcon","GlobeIcon","CheckIcon","SettingsIcon","CodeIcon","ChevronRightIcon","ChevronLeftIcon","ShieldIcon","RefreshDoubleIcon","PackageIcon","SettingsContext","useSettings","buttonVariants","Button","ButtonGroup","Children","child","index","isValidElement","isFirst","isLast","cloneElement","hexToHsl","hexString","hex","b","rNorm","gNorm","bNorm","max","min","h","s","d","hDeg","sPercent","lPercent","result","defaultTheme","blueTheme","warmYellowTheme","themeRegistry","registerTheme","theme","getTheme","name","getAllThemes","applyTheme","isDark","root","colors","primaryHsl","head","link","fontFile","style","fontName","bodyFont","headingFont","bodyShadow","match","rgba","values","opacity","actualPrimary","hslFormat","SunIcon","MoonIcon","MonitorIcon","ThemePreview","isSelected","Appearance","settings","updateSetting","currentTheme","currentThemeName","availableThemes","setAvailableThemes","useEffect","themeDef","isDarkForPreview","setIsDarkForPreview","updatePreview","mediaQuery","handleChange","modeThemes","Icon","allSupportedLanguages","resources","enCommon","enSettings","enCookieConsent","frCommon","frSettings","frCookieConsent","getInitialLanguage","enabledLanguages","stored","languageCode","isInitialized","initializeI18n","validLangs","lang","supported","finalLangs","initialLang","i18n","initReactI18next","getSupportedLanguages","enabledLangs","Select","ClockIcon","TIMEZONE_GROUPS","formatDate","date","timezone","formatTime","getBrowserTimezone","getTimezoneDisplayName","timeZoneName","part","LanguageAndRegion","currentLanguage","browserTimezone","currentTimezone","isUsingBrowserTimezone","supportedLanguages","handleResetRegion","currentDateTime","setCurrentDateTime","now","updateDateTime","interval","e","group","tz","isBrowserTimezone","wb","updateAvailable","waitingServiceWorker","registrationPromise","statusListeners","isInitialRegistration","eventListenersAdded","toastShownForServiceWorkerId","isIntentionalUpdate","isRegistering","registrationStartTime","REGISTRATION_GRACE_PERIOD","waitingHandler","activatedHandler","controllingHandler","registeredHandler","redundantHandler","serviceWorkerErrorHandler","messageErrorHandler","hasTauriOnWindow","w","o","isTauri","swFileExistsCache","swFileExistsCacheTime","SW_FILE_EXISTS_CACHE_TTL","notifyStatusListeners","status","isServiceWorkerRegistered","listener","disableCachingAutomatically","reason","timeSinceRegistrationStart","unregisterServiceWorker","STORAGE_KEY","shellui","defaultSettings","error","serviceWorkerFileExists","response","contentType","isJavaScript","text","looksLikeServiceWorker","registerServiceWorker","options","retryExists","existingRegistration","waitingSW","isNewWorkbox","Workbox","UPDATE_AVAILABLE_TOAST_ID","isAutoActivating","registration","currentWaitingSW","currentWaitingSWId","actionHandler","updateServiceWorker","swRegistration","event","evt","isIntentionalUpdatePersisted","shouldReload","wasAutoActivated","hasWaitingAsync","hasInstallingAsync","hasActiveAsync","evtError","errorMessage","errorName","waitingSWId","visibilityHandler","reloadApp","updateControllingHandler","cacheNames","getServiceWorkerStatus","registered","actuallyUpdateAvailable","checkForServiceWorkerUpdate","addStatusListener","l","UpdateApp","setUpdateAvailable","checking","setChecking","showUpToDateInButton","setShowUpToDateInButton","checkError","setCheckError","serviceWorkerEnabled","handleCheckForUpdate","resolve","version","Fragment","Switch","checked","onCheckedChange","getConfig","raw","getStoredCookieConsent","parsed","getCookieConsentAccepted","host","c","acceptedHosts","getCookieConsentNeedsRenewal","consentedCookieHosts","currentHosts","getCookieConsentNewHosts","consentedSet","SETTINGS_KEY","sentryLoaded","isErrorReportingEnabled","initSentry","dsn","Sentry","closeSentry","Advanced","resetAllData","errorReportingConfigured","handleErrorReportingChange","handleResetClick","resolveLocalizedString","flattenNavigationItems","navigation","item","filterNavigationByViewport","viewport","hideOnMobile","hideOnDesktop","visibleItems","navItem","filterNavigationForSidebar","splitNavigationByPosition","start","end","ToastTestButtons","toastId","DialogTestButtons","ModalTestButtons","urls","DrawerTestButtons","openDrawer","Develop","effectiveLayout","navItems","self","i","path","layoutMode","DataPrivacy","cookies","hasCookieConsent","hasConsented","allHosts","strictNecessaryHosts","acceptedAll","rejectedAll","isCustom","handleResetCookieConsent","ServiceWorker","isRegistered","setIsRegistered","isLoading","setIsLoading","swFileExists","setSwFileExists","initialCheck","exists","refreshStatus","unsubscribe","handleToggleServiceWorker","enabled","currentEnabled","handleUpdateNow","handleResetToLatest","createSettingsRoutes","SettingsView","location","useLocation","navigate","useNavigate","isTauriEnv","setIsTauriEnv","tid","settingsLabel","settingsRoutes","useMemo","routesWithoutTauriSw","route","filteredRoutes","groupedRoutes","developerOnlyPaths","getSelectedItemFromUrl","pathname","normalizedPathname","normalizedItemPath","selectedItem","isSettingsRoot","normalizedSettingsPath","settingsPathWithSlash","handleBackToSettings","itemIndex","Routes","Route","Navigate","CATEGORY_ORDER","formatDuration","seconds","CookiePreferencesView","isInitialConsent","currentAcceptedHosts","localAcceptedHosts","setLocalAcceptedHosts","actionClickedRef","useRef","handleDrawerClose","cookiesByCategory","grouped","cookie","existing","toggleCookie","toggleCategory","category","categoryHosts","hostsSet","getCategoryState","enabledCount","handleAcceptAll","handleRejectAll","handleSave","hostsToSave","hasChanges","sortedLocal","sortedCurrent","categoryCookies","categoryState","isStrictNecessary","isEnabled","LoadingOverlay","ContentView","url","pathPrefix","ignoreMessages","iframeRef","isInternalNavigation","initialUrl","iframeId","addIframe","removeIframe","cleanup","data","search","hash","cleanPathname","newShellPath","urlParts","pathnamePart","queryHashPart","currentPath","newPathParts","normalizedNewPath","_data","timeoutId","iframe","handleLoad","iframeWindow","iframeDoc","script","originalWarn","args","message","ViewRoute","subPath","finalUrl","NotFoundView","handleNavigate","isChunkLoadError","msg","getErrorMessage","isRouteErrorResponse","getErrorStack","getErrorDetailsText","stack","RouteErrorBoundary","useRouteError","isChunkError","detailsText","validateAndNormalizeUrl","urlObj","currentOrigin","normalizedPath","ModalContext","useModal","ModalProvider","isOpen","setIsOpen","modalUrl","setModalUrl","openModal","validatedUrl","closeModal","cleanupOpenModal","payload","cleanupCloseModal","DEFAULT_DRAWER_POSITION","DrawerContext","useDrawer","DrawerProvider","drawerUrl","setDrawerUrl","position","setPosition","setSize","closeDrawer","cleanupOpen","cleanupClose","SonnerContext","SonnerProvider","toast","id","title","description","type","duration","action","cancel","onDismiss","onAutoClose","toastOptions","sonnerToast","cleanupToast","actionSent","cancelSent","cleanupToastUpdate","LayoutProviders","Dialog","DialogPrimitive","DialogPortal","DialogOverlay","DialogContent","onPointerDownOutside","hideCloseButton","hasContent","handlePointerDownOutside","DialogTitle","DialogDescription","Drawer","open","onOpenChange","direction","VaulDrawer","DrawerTrigger","DrawerPortal","DrawerOverlay","drawerContentByDirection","DrawerContent","pos","isVertical","effectiveSize","sizeStyle","DrawerClose","DrawerTitle","DrawerDescription","Toaster","Sonner","OverlayShell","navigationItems","isDrawerOpen","drawerPosition","drawerSize","rawUrl","getExternalFaviconUrl","hostname","NavigationContent","hasAnyIcons","isGroup","renderNavItem","isOverlay","isExternal","itemLabel","faviconUrl","iconSrc","iconEl","content","ExternalLinkIcon","linkOrTrigger","Link","groupTitle","SidebarInner","logo","startNav","endItems","resolveLocalizedLabel","BOTTOM_NAV_SLOT_WIDTH","BOTTOM_NAV_GAP","BOTTOM_NAV_PX","BOTTOM_NAV_MAX_SLOTS","isAppIcon","src","BottomNavItem","label","applyIconTheme","baseClass","CaretUpIcon","CaretDownIcon","HomeIcon","MobileBottomNav","items","expanded","setExpanded","navRef","rowWidth","setRowWidth","useLayoutEffect","el","ro","entries","rowItems","overflowItems","hasMore","list","contentWidth","slotTotal","computedSlots","totalSlots","slotsForNav","maxInRow","row","rowPaths","overflow","renderItem","resolveNavLabel","DefaultLayoutContent","mobileNavItems","desktopNav","mobileNav","flat","mobileFlat","segment","Outlet","DefaultLayout","appIcon","FullscreenLayout","genId","MIN_WIDTH","MIN_HEIGHT","DEFAULT_WIDTH","DEFAULT_HEIGHT","TASKBAR_HEIGHT","getMaximizedBounds","buildFinalUrl","baseUrl","AppWindow","win","isFocused","onFocus","onClose","onBoundsChange","maxZIndex","zIndex","windowLabel","bounds","setBounds","isMaximized","setIsMaximized","boundsBeforeMaximizeRef","containerRef","dragRef","resizeRef","resizeRafRef","pendingResizeBoundsRef","onResize","onPointerMove","dx","dy","onPointerUp","finalBounds","handleTitlePointerDown","handleMaximizeToggle","onResizePointerMove","edge","startX","startY","startBounds","next","newW","newH","pending","onResizePointerUp","handleResizePointerDown","z","RestoreIcon","MaximizeIcon","CloseIcon","StartIcon","WindowsLayout","_appIcon","_logo","timeZone","startNavItems","endNavItems","windows","setWindows","frontWindowId","setFrontWindowId","startMenuOpen","setStartMenuOpen","setNow","startPanelRef","openWindow","icon","closeWindow","current","focusWindow","updateWindowBounds","onDocClick","handleNavClick","n","__imported_DefaultLayout_0__","__imported_FullscreenLayout_1__","__imported_WindowsLayout_2__","LayoutFallback","AppLayout","layout","LayoutComponent","layoutProps","Suspense","__imported_HomeView_0__","__imported_SettingsView_1__","__imported_CookiePreferencesView_2__","__imported_ViewRoute_3__","__imported_NotFoundView_4__","RouteFallback","createRoutes","routes","layoutRoute","createAppRouter","createBrowserRouter","resolveLabel","buildSettingsWithNavigation","SettingsProvider","settingsRef","setSettings","initialSettings","newSettings","settingsToPropagate","cleanupSettingsRequested","currentSettings","settingsWithNav","cleanupSettings","updateSettings","updates","key","currentValue","mergedValue","keysToRemove","applyThemeToDocument","useTheme","themeName","effectiveThemeName","themeDefinition","ThemeProvider","I18nProvider","AlertDialog","AlertDialogPrimitive","AlertDialogPortal","AlertDialogOverlay","alertDialogContentVariants","AlertDialogContent","AlertDialogHeader","AlertDialogMedia","AlertDialogFooter","AlertDialogTitle","AlertDialogDescription","AlertDialogAction","AlertDialogCancel","DIALOG_EXIT_ANIMATION_MS","TrashIcon","CookieIcon","DialogContext","useDialog","DialogProvider","dialogState","setDialogState","unmountTimeoutRef","scheduleUnmount","handleOpenChange","handleOk","handleCancel","handleSecondary","dialog","dialogId","cleanupDialog","cleanupDialogUpdate","renderButtons","mode","okLabel","cancelLabel","secondaryButton","renderCookieConsentDialog","CookieConsentModal","showDialog","closedByChoiceRef","dialogShownRef","consentedHosts","hasNewCookies","neverConsented","isRenewal","shouldShow","saveAccept","saveReject","handleAccept","handleReject","handleSetPreferences","AppContent","router","RouterProvider","App","useCookieConsent","isAccepted","needsConsent"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/features/config/ConfigProvider.ts","../src/features/config/useConfig.ts","../src/lib/utils.ts","../src/components/ui/button.tsx","../src/components/RouteErrorBoundary.tsx","../src/features/settings/SettingsContext.tsx","../src/lib/z-index.ts","../src/components/ui/sidebar.tsx","../src/features/layouts/utils.ts","../src/features/modal/ModalContext.tsx","../src/features/drawer/DrawerContext.tsx","../src/features/sonner/SonnerContext.tsx","../src/features/layouts/LayoutProviders.tsx","../src/components/ui/dialog.tsx","../src/components/ui/drawer.tsx","../src/features/settings/hooks/useSettings.tsx","../src/components/ui/sonner.tsx","../src/components/LoadingOverlay.tsx","../src/components/ContentView.tsx","../src/features/layouts/OverlayShell.tsx","../src/features/layouts/DefaultLayout.tsx","../src/features/layouts/FullscreenLayout.tsx","../src/features/layouts/WindowsLayout.tsx","../src/features/layouts/AppLayout.tsx","../src/components/HomeView.tsx","../src/components/ui/breadcrumb.tsx","../src/features/settings/SettingsIcons.tsx","../src/components/ui/button-group.tsx","../src/features/theme/themes.ts","../src/features/settings/components/Appearance.tsx","../src/i18n/config.ts","../src/components/ui/select.tsx","../src/features/settings/components/LanguageAndRegion.tsx","../src/service-worker/register.ts","../src/features/settings/components/UpdateApp.tsx","../src/components/ui/switch.tsx","../src/features/cookieConsent/cookieConsent.ts","../src/features/sentry/initSentry.ts","../src/features/settings/components/Advanced.tsx","../src/features/settings/components/develop/ToastTestButtons.tsx","../src/features/settings/components/develop/DialogTestButtons.tsx","../src/features/settings/components/develop/ModalTestButtons.tsx","../src/features/settings/components/develop/DrawerTestButtons.tsx","../src/features/settings/components/Develop.tsx","../src/features/settings/components/DataPrivacy.tsx","../src/features/settings/components/ServiceWorker.tsx","../src/features/settings/SettingsRoutes.tsx","../src/features/settings/SettingsView.tsx","../src/features/cookieConsent/CookiePreferencesView.tsx","../src/components/ViewRoute.tsx","../src/components/NotFoundView.tsx","../src/router/routes.tsx","../src/router/router.tsx","../src/features/settings/SettingsProvider.tsx","../src/features/theme/useTheme.tsx","../src/features/theme/ThemeProvider.tsx","../src/i18n/I18nProvider.tsx","../src/components/ui/alert-dialog.tsx","../src/features/alertDialog/DialogContext.tsx","../src/features/cookieConsent/CookieConsentModal.tsx","../src/app.tsx","../src/features/cookieConsent/useCookieConsent.ts"],"sourcesContent":["import { createContext, useState, createElement, type ReactNode } from 'react';\nimport { getLogger } from '@shellui/sdk';\nimport type { ShellUIConfig } from './types';\n\nconst logger = getLogger('shellcore');\n\nexport interface ConfigContextValue {\n config: ShellUIConfig;\n}\n\nexport const ConfigContext = createContext<ConfigContextValue | null>(null);\n\nexport interface ConfigProviderProps {\n children: ReactNode;\n}\n\n// Track if config has been logged to prevent duplicate logs in dev mode\n// (can happen with React StrictMode or when app renders in multiple contexts)\nlet configLogged = false;\n\n/**\n * Loads ShellUI config from __SHELLUI_CONFIG__ (injected by Vite at build time)\n * and provides it via context. Children can use useConfig() to read config.\n */\n\nexport function ConfigProvider(props: ConfigProviderProps): ReturnType<typeof createElement> {\n const [config] = useState<ShellUIConfig>(() => {\n try {\n // __SHELLUI_CONFIG__ is replaced by Vite at build time via define\n // After replacement, it will be a JSON string like: \"{\\\"title\\\":\\\"shellui\\\",...}\"\n // Vite's define inserts the string value directly, so we only need to parse once\n // Access it directly (no typeof check) so Vite can statically analyze and replace it\n // @ts-expect-error - __SHELLUI_CONFIG__ is injected by Vite at build time\n const configValue: unknown = __SHELLUI_CONFIG__;\n\n // After Vite replacement, configValue will be a JSON string\n // Example: \"{\\\"title\\\":\\\"shellui\\\"}\" -> parse -> {title: \"shellui\"}\n if (configValue !== undefined && configValue !== null && typeof configValue === 'string') {\n try {\n // Parse the JSON string to get the config object\n const parsedConfig: ShellUIConfig = JSON.parse(configValue);\n if (typeof window !== 'undefined' && parsedConfig.runtime === 'tauri') {\n (window as Window & { __SHELLUI_TAURI__?: boolean }).__SHELLUI_TAURI__ = true;\n }\n\n // Log in dev mode to help debug (only once per page load)\n if (process.env.NODE_ENV === 'development' && !configLogged) {\n configLogged = true;\n logger.info('Config loaded from __SHELLUI_CONFIG__', {\n hasNavigation: !!parsedConfig.navigation,\n navigationItems: parsedConfig.navigation?.length || 0,\n });\n }\n\n return parsedConfig;\n } catch (parseError) {\n logger.error('Failed to parse config JSON:', { error: parseError });\n logger.error('Config value (first 200 chars):', { value: configValue.substring(0, 200) });\n // Fall through to return empty config\n }\n }\n\n // Fallback: try to read from globalThis (for edge cases or if define didn't work)\n const g = globalThis as unknown as { __SHELLUI_CONFIG__?: unknown };\n if (typeof g.__SHELLUI_CONFIG__ !== 'undefined') {\n const fallbackValue = g.__SHELLUI_CONFIG__;\n const parsedConfig: ShellUIConfig =\n typeof fallbackValue === 'string'\n ? JSON.parse(fallbackValue)\n : (fallbackValue as ShellUIConfig);\n if (typeof window !== 'undefined' && parsedConfig.runtime === 'tauri') {\n (window as Window & { __SHELLUI_TAURI__?: boolean }).__SHELLUI_TAURI__ = true;\n }\n\n if (process.env.NODE_ENV === 'development') {\n logger.warn('Config loaded from globalThis fallback (define may not have worked)');\n }\n\n return parsedConfig;\n }\n\n // Return empty config if __SHELLUI_CONFIG__ is undefined (fallback for edge cases)\n logger.warn(\n 'Config not found. Using empty config. Make sure shellui.config.ts is properly loaded during build.',\n );\n return {} as ShellUIConfig;\n } catch (err) {\n logger.error('Failed to load ShellUI config:', { error: err });\n // Don't throw - return empty config instead to prevent app crash\n return {} as ShellUIConfig;\n }\n });\n\n const value: ConfigContextValue = { config };\n return createElement(ConfigContext.Provider, { value }, props.children);\n}\n","import { useContext } from 'react';\nimport { ConfigContext, type ConfigContextValue } from './ConfigProvider';\n\n/**\n * Hook to access ShellUI configuration from ConfigProvider context.\n * Must be used within a ConfigProvider.\n * @returns {ConfigContextValue} Configuration object and loading state\n */\nexport function useConfig(): ConfigContextValue {\n const context = useContext(ConfigContext);\n if (context === null) {\n throw new Error('useConfig must be used within a ConfigProvider');\n }\n return context;\n}\n","import { type ClassValue, clsx } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { forwardRef, type ButtonHTMLAttributes } from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer disabled:pointer-events-none disabled:opacity-50 disabled:cursor-not-allowed [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n default: 'bg-primary text-primary-foreground hover:bg-primary/90',\n destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',\n outline: 'border border-input bg-background hover:bg-accent hover:text-accent-foreground',\n secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',\n ghost: 'hover:bg-accent hover:text-accent-foreground',\n link: 'text-primary underline-offset-4 hover:underline',\n },\n size: {\n default: 'h-10 px-4 py-2',\n sm: 'h-9 rounded-md px-3',\n lg: 'h-11 rounded-md px-8',\n icon: 'h-10 w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nexport interface ButtonProps\n extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {\n asChild?: boolean;\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n className={cn(buttonVariants({ variant, size, className }))}\n ref={ref}\n {...props}\n />\n );\n },\n);\nButton.displayName = 'Button';\n\nexport { Button, buttonVariants };\n","import { useRouteError, isRouteErrorResponse } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { Button } from '@/components/ui/button';\n\nfunction isChunkLoadError(error: unknown): boolean {\n if (error instanceof Error) {\n const msg = error.message.toLowerCase();\n return (\n msg.includes('loading dynamically imported module') ||\n msg.includes('chunk') ||\n msg.includes('failed to fetch dynamically imported module')\n );\n }\n return false;\n}\n\nfunction getErrorMessage(error: unknown): string {\n if (isRouteErrorResponse(error)) {\n return error.data?.message ?? error.statusText ?? 'Something went wrong';\n }\n if (error instanceof Error) {\n return error.message;\n }\n return String(error);\n}\n\nfunction getErrorStack(error: unknown): string | null {\n if (error instanceof Error && error.stack) {\n return error.stack;\n }\n return null;\n}\n\nfunction getErrorDetailsText(error: unknown): string {\n const message = getErrorMessage(error);\n const stack = getErrorStack(error);\n if (stack) {\n return `Message:\\n${message}\\n\\nStack:\\n${stack}`;\n }\n return message;\n}\n\nexport function RouteErrorBoundary() {\n const error = useRouteError();\n const { t } = useTranslation('common');\n const isChunkError = isChunkLoadError(error);\n const detailsText = getErrorDetailsText(error);\n\n return (\n <div\n className=\"flex min-h-screen flex-col items-center justify-center bg-background px-4 py-12\"\n style={{ fontFamily: 'var(--heading-font-family, system-ui, sans-serif)' }}\n >\n <div className=\"w-full max-w-md space-y-6 text-center\">\n <div className=\"space-y-2\">\n <h1 className=\"text-xl font-semibold text-foreground\">\n {isChunkError ? t('errorBoundary.titleChunk') : t('errorBoundary.titleGeneric')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {isChunkError\n ? t('errorBoundary.descriptionChunk')\n : t('errorBoundary.descriptionGeneric')}\n </p>\n </div>\n\n <div className=\"flex flex-col gap-3 sm:flex-row sm:justify-center\">\n <Button\n variant=\"default\"\n onClick={() => window.location.reload()}\n className=\"shrink-0\"\n >\n {t('errorBoundary.tryAgain')}\n </Button>\n <Button\n variant=\"outline\"\n onClick={() => shellui.navigate('/')}\n className=\"shrink-0\"\n >\n {t('errorBoundary.goToHome')}\n </Button>\n </div>\n\n <details className=\"rounded-lg border border-border bg-muted/30 text-left\">\n <summary className=\"cursor-pointer px-4 py-3 text-xs font-medium text-muted-foreground hover:text-foreground\">\n {t('errorBoundary.errorDetails')}\n </summary>\n <pre className=\"max-h-64 overflow-auto whitespace-pre-wrap break-all px-4 pb-3 pt-1 text-xs text-muted-foreground font-mono\">\n {detailsText}\n </pre>\n </details>\n </div>\n </div>\n );\n}\n","import { useContext, createContext } from 'react';\nimport type { Settings } from '@shellui/sdk';\n\nexport interface SettingsContextValue {\n settings: Settings;\n updateSettings: (updates: Partial<Settings>) => void;\n updateSetting: <K extends keyof Settings>(key: K, updates: Partial<Settings[K]>) => void;\n resetAllData: () => void;\n}\n\nexport const SettingsContext = createContext<SettingsContextValue | undefined>(undefined);\n\nexport function useSettings() {\n const context = useContext(SettingsContext);\n if (context === undefined) {\n throw new Error('useSettings must be used within a SettingsProvider');\n }\n return context;\n}\n","/**\n * Central z-index scale for overlay layers.\n * Order (bottom to top): modal/drawer → toast → alert-dialog.\n * Use these constants everywhere so stacking stays consistent.\n */\nexport const Z_INDEX = {\n /** Sidebar trigger (above main content, below modals) */\n SIDEBAR_TRIGGER: 9999,\n /** Modal overlay and content (settings panel, etc.) */\n MODAL_OVERLAY: 10000,\n MODAL_CONTENT: 10001,\n /** Drawer overlay and content (slide-out panels; same level as modal) */\n DRAWER_OVERLAY: 10000,\n DRAWER_CONTENT: 10001,\n /** Toasts (above modals so they stay clickable when modal is open) */\n TOAST: 10100,\n /** Alert dialog overlay and content (confirmations; above toasts) */\n ALERT_DIALOG_OVERLAY: 10200,\n ALERT_DIALOG_CONTENT: 10201,\n /** Cookie consent (above everything to ensure visibility) */\n COOKIE_CONSENT_OVERLAY: 10300,\n COOKIE_CONSENT_CONTENT: 10301,\n /** Windows layout: taskbar (below windows), windows use dynamic z-index above this */\n WINDOWS_TASKBAR: 9000,\n /** Base z-index for windows; each window gets base + order */\n WINDOWS_WINDOW_BASE: 9001,\n} as const;\n\nexport type ZIndexLayer = keyof typeof Z_INDEX;\n","import {\n createContext,\n useContext,\n useState,\n useCallback,\n forwardRef,\n type ReactNode,\n type HTMLAttributes,\n type ButtonHTMLAttributes,\n type AnchorHTMLAttributes,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ntype SidebarContextValue = {\n isCollapsed: boolean;\n toggle: () => void;\n};\n\nconst SidebarContext = createContext<SidebarContextValue | undefined>(undefined);\n\nconst useSidebar = () => {\n const context = useContext(SidebarContext);\n if (!context) {\n throw new Error('useSidebar must be used within a SidebarProvider');\n }\n return context;\n};\n\nconst SidebarProvider = ({ children }: { children: ReactNode }) => {\n const [isCollapsed, setIsCollapsed] = useState(false);\n\n const toggle = useCallback(() => {\n setIsCollapsed((prev) => !prev);\n }, []);\n\n return (\n <SidebarContext.Provider value={{ isCollapsed, toggle }}>{children}</SidebarContext.Provider>\n );\n};\n\nconst Sidebar = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n const { isCollapsed } = useSidebar();\n\n return (\n <div\n ref={ref}\n data-sidebar=\"sidebar\"\n data-collapsed={isCollapsed}\n className={cn(\n 'flex h-full flex-col gap-2 border-r bg-sidebar-background p-2 text-sidebar-foreground transition-all duration-300 ease-in-out overflow-hidden',\n isCollapsed ? 'w-0 border-r-0 p-0' : 'w-64',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebar.displayName = 'Sidebar';\n\n/** Inline SVG: panel-left-open (expand sidebar) */\nconst PanelLeftOpenIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-5 w-5 transition-transform duration-300\"\n aria-hidden\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m14 9 3 3-3 3\" />\n </svg>\n);\n\n/** Inline SVG: panel-left-close (collapse sidebar) */\nconst PanelLeftCloseIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-5 w-5 transition-transform duration-300\"\n aria-hidden\n >\n <rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" />\n <path d=\"M9 3v18\" />\n <path d=\"m16 15-3-3 3-3\" />\n </svg>\n);\n\nconst SidebarTrigger = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement>>(\n ({ className, ...props }, ref) => {\n const { toggle, isCollapsed } = useSidebar();\n\n return (\n <button\n ref={ref}\n onClick={toggle}\n className={cn(\n 'relative flex items-center justify-center rounded-md p-2 text-foreground transition-colors hover:opacity-90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring shadow-lg backdrop-blur-md cursor-pointer bg-background/95 border border-border',\n className,\n )}\n aria-label={isCollapsed ? 'Expand sidebar' : 'Collapse sidebar'}\n style={{ zIndex: Z_INDEX.SIDEBAR_TRIGGER }}\n {...props}\n >\n {isCollapsed ? <PanelLeftOpenIcon /> : <PanelLeftCloseIcon />}\n </button>\n );\n },\n);\nSidebarTrigger.displayName = 'SidebarTrigger';\n\nconst SidebarHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n },\n);\nSidebarHeader.displayName = 'SidebarHeader';\n\nconst SidebarContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-1 flex-col gap-2 overflow-auto', className)}\n {...props}\n />\n );\n },\n);\nSidebarContent.displayName = 'SidebarContent';\n\nconst SidebarFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 p-2', className)}\n {...props}\n />\n );\n },\n);\nSidebarFooter.displayName = 'SidebarFooter';\n\nconst SidebarGroup = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('group/sidebar-group', className)}\n {...props}\n />\n );\n },\n);\nSidebarGroup.displayName = 'SidebarGroup';\n\nconst SidebarGroupLabel = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opa] ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0',\n className,\n )}\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n {...props}\n />\n );\n },\n);\nSidebarGroupLabel.displayName = 'SidebarGroupLabel';\n\nconst SidebarGroupAction = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n asChild?: boolean;\n }\n>(({ className, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1.5 text-sidebar-foreground outline-none ring-sidebar-ring transition-opacity hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:opacity-100 focus-visible:ring-2 group-hover/sidebar-group:opacity-100 peer-data-[size=sm]/sidebar-group-action:opacity-0 [&>svg]:size-4 [&>svg]:shrink-0',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarGroupAction.displayName = 'SidebarGroupAction';\n\nconst SidebarGroupContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('w-full text-sm', className)}\n {...props}\n />\n );\n },\n);\nSidebarGroupContent.displayName = 'SidebarGroupContent';\n\nconst sidebarMenuButtonVariants = cva(\n 'flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm transition-colors hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:bg-sidebar-accent focus-visible:text-sidebar-accent-foreground focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground',\n {\n variants: {\n variant: {\n default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\n outline:\n 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-ring))]',\n },\n size: {\n default: 'h-8 text-sm',\n sm: 'h-7 text-xs',\n lg: 'h-12 text-base',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nconst SidebarMenuButton = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> &\n VariantProps<typeof sidebarMenuButtonVariants> & {\n asChild?: boolean;\n isActive?: boolean;\n }\n>(({ className, variant, size, asChild = false, isActive, children, ...props }, ref) => {\n const { isCollapsed } = useSidebar();\n const Comp = asChild ? Slot : 'button';\n\n return (\n <Comp\n ref={ref}\n data-active={isActive}\n data-collapsed={isCollapsed}\n className={cn(\n sidebarMenuButtonVariants({ variant, size }),\n isCollapsed && 'justify-center',\n className,\n )}\n {...props}\n >\n {children}\n </Comp>\n );\n});\nSidebarMenuButton.displayName = 'SidebarMenuButton';\n\nconst SidebarMenu = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(\n ({ className, ...props }, ref) => {\n return (\n <ul\n ref={ref}\n className={cn('flex w-full min-w-0 flex-col gap-1', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenu.displayName = 'SidebarMenu';\n\nconst SidebarMenuItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, ...props }, ref) => {\n return (\n <li\n ref={ref}\n className={cn('group/menu-item relative', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenuItem.displayName = 'SidebarMenuItem';\n\nconst SidebarMenuAction = forwardRef<\n HTMLButtonElement,\n ButtonHTMLAttributes<HTMLButtonElement> & {\n asChild?: boolean;\n }\n>(({ className, asChild = false, ...props }, ref) => {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 flex -translate-y-1/2 items-center justify-center rounded-md p-1 text-sidebar-foreground opacity-0 transition-opacity group-hover/menu-item:opacity-100 group-focus/menu-item:opacity-100 [&:has(~:hover)]:opacity-100 [&:has(~:focus)]:opacity-100',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarMenuAction.displayName = 'SidebarMenuAction';\n\nconst SidebarMenuBadge = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'absolute right-2 top-1/2 flex -translate-y-1/2 items-center justify-center rounded-md px-1.5 py-0.5 text-xs font-medium tabular-nums text-sidebar-foreground',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebarMenuBadge.displayName = 'SidebarMenuBadge';\n\nconst SidebarMenuSkeleton = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement> & {\n showIcon?: boolean;\n }\n>(({ className, showIcon = false, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('flex items-center gap-2 px-2 py-1.5', className)}\n {...props}\n >\n {showIcon && <div className=\"flex h-4 w-4 rounded-md bg-sidebar-primary/10\" />}\n <div className=\"flex flex-1 flex-col gap-1.5\">\n <div className=\"h-2.5 w-16 rounded-md bg-sidebar-primary/10\" />\n <div className=\"h-2.5 w-24 rounded-md bg-sidebar-primary/10\" />\n </div>\n </div>\n );\n});\nSidebarMenuSkeleton.displayName = 'SidebarMenuSkeleton';\n\nconst SidebarMenuSub = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(\n ({ className, ...props }, ref) => {\n return (\n <ul\n ref={ref}\n className={cn(\n 'ml-4 mt-1 flex min-w-0 flex-col gap-0.5 border-l border-sidebar-border pl-2.5',\n className,\n )}\n {...props}\n />\n );\n },\n);\nSidebarMenuSub.displayName = 'SidebarMenuSub';\n\nconst SidebarMenuSubButton = forwardRef<\n HTMLAnchorElement,\n AnchorHTMLAttributes<HTMLAnchorElement> & {\n asChild?: boolean;\n size?: 'sm' | 'md' | 'lg';\n isActive?: boolean;\n }\n>(({ className, asChild = false, size = 'md', isActive, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a';\n return (\n <Comp\n ref={ref}\n data-size={size}\n data-active={isActive}\n className={cn(\n 'flex min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md p-2 text-sidebar-foreground outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0',\n size === 'sm' && 'text-xs',\n size === 'md' && 'text-sm',\n size === 'lg' && 'text-base',\n className,\n )}\n {...props}\n />\n );\n});\nSidebarMenuSubButton.displayName = 'SidebarMenuSubButton';\n\nconst SidebarMenuSubItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(\n ({ className, ...props }, ref) => {\n return (\n <li\n ref={ref}\n className={cn('group/menu-sub-item relative', className)}\n {...props}\n />\n );\n },\n);\nSidebarMenuSubItem.displayName = 'SidebarMenuSubItem';\n\nexport {\n Sidebar,\n SidebarProvider,\n SidebarTrigger,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarGroupAction,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarMenuAction,\n SidebarMenuBadge,\n SidebarMenuSkeleton,\n SidebarMenuSub,\n SidebarMenuSubButton,\n SidebarMenuSubItem,\n useSidebar,\n};\n","import type { NavigationItem, NavigationGroup, LocalizedString } from '../config/types';\n\n/** Resolve a localized string to a single string for the given language. */\nexport function resolveLocalizedString(value: LocalizedString | undefined, lang: string): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Flatten navigation items from groups or flat array. */\nexport function flattenNavigationItems(\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] {\n if (navigation.length === 0) {\n return [];\n }\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) {\n return (item as NavigationGroup).items;\n }\n return item as NavigationItem;\n });\n}\n\nexport type Viewport = 'mobile' | 'desktop';\n\n/** Filter navigation by viewport: remove hidden and viewport-specific hidden items (and empty groups). */\nexport function filterNavigationByViewport(\n navigation: (NavigationItem | NavigationGroup)[],\n viewport: Viewport,\n): (NavigationItem | NavigationGroup)[] {\n if (navigation.length === 0) return [];\n const hideOnMobile = viewport === 'mobile';\n const hideOnDesktop = viewport === 'desktop';\n return navigation\n .map((item) => {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n const visibleItems = group.items.filter((navItem) => {\n if (navItem.hidden) return false;\n if (hideOnMobile && navItem.hiddenOnMobile) return false;\n if (hideOnDesktop && navItem.hiddenOnDesktop) return false;\n return true;\n });\n if (visibleItems.length === 0) return null;\n return { ...group, items: visibleItems };\n }\n const navItem = item as NavigationItem;\n if (navItem.hidden) return null;\n if (hideOnMobile && navItem.hiddenOnMobile) return null;\n if (hideOnDesktop && navItem.hiddenOnDesktop) return null;\n return item;\n })\n .filter((item): item is NavigationItem | NavigationGroup => item !== null);\n}\n\n/** Filter navigation for sidebar: remove hidden items and groups that become empty. */\nexport function filterNavigationForSidebar(\n navigation: (NavigationItem | NavigationGroup)[],\n): (NavigationItem | NavigationGroup)[] {\n if (navigation.length === 0) return [];\n return navigation\n .map((item) => {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n const visibleItems = group.items.filter((navItem) => !navItem.hidden);\n if (visibleItems.length === 0) return null;\n return { ...group, items: visibleItems };\n }\n const navItem = item as NavigationItem;\n if (navItem.hidden) return null;\n return item;\n })\n .filter((item): item is NavigationItem | NavigationGroup => item !== null);\n}\n\n/** Split navigation by position: start (main content) and end (footer). */\nexport function splitNavigationByPosition(navigation: (NavigationItem | NavigationGroup)[]): {\n start: (NavigationItem | NavigationGroup)[];\n end: NavigationItem[];\n} {\n const start: (NavigationItem | NavigationGroup)[] = [];\n const end: NavigationItem[] = [];\n for (const item of navigation) {\n const position = 'position' in item ? (item.position ?? 'start') : 'start';\n if (position === 'end') {\n if ('title' in item && 'items' in item) {\n const group = item as NavigationGroup;\n end.push(...group.items.filter((navItem) => !navItem.hidden));\n } else {\n const navItem = item as NavigationItem;\n if (!navItem.hidden) end.push(navItem);\n }\n } else {\n start.push(item);\n }\n }\n return { start, end };\n}\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';\n\n/**\n * Validates and normalizes a URL to ensure it's from the same domain or localhost\n * @param url - The URL or path to validate\n * @returns The normalized absolute URL or null if invalid\n */\nexport const validateAndNormalizeUrl = (url: string | undefined | null): string | null => {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n try {\n // If it's already an absolute URL, check if it's same origin or localhost\n if (url.startsWith('http://') || url.startsWith('https://')) {\n const urlObj = new URL(url);\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n\n // Allow same origin\n if (urlObj.origin === currentOrigin) {\n return url;\n }\n\n // Allow localhost URLs (for development)\n if (urlObj.hostname === 'localhost' || urlObj.hostname === '127.0.0.1') {\n return url;\n }\n\n return null; // Different origin, reject for security\n }\n\n // If it's a relative URL, make it absolute using current origin\n if (url.startsWith('/') || url.startsWith('./') || !url.startsWith('//')) {\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n // Ensure relative paths start with /\n const normalizedPath = url.startsWith('/') ? url : `/${url}`;\n return `${currentOrigin}${normalizedPath}`;\n }\n\n // Reject protocol-relative URLs (//example.com) for security\n return null;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.error('Invalid URL:', url, error);\n return null;\n }\n};\n\ninterface ModalContextValue {\n isOpen: boolean;\n modalUrl: string | null;\n openModal: (url?: string) => void;\n closeModal: () => void;\n}\n\nconst ModalContext = createContext<ModalContextValue | undefined>(undefined);\n\nexport const useModal = () => {\n const context = useContext(ModalContext);\n if (!context) {\n throw new Error('useModal must be used within a ModalProvider');\n }\n return context;\n};\n\ninterface ModalProviderProps {\n children: ReactNode;\n}\n\nexport const ModalProvider = ({ children }: ModalProviderProps) => {\n const [isOpen, setIsOpen] = useState(false);\n const [modalUrl, setModalUrl] = useState<string | null>(null);\n\n const openModal = useCallback((url?: string) => {\n const validatedUrl = url ? validateAndNormalizeUrl(url) : null;\n setModalUrl(validatedUrl);\n setIsOpen(true);\n }, []);\n\n const closeModal = useCallback(() => {\n setIsOpen(false);\n // Clear URL after a short delay to allow animation to complete\n setTimeout(() => setModalUrl(null), 200);\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n const cleanupOpenModal = shellui.addMessageListener(\n 'SHELLUI_OPEN_MODAL',\n (data: ShellUIMessage) => {\n const payload = data.payload as { url?: string };\n openModal(payload.url);\n },\n );\n\n const cleanupCloseModal = shellui.addMessageListener('SHELLUI_CLOSE_MODAL', () => {\n closeModal();\n });\n\n return () => {\n cleanupOpenModal();\n cleanupCloseModal();\n };\n }, [openModal, closeModal]);\n\n return (\n <ModalContext.Provider value={{ isOpen, modalUrl, openModal, closeModal }}>\n {children}\n </ModalContext.Provider>\n );\n};\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from 'react';\nimport type { DrawerDirection } from '@/components/ui/drawer';\nimport { useModal } from '../modal/ModalContext';\n\n/**\n * Validates and normalizes a URL for the drawer iframe.\n * Allows same-origin, localhost, and external http(s) URLs (e.g. from nav config).\n */\nconst validateAndNormalizeUrl = (url: string | undefined | null): string | null => {\n if (!url || typeof url !== 'string') {\n return null;\n }\n\n try {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n new URL(url); // validate\n return url;\n }\n\n if (url.startsWith('/') || url.startsWith('./') || !url.startsWith('//')) {\n const currentOrigin = typeof window !== 'undefined' ? window.location.origin : '';\n const normalizedPath = url.startsWith('/') ? url : `/${url}`;\n return `${currentOrigin}${normalizedPath}`;\n }\n\n return null;\n } catch {\n return null;\n }\n};\n\nexport const DEFAULT_DRAWER_POSITION: DrawerDirection = 'right';\n\ninterface OpenDrawerOptions {\n url?: string;\n position?: DrawerDirection;\n /** CSS length: height for top/bottom (e.g. \"80vh\", \"400px\"), width for left/right (e.g. \"50vw\", \"320px\") */\n size?: string;\n}\n\ninterface DrawerContextValue {\n isOpen: boolean;\n drawerUrl: string | null;\n position: DrawerDirection;\n size: string | null;\n openDrawer: (options?: OpenDrawerOptions) => void;\n closeDrawer: () => void;\n}\n\nconst DrawerContext = createContext<DrawerContextValue | undefined>(undefined);\n\nexport const useDrawer = () => {\n const context = useContext(DrawerContext);\n if (!context) {\n throw new Error('useDrawer must be used within a DrawerProvider');\n }\n return context;\n};\n\ninterface DrawerProviderProps {\n children: ReactNode;\n}\n\nexport const DrawerProvider = ({ children }: DrawerProviderProps) => {\n const { closeModal } = useModal();\n const [isOpen, setIsOpen] = useState(false);\n const [drawerUrl, setDrawerUrl] = useState<string | null>(null);\n const [position, setPosition] = useState<DrawerDirection>(DEFAULT_DRAWER_POSITION);\n const [size, setSize] = useState<string | null>(null);\n\n const openDrawer = useCallback(\n (options?: OpenDrawerOptions) => {\n closeModal();\n const url = options?.url;\n const validatedUrl = url ? validateAndNormalizeUrl(url) : null;\n setDrawerUrl(validatedUrl);\n setPosition(options?.position ?? DEFAULT_DRAWER_POSITION);\n setSize(options?.size ?? null);\n setIsOpen(true);\n },\n [closeModal],\n );\n\n const closeDrawer = useCallback(() => {\n setIsOpen(false);\n // Do not reset drawerUrl/position here — Vaul's close animation uses the current\n // direction. Resetting position (e.g. to 'right') mid-animation would make\n // non-right drawers jump. State is set on next openDrawer().\n }, []);\n\n useEffect(() => {\n const cleanupOpen = shellui.addMessageListener(\n 'SHELLUI_OPEN_DRAWER',\n (data: ShellUIMessage) => {\n const payload = data.payload as { url?: string; position?: DrawerDirection; size?: string };\n openDrawer({ url: payload.url, position: payload.position, size: payload.size });\n },\n );\n\n const cleanupClose = shellui.addMessageListener('SHELLUI_CLOSE_DRAWER', () => {\n closeDrawer();\n });\n\n return () => {\n cleanupOpen();\n cleanupClose();\n };\n }, [openDrawer, closeDrawer]);\n\n return (\n <DrawerContext.Provider value={{ isOpen, drawerUrl, position, size, openDrawer, closeDrawer }}>\n {children}\n </DrawerContext.Provider>\n );\n};\n","import { shellui, type ShellUIMessage } from '@shellui/sdk';\nimport { createContext, useContext, useCallback, useEffect, type ReactNode } from 'react';\nimport { toast as sonnerToast } from 'sonner';\n\ninterface ToastOptions {\n id?: string;\n title?: string;\n description?: string;\n type?: 'default' | 'success' | 'error' | 'warning' | 'info' | 'loading';\n duration?: number;\n position?:\n | 'top-left'\n | 'top-center'\n | 'top-right'\n | 'bottom-left'\n | 'bottom-center'\n | 'bottom-right';\n action?: {\n label: string;\n onClick: () => void;\n };\n cancel?: {\n label: string;\n onClick: () => void;\n };\n onDismiss?: () => void;\n onAutoClose?: () => void;\n}\n\ninterface SonnerContextValue {\n toast: (options: ToastOptions) => void;\n}\n\nconst SonnerContext = createContext<SonnerContextValue | undefined>(undefined);\n\nexport function useSonner() {\n const context = useContext(SonnerContext);\n if (!context) {\n throw new Error('useSonner must be used within a SonnerProvider');\n }\n return context;\n}\n\ninterface SonnerProviderProps {\n children: ReactNode;\n}\n\nexport const SonnerProvider = ({ children }: SonnerProviderProps) => {\n const toast = useCallback((options: ToastOptions) => {\n const {\n id,\n title,\n description,\n type = 'default',\n duration,\n position,\n action,\n cancel,\n onDismiss,\n onAutoClose,\n } = options;\n\n const toastOptions: Parameters<typeof sonnerToast>[1] = {\n id,\n duration,\n position,\n action: action\n ? {\n label: action.label,\n onClick: action.onClick,\n }\n : undefined,\n cancel: cancel\n ? {\n label: cancel.label,\n onClick: cancel.onClick,\n }\n : undefined,\n onDismiss: onDismiss,\n onAutoClose: onAutoClose,\n };\n\n // If ID is provided, this is an update operation\n if (id) {\n switch (type) {\n case 'success':\n sonnerToast.success(title || 'Success', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'error':\n sonnerToast.error(title || 'Error', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'warning':\n sonnerToast.warning(title || 'Warning', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'info':\n sonnerToast.info(title || 'Info', {\n id,\n description,\n ...toastOptions,\n });\n break;\n case 'loading':\n sonnerToast.loading(title || 'Loading...', {\n id,\n description,\n ...toastOptions,\n });\n break;\n default:\n sonnerToast(title || 'Notification', {\n id,\n description,\n ...toastOptions,\n });\n break;\n }\n return;\n }\n\n // Create new toast\n switch (type) {\n case 'success':\n sonnerToast.success(title || 'Success', {\n description,\n ...toastOptions,\n });\n break;\n case 'error':\n sonnerToast.error(title || 'Error', {\n description,\n ...toastOptions,\n });\n break;\n case 'warning':\n sonnerToast.warning(title || 'Warning', {\n description,\n ...toastOptions,\n });\n break;\n case 'info':\n sonnerToast.info(title || 'Info', {\n description,\n ...toastOptions,\n });\n break;\n case 'loading':\n sonnerToast.loading(title || 'Loading...', {\n description,\n ...toastOptions,\n });\n break;\n default:\n sonnerToast(title || 'Notification', {\n description,\n ...toastOptions,\n });\n break;\n }\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n const cleanupToast = shellui.addMessageListener('SHELLUI_TOAST', (data: ShellUIMessage) => {\n const payload = data.payload as ToastOptions;\n toast({\n ...payload,\n onDismiss: () => {\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CLEAR',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n onAutoClose: () => {\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CLEAR',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n action:\n payload.action &&\n (() => {\n let actionSent = false;\n return {\n label: payload.action?.label ?? undefined,\n onClick: () => {\n if (actionSent) return;\n actionSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_ACTION',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n cancel:\n payload.cancel &&\n (() => {\n let cancelSent = false;\n return {\n label: payload.cancel?.label ?? undefined,\n onClick: () => {\n if (cancelSent) return;\n cancelSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CANCEL',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n });\n });\n\n const cleanupToastUpdate = shellui.addMessageListener(\n 'SHELLUI_TOAST_UPDATE',\n (data: ShellUIMessage) => {\n const payload = data.payload as ToastOptions;\n // CRITICAL: When updating a toast, we MUST re-register action handlers\n // The callbackRegistry still has the callbacks, but the toast button needs onClick handlers\n // that trigger the callbackRegistry via SHELLUI_TOAST_ACTION messages\n toast({\n ...payload,\n // Re-register action handlers so the button works after update\n // These handlers send messages that trigger the callbackRegistry\n action:\n payload.action &&\n (() => {\n let actionSent = false;\n return {\n label: payload.action?.label ?? undefined,\n onClick: () => {\n if (actionSent) return;\n actionSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_ACTION',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n cancel:\n payload.cancel &&\n (() => {\n let cancelSent = false;\n return {\n label: payload.cancel?.label ?? undefined,\n onClick: () => {\n if (cancelSent) return;\n cancelSent = true;\n shellui.sendMessage({\n type: 'SHELLUI_TOAST_CANCEL',\n payload: { id: payload.id },\n to: data.from,\n });\n },\n };\n })(),\n });\n },\n );\n\n return () => {\n cleanupToast();\n cleanupToastUpdate();\n };\n }, [toast]);\n\n return <SonnerContext.Provider value={{ toast }}>{children}</SonnerContext.Provider>;\n};\n","import type { ReactNode } from 'react';\nimport { ModalProvider } from '../modal/ModalContext';\nimport { DrawerProvider } from '../drawer/DrawerContext';\nimport { SonnerProvider } from '../sonner/SonnerContext';\n\ninterface LayoutProvidersProps {\n children: ReactNode;\n}\n\n/** Wraps layout content with Modal, Drawer and Sonner providers.\n * Note: DialogProvider is now at the app level in app.tsx */\nexport function LayoutProviders({ children }: LayoutProvidersProps) {\n return (\n <ModalProvider>\n <DrawerProvider>\n <SonnerProvider>{children}</SonnerProvider>\n </DrawerProvider>\n </ModalProvider>\n );\n}\n","import {\n forwardRef,\n useCallback,\n Children,\n type ElementRef,\n type ComponentPropsWithoutRef,\n type ComponentProps,\n type HTMLAttributes,\n} from 'react';\nimport * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\nconst Dialog = DialogPrimitive.Root;\n\nconst DialogTrigger = DialogPrimitive.Trigger;\n\nconst DialogPortal = DialogPrimitive.Portal;\n\nconst DialogClose = DialogPrimitive.Close;\n\nconst DialogOverlay = forwardRef<\n ElementRef<typeof DialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Overlay\n ref={ref}\n data-dialog-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.MODAL_OVERLAY }}\n {...props}\n />\n));\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;\n\ninterface DialogContentProps extends ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {\n /** When true, the default close (X) button is not rendered. Escape and overlay still close. */\n hideCloseButton?: boolean;\n}\n\nconst DialogContent = forwardRef<ElementRef<typeof DialogPrimitive.Content>, DialogContentProps>(\n ({ className, children, onPointerDownOutside, hideCloseButton, ...props }, ref) => {\n const hasContent = Children.count(children) > 2;\n\n const handlePointerDownOutside = useCallback(\n (\n event: Parameters<NonNullable<ComponentProps<typeof DialogPrimitive.Content>['onPointerDownOutside']>>[0],\n ) => {\n const target = event?.target as Element | null;\n if (target?.closest?.('[data-sonner-toaster]')) {\n event.preventDefault();\n }\n onPointerDownOutside?.(event);\n },\n [onPointerDownOutside],\n );\n\n return (\n <DialogPortal>\n <DialogOverlay />\n <DialogPrimitive.Content\n ref={ref}\n data-dialog-content\n data-has-content={hasContent}\n className={cn(\n 'fixed left-[50%] top-[50%] grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-6 border bg-background px-6 pt-0 pb-0 shadow-lg sm:rounded-lg',\n 'data-[has-content=false]:gap-0 data-[has-content=false]:[&>[data-dialog-header]]:border-b-0 data-[has-content=false]:[&>[data-dialog-header]]:pb-0',\n className,\n )}\n style={{ backgroundColor: 'hsl(var(--background))', zIndex: Z_INDEX.MODAL_CONTENT }}\n onPointerDownOutside={handlePointerDownOutside}\n {...props}\n >\n {children}\n {!hideCloseButton && (\n <DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground cursor-pointer\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n <span className=\"sr-only\">Close</span>\n </DialogPrimitive.Close>\n )}\n </DialogPrimitive.Content>\n </DialogPortal>\n );\n },\n);\nDialogContent.displayName = DialogPrimitive.Content.displayName;\n\nconst DialogHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-dialog-header\n className={cn(\n '-mx-6 flex flex-col space-y-2.5 border-b border-border/60 px-6 pt-5 pb-4 text-left',\n className,\n )}\n {...props}\n />\n);\nDialogHeader.displayName = 'DialogHeader';\n\nconst DialogFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n '-mx-6 mt-4 flex flex-col-reverse gap-2 rounded-b-lg border-t border-border bg-sidebar-background px-6 py-2 text-sidebar-foreground sm:flex-row sm:justify-end sm:space-x-2 [&_button]:h-8 [&_button]:px-3 [&_button]:text-xs',\n className,\n )}\n {...props}\n />\n);\nDialogFooter.displayName = 'DialogFooter';\n\nconst DialogTitle = forwardRef<\n ElementRef<typeof DialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDialogTitle.displayName = DialogPrimitive.Title.displayName;\n\nconst DialogDescription = forwardRef<\n ElementRef<typeof DialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof DialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <DialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nDialogDescription.displayName = DialogPrimitive.Description.displayName;\n\nexport {\n Dialog,\n DialogPortal,\n DialogOverlay,\n DialogClose,\n DialogTrigger,\n DialogContent,\n DialogHeader,\n DialogFooter,\n DialogTitle,\n DialogDescription,\n};\n","'use client';\n\nimport {\n forwardRef,\n type ComponentProps,\n type ComponentPropsWithoutRef,\n type ComponentRef,\n type ReactNode,\n type CSSProperties,\n type HTMLAttributes,\n} from 'react';\nimport { Drawer as VaulDrawer } from 'vaul';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\nexport type DrawerDirection = 'top' | 'bottom' | 'left' | 'right';\n\nconst Drawer = ({\n open,\n onOpenChange,\n direction = 'right',\n ...props\n}: ComponentProps<typeof VaulDrawer.Root> & {\n direction?: DrawerDirection;\n}) => (\n <VaulDrawer.Root\n open={open}\n onOpenChange={onOpenChange}\n direction={direction}\n {...props}\n />\n);\nDrawer.displayName = 'Drawer';\n\nconst DrawerTrigger = VaulDrawer.Trigger;\nDrawerTrigger.displayName = 'DrawerTrigger';\n\nconst DrawerPortal = VaulDrawer.Portal;\n(DrawerPortal as unknown as { displayName: string }).displayName = 'DrawerPortal';\n\nconst DrawerOverlay = forwardRef<\n ComponentRef<typeof VaulDrawer.Overlay>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Overlay>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Overlay\n ref={ref}\n data-drawer-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.DRAWER_OVERLAY }}\n {...props}\n />\n));\nDrawerOverlay.displayName = VaulDrawer.Overlay.displayName;\n\n/** Base layout classes per direction — max dimension is applied via style so size prop can override. */\nconst drawerContentByDirection: Record<DrawerDirection, string> = {\n bottom: 'fixed inset-x-0 bottom-0 mt-24 flex h-auto flex-col border border-border bg-background',\n top: 'fixed inset-x-0 top-0 mb-24 flex h-auto flex-col border border-border bg-background',\n left: 'fixed inset-y-0 left-0 mr-24 flex h-full w-auto flex-col border border-border bg-background',\n right:\n 'fixed inset-y-0 right-0 ml-24 flex h-full w-auto flex-col border border-border bg-background',\n};\n\ninterface DrawerContentProps extends Omit<\n ComponentPropsWithoutRef<typeof VaulDrawer.Content>,\n 'direction'\n> {\n direction?: DrawerDirection;\n /** CSS length: height for top/bottom (e.g. \"80vh\", \"400px\"), width for left/right (e.g. \"50vw\", \"320px\") */\n size?: string | null;\n className?: string;\n children?: ReactNode;\n style?: CSSProperties;\n}\n\nconst DrawerContent = forwardRef<ComponentRef<typeof VaulDrawer.Content>, DrawerContentProps>(\n ({ className, direction = 'right', size, children, style, ...props }, ref) => {\n const pos: DrawerDirection = direction;\n const isVertical = pos === 'top' || pos === 'bottom';\n // Set dimension via inline style; use both width/height and max so Vaul/defaults don't override.\n const effectiveSize = size?.trim() || (isVertical ? '80vh' : '80vw');\n const sizeStyle = isVertical\n ? { height: effectiveSize, maxHeight: effectiveSize }\n : { width: effectiveSize, maxWidth: effectiveSize };\n return (\n <DrawerPortal>\n <DrawerOverlay />\n <VaulDrawer.Content\n ref={ref}\n data-drawer-content\n className={cn('outline-none', drawerContentByDirection[pos], className)}\n style={{\n backgroundColor: 'hsl(var(--background))',\n zIndex: Z_INDEX.DRAWER_CONTENT,\n ...sizeStyle,\n ...style,\n }}\n {...props}\n >\n {children}\n <VaulDrawer.Close\n className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground cursor-pointer\"\n aria-label=\"Close\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n <span className=\"sr-only\">Close</span>\n </VaulDrawer.Close>\n </VaulDrawer.Content>\n </DrawerPortal>\n );\n },\n);\nDrawerContent.displayName = 'DrawerContent';\n\nconst DrawerClose = VaulDrawer.Close;\nDrawerClose.displayName = 'DrawerClose';\n\nconst DrawerHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-drawer-header\n className={cn(\n 'flex flex-col space-y-2 border-b border-border/60 px-6 pt-5 pb-4 text-left',\n className,\n )}\n {...props}\n />\n);\nDrawerHeader.displayName = 'DrawerHeader';\n\nconst DrawerFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'mt-auto flex flex-col-reverse gap-2 border-t border-border px-6 py-4 sm:flex-row sm:justify-end',\n className,\n )}\n {...props}\n />\n);\nDrawerFooter.displayName = 'DrawerFooter';\n\nconst DrawerTitle = forwardRef<\n ComponentRef<typeof VaulDrawer.Title>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Title>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nDrawerTitle.displayName = VaulDrawer.Title.displayName;\n\nconst DrawerDescription = forwardRef<\n ComponentRef<typeof VaulDrawer.Description>,\n ComponentPropsWithoutRef<typeof VaulDrawer.Description>\n>(({ className, ...props }, ref) => (\n <VaulDrawer.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nDrawerDescription.displayName = VaulDrawer.Description.displayName;\n\nconst DrawerHandle = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n data-drawer-handle\n className={cn('mx-auto mt-4 h-2 w-[100px] rounded-full bg-muted', className)}\n {...props}\n />\n);\nDrawerHandle.displayName = 'DrawerHandle';\n\nexport {\n Drawer,\n DrawerTrigger,\n DrawerPortal,\n DrawerOverlay,\n DrawerContent,\n DrawerClose,\n DrawerHeader,\n DrawerFooter,\n DrawerTitle,\n DrawerDescription,\n DrawerHandle,\n};\n","import { useContext } from 'react';\nimport { SettingsContext } from '../SettingsContext';\n\nexport function useSettings() {\n const context = useContext(SettingsContext);\n if (context === undefined) {\n throw new Error('useSettings must be used within a SettingsProvider');\n }\n return context;\n}\n","import type { ComponentProps } from 'react';\nimport { useSettings } from '@/features/settings/hooks/useSettings';\nimport { Toaster as Sonner } from 'sonner';\nimport { Z_INDEX } from '@/lib/z-index';\n\ntype ToasterProps = ComponentProps<typeof Sonner>;\n\nconst Toaster = ({ ...props }: ToasterProps) => {\n const { settings } = useSettings();\n\n return (\n <Sonner\n position=\"top-center\"\n theme={settings.appearance.theme as 'light' | 'dark' | 'system'}\n className=\"toaster group\"\n style={{\n zIndex: Z_INDEX.TOAST,\n // Re-enable pointer events so toasts stay clickable when a Radix modal is open\n // (Radix sets body.style.pointerEvents = 'none' and only the dialog content gets 'auto')\n pointerEvents: 'auto',\n }}\n toastOptions={{\n classNames: {\n toast:\n 'group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border-border group-[.toaster]:shadow-lg',\n description: 'group-[.toast]:text-muted-foreground',\n actionButton: 'group-[.toast]:bg-primary group-[.toast]:text-primary-foreground',\n cancelButton: 'group-[.toast]:bg-muted group-[.toast]:text-muted-foreground',\n },\n }}\n {...props}\n />\n );\n};\n\nexport { Toaster };\n","export function LoadingOverlay() {\n return (\n <div className=\"absolute inset-0 z-10 flex flex-col bg-background\">\n <div className=\"h-1 w-full overflow-hidden bg-muted/30\">\n <div\n className=\"h-full w-0 bg-muted-foreground/50\"\n style={{ animation: 'loading-bar-slide 400ms linear infinite' }}\n />\n </div>\n </div>\n );\n}\n","/* eslint-disable no-console */\nimport type { NavigationItem } from '@/features/config/types';\nimport {\n addIframe,\n removeIframe,\n shellui,\n getLogger,\n type ShellUIUrlPayload,\n type ShellUIMessage,\n} from '@shellui/sdk';\nimport { useEffect, useRef, useState } from 'react';\nimport { useNavigate } from 'react-router';\nimport { LoadingOverlay } from './LoadingOverlay';\n\nconst logger = getLogger('shellcore');\n\ninterface ContentViewProps {\n url: string;\n pathPrefix: string;\n ignoreMessages?: boolean;\n navItem: NavigationItem;\n}\n\nexport const ContentView = ({\n url,\n pathPrefix,\n ignoreMessages = false,\n navItem,\n}: ContentViewProps) => {\n const navigate = useNavigate();\n const iframeRef = useRef<HTMLIFrameElement>(null);\n const isInternalNavigation = useRef(false);\n const [initialUrl] = useState(url);\n const [isLoading, setIsLoading] = useState(true);\n\n useEffect(() => {\n if (!iframeRef.current) {\n return;\n }\n const iframeId = addIframe(iframeRef.current);\n return () => {\n removeIframe(iframeId);\n };\n }, []);\n\n // Sync parent URL when iframe notifies us of a change\n useEffect(() => {\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_URL_CHANGED',\n (data: ShellUIMessage, event: MessageEvent) => {\n if (ignoreMessages) {\n return;\n }\n\n // Ignore URL CHANGE from other than ContentView iframe\n if (event.source !== iframeRef.current?.contentWindow) {\n return;\n }\n\n const { pathname, search, hash } = data.payload as ShellUIUrlPayload;\n // Remove leading slash and trailing slashes from iframe pathname\n let cleanPathname = pathname.startsWith(navItem.url)\n ? pathname.slice(navItem.url.length)\n : pathname;\n cleanPathname = cleanPathname.startsWith('/') ? cleanPathname.slice(1) : cleanPathname;\n cleanPathname = cleanPathname.replace(/\\/+$/, ''); // Remove trailing slashes\n // Construct the new path without trailing slashes\n let newShellPath = cleanPathname\n ? `/${pathPrefix}/${cleanPathname}${search}${hash}`\n : `/${pathPrefix}${search}${hash}`;\n\n // Normalize: remove trailing slashes from pathname part only (preserve query/hash)\n const urlParts = newShellPath.match(/^([^?#]*)([?#].*)?$/);\n if (urlParts) {\n const pathnamePart = urlParts[1].replace(/\\/+$/, '') || '/';\n const queryHashPart = urlParts[2] || '';\n newShellPath = pathnamePart + queryHashPart;\n }\n\n // Normalize current path for comparison (remove trailing slashes from pathname)\n const currentPathname = window.location.pathname.replace(/\\/+$/, '') || '/';\n const currentPath = currentPathname + window.location.search + window.location.hash;\n\n // Normalize new path for comparison\n const newPathParts = newShellPath.match(/^([^?#]*)([?#].*)?$/);\n const normalizedNewPathname = newPathParts?.[1]?.replace(/\\/+$/, '') || '/';\n const normalizedNewPath = normalizedNewPathname + (newPathParts?.[2] || '');\n\n if (currentPath !== normalizedNewPath) {\n // Mark this navigation as internal so we don't try to \"push\" it back to the iframe\n isInternalNavigation.current = true;\n navigate(newShellPath, { replace: true });\n\n // Reset the flag after a short delay to allow the render cycle to complete\n setTimeout(() => {\n isInternalNavigation.current = false;\n }, 100);\n }\n },\n );\n\n return () => {\n cleanup();\n };\n }, [pathPrefix, navigate]);\n\n // Hide loading overlay when iframe sends SHELLUI_INITIALIZED\n useEffect(() => {\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_INITIALIZED',\n (_data: ShellUIMessage, event: MessageEvent) => {\n if (event.source === iframeRef.current?.contentWindow) {\n setIsLoading(false);\n }\n },\n );\n return () => cleanup();\n }, []);\n\n // Fallback: hide overlay after 400ms if SHELLUI_INITIALIZED was not received\n useEffect(() => {\n if (!isLoading) return;\n const timeoutId = setTimeout(() => {\n logger.info('ContentView: Timeout expired, hiding loading overlay');\n setIsLoading(false);\n }, 400);\n return () => clearTimeout(timeoutId);\n }, [isLoading]);\n\n // Handle external URL changes (e.g. from Sidebar)\n useEffect(() => {\n if (iframeRef.current && !isInternalNavigation.current) {\n // Only update iframe src if it's actually different from its current src\n // to avoid unnecessary reloads\n if (iframeRef.current.src !== url) {\n iframeRef.current.src = url;\n setIsLoading(true);\n }\n }\n }, [url]);\n\n // Inject script to prevent \"Layout was forced\" warning by deferring layout until stylesheets load\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n const handleLoad = () => {\n try {\n const iframeWindow = iframe.contentWindow;\n const iframeDoc = iframe.contentDocument || iframeWindow?.document;\n if (!iframeDoc || !iframeWindow) return;\n\n // Inject a script that waits for stylesheets before allowing layout calculations\n const script = iframeDoc.createElement('script');\n script.textContent = `\n (function() {\n // Wait for all stylesheets to load\n function waitForStylesheets() {\n const styleSheets = Array.from(document.styleSheets);\n const pendingSheets = styleSheets.filter(function(sheet) {\n try {\n return sheet.cssRules === null;\n } catch (e) {\n return false; // Cross-origin stylesheets, assume loaded\n }\n });\n \n if (pendingSheets.length === 0) {\n // All stylesheets loaded\n return;\n }\n \n // Check again after a short delay\n setTimeout(waitForStylesheets, 10);\n }\n \n // Start checking after DOM is ready\n if (document.readyState === 'complete') {\n waitForStylesheets();\n } else {\n window.addEventListener('load', waitForStylesheets);\n }\n })();\n `;\n iframeDoc.head.appendChild(script);\n } catch (error) {\n // Cross-origin or other errors - ignore (this is expected for some iframes)\n logger.debug('Could not inject stylesheet wait script:', { error });\n }\n };\n\n // Wait for iframe to load before injecting script\n iframe.addEventListener('load', handleLoad);\n\n // Also try immediately if already loaded\n if (iframe.contentDocument?.readyState === 'complete') {\n handleLoad();\n }\n\n return () => {\n iframe.removeEventListener('load', handleLoad);\n };\n }, [initialUrl]);\n\n // Suppress browser warnings that are expected and acceptable\n useEffect(() => {\n if (process.env.NODE_ENV === 'development') {\n const originalWarn = console.warn;\n console.warn = (...args: unknown[]) => {\n const message = String(args[0] ?? '');\n // Suppress the specific sandbox warning\n if (\n message.includes('allow-scripts') &&\n message.includes('allow-same-origin') &&\n message.includes('sandbox')\n ) {\n return;\n }\n // Suppress \"Layout was forced\" warning from iframe content\n // This is a performance warning that occurs when iframe content calculates layout before stylesheets load\n // It's harmless and common in iframe scenarios, especially with React apps\n if (\n message.includes('Layout was forced') &&\n message.includes('before the page was fully loaded')\n ) {\n return;\n }\n originalWarn.apply(console, args);\n };\n return () => {\n console.warn = originalWarn;\n };\n }\n }, []);\n\n return (\n <div style={{ width: '100%', height: '100%', display: 'flex', position: 'relative' }}>\n {/* Note: allow-same-origin is required for same-origin iframe content (e.g., Vite dev server, cookies, localStorage).\n While this allows the iframe to remove its own sandboxing, it's acceptable here because the iframe content\n is trusted microfrontend content from the same application origin.\n Browser security warnings about this combination cannot be suppressed programmatically. */}\n <iframe\n ref={iframeRef}\n src={initialUrl}\n style={{\n width: '100%',\n height: '100%',\n border: 'none',\n display: 'block',\n }}\n title=\"Content Frame\"\n sandbox=\"allow-same-origin allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox\"\n referrerPolicy=\"no-referrer-when-downgrade\"\n />\n {isLoading && <LoadingOverlay />}\n </div>\n );\n};\n","import { useEffect, type ReactNode } from 'react';\nimport { useNavigate } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem } from '../config/types';\nimport { Dialog, DialogContent, DialogTitle, DialogDescription } from '@/components/ui/dialog';\nimport { Drawer, DrawerContent } from '@/components/ui/drawer';\nimport { Toaster } from '@/components/ui/sonner';\nimport { ContentView } from '@/components/ContentView';\nimport { useModal } from '../modal/ModalContext';\nimport { useDrawer } from '../drawer/DrawerContext';\nimport { resolveLocalizedString } from './utils';\n\ninterface OverlayShellProps {\n navigationItems: NavigationItem[];\n children: ReactNode;\n}\n\n/** Renders modal, drawer and toaster overlays and handles SHELLUI_OPEN_MODAL / SHELLUI_NAVIGATE. */\nexport function OverlayShell({ navigationItems, children }: OverlayShellProps) {\n const navigate = useNavigate();\n const { isOpen, modalUrl, closeModal } = useModal();\n const {\n isOpen: isDrawerOpen,\n drawerUrl,\n position: drawerPosition,\n size: drawerSize,\n closeDrawer,\n } = useDrawer();\n const { t, i18n } = useTranslation('common');\n const currentLanguage = i18n.language || 'en';\n\n useEffect(() => {\n const cleanup = shellui.addMessageListener('SHELLUI_OPEN_MODAL', () => {\n closeDrawer();\n });\n return () => cleanup();\n }, [closeDrawer]);\n\n useEffect(() => {\n const cleanup = shellui.addMessageListener('SHELLUI_NAVIGATE', (data) => {\n const payload = data.payload as { url?: string };\n const rawUrl = payload?.url;\n if (typeof rawUrl !== 'string' || !rawUrl.trim()) return;\n\n let pathname: string;\n if (rawUrl.startsWith('http://') || rawUrl.startsWith('https://')) {\n try {\n pathname = new URL(rawUrl).pathname;\n } catch {\n pathname = rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`;\n }\n } else {\n pathname = rawUrl.startsWith('/') ? rawUrl : `/${rawUrl}`;\n }\n\n closeModal();\n closeDrawer();\n\n const isHomepage = pathname === '/' || pathname === '';\n const isAllowed =\n isHomepage ||\n navigationItems.some(\n (item) => pathname === `/${item.path}` || pathname.startsWith(`/${item.path}/`),\n );\n if (isAllowed) {\n navigate(pathname || '/');\n } else {\n shellui.toast({\n type: 'error',\n title: t('navigationError') ?? 'Navigation error',\n description:\n t('navigationNotAllowed') ?? 'This URL is not configured in the app navigation.',\n });\n }\n });\n return () => cleanup();\n }, [navigate, closeModal, closeDrawer, navigationItems, t]);\n\n return (\n <>\n {children}\n <Dialog\n open={isOpen}\n onOpenChange={closeModal}\n >\n <DialogContent className=\"max-w-4xl w-full h-[80vh] max-h-[680px] flex flex-col p-0 overflow-hidden\">\n {modalUrl ? (\n <>\n <DialogTitle className=\"sr-only\">\n {resolveLocalizedString(\n navigationItems.find((item) => item.url === modalUrl)?.label,\n currentLanguage,\n )}\n </DialogTitle>\n <DialogDescription className=\"sr-only\">\n {t('modalContent') ?? 'Modal content'}\n </DialogDescription>\n <div\n className=\"flex-1\"\n style={{ minHeight: 0 }}\n >\n <ContentView\n url={modalUrl}\n pathPrefix=\"settings\"\n ignoreMessages={true}\n navItem={navigationItems.find((item) => item.url === modalUrl) as NavigationItem}\n />\n </div>\n </>\n ) : (\n <>\n <DialogTitle className=\"sr-only\">Error: Modal URL is undefined</DialogTitle>\n <DialogDescription className=\"sr-only\">\n The openModal function was called without a valid URL parameter.\n </DialogDescription>\n <div className=\"flex-1 p-4\">\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-4\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n Error: Modal URL is undefined\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n The <code className=\"text-xs bg-background px-1 py-0.5 rounded\">openModal</code>{' '}\n function was called without a valid URL parameter. Please ensure you provide a\n URL when opening the modal.\n </p>\n </div>\n </div>\n </>\n )}\n </DialogContent>\n </Dialog>\n <Drawer\n open={isDrawerOpen}\n onOpenChange={(open) => !open && closeDrawer()}\n direction={drawerPosition}\n >\n <DrawerContent\n direction={drawerPosition}\n size={drawerSize}\n className=\"p-0 overflow-hidden flex flex-col\"\n >\n {drawerUrl ? (\n <div className=\"flex-1 min-h-0 flex flex-col\">\n <ContentView\n url={drawerUrl}\n pathPrefix=\"settings\"\n ignoreMessages={true}\n navItem={navigationItems.find((item) => item.url === drawerUrl) as NavigationItem}\n />\n </div>\n ) : (\n <div className=\"flex-1 p-4\">\n <div className=\"rounded-lg border border-destructive/50 bg-destructive/10 p-4\">\n <h3 className=\"font-semibold text-destructive mb-2\">\n Error: Drawer URL is undefined\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n The <code className=\"text-xs bg-background px-1 py-0.5 rounded\">openDrawer</code>{' '}\n function was called without a valid URL parameter. Please ensure you provide a URL\n when opening the drawer.\n </p>\n </div>\n </div>\n )}\n </DrawerContent>\n </Drawer>\n <Toaster />\n </>\n );\n}\n","import { Link, useLocation, Outlet } from 'react-router';\nimport { useMemo, useEffect, useState, useRef, useLayoutEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n Sidebar,\n SidebarProvider,\n SidebarHeader,\n SidebarContent,\n SidebarFooter,\n SidebarGroup,\n SidebarGroupLabel,\n SidebarGroupContent,\n SidebarMenu,\n SidebarMenuItem,\n SidebarMenuButton,\n} from '@/components/ui/sidebar';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\nimport {\n filterNavigationByViewport,\n filterNavigationForSidebar,\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface DefaultLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\n// DuckDuckGo favicon URL for a given page URL (used when openIn === 'external' and no icon is set)\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\nconst NavigationContent = ({\n navigation,\n}: {\n navigation: (NavigationItem | NavigationGroup)[];\n}) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n // Helper function to resolve localized strings\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') {\n return value;\n }\n // Try current language first, then English as fallback\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n // Check if at least one navigation item has an icon\n const hasAnyIcons = useMemo(() => {\n return navigation.some((item) => {\n if ('title' in item && 'items' in item) {\n // It's a group\n return (item as NavigationGroup).items.some((navItem) => !!navItem.icon);\n }\n // It's a standalone item\n return !!(item as NavigationItem).icon;\n });\n }, [navigation]);\n\n // Helper to check if an item is a group\n const isGroup = (item: NavigationItem | NavigationGroup): item is NavigationGroup => {\n return 'title' in item && 'items' in item;\n };\n\n // Render a single nav item link or modal/drawer trigger\n const renderNavItem = (navItem: NavigationItem) => {\n const pathPrefix = `/${navItem.path}`;\n const isOverlay = navItem.openIn === 'modal' || navItem.openIn === 'drawer';\n const isExternal = navItem.openIn === 'external';\n const isActive =\n !isOverlay &&\n !isExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const itemLabel = resolveLocalizedString(navItem.label, currentLanguage);\n const faviconUrl = isExternal && !navItem.icon ? getExternalFaviconUrl(navItem.url) : null;\n const iconSrc = navItem.icon ?? faviconUrl ?? null;\n const iconEl = iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn('h-4 w-4', 'shrink-0')}\n />\n ) : hasAnyIcons ? (\n <span className=\"h-4 w-4 shrink-0\" />\n ) : null;\n const externalIcon = isExternal ? (\n <ExternalLinkIcon className=\"ml-auto h-4 w-4 shrink-0 opacity-70\" />\n ) : null;\n const content = (\n <>\n {iconEl}\n <span className=\"truncate\">{itemLabel}</span>\n {externalIcon}\n </>\n );\n const linkOrTrigger =\n navItem.openIn === 'modal' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(navItem.url)}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'drawer' ? (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: navItem.url, position: navItem.drawerPosition })}\n className=\"flex items-center gap-2 w-full cursor-pointer text-left\"\n >\n {content}\n </button>\n ) : navItem.openIn === 'external' ? (\n <a\n href={navItem.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </a>\n ) : (\n <Link\n to={`/${navItem.path}`}\n className=\"flex items-center gap-2 w-full\"\n >\n {content}\n </Link>\n );\n return (\n <SidebarMenuButton\n asChild\n isActive={isActive}\n className={cn('w-full', isActive && 'bg-sidebar-accent text-sidebar-accent-foreground')}\n >\n {linkOrTrigger}\n </SidebarMenuButton>\n );\n };\n\n // Render navigation items - handle both groups and standalone items\n return (\n <>\n {navigation.map((item) => {\n if (isGroup(item)) {\n // Render as a group\n const groupTitle = resolveLocalizedString(item.title, currentLanguage);\n return (\n <SidebarGroup\n key={groupTitle}\n className=\"mt-0\"\n >\n <SidebarGroupLabel className=\"mb-1\">{groupTitle}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu className=\"gap-0.5\">\n {item.items.map((navItem) => (\n <SidebarMenuItem key={navItem.path}>{renderNavItem(navItem)}</SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n );\n } else {\n // Render as a standalone item\n return (\n <SidebarMenu\n key={item.path}\n className=\"gap-0.5\"\n >\n <SidebarMenuItem>{renderNavItem(item)}</SidebarMenuItem>\n </SidebarMenu>\n );\n }\n })}\n </>\n );\n};\n\n/** Reusable sidebar inner: header, main nav, footer. Used in desktop Sidebar and mobile Drawer. */\nconst SidebarInner = ({\n title,\n logo,\n startNav,\n endItems,\n}: {\n title?: string;\n logo?: string;\n startNav: (NavigationItem | NavigationGroup)[];\n endItems: (NavigationItem | NavigationGroup)[];\n}) => (\n <>\n <SidebarHeader className=\"border-b border-sidebar-border pb-4\">\n {(title || logo) && (\n <Link\n to=\"/\"\n className=\"flex items-center pl-1 pr-3 py-2 text-lg font-semibold text-sidebar-foreground hover:text-sidebar-foreground/80 transition-colors\"\n >\n {logo && logo.trim() ? (\n <img\n src={logo}\n alt={title || 'Logo'}\n className=\"h-5 w-auto shrink-0 object-contain sidebar-logo\"\n />\n ) : title ? (\n <span className=\"leading-none\">{title}</span>\n ) : null}\n </Link>\n )}\n </SidebarHeader>\n <SidebarContent className=\"gap-1\">\n <NavigationContent navigation={startNav} />\n </SidebarContent>\n {endItems.length > 0 && (\n <SidebarFooter>\n <NavigationContent navigation={endItems} />\n </SidebarFooter>\n )}\n </>\n);\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Approximate width per slot (icon + label + padding) and gap for dynamic slot count. */\nconst BOTTOM_NAV_SLOT_WIDTH = 64;\nconst BOTTOM_NAV_GAP = 4;\nconst BOTTOM_NAV_PX = 12;\n/** Max slots in the row (Home + nav + optional More) to avoid overflow/duplicated wrap. */\nconst BOTTOM_NAV_MAX_SLOTS = 6;\n\n/** True when the icon is a local app icon (/icons/); external images (avatars, favicons) are shown as-is. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\n/** Single nav item for bottom bar: icon + label, link or action. */\nconst BottomNavItem = ({\n item,\n label,\n isActive,\n iconSrc,\n applyIconTheme,\n}: {\n item: NavigationItem;\n label: string;\n isActive: boolean;\n iconSrc: string | null;\n applyIconTheme: boolean;\n}) => {\n const pathPrefix = `/${item.path}`;\n const content = (\n <span className=\"flex flex-col items-center justify-center gap-1 w-full min-w-0 max-w-full overflow-hidden\">\n {iconSrc ? (\n <img\n src={iconSrc}\n alt=\"\"\n className={cn(\n 'size-4 shrink-0 rounded-sm object-cover',\n applyIconTheme && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"size-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-[11px] leading-tight truncate w-full min-w-0 text-center block\">\n {label}\n </span>\n </span>\n );\n const baseClass = cn(\n 'flex flex-col items-center justify-center rounded-md py-1.5 px-2 min-w-0 max-w-full transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isActive\n ? 'bg-accent text-accent-foreground [&_span]:text-accent-foreground'\n : 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground [&_span]:inherit',\n );\n if (item.openIn === 'modal') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openModal(item.url)}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'drawer') {\n return (\n <button\n type=\"button\"\n onClick={() => shellui.openDrawer({ url: item.url, position: item.drawerPosition })}\n className={baseClass}\n >\n {content}\n </button>\n );\n }\n if (item.openIn === 'external') {\n return (\n <a\n href={item.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={baseClass}\n >\n {content}\n </a>\n );\n }\n return (\n <Link\n to={pathPrefix}\n className={baseClass}\n >\n {content}\n </Link>\n );\n};\n\n/** Inline SVG: external-link icon. Bundled so consumers don't need to serve static SVGs. */\nconst ExternalLinkIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6\" />\n <polyline points=\"15 3 21 3 21 9\" />\n <line x1=\"10\" y1=\"14\" x2=\"21\" y2=\"3\" />\n </svg>\n);\n\n/** Caret up: expand (show second line). */\nconst CaretUpIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m18 15-6-6-6 6\" />\n </svg>\n);\n\n/** Caret down: collapse (hide second line). */\nconst CaretDownIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\n/** Home icon for mobile bottom bar (same as sidebar logo action). */\nconst HomeIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('shrink-0', className)}\n aria-hidden\n >\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <polyline points=\"9 22 9 12 15 12 15 22\" />\n </svg>\n);\n\n/** Mobile bottom nav: Home + nav items; More only when not all fit. Dynamic from width. */\nconst MobileBottomNav = ({\n items,\n currentLanguage,\n}: {\n items: NavigationItem[];\n currentLanguage: string;\n}) => {\n const location = useLocation();\n const [expanded, setExpanded] = useState(false);\n const navRef = useRef<HTMLElement>(null);\n const [rowWidth, setRowWidth] = useState(0);\n\n useLayoutEffect(() => {\n const el = navRef.current;\n if (!el) return;\n const ro = new ResizeObserver((entries) => {\n const w = entries[0]?.contentRect.width ?? 0;\n setRowWidth(w);\n });\n ro.observe(el);\n setRowWidth(el.getBoundingClientRect().width);\n return () => ro.disconnect();\n }, []);\n\n const { rowItems, overflowItems, hasMore } = useMemo(() => {\n const list = items.slice();\n const contentWidth = Math.max(0, rowWidth - BOTTOM_NAV_PX * 2);\n const slotTotal = BOTTOM_NAV_SLOT_WIDTH + BOTTOM_NAV_GAP;\n const computedSlots =\n rowWidth > 0 ? Math.floor((contentWidth + BOTTOM_NAV_GAP) / slotTotal) : 5;\n const totalSlots = Math.min(Math.max(0, computedSlots), BOTTOM_NAV_MAX_SLOTS);\n const slotsForNav = totalSlots - 1;\n const allFit = list.length <= slotsForNav;\n const maxInRow = allFit ? list.length : Math.max(0, totalSlots - 2);\n const row = list.slice(0, maxInRow);\n const rowPaths = new Set(row.map((i) => i.path));\n const overflow = list.filter((item) => !rowPaths.has(item.path));\n return {\n rowItems: row,\n overflowItems: overflow,\n hasMore: overflow.length > 0,\n };\n }, [items, rowWidth]);\n\n useEffect(() => {\n setExpanded(false);\n }, [location.pathname]);\n\n const renderItem = (item: NavigationItem, index: number) => {\n const pathPrefix = `/${item.path}`;\n const isOverlayOrExternal =\n item.openIn === 'modal' || item.openIn === 'drawer' || item.openIn === 'external';\n const isActive =\n !isOverlayOrExternal &&\n (location.pathname === pathPrefix || location.pathname.startsWith(`${pathPrefix}/`));\n const label = resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const iconSrc = item.icon ?? faviconUrl ?? null;\n const applyIconTheme = iconSrc ? isAppIcon(iconSrc) : false;\n return (\n <BottomNavItem\n key={`${item.path}-${item.url}-${index}`}\n item={item}\n label={label}\n isActive={isActive}\n iconSrc={iconSrc}\n applyIconTheme={applyIconTheme}\n />\n );\n };\n\n return (\n <nav\n ref={navRef}\n className=\"fixed bottom-0 left-0 right-0 z-[9999] md:hidden border-t border-sidebar-border bg-sidebar-background overflow-hidden pt-2\"\n style={{\n zIndex: Z_INDEX.SIDEBAR_TRIGGER,\n paddingBottom: 'calc(0.5rem + env(safe-area-inset-bottom, 0px))',\n }}\n >\n {/* Top row: Home + nav items + More/Less — single row, no wrap */}\n <div className=\"flex flex-row flex-nowrap items-center justify-center gap-1 px-3 overflow-x-hidden\">\n <Link\n to=\"/\"\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n location.pathname === '/' || location.pathname === ''\n ? 'bg-sidebar-accent text-sidebar-accent-foreground [&_span]:text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground [&_span]:inherit',\n )}\n aria-label=\"Home\"\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center [&_svg]:text-current\">\n <HomeIcon className=\"size-4\" />\n </span>\n <span className=\"text-[11px] leading-tight\">Home</span>\n </Link>\n {rowItems.map((item, i) => renderItem(item, i))}\n {hasMore && (\n <button\n type=\"button\"\n onClick={() => setExpanded((e) => !e)}\n className={cn(\n 'flex flex-col items-center justify-center gap-1 rounded-md py-1.5 px-2 min-w-0 transition-colors cursor-pointer',\n 'text-muted-foreground hover:bg-accent/50 hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n )}\n aria-expanded={expanded}\n aria-label={expanded ? 'Show less' : 'Show more'}\n >\n <span className=\"size-4 shrink-0 flex items-center justify-center\">\n {expanded ? <CaretDownIcon className=\"size-4\" /> : <CaretUpIcon className=\"size-4\" />}\n </span>\n <span className=\"text-[11px] leading-tight\">{expanded ? 'Less' : 'More'}</span>\n </button>\n )}\n </div>\n\n {/* Expanded: only overflow items — render list only when expanded so it clears when collapsed */}\n <div\n className={cn(\n 'grid transition-[grid-template-rows] duration-300 ease-out',\n expanded ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]',\n )}\n >\n <div className=\"min-h-0 overflow-hidden\">\n <div className=\"px-4 pt-3 pb-2 border-t border-sidebar-border/50 mt-1\">\n <div className=\"grid grid-cols-5 gap-2 justify-items-center max-w-xs mx-auto\">\n {expanded ? overflowItems.map((item, i) => renderItem(item, i)) : null}\n </div>\n </div>\n </div>\n </div>\n </nav>\n );\n};\n\nconst DefaultLayoutContent = ({ title, logo, navigation }: DefaultLayoutProps) => {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const { startNav, endItems, navigationItems, mobileNavItems } = useMemo(() => {\n const desktopNav = filterNavigationByViewport(navigation, 'desktop');\n const mobileNav = filterNavigationByViewport(navigation, 'mobile');\n const { start, end } = splitNavigationByPosition(desktopNav);\n const flat = flattenNavigationItems(desktopNav);\n const mobileFlat = flattenNavigationItems(mobileNav);\n return {\n startNav: filterNavigationForSidebar(start),\n endItems: end,\n navigationItems: flat,\n mobileNavItems: mobileFlat,\n };\n }, [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <SidebarProvider>\n <OverlayShell navigationItems={navigationItems}>\n <div className=\"flex h-screen overflow-hidden\">\n {/* Desktop sidebar: visible from md up */}\n <Sidebar className={cn('hidden md:flex shrink-0')}>\n <SidebarInner\n title={title}\n logo={logo}\n startNav={startNav}\n endItems={endItems}\n />\n </Sidebar>\n\n <main className=\"flex-1 flex flex-col overflow-hidden bg-background relative min-w-0\">\n <div className=\"flex-1 flex flex-col overflow-auto pb-16 md:pb-0\">\n <Outlet />\n </div>\n </main>\n </div>\n\n {/* Mobile bottom nav: visible only below md */}\n <MobileBottomNav\n items={mobileNavItems}\n currentLanguage={currentLanguage}\n />\n </OverlayShell>\n </SidebarProvider>\n </LayoutProviders>\n );\n};\n\nexport const DefaultLayout = ({ title, appIcon, logo, navigation }: DefaultLayoutProps) => {\n return (\n <DefaultLayoutContent\n title={title}\n appIcon={appIcon}\n logo={logo}\n navigation={navigation}\n />\n );\n};\n","import { useMemo, useEffect } from 'react';\nimport { Outlet, useLocation } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport { flattenNavigationItems } from './utils';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\n\ninterface FullscreenLayoutProps {\n title?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nfunction resolveLocalizedLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\n/** Full-width layout with no sidebar or navigation; only content area. Modal, drawer and providers are still active. */\nexport function FullscreenLayout({ title, navigation }: FullscreenLayoutProps) {\n const location = useLocation();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n const navigationItems = useMemo(() => flattenNavigationItems(navigation), [navigation]);\n\n useEffect(() => {\n if (!title) return;\n const pathname = location.pathname.replace(/^\\/+|\\/+$/g, '') || '';\n const segment = pathname.split('/')[0];\n if (!segment) {\n document.title = title;\n return;\n }\n const navItem = navigationItems.find((item) => item.path === segment);\n if (navItem) {\n const label = resolveLocalizedLabel(navItem.label, currentLanguage);\n document.title = `${label} | ${title}`;\n } else {\n document.title = title;\n }\n }, [location.pathname, title, navigationItems, currentLanguage]);\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <main className=\"flex flex-col w-full h-screen overflow-hidden bg-background\">\n <Outlet />\n </main>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n","import {\n useMemo,\n useState,\n useCallback,\n useRef,\n useEffect,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\nimport { ContentView } from '@/components/ContentView';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ninterface WindowsLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\n/** True when the icon is a local app icon (/icons/); apply theme (dark invert) so it matches foreground. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\nconst genId = () => `win-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\nexport interface WindowState {\n id: string;\n path: string;\n pathname: string;\n baseUrl: string;\n label: string;\n icon: string | null;\n bounds: { x: number; y: number; w: number; h: number };\n}\n\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 200;\nconst DEFAULT_WIDTH = 720;\nconst DEFAULT_HEIGHT = 480;\nconst TASKBAR_HEIGHT = 48;\n\nfunction getMaximizedBounds(): WindowState['bounds'] {\n return {\n x: 0,\n y: 0,\n w: typeof window !== 'undefined' ? window.innerWidth : 800,\n h: typeof window !== 'undefined' ? window.innerHeight - TASKBAR_HEIGHT : 600,\n };\n}\n\nfunction buildFinalUrl(baseUrl: string, path: string, pathname: string): string {\n const pathPrefix = `/${path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n if (!subPath) return baseUrl;\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${subPath}`;\n}\n\n/** Single draggable/resizable window */\nfunction AppWindow({\n win,\n navItem,\n currentLanguage,\n isFocused,\n onFocus,\n onClose,\n onBoundsChange,\n maxZIndex,\n zIndex,\n}: {\n win: WindowState;\n navItem: NavigationItem;\n currentLanguage: string;\n isFocused: boolean;\n onFocus: () => void;\n onClose: () => void;\n onBoundsChange: (bounds: WindowState['bounds']) => void;\n maxZIndex: number;\n zIndex: number;\n}) {\n const windowLabel = resolveNavLabel(navItem.label, currentLanguage);\n const [bounds, setBounds] = useState(win.bounds);\n const [isMaximized, setIsMaximized] = useState(false);\n const boundsBeforeMaximizeRef = useRef<WindowState['bounds']>(bounds);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n lastDx: number;\n lastDy: number;\n } | null>(null);\n const resizeRef = useRef<{\n edge: string;\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n } | null>(null);\n const resizeRafRef = useRef<number | null>(null);\n const pendingResizeBoundsRef = useRef<WindowState['bounds'] | null>(null);\n\n useEffect(() => {\n setBounds(win.bounds);\n }, [win.bounds]);\n\n useEffect(() => {\n onBoundsChange(bounds);\n }, [bounds, onBoundsChange]);\n\n // When maximized, keep filling the viewport on window resize\n useEffect(() => {\n if (!isMaximized) return;\n const onResize = () => setBounds(getMaximizedBounds());\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isMaximized]);\n\n const onPointerMove = useCallback((e: PointerEvent) => {\n if (!dragRef.current) return;\n const d = dragRef.current;\n const dx = e.clientX - d.startX;\n const dy = e.clientY - d.startY;\n d.lastDx = dx;\n d.lastDy = dy;\n const el = containerRef.current;\n if (el) {\n el.style.willChange = 'transform';\n el.style.transform = `translate(${dx}px, ${dy}px)`;\n }\n }, []);\n\n const onPointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n if (dragRef.current) {\n const d = dragRef.current;\n if (el) {\n el.style.transform = '';\n el.style.willChange = '';\n }\n const finalBounds: WindowState['bounds'] = {\n ...d.startBounds,\n x: Math.max(0, d.startBounds.x + d.lastDx),\n y: Math.max(0, d.startBounds.y + d.lastDy),\n };\n setBounds(finalBounds);\n dragRef.current = null;\n }\n },\n [onPointerMove],\n );\n\n const handleTitlePointerDown = useCallback(\n (e: ReactPointerEvent) => {\n if (e.button !== 0 || isMaximized) return;\n // Don't start drag when clicking a button (close, maximize) so their click handlers run\n if ((e.target as Element).closest('button')) return;\n e.preventDefault();\n onFocus();\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n lastDx: 0,\n lastDy: 0,\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onPointerMove, { passive: true });\n el.addEventListener('pointerup', onPointerUp as (e: Event) => void);\n }\n },\n [bounds, isMaximized, onFocus, onPointerMove, onPointerUp],\n );\n\n const handleMaximizeToggle = useCallback(() => {\n if (isMaximized) {\n setBounds(boundsBeforeMaximizeRef.current);\n setIsMaximized(false);\n } else {\n boundsBeforeMaximizeRef.current = { ...bounds };\n setBounds(getMaximizedBounds());\n setIsMaximized(true);\n }\n }, [isMaximized, bounds]);\n\n const onResizePointerMove = useCallback((e: PointerEvent) => {\n if (!resizeRef.current) return;\n const { edge, startX, startY, startBounds } = resizeRef.current;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n const next: WindowState['bounds'] = { ...startBounds };\n if (edge.includes('e')) next.w = Math.max(MIN_WIDTH, startBounds.w + dx);\n if (edge.includes('w')) {\n const newW = Math.max(MIN_WIDTH, startBounds.w - dx);\n next.x = startBounds.x + startBounds.w - newW;\n next.w = newW;\n }\n if (edge.includes('s')) next.h = Math.max(MIN_HEIGHT, startBounds.h + dy);\n if (edge.includes('n')) {\n const newH = Math.max(MIN_HEIGHT, startBounds.h - dy);\n next.y = startBounds.y + startBounds.h - newH;\n next.h = newH;\n }\n pendingResizeBoundsRef.current = next;\n if (resizeRafRef.current === null) {\n resizeRafRef.current = requestAnimationFrame(() => {\n const pending = pendingResizeBoundsRef.current;\n resizeRafRef.current = null;\n pendingResizeBoundsRef.current = null;\n if (pending) setBounds(pending);\n });\n }\n }, []);\n\n const onResizePointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onResizePointerMove as (e: Event) => void);\n el.removeEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n resizeRef.current = null;\n },\n [onResizePointerMove],\n );\n\n const handleResizePointerDown = useCallback(\n (e: ReactPointerEvent, edge: string) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n onFocus();\n resizeRef.current = {\n edge,\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onResizePointerMove as (e: Event) => void, {\n passive: true,\n });\n el.addEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n }\n },\n [bounds, onFocus, onResizePointerMove, onResizePointerUp],\n );\n\n const finalUrl = useMemo(\n () => buildFinalUrl(win.baseUrl, win.path, win.pathname),\n [win.baseUrl, win.path, win.pathname],\n );\n\n const z = isFocused ? maxZIndex : zIndex;\n\n return (\n <div\n ref={containerRef}\n className=\"absolute flex flex-col rounded-lg border border-border bg-card shadow-lg overflow-hidden\"\n style={{\n left: bounds.x,\n top: bounds.y,\n width: bounds.w,\n height: bounds.h,\n zIndex: z,\n }}\n onClick={onFocus}\n onMouseDown={onFocus}\n >\n {/* Title bar: pointer capture so drag continues when cursor is over iframe or outside window */}\n <div\n className=\"flex items-center gap-2 pl-2 pr-1 py-1 bg-muted/80 border-b border-border cursor-move select-none shrink-0\"\n onPointerDown={handleTitlePointerDown}\n >\n {win.icon && (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n )}\n <span className=\"flex-1 text-sm font-medium truncate min-w-0\">{windowLabel}</span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleMaximizeToggle();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label={isMaximized ? 'Restore' : 'Maximize'}\n >\n {isMaximized ? <RestoreIcon className=\"h-4 w-4\" /> : <MaximizeIcon className=\"h-4 w-4\" />}\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-destructive/20 hover:text-destructive transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label=\"Close\"\n >\n <CloseIcon className=\"h-4 w-4\" />\n </button>\n </div>\n {/* Content */}\n <div className=\"flex-1 min-h-0 relative bg-background\">\n {/* When not focused, overlay captures clicks to bring window to front */}\n {!isFocused && (\n <div\n className=\"absolute inset-0 z-10 cursor-pointer\"\n onClick={onFocus}\n onMouseDown={(e) => {\n e.stopPropagation();\n onFocus();\n }}\n aria-hidden\n />\n )}\n <ContentView\n url={finalUrl}\n pathPrefix={win.path}\n ignoreMessages={true}\n navItem={navItem}\n />\n </div>\n {/* Resize handles (hidden when maximized) */}\n {!isMaximized &&\n (['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as const).map((edge) => (\n <div\n key={edge}\n className={cn(\n 'absolute bg-transparent',\n edge.includes('n') && 'top-0 h-2 cursor-n-resize',\n edge.includes('s') && 'bottom-0 h-2 cursor-s-resize',\n edge.includes('e') && 'right-0 w-2 cursor-e-resize',\n edge.includes('w') && 'left-0 w-2 cursor-w-resize',\n edge === 'n' && 'left-2 right-2',\n edge === 's' && 'left-2 right-2',\n edge === 'e' && 'top-2 bottom-2',\n edge === 'w' && 'top-2 bottom-2',\n edge === 'ne' && 'top-0 right-0 w-2 h-2 cursor-ne-resize',\n edge === 'nw' && 'top-0 left-0 w-2 h-2 cursor-nw-resize',\n edge === 'se' && 'bottom-0 right-0 w-2 h-2 cursor-se-resize',\n edge === 'sw' && 'bottom-0 left-0 w-2 h-2 cursor-sw-resize',\n )}\n style={\n edge === 'n'\n ? { left: 8, right: 8 }\n : edge === 's'\n ? { left: 8, right: 8 }\n : edge === 'e'\n ? { top: 8, bottom: 8 }\n : edge === 'w'\n ? { top: 8, bottom: 8 }\n : undefined\n }\n onPointerDown={(e) => handleResizePointerDown(e, edge)}\n />\n ))}\n </div>\n );\n}\n\nfunction MaximizeIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nfunction RestoreIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n <rect\n x=\"11\"\n y=\"11\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n </svg>\n );\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/** Start menu icon (Windows-style) */\nfunction StartIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className={className}\n aria-hidden\n >\n <path d=\"M3 3h8v8H3V3zm10 0h8v8h-8V3zM3 13h8v8H3v-8zm10 0h8v8h-8v-8z\" />\n </svg>\n );\n}\n\nfunction getBrowserTimezone(): string {\n if (typeof window !== 'undefined' && Intl.DateTimeFormat) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n}\n\nexport function WindowsLayout({\n title,\n appIcon: _appIcon,\n logo: _logo,\n navigation,\n}: WindowsLayoutProps) {\n const { i18n } = useTranslation();\n const { settings } = useSettings();\n const currentLanguage = i18n.language || 'en';\n const timeZone = settings.region?.timezone ?? getBrowserTimezone();\n const { startNavItems, endNavItems, navigationItems } = useMemo(() => {\n const { start, end } = splitNavigationByPosition(navigation);\n return {\n startNavItems: flattenNavigationItems(start),\n endNavItems: end,\n navigationItems: flattenNavigationItems(navigation),\n };\n }, [navigation]);\n\n const [windows, setWindows] = useState<WindowState[]>([]);\n /** Id of the window that is on top (first plan). Clicking a window or its taskbar button sets this. */\n const [frontWindowId, setFrontWindowId] = useState<string | null>(null);\n const [startMenuOpen, setStartMenuOpen] = useState(false);\n const [now, setNow] = useState(() => new Date());\n const startPanelRef = useRef<HTMLDivElement>(null);\n\n // Update date/time every second for taskbar clock\n useEffect(() => {\n const interval = setInterval(() => setNow(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n /** Highest z-index: front window always gets this so it stays on top. */\n const maxZIndex = useMemo(\n () => Z_INDEX.WINDOWS_WINDOW_BASE + Math.max(windows.length, 1),\n [windows.length],\n );\n\n const openWindow = useCallback(\n (item: NavigationItem) => {\n const label =\n typeof item.label === 'string' ? item.label : resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const icon = item.icon ?? faviconUrl ?? null;\n const id = genId();\n const bounds = {\n x: 60 + windows.length * 24,\n y: 60 + windows.length * 24,\n w: DEFAULT_WIDTH,\n h: DEFAULT_HEIGHT,\n };\n setWindows((prev) => [\n ...prev,\n {\n id,\n path: item.path,\n pathname: `/${item.path}`,\n baseUrl: item.url,\n label,\n icon,\n bounds,\n },\n ]);\n setFrontWindowId(id);\n setStartMenuOpen(false);\n },\n [currentLanguage, windows.length],\n );\n\n const closeWindow = useCallback((id: string) => {\n setWindows((prev) => prev.filter((w) => w.id !== id));\n setFrontWindowId((current) => (current === id ? null : current));\n }, []);\n\n // When front window is closed or missing, bring first window to front\n useEffect(() => {\n if (windows.length === 0) {\n setFrontWindowId(null);\n return;\n }\n const frontStillExists = frontWindowId !== null && windows.some((w) => w.id === frontWindowId);\n if (!frontStillExists) {\n setFrontWindowId(windows[0].id);\n }\n }, [windows, frontWindowId]);\n\n /** Bring the window to front (first plan). Used when clicking the window or its taskbar button. */\n const focusWindow = useCallback((id: string) => {\n setFrontWindowId(id);\n }, []);\n\n const updateWindowBounds = useCallback((id: string, bounds: WindowState['bounds']) => {\n setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, bounds } : w)));\n }, []);\n\n // Close start menu on click outside\n useEffect(() => {\n if (!startMenuOpen) return;\n const onDocClick = (e: MouseEvent) => {\n if (startPanelRef.current && !startPanelRef.current.contains(e.target as Node)) {\n setStartMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDocClick);\n return () => document.removeEventListener('mousedown', onDocClick);\n }, [startMenuOpen]);\n\n const handleNavClick = useCallback(\n (item: NavigationItem) => {\n if (item.openIn === 'modal') {\n shellui.openModal(item.url);\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'drawer') {\n shellui.openDrawer({ url: item.url, position: item.drawerPosition });\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'external') {\n window.open(item.url, '_blank', 'noopener,noreferrer');\n setStartMenuOpen(false);\n return;\n }\n openWindow(item);\n },\n [openWindow],\n );\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <div\n className=\"fixed inset-0 bg-muted/30\"\n style={{ paddingBottom: TASKBAR_HEIGHT }}\n >\n {/* Desktop area: windows */}\n {windows.map((win, index) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n if (!navItem) return null;\n const isFocused = win.id === frontWindowId;\n const zIndex = Z_INDEX.WINDOWS_WINDOW_BASE + index;\n return (\n <AppWindow\n key={win.id}\n win={win}\n navItem={navItem}\n currentLanguage={currentLanguage}\n isFocused={isFocused}\n onFocus={() => focusWindow(win.id)}\n onClose={() => closeWindow(win.id)}\n onBoundsChange={(bounds) => updateWindowBounds(win.id, bounds)}\n maxZIndex={maxZIndex}\n zIndex={zIndex}\n />\n );\n })}\n </div>\n\n {/* Taskbar */}\n <div\n className=\"fixed left-0 right-0 bottom-0 flex items-center gap-1 px-2 border-t border-border bg-sidebar-background\"\n style={{\n height: TASKBAR_HEIGHT,\n zIndex: Z_INDEX.WINDOWS_TASKBAR,\n paddingBottom: 'env(safe-area-inset-bottom, 0px)',\n }}\n >\n {/* Start button */}\n <div\n className=\"relative shrink-0\"\n ref={startPanelRef}\n >\n <button\n type=\"button\"\n onClick={() => setStartMenuOpen((o) => !o)}\n className={cn(\n 'flex items-center gap-2 h-9 px-3 rounded cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n startMenuOpen\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n aria-expanded={startMenuOpen}\n aria-haspopup=\"true\"\n aria-label=\"Start\"\n >\n <StartIcon className=\"h-5 w-5\" />\n <span className=\"font-semibold text-sm hidden sm:inline\">{title || 'Start'}</span>\n </button>\n {/* Start menu panel */}\n {startMenuOpen && (\n <div\n className=\"absolute bottom-full left-0 mb-1 w-64 max-h-[70vh] overflow-y-auto rounded-lg border border-border bg-popover shadow-lg py-2 z-[10001]\"\n style={{ zIndex: Z_INDEX.MODAL_CONTENT }}\n >\n <div className=\"px-2 pb-2 border-b border-border mb-2\">\n <span className=\"text-sm font-semibold text-popover-foreground\">\n {title || 'Applications'}\n </span>\n </div>\n <div className=\"grid gap-0.5\">\n {startNavItems\n .filter((item) => !item.hidden)\n .map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-3 w-full px-3 py-2 text-left text-sm cursor-pointer text-popover-foreground hover:bg-accent hover:text-accent-foreground rounded-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-5 w-5 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-5 w-5 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"truncate\">{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n\n {/* Window list */}\n <div className=\"flex-1 flex items-center gap-1 min-w-0 overflow-x-auto\">\n {windows.map((win) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n const windowLabel = navItem\n ? resolveNavLabel(navItem.label, currentLanguage)\n : win.label;\n const isFocused = win.id === frontWindowId;\n return (\n <button\n key={win.id}\n type=\"button\"\n onClick={() => focusWindow(win.id)}\n onContextMenu={(e) => {\n e.preventDefault();\n closeWindow(win.id);\n }}\n className={cn(\n 'flex items-center gap-2 h-8 px-2 rounded min-w-0 max-w-[140px] shrink-0 cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isFocused\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n title={windowLabel}\n >\n {win.icon ? (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate\">{windowLabel}</span>\n </button>\n );\n })}\n </div>\n\n {/* End navigation items (right side of taskbar) */}\n {endNavItems.length > 0 && (\n <div className=\"flex items-center gap-0.5 shrink-0 border-l border-sidebar-border pl-2 ml-1\">\n {endNavItems.map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-2 h-8 px-2 rounded cursor-pointer text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n title={label}\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate max-w-[100px]\">{label}</span>\n </button>\n );\n })}\n </div>\n )}\n\n {/* Date and time (extreme bottom right, OS-style); uses region timezone from settings */}\n <div\n className=\"flex flex-col items-end justify-center shrink-0 px-3 py-1 text-sidebar-foreground border-l border-sidebar-border ml-1 min-w-0\"\n style={{ paddingRight: 'max(0.75rem, env(safe-area-inset-right))' }}\n role=\"timer\"\n aria-live=\"off\"\n aria-label={new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n dateStyle: 'full',\n timeStyle: 'medium',\n }).format(now)}\n >\n <time\n dateTime={now.toISOString()}\n className=\"text-xs leading-tight tabular-nums whitespace-nowrap\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n }).format(now)}\n </time>\n <time\n dateTime={now.toISOString()}\n className=\"text-[10px] leading-tight whitespace-nowrap text-sidebar-foreground/90\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n }).format(now)}\n </time>\n </div>\n </div>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n","import { lazy, Suspense, type LazyExoticComponent, type ComponentType } from 'react';\nimport type { LayoutType, NavigationItem, NavigationGroup } from '../config/types';\nimport { useSettings } from '../settings/SettingsContext';\n\nconst DefaultLayout = lazy(() =>\n import('./DefaultLayout').then((m) => ({ default: m.DefaultLayout })),\n);\nconst FullscreenLayout = lazy(() =>\n import('./FullscreenLayout').then((m) => ({ default: m.FullscreenLayout })),\n);\nconst WindowsLayout = lazy(() =>\n import('./WindowsLayout').then((m) => ({ default: m.WindowsLayout })),\n);\n\ninterface AppLayoutProps {\n layout?: LayoutType;\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nfunction LayoutFallback() {\n return (\n <div\n className=\"min-h-screen bg-background\"\n aria-hidden\n />\n );\n}\n\n/** Renders the layout based on settings.layout (override) or config.layout: 'sidebar' (default), 'fullscreen', or 'windows'. Lazy-loads only the active layout. */\nexport function AppLayout({\n layout = 'sidebar',\n title,\n appIcon,\n logo,\n navigation,\n}: AppLayoutProps) {\n const { settings } = useSettings();\n const effectiveLayout: LayoutType = settings.layout ?? layout;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let LayoutComponent: LazyExoticComponent<ComponentType<any>>;\n let layoutProps: Record<string, unknown>;\n\n if (effectiveLayout === 'fullscreen') {\n LayoutComponent = FullscreenLayout;\n layoutProps = { title, navigation };\n } else if (effectiveLayout === 'windows') {\n LayoutComponent = WindowsLayout;\n layoutProps = { title, appIcon, logo, navigation };\n } else {\n LayoutComponent = DefaultLayout;\n layoutProps = { title, appIcon, logo, navigation };\n }\n\n return (\n <Suspense fallback={<LayoutFallback />}>\n <LayoutComponent {...layoutProps} />\n </Suspense>\n );\n}\n","import { useTranslation } from 'react-i18next';\nimport { useConfig } from '../features/config/useConfig';\n\nexport const HomeView = () => {\n const { t } = useTranslation('common');\n const { config } = useConfig();\n\n return (\n <div className=\"flex flex-col items-center justify-center h-full p-8 md:p-10\">\n <h1\n className=\"m-0 text-3xl font-light text-foreground\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('welcome', { title: config.title })}\n </h1>\n <p className=\"mt-4 text-lg text-muted-foreground\">{t('getStarted')}</p>\n </div>\n );\n};\n","import {\n forwardRef,\n type ComponentPropsWithoutRef,\n type ComponentProps,\n type ReactNode,\n} from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cn } from '@/lib/utils';\n\nconst Breadcrumb = forwardRef<\n HTMLElement,\n ComponentPropsWithoutRef<'nav'> & {\n separator?: ReactNode;\n }\n>(({ ...props }, ref) => (\n <nav\n ref={ref}\n aria-label=\"breadcrumb\"\n {...props}\n />\n));\nBreadcrumb.displayName = 'Breadcrumb';\n\nconst BreadcrumbList = forwardRef<HTMLOListElement, ComponentPropsWithoutRef<'ol'>>(\n ({ className, ...props }, ref) => (\n <ol\n ref={ref}\n className={cn(\n 'flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5',\n className,\n )}\n {...props}\n />\n ),\n);\nBreadcrumbList.displayName = 'BreadcrumbList';\n\nconst BreadcrumbItem = forwardRef<HTMLLIElement, ComponentPropsWithoutRef<'li'>>(\n ({ className, ...props }, ref) => (\n <li\n ref={ref}\n className={cn('inline-flex items-center gap-1.5', className)}\n {...props}\n />\n ),\n);\nBreadcrumbItem.displayName = 'BreadcrumbItem';\n\nconst BreadcrumbLink = forwardRef<\n HTMLAnchorElement,\n ComponentPropsWithoutRef<'a'> & {\n asChild?: boolean;\n }\n>(({ asChild, className, ...props }, ref) => {\n const Comp = asChild ? Slot : 'a';\n\n return (\n <Comp\n ref={ref}\n className={cn('transition-colors hover:text-foreground', className)}\n {...props}\n />\n );\n});\nBreadcrumbLink.displayName = 'BreadcrumbLink';\n\nconst BreadcrumbPage = forwardRef<HTMLSpanElement, ComponentPropsWithoutRef<'span'>>(\n ({ className, ...props }, ref) => (\n <span\n ref={ref}\n role=\"link\"\n aria-disabled=\"true\"\n aria-current=\"page\"\n className={cn('font-normal text-foreground', className)}\n {...props}\n />\n ),\n);\nBreadcrumbPage.displayName = 'BreadcrumbPage';\n\nconst BreadcrumbSeparator = ({ children, className, ...props }: ComponentProps<'li'>) => (\n <li\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('[&>svg]:size-3.5', className)}\n {...props}\n >\n {children ?? (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n )}\n </li>\n);\nBreadcrumbSeparator.displayName = 'BreadcrumbSeparator';\n\nconst BreadcrumbEllipsis = ({ className, ...props }: ComponentProps<'span'>) => (\n <span\n role=\"presentation\"\n aria-hidden=\"true\"\n className={cn('flex h-9 w-9 items-center justify-center', className)}\n {...props}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className=\"h-4 w-4\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"1\"\n />\n <circle\n cx=\"19\"\n cy=\"12\"\n r=\"1\"\n />\n <circle\n cx=\"5\"\n cy=\"12\"\n r=\"1\"\n />\n </svg>\n <span className=\"sr-only\">More</span>\n </span>\n);\nBreadcrumbEllipsis.displayName = 'BreadcrumbEllipsis';\n\nexport {\n Breadcrumb,\n BreadcrumbList,\n BreadcrumbItem,\n BreadcrumbLink,\n BreadcrumbPage,\n BreadcrumbSeparator,\n BreadcrumbEllipsis,\n};\n","// Simple icon components (since we don't have lucide-react)\nexport const MenuIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"12\"\n y2=\"12\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"6\"\n y2=\"6\"\n />\n <line\n x1=\"4\"\n x2=\"20\"\n y1=\"18\"\n y2=\"18\"\n />\n </svg>\n);\n\nexport const HomeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z\" />\n <polyline points=\"9 22 9 12 15 12 15 22\" />\n </svg>\n);\n\nexport const PaintbrushIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path\n fill=\"none\"\n d=\"m14.622 17.897l-10.68-2.913M18.376 2.622a1 1 0 1 1 3.002 3.002L17.36 9.643a.5.5 0 0 0 0 .707l.944.944a2.41 2.41 0 0 1 0 3.408l-.944.944a.5.5 0 0 1-.707 0L8.354 7.348a.5.5 0 0 1 0-.707l.944-.944a2.41 2.41 0 0 1 3.408 0l.944.944a.5.5 0 0 0 .707 0zM9 8c-1.804 2.71-3.97 3.46-6.583 3.948a.507.507 0 0 0-.302.819l7.32 8.883a1 1 0 0 0 1.185.204C12.735 20.405 16 16.792 16 15\"\n />\n </svg>\n);\n\nexport const MessageCircleIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22Z\" />\n </svg>\n);\n\nexport const GlobeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <line\n x1=\"2\"\n x2=\"22\"\n y1=\"12\"\n y2=\"12\"\n />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n);\n\nexport const KeyboardIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"16\"\n x=\"2\"\n y=\"4\"\n rx=\"2\"\n />\n <path d=\"M6 8h.01\" />\n <path d=\"M10 8h.01\" />\n <path d=\"M14 8h.01\" />\n <path d=\"M18 8h.01\" />\n <path d=\"M8 12h.01\" />\n <path d=\"M12 12h.01\" />\n <path d=\"M16 12h.01\" />\n <path d=\"M7 16h10\" />\n </svg>\n);\n\nexport const CheckIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n);\n\nexport const VideoIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5\" />\n <rect\n x=\"2\"\n y=\"6\"\n width=\"14\"\n height=\"12\"\n rx=\"2\"\n />\n </svg>\n);\n\nexport const LinkIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71\" />\n </svg>\n);\n\nexport const LockIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"18\"\n height=\"11\"\n x=\"3\"\n y=\"11\"\n rx=\"2\"\n ry=\"2\"\n />\n <path d=\"M7 11V7a5 5 0 0 1 10 0v4\" />\n </svg>\n);\n\nexport const SettingsIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\" />\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"3\"\n />\n </svg>\n);\n\nexport const CodeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"16 18 22 12 16 6\" />\n <polyline points=\"8 6 2 12 8 18\" />\n </svg>\n);\n\nexport const ChevronRightIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\nexport const ChevronLeftIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"15 18 9 12 15 6\" />\n </svg>\n);\n\nexport const ShieldIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\" />\n </svg>\n);\n\nexport const HardDriveIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <line\n x1=\"22\"\n y1=\"12\"\n x2=\"2\"\n y2=\"12\"\n />\n <path d=\"M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z\" />\n <line\n x1=\"6\"\n y1=\"16\"\n x2=\"6.01\"\n y2=\"16\"\n />\n <line\n x1=\"10\"\n y1=\"16\"\n x2=\"10.01\"\n y2=\"16\"\n />\n </svg>\n);\n\nexport const RefreshCwIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5\" />\n </svg>\n);\n\n/** Double-arrow refresh / sync icon (two curved arrows in a circle). */\nexport const RefreshDoubleIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n width=\"16\"\n height=\"16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M21 12a9 9 0 0 0-9-9a9.75 9.75 0 0 0-6.74 2.74L3 8\" />\n <path d=\"M3 3v5h5m-5 4a9 9 0 0 0 9 9a9.75 9.75 0 0 0 6.74-2.74L21 16\" />\n <path d=\"M16 16h5v5\" />\n </svg>\n);\n\nexport const ServerIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"8\"\n x=\"2\"\n y=\"2\"\n rx=\"2\"\n ry=\"2\"\n />\n <rect\n width=\"20\"\n height=\"8\"\n x=\"2\"\n y=\"14\"\n rx=\"2\"\n ry=\"2\"\n />\n <line\n x1=\"6\"\n y1=\"6\"\n x2=\"6.01\"\n y2=\"6\"\n />\n <line\n x1=\"6\"\n y1=\"18\"\n x2=\"6.01\"\n y2=\"18\"\n />\n <line\n x1=\"10\"\n y1=\"6\"\n x2=\"10.01\"\n y2=\"6\"\n />\n <line\n x1=\"10\"\n y1=\"18\"\n x2=\"10.01\"\n y2=\"18\"\n />\n </svg>\n);\n\nexport const PackageIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"m7.5 4.27 9 5.15\" />\n <path d=\"M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z\" />\n <path d=\"m3.3 7 8.7 5 8.7-5\" />\n <path d=\"M12 22V12\" />\n </svg>\n);\n","import {\n forwardRef,\n Children,\n isValidElement,\n cloneElement,\n type HTMLAttributes,\n type ReactNode,\n type ReactElement,\n} from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface ButtonGroupProps extends HTMLAttributes<HTMLDivElement> {\n children: ReactNode;\n}\n\nconst ButtonGroup = forwardRef<HTMLDivElement, ButtonGroupProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn('inline-flex rounded-md', className)}\n role=\"group\"\n {...props}\n >\n {Children.map(children, (child, index) => {\n if (isValidElement(child)) {\n const isFirst = index === 0;\n const isLast = index === Children.count(children) - 1;\n\n return cloneElement(child as ReactElement<Record<string, unknown>>, {\n className: cn(\n // Remove rounded corners from all buttons\n 'rounded-none',\n // First button: rounded left only (uses theme radius)\n isFirst && 'rounded-l-md',\n // Last button: rounded right only (uses theme radius)\n isLast && 'rounded-r-md',\n // Remove left border from all except first, using theme border color\n !isFirst && 'border-l-0 -ml-px',\n (child as ReactElement<{ className?: string }>).props.className,\n ),\n });\n }\n return child;\n })}\n </div>\n );\n },\n);\nButtonGroup.displayName = 'ButtonGroup';\n\nexport { ButtonGroup };\n","/* eslint-disable no-console */\n/**\n * Theme color definitions following shadcn/ui CSS variable structure\n * Each theme has light and dark mode variants\n * Colors are stored in hex format (e.g., \"#4CAF50\" or \"4CAF50\")\n * and converted to HSL when applied to CSS variables\n */\n\n/**\n * Convert hex color (format: \"#RRGGBB\" or \"RRGGBB\") to HSL string (format: \"H S% L%\")\n */\nfunction hexToHsl(hexString: string): string {\n // Handle non-color values like radius\n if (!hexString || typeof hexString !== 'string') {\n return hexString;\n }\n\n // Check if it's a hex color\n if (!hexString.match(/^#?[0-9A-Fa-f]{6}$/)) {\n // If it's not a hex color, return as-is (might be radius or other value)\n return hexString;\n }\n\n // Remove # if present\n const hex = hexString.replace('#', '');\n\n // Parse RGB values\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n\n // Validate parsed values\n if (isNaN(r) || isNaN(g) || isNaN(b)) {\n console.warn(`[Theme] Invalid hex color: ${hexString}`);\n return hexString;\n }\n\n // Normalize RGB values to 0-1\n const rNorm = r / 255;\n const gNorm = g / 255;\n const bNorm = b / 255;\n\n const max = Math.max(rNorm, gNorm, bNorm);\n const min = Math.min(rNorm, gNorm, bNorm);\n let h = 0;\n let s = 0;\n const l = (max + min) / 2;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case rNorm:\n h = ((gNorm - bNorm) / d + (gNorm < bNorm ? 6 : 0)) / 6;\n break;\n case gNorm:\n h = ((bNorm - rNorm) / d + 2) / 6;\n break;\n case bNorm:\n h = ((rNorm - gNorm) / d + 4) / 6;\n break;\n }\n }\n\n // Convert to degrees and percentages\n const hDeg = Math.round(h * 360 * 10) / 10; // Keep one decimal for precision\n const sPercent = Math.round(s * 100 * 10) / 10;\n const lPercent = Math.round(l * 100 * 10) / 10;\n\n const result = `${hDeg} ${sPercent}% ${lPercent}%`;\n\n // Validate result\n if (!result.match(/^\\d+(\\.\\d+)?\\s+\\d+(\\.\\d+)?%\\s+\\d+(\\.\\d+)?%$/)) {\n console.warn(`[Theme] Invalid HSL conversion result for ${hexString}: ${result}`);\n return hexString;\n }\n\n return result;\n}\n\nexport interface ThemeColors {\n light: {\n background: string;\n foreground: string;\n card: string;\n cardForeground: string;\n popover: string;\n popoverForeground: string;\n primary: string;\n primaryForeground: string;\n secondary: string;\n secondaryForeground: string;\n muted: string;\n mutedForeground: string;\n accent: string;\n accentForeground: string;\n destructive: string;\n destructiveForeground: string;\n border: string;\n input: string;\n ring: string;\n radius: string;\n sidebarBackground: string;\n sidebarForeground: string;\n sidebarPrimary: string;\n sidebarPrimaryForeground: string;\n sidebarAccent: string;\n sidebarAccentForeground: string;\n sidebarBorder: string;\n sidebarRing: string;\n };\n dark: {\n background: string;\n foreground: string;\n card: string;\n cardForeground: string;\n popover: string;\n popoverForeground: string;\n primary: string;\n primaryForeground: string;\n secondary: string;\n secondaryForeground: string;\n muted: string;\n mutedForeground: string;\n accent: string;\n accentForeground: string;\n destructive: string;\n destructiveForeground: string;\n border: string;\n input: string;\n ring: string;\n radius: string;\n sidebarBackground: string;\n sidebarForeground: string;\n sidebarPrimary: string;\n sidebarPrimaryForeground: string;\n sidebarAccent: string;\n sidebarAccentForeground: string;\n sidebarBorder: string;\n sidebarRing: string;\n };\n}\n\nexport interface ThemeDefinition {\n name: string;\n displayName: string;\n colors: ThemeColors;\n fontFamily?: string; // Optional custom font family (backward compatible)\n headingFontFamily?: string; // Optional font family for headings (h1-h6)\n bodyFontFamily?: string; // Optional font family for body text\n fontFiles?: string[]; // Optional array of font file URLs or paths to load (e.g., Google Fonts links or local paths)\n letterSpacing?: string; // Optional custom letter spacing (e.g., \"0.02em\")\n textShadow?: string; // Optional custom text shadow (e.g., \"1px 1px 2px rgba(0, 0, 0, 0.1)\")\n lineHeight?: string; // Optional custom line height (e.g., \"1.6\")\n}\n\n/**\n * Default theme - Green (current ShellUI theme)\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const defaultTheme: ThemeDefinition = {\n name: 'default',\n displayName: 'Default',\n colors: {\n light: {\n background: '#FFFFFF', // White\n foreground: '#020617', // Very dark blue-gray\n card: '#FFFFFF', // White\n cardForeground: '#020617', // Very dark blue-gray\n popover: '#FFFFFF', // White\n popoverForeground: '#020617', // Very dark blue-gray\n primary: '#22C55E', // Green\n primaryForeground: '#FFFFFF', // White\n secondary: '#F1F5F9', // Light gray-blue\n secondaryForeground: '#0F172A', // Dark blue-gray\n muted: '#F1F5F9', // Light gray-blue\n mutedForeground: '#64748B', // Medium gray-blue\n accent: '#F1F5F9', // Light gray-blue\n accentForeground: '#0F172A', // Dark blue-gray\n destructive: '#EF4444', // Red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#E2E8F0', // Light gray\n input: '#E2E8F0', // Light gray\n ring: '#020617', // Very dark blue-gray\n radius: '0.5rem',\n sidebarBackground: '#FAFAFA', // Off-white\n sidebarForeground: '#334155', // Dark gray-blue\n sidebarPrimary: '#0F172A', // Very dark blue-gray\n sidebarPrimaryForeground: '#FAFAFA', // Off-white\n sidebarAccent: '#F4F4F5', // Light gray\n sidebarAccentForeground: '#0F172A', // Very dark blue-gray\n sidebarBorder: '#E2E8F0', // Light gray\n sidebarRing: '#3B82F6', // Blue\n },\n dark: {\n background: '#020617', // Very dark blue-gray\n foreground: '#F8FAFC', // Off-white\n card: '#020617', // Very dark blue-gray\n cardForeground: '#F8FAFC', // Off-white\n popover: '#020617', // Very dark blue-gray\n popoverForeground: '#F8FAFC', // Off-white\n primary: '#4ADE80', // Bright green\n primaryForeground: '#FFFFFF', // White\n secondary: '#1E293B', // Dark blue-gray\n secondaryForeground: '#F8FAFC', // Off-white\n muted: '#1E293B', // Dark blue-gray\n mutedForeground: '#94A3B8', // Medium gray-blue\n accent: '#1E293B', // Dark blue-gray\n accentForeground: '#F8FAFC', // Off-white\n destructive: '#991B1B', // Dark red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#1E293B', // Dark blue-gray\n input: '#1E293B', // Dark blue-gray\n ring: '#CBD5E1', // Light gray-blue\n radius: '0.5rem',\n sidebarBackground: '#0F172A', // Very dark blue-gray\n sidebarForeground: '#F1F5F9', // Light gray-blue\n sidebarPrimary: '#E0E7FF', // Very light blue\n sidebarPrimaryForeground: '#0F172A', // Very dark blue-gray\n sidebarAccent: '#18181B', // Very dark gray\n sidebarAccentForeground: '#F1F5F9', // Light gray-blue\n sidebarBorder: '#18181B', // Very dark gray\n sidebarRing: '#3B82F6', // Blue\n },\n },\n};\n\n/**\n * Blue theme\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const blueTheme: ThemeDefinition = {\n name: 'blue',\n displayName: 'Blue',\n colors: {\n light: {\n background: '#FFFFFF', // White\n foreground: '#020617', // Very dark blue-gray\n card: '#FFFFFF', // White\n cardForeground: '#020617', // Very dark blue-gray\n popover: '#FFFFFF', // White\n popoverForeground: '#020617', // Very dark blue-gray\n primary: '#3B82F6', // Blue\n primaryForeground: '#FFFFFF', // White\n secondary: '#F1F5F9', // Light gray-blue\n secondaryForeground: '#0F172A', // Dark blue-gray\n muted: '#F1F5F9', // Light gray-blue\n mutedForeground: '#64748B', // Medium gray-blue\n accent: '#F1F5F9', // Light gray-blue\n accentForeground: '#0F172A', // Dark blue-gray\n destructive: '#EF4444', // Red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#E2E8F0', // Light gray\n input: '#E2E8F0', // Light gray\n ring: '#3B82F6', // Blue\n radius: '0.5rem',\n sidebarBackground: '#FAFAFA', // Off-white\n sidebarForeground: '#334155', // Dark gray-blue\n sidebarPrimary: '#3B82F6', // Blue\n sidebarPrimaryForeground: '#FFFFFF', // White\n sidebarAccent: '#F4F4F5', // Light gray\n sidebarAccentForeground: '#0F172A', // Very dark blue-gray\n sidebarBorder: '#E2E8F0', // Light gray\n sidebarRing: '#3B82F6', // Blue\n },\n dark: {\n background: '#020617', // Very dark blue-gray\n foreground: '#F8FAFC', // Off-white\n card: '#020617', // Very dark blue-gray\n cardForeground: '#F8FAFC', // Off-white\n popover: '#020617', // Very dark blue-gray\n popoverForeground: '#F8FAFC', // Off-white\n primary: '#3B82F6', // Blue\n primaryForeground: '#FFFFFF', // White\n secondary: '#1E293B', // Dark blue-gray\n secondaryForeground: '#F8FAFC', // Off-white\n muted: '#1E293B', // Dark blue-gray\n mutedForeground: '#94A3B8', // Medium gray-blue\n accent: '#1E293B', // Dark blue-gray\n accentForeground: '#F8FAFC', // Off-white\n destructive: '#991B1B', // Dark red\n destructiveForeground: '#F8FAFC', // Off-white\n border: '#1E293B', // Dark blue-gray\n input: '#1E293B', // Dark blue-gray\n ring: '#3B82F6', // Blue\n radius: '0.5rem',\n sidebarBackground: '#0F172A', // Very dark blue-gray\n sidebarForeground: '#F1F5F9', // Light gray-blue\n sidebarPrimary: '#3B82F6', // Blue\n sidebarPrimaryForeground: '#0F172A', // Dark blue-gray\n sidebarAccent: '#18181B', // Very dark gray\n sidebarAccentForeground: '#F1F5F9', // Light gray-blue\n sidebarBorder: '#18181B', // Very dark gray\n sidebarRing: '#3B82F6', // Blue\n },\n },\n};\n\n/**\n * Warm Yellow theme - Custom yellowish theme with warm tones\n * Colors are in hex format (e.g., \"#FFFFFF\" or \"FFFFFF\" for white)\n */\nexport const warmYellowTheme: ThemeDefinition = {\n name: 'warm-yellow',\n displayName: 'Warm Yellow',\n fontFamily: '\"Comic Sans MS\", \"Comic Sans\", \"Chalkboard SE\", \"Comic Neue\", cursive, sans-serif',\n letterSpacing: '0.02em',\n textShadow: '1px 1px 2px rgba(0, 0, 0, 0.1)',\n lineHeight: '1.6',\n colors: {\n light: {\n background: '#FFF8E7', // Warm cream/yellowish\n foreground: '#3E2723', // Warm dark brown\n card: '#FFFEF5', // Slightly off-white cream\n cardForeground: '#3E2723', // Warm dark brown\n popover: '#FFFEF5', // Slightly off-white cream\n popoverForeground: '#3E2723', // Warm dark brown\n primary: '#F59E0B', // Warm golden amber (complements yellow)\n primaryForeground: '#FFFFFF', // White\n secondary: '#F5E6D3', // Warm beige\n secondaryForeground: '#3E2723', // Warm dark brown\n muted: '#F5E6D3', // Warm beige\n mutedForeground: '#6D4C41', // Medium warm brown\n accent: '#FFE082', // Light warm yellow\n accentForeground: '#3E2723', // Warm dark brown\n destructive: '#E57373', // Soft red (works with warm tones)\n destructiveForeground: '#FFFFFF', // White\n border: '#E8D5B7', // Warm tan border\n input: '#E8D5B7', // Warm tan input border\n ring: '#F59E0B', // Warm golden amber ring\n radius: '0.5rem',\n sidebarBackground: '#FFF5E1', // Slightly warmer cream (subtle contrast with main background)\n sidebarForeground: '#5D4037', // Medium warm brown\n sidebarPrimary: '#F59E0B', // Warm golden amber\n sidebarPrimaryForeground: '#FFFFFF', // White\n sidebarAccent: '#F5E6D3', // Warm beige\n sidebarAccentForeground: '#3E2723', // Warm dark brown\n sidebarBorder: '#E8D5B7', // Warm tan\n sidebarRing: '#F59E0B', // Warm golden amber\n },\n dark: {\n background: '#2E2419', // Dark warm brown\n foreground: '#FFF8E7', // Warm cream (inverted)\n card: '#3E2723', // Dark warm brown\n cardForeground: '#FFF8E7', // Warm cream\n popover: '#3E2723', // Dark warm brown\n popoverForeground: '#FFF8E7', // Warm cream\n primary: '#FBBF24', // Bright golden amber (lighter for dark mode)\n primaryForeground: '#FFFFFF', // White for better contrast\n secondary: '#4E342E', // Medium dark warm brown\n secondaryForeground: '#FFF8E7', // Warm cream\n muted: '#4E342E', // Medium dark warm brown\n mutedForeground: '#D7CCC8', // Light warm gray\n accent: '#FFB74D', // Warm orange accent\n accentForeground: '#2E2419', // Dark warm brown for better contrast\n destructive: '#EF5350', // Softer red for dark mode\n destructiveForeground: '#FFF8E7', // Warm cream\n border: '#5D4037', // Medium warm brown border\n input: '#5D4037', // Medium warm brown input border\n ring: '#FBBF24', // Bright golden amber ring\n radius: '0.5rem',\n sidebarBackground: '#35281F', // Slightly warmer dark brown (subtle contrast with main background)\n sidebarForeground: '#D7CCC8', // Light warm gray\n sidebarPrimary: '#FBBF24', // Bright golden amber\n sidebarPrimaryForeground: '#2E2419', // Dark warm brown for better contrast\n sidebarAccent: '#4E342E', // Medium dark warm brown\n sidebarAccentForeground: '#FFF8E7', // Warm cream\n sidebarBorder: '#5D4037', // Medium warm brown\n sidebarRing: '#FBBF24', // Bright golden amber\n },\n },\n};\n\n/**\n * Registry of all available themes\n */\nconst themeRegistry = new Map<string, ThemeDefinition>([\n ['default', defaultTheme],\n ['blue', blueTheme],\n ['warm-yellow', warmYellowTheme],\n]);\n\n/**\n * Register a custom theme\n */\nexport function registerTheme(theme: ThemeDefinition): void {\n themeRegistry.set(theme.name, theme);\n}\n\n/**\n * Get a theme by name\n */\nexport function getTheme(name: string): ThemeDefinition | undefined {\n return themeRegistry.get(name);\n}\n\n/**\n * Get all available themes\n */\nexport function getAllThemes(): ThemeDefinition[] {\n return Array.from(themeRegistry.values());\n}\n\n/**\n * Apply theme colors to the document\n * Converts hex format colors to HSL format for CSS variables\n * Sets variables directly on :root to ensure they override CSS defaults\n */\nexport function applyTheme(theme: ThemeDefinition, isDark: boolean): void {\n if (typeof document === 'undefined') {\n return;\n }\n\n const root = document.documentElement;\n const colors = isDark ? theme.colors.dark : theme.colors.light;\n\n // Convert hex to HSL for all colors\n const primaryHsl = hexToHsl(colors.primary);\n\n // Apply CSS variables directly on :root element\n // Inline styles have the highest specificity and will override CSS defaults\n // Format: HSL values without hsl() wrapper (e.g., \"142 71% 45%\")\n root.style.setProperty('--background', hexToHsl(colors.background));\n root.style.setProperty('--foreground', hexToHsl(colors.foreground));\n root.style.setProperty('--card', hexToHsl(colors.card));\n root.style.setProperty('--card-foreground', hexToHsl(colors.cardForeground));\n root.style.setProperty('--popover', hexToHsl(colors.popover));\n root.style.setProperty('--popover-foreground', hexToHsl(colors.popoverForeground));\n root.style.setProperty('--primary', primaryHsl);\n root.style.setProperty('--primary-foreground', hexToHsl(colors.primaryForeground));\n root.style.setProperty('--secondary', hexToHsl(colors.secondary));\n root.style.setProperty('--secondary-foreground', hexToHsl(colors.secondaryForeground));\n root.style.setProperty('--muted', hexToHsl(colors.muted));\n root.style.setProperty('--muted-foreground', hexToHsl(colors.mutedForeground));\n root.style.setProperty('--accent', hexToHsl(colors.accent));\n root.style.setProperty('--accent-foreground', hexToHsl(colors.accentForeground));\n root.style.setProperty('--destructive', hexToHsl(colors.destructive));\n root.style.setProperty('--destructive-foreground', hexToHsl(colors.destructiveForeground));\n root.style.setProperty('--border', hexToHsl(colors.border));\n root.style.setProperty('--input', hexToHsl(colors.input));\n root.style.setProperty('--ring', hexToHsl(colors.ring));\n root.style.setProperty('--radius', colors.radius); // radius is not a color\n root.style.setProperty('--sidebar-background', hexToHsl(colors.sidebarBackground));\n root.style.setProperty('--sidebar-foreground', hexToHsl(colors.sidebarForeground));\n root.style.setProperty('--sidebar-primary', hexToHsl(colors.sidebarPrimary));\n root.style.setProperty('--sidebar-primary-foreground', hexToHsl(colors.sidebarPrimaryForeground));\n root.style.setProperty('--sidebar-accent', hexToHsl(colors.sidebarAccent));\n root.style.setProperty('--sidebar-accent-foreground', hexToHsl(colors.sidebarAccentForeground));\n root.style.setProperty('--sidebar-border', hexToHsl(colors.sidebarBorder));\n root.style.setProperty('--sidebar-ring', hexToHsl(colors.sidebarRing));\n\n // Load custom font files if provided\n // Always clean up existing theme fonts first (for theme switching)\n const head = document.head || document.getElementsByTagName('head')[0];\n const existingFontLinks = head.querySelectorAll('link[data-theme-font], style[data-theme-font]');\n existingFontLinks.forEach((link) => link.remove());\n\n if (theme.fontFiles && theme.fontFiles.length > 0) {\n theme.fontFiles.forEach((fontFile, index) => {\n // Check if it's a Google Fonts link or a regular stylesheet\n if (fontFile.includes('fonts.googleapis.com') || fontFile.endsWith('.css')) {\n const link = document.createElement('link');\n link.rel = 'stylesheet';\n link.href = fontFile;\n link.setAttribute('data-theme-font', theme.name);\n head.appendChild(link);\n } else {\n // Assume it's a font file URL - create @font-face rule\n const style = document.createElement('style');\n style.setAttribute('data-theme-font', theme.name);\n // Extract font name from URL or use a generic name\n const fontName = `ThemeFont-${theme.name}-${index}`;\n style.textContent = `\n @font-face {\n font-family: '${fontName}';\n src: url('${fontFile}') format('woff2');\n }\n `;\n head.appendChild(style);\n }\n });\n }\n\n // Apply custom font families\n // Priority: headingFontFamily/bodyFontFamily > fontFamily (backward compatible)\n const bodyFont = theme.bodyFontFamily || theme.fontFamily;\n const headingFont = theme.headingFontFamily || theme.fontFamily || bodyFont;\n\n if (bodyFont) {\n root.style.setProperty('--body-font-family', bodyFont);\n root.style.setProperty('--font-family', bodyFont); // Backward compatibility\n document.body.style.fontFamily = bodyFont;\n } else {\n root.style.removeProperty('--body-font-family');\n root.style.removeProperty('--font-family');\n document.body.style.fontFamily = '';\n }\n\n if (headingFont) {\n root.style.setProperty('--heading-font-family', headingFont);\n // Apply to headings via CSS variable (will be used in CSS)\n } else {\n root.style.removeProperty('--heading-font-family');\n }\n\n // Apply optional font styling properties generically\n if (theme.letterSpacing) {\n root.style.setProperty('--letter-spacing', theme.letterSpacing);\n root.style.letterSpacing = theme.letterSpacing;\n } else {\n root.style.removeProperty('--letter-spacing');\n root.style.letterSpacing = '';\n }\n\n if (theme.textShadow) {\n root.style.setProperty('--text-shadow', theme.textShadow);\n // Apply slightly lighter shadow to body for better readability\n const bodyShadow = theme.textShadow.replace(/rgba\\(([^)]+)\\)/, (match, rgba) => {\n // Reduce opacity by ~20% for body text\n const values = rgba.split(',').map((v: string) => v.trim());\n if (values.length === 4) {\n const opacity = parseFloat(values[3]);\n return `rgba(${values[0]}, ${values[1]}, ${values[2]}, ${Math.max(0, opacity * 0.8)})`;\n }\n return match;\n });\n document.body.style.textShadow = bodyShadow;\n } else {\n root.style.removeProperty('--text-shadow');\n document.body.style.textShadow = '';\n }\n\n if (theme.lineHeight) {\n root.style.setProperty('--line-height', theme.lineHeight);\n document.body.style.lineHeight = theme.lineHeight;\n } else {\n root.style.removeProperty('--line-height');\n document.body.style.lineHeight = '';\n }\n\n // Verify primary color is set (for debugging)\n const actualPrimary = root.style.getPropertyValue('--primary');\n\n // Validate HSL format (should be \"H S% L%\" like \"142 71% 45%\")\n const hslFormat = /^\\d+(\\.\\d+)?\\s+\\d+(\\.\\d+)?%\\s+\\d+(\\.\\d+)?%$/;\n\n if (!actualPrimary || actualPrimary.trim() === '') {\n console.error(\n `[Theme] Failed to set --primary CSS variable. Expected HSL from ${colors.primary}, got: \"${actualPrimary}\"`,\n );\n } else if (!hslFormat.test(actualPrimary.trim())) {\n console.error(\n `[Theme] Invalid HSL format for --primary: \"${actualPrimary}\". Expected format: \"H S% L%\"`,\n );\n }\n\n // Force a reflow to ensure Tailwind picks up the changes\n // This is sometimes needed for Tailwind v4 to recognize CSS variable changes\n void root.offsetHeight;\n}\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { cn } from '@/lib/utils';\nimport { useEffect, useState } from 'react';\nimport { getAllThemes, registerTheme, type ThemeDefinition } from '@/features/theme/themes';\n\nconst SunIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"4\"\n />\n <path d=\"M12 2v2\" />\n <path d=\"M12 20v2\" />\n <path d=\"m4.93 4.93 1.41 1.41\" />\n <path d=\"m17.66 17.66 1.41 1.41\" />\n <path d=\"M2 12h2\" />\n <path d=\"M20 12h2\" />\n <path d=\"m6.34 17.66-1.41 1.41\" />\n <path d=\"m19.07 4.93-1.41 1.41\" />\n </svg>\n);\n\nconst MoonIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\" />\n </svg>\n);\n\nconst MonitorIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <rect\n width=\"20\"\n height=\"14\"\n x=\"2\"\n y=\"3\"\n rx=\"2\"\n />\n <line\n x1=\"8\"\n x2=\"16\"\n y1=\"21\"\n y2=\"21\"\n />\n <line\n x1=\"12\"\n x2=\"12\"\n y1=\"17\"\n y2=\"21\"\n />\n </svg>\n);\n\n// Theme color preview component\nconst ThemePreview = ({\n theme,\n isSelected,\n isDark,\n}: {\n theme: ThemeDefinition;\n isSelected: boolean;\n isDark: boolean;\n}) => {\n const colors = isDark ? theme.colors.dark : theme.colors.light;\n\n return (\n <div\n className={cn(\n 'relative overflow-hidden rounded-lg border-2 transition-all',\n isSelected ? 'border-primary shadow-lg' : 'border-border',\n )}\n style={{ backgroundColor: colors.background }}\n >\n <div className=\"p-3 space-y-2\">\n {/* Primary color */}\n <div\n className=\"h-8 rounded-md\"\n style={{ backgroundColor: colors.primary }}\n />\n {/* Secondary colors */}\n <div className=\"flex gap-1\">\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.background }}\n />\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.secondary }}\n />\n <div\n className=\"h-6 flex-1 rounded\"\n style={{ backgroundColor: colors.accent }}\n />\n </div>\n {/* Accent colors */}\n <div className=\"flex gap-1\">\n <div\n className=\"h-4 flex-1 rounded\"\n style={{ backgroundColor: colors.muted }}\n />\n <div\n className=\"h-4 flex-1 rounded\"\n style={{ backgroundColor: colors.border }}\n />\n </div>\n </div>\n {/* Theme name overlay */}\n <div\n className=\"absolute bottom-0 left-0 right-0 bg-background/90 backdrop-blur-sm px-2 py-1\"\n style={{ backgroundColor: colors.background }}\n >\n <p\n className=\"text-xs font-medium text-center\"\n style={\n theme.fontFamily\n ? {\n fontFamily: theme.fontFamily,\n letterSpacing: theme.letterSpacing || 'normal',\n textShadow: theme.textShadow || 'none',\n }\n : {}\n }\n >\n {theme.displayName}\n </p>\n </div>\n </div>\n );\n};\n\nexport const Appearance = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentTheme = settings.appearance?.theme || 'system';\n const currentThemeName = settings.appearance?.themeName || 'default';\n\n const [availableThemes, setAvailableThemes] = useState<ThemeDefinition[]>([]);\n\n // Register custom themes from config and get all themes\n useEffect(() => {\n if (config?.themes) {\n config.themes.forEach((themeDef: ThemeDefinition) => {\n registerTheme(themeDef);\n });\n }\n setAvailableThemes(getAllThemes());\n }, [config]);\n\n // Determine if we're in dark mode for preview\n const [isDarkForPreview, setIsDarkForPreview] = useState(() => {\n if (typeof window === 'undefined') return false;\n return (\n currentTheme === 'dark' ||\n (currentTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches)\n );\n });\n\n // Update preview mode when theme changes\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const updatePreview = () => {\n setIsDarkForPreview(\n currentTheme === 'dark' ||\n (currentTheme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches),\n );\n };\n\n updatePreview();\n\n if (currentTheme === 'system') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n const handleChange = () => updatePreview();\n\n if (mediaQuery.addEventListener) {\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n } else if (mediaQuery.addListener) {\n mediaQuery.addListener(handleChange);\n return () => mediaQuery.removeListener(handleChange);\n }\n }\n }, [currentTheme]);\n\n const modeThemes = [\n { value: 'light' as const, label: t('appearance.themes.light'), icon: SunIcon },\n { value: 'dark' as const, label: t('appearance.themes.dark'), icon: MoonIcon },\n { value: 'system' as const, label: t('appearance.themes.system'), icon: MonitorIcon },\n ];\n\n return (\n <div className=\"space-y-6\">\n {/* Theme Mode Selection (Light/Dark/System) */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('appearance.mode')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('appearance.modeDescription')}</p>\n </div>\n <div className=\"mt-2\">\n <ButtonGroup>\n {modeThemes.map((theme) => {\n const Icon = theme.icon;\n const isSelected = currentTheme === theme.value;\n return (\n <Button\n key={theme.value}\n variant={isSelected ? 'default' : 'outline'}\n onClick={() => {\n updateSetting('appearance', { theme: theme.value });\n }}\n className={cn(\n 'h-10 px-4 transition-all flex items-center gap-2 cursor-pointer',\n isSelected && ['font-semibold'],\n !isSelected && ['bg-background hover:bg-accent/50', 'text-muted-foreground'],\n )}\n aria-label={theme.label}\n title={theme.label}\n >\n <Icon />\n <span className=\"text-sm font-medium\">{theme.label}</span>\n </Button>\n );\n })}\n </ButtonGroup>\n </div>\n </div>\n\n {/* Theme Selection (Color Scheme) */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('appearance.colorTheme')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('appearance.colorThemeDescription')}</p>\n </div>\n <div className=\"mt-2 grid grid-cols-2 md:grid-cols-3 gap-4\">\n {availableThemes.map((theme) => {\n const isSelected = currentThemeName === theme.name;\n return (\n <button\n key={theme.name}\n onClick={() => {\n updateSetting('appearance', { themeName: theme.name });\n }}\n className={cn(\n 'text-left transition-all cursor-pointer',\n isSelected && 'ring-2 ring-primary ring-offset-2 rounded-lg',\n )}\n aria-label={theme.displayName}\n >\n <ThemePreview\n theme={theme}\n isSelected={isSelected}\n isDark={isDarkForPreview}\n />\n </button>\n );\n })}\n </div>\n </div>\n </div>\n );\n};\n","import i18n from 'i18next';\nimport { initReactI18next } from 'react-i18next';\nimport enCommon from './translations/en/common.json';\nimport enSettings from './translations/en/settings.json';\nimport enCookieConsent from './translations/en/cookieConsent.json';\nimport frCommon from './translations/fr/common.json';\nimport frSettings from './translations/fr/settings.json';\nimport frCookieConsent from './translations/fr/cookieConsent.json';\n\nexport const allSupportedLanguages = [\n { code: 'en', name: 'English', nativeName: 'English' },\n { code: 'fr', name: 'French', nativeName: 'Français' },\n] as const;\n\nexport type SupportedLanguage = (typeof allSupportedLanguages)[number]['code'];\n\nconst resources = {\n en: {\n common: enCommon,\n settings: enSettings,\n cookieConsent: enCookieConsent,\n },\n fr: {\n common: frCommon,\n settings: frSettings,\n cookieConsent: frCookieConsent,\n },\n};\n\n// Get initial language from localStorage if available\nconst getInitialLanguage = (enabledLanguages: string[]): SupportedLanguage => {\n if (typeof window !== 'undefined') {\n try {\n const stored = localStorage.getItem('shellui:settings');\n if (stored) {\n const parsed = JSON.parse(stored);\n const languageCode = parsed.language?.code;\n // Only use stored language if it's in the enabled languages list\n if (languageCode && enabledLanguages.includes(languageCode)) {\n return languageCode as SupportedLanguage;\n }\n }\n } catch (_error) {\n // Ignore errors, fall back to default\n }\n }\n // Fallback to first enabled language or 'en'\n return (enabledLanguages[0] || 'en') as SupportedLanguage;\n};\n\n// Initialize i18n with default settings (will be updated when config loads)\nlet isInitialized = false;\n\nexport const initializeI18n = (enabledLanguages?: string | string[]) => {\n // Normalize to array\n const enabledLangs = enabledLanguages\n ? Array.isArray(enabledLanguages)\n ? enabledLanguages\n : [enabledLanguages]\n : allSupportedLanguages.map((lang) => lang.code);\n\n // Filter to only include languages we have translations for\n const validLangs = enabledLangs.filter((lang) =>\n allSupportedLanguages.some((supported) => supported.code === lang),\n );\n\n // Ensure at least 'en' is available\n const finalLangs = validLangs.length > 0 ? validLangs : ['en'];\n const initialLang = getInitialLanguage(finalLangs);\n\n if (!isInitialized) {\n i18n.use(initReactI18next).init({\n resources,\n defaultNS: 'common',\n lng: initialLang,\n fallbackLng: 'en',\n supportedLngs: finalLangs,\n interpolation: {\n escapeValue: false, // React already escapes values\n },\n react: {\n useSuspense: false, // Disable suspense for better PWA compatibility\n },\n });\n isInitialized = true;\n } else {\n // Update supported languages if config changes\n i18n.changeLanguage(initialLang);\n }\n\n return finalLangs;\n};\n\n// Initialize with all languages by default (will be filtered when config loads)\ninitializeI18n();\n\nexport const getSupportedLanguages = (enabledLanguages?: string | string[]) => {\n const enabledLangs = enabledLanguages\n ? Array.isArray(enabledLanguages)\n ? enabledLanguages\n : [enabledLanguages]\n : allSupportedLanguages.map((lang) => lang.code);\n\n return allSupportedLanguages.filter((lang) => enabledLangs.includes(lang.code));\n};\n\nexport default i18n;\n","import { forwardRef, type SelectHTMLAttributes } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport type SelectProps = SelectHTMLAttributes<HTMLSelectElement>;\n\nconst Select = forwardRef<HTMLSelectElement, SelectProps>(\n ({ className, children, ...props }, ref) => {\n return (\n <select\n className={cn(\n 'select-field flex h-10 w-full rounded-md border border-input bg-background pl-3 pr-10 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 cursor-pointer disabled:cursor-not-allowed disabled:opacity-50',\n className,\n )}\n ref={ref}\n {...props}\n >\n {children}\n </select>\n );\n },\n);\nSelect.displayName = 'Select';\n\nexport { Select };\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { getSupportedLanguages } from '@/i18n/config';\nimport { Button } from '@/components/ui/button';\nimport { ButtonGroup } from '@/components/ui/button-group';\nimport { Select } from '@/components/ui/select';\nimport { cn } from '@/lib/utils';\nimport { useState, useEffect } from 'react';\n\nconst GlobeIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <line\n x1=\"2\"\n x2=\"22\"\n y1=\"12\"\n y2=\"12\"\n />\n <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\" />\n </svg>\n);\n\nconst ClockIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n />\n <polyline points=\"12 6 12 12 16 14\" />\n </svg>\n);\n\n// Timezones organized by region\nconst TIMEZONE_GROUPS = [\n {\n label: 'UTC',\n timezones: [{ value: 'UTC', label: 'UTC (Coordinated Universal Time)' }],\n },\n {\n label: 'North America',\n timezones: [\n { value: 'America/New_York', label: 'Eastern Time (US & Canada)' },\n { value: 'America/Chicago', label: 'Central Time (US & Canada)' },\n { value: 'America/Denver', label: 'Mountain Time (US & Canada)' },\n { value: 'America/Los_Angeles', label: 'Pacific Time (US & Canada)' },\n { value: 'America/Toronto', label: 'Toronto' },\n { value: 'America/Vancouver', label: 'Vancouver' },\n { value: 'America/Mexico_City', label: 'Mexico City' },\n ],\n },\n {\n label: 'South America',\n timezones: [\n { value: 'America/Sao_Paulo', label: 'São Paulo' },\n { value: 'America/Buenos_Aires', label: 'Buenos Aires' },\n ],\n },\n {\n label: 'Europe',\n timezones: [\n { value: 'Europe/London', label: 'London' },\n { value: 'Europe/Paris', label: 'Paris' },\n { value: 'Europe/Berlin', label: 'Berlin' },\n { value: 'Europe/Rome', label: 'Rome' },\n { value: 'Europe/Madrid', label: 'Madrid' },\n { value: 'Europe/Amsterdam', label: 'Amsterdam' },\n { value: 'Europe/Stockholm', label: 'Stockholm' },\n { value: 'Europe/Zurich', label: 'Zurich' },\n ],\n },\n {\n label: 'Asia',\n timezones: [\n { value: 'Asia/Tokyo', label: 'Tokyo' },\n { value: 'Asia/Shanghai', label: 'Shanghai' },\n { value: 'Asia/Hong_Kong', label: 'Hong Kong' },\n { value: 'Asia/Singapore', label: 'Singapore' },\n { value: 'Asia/Dubai', label: 'Dubai' },\n { value: 'Asia/Kolkata', label: 'Mumbai, New Delhi' },\n { value: 'Asia/Bangkok', label: 'Bangkok' },\n ],\n },\n {\n label: 'Australia & Pacific',\n timezones: [\n { value: 'Australia/Sydney', label: 'Sydney' },\n { value: 'Australia/Melbourne', label: 'Melbourne' },\n { value: 'Pacific/Auckland', label: 'Auckland' },\n ],\n },\n];\n\n// Format date based on timezone and language\nconst formatDate = (date: Date, timezone: string, lang: string): string => {\n try {\n return new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n }).format(date);\n } catch {\n return date.toLocaleDateString(lang);\n }\n};\n\n// Format time based on timezone and language\nconst formatTime = (date: Date, timezone: string, lang: string): string => {\n try {\n return new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n hour12: false,\n }).format(date);\n } catch {\n return date.toLocaleTimeString(lang);\n }\n};\n\n// Get browser's current timezone\nconst getBrowserTimezone = (): string => {\n if (typeof Intl !== 'undefined') {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n};\n\n// Get human-readable timezone name\nconst getTimezoneDisplayName = (timezone: string, lang = 'en'): string => {\n try {\n // Try to get a friendly name from Intl\n const formatter = new Intl.DateTimeFormat(lang, {\n timeZone: timezone,\n timeZoneName: 'long',\n });\n const parts = formatter.formatToParts(new Date());\n const timeZoneName = parts.find((part) => part.type === 'timeZoneName')?.value;\n\n if (timeZoneName) {\n return timeZoneName;\n }\n\n // Fallback: try to get city name from timezone string\n const cityName = timezone.split('/').pop()?.replace(/_/g, ' ') || timezone;\n return cityName;\n } catch {\n // Final fallback: use the timezone code\n return timezone;\n }\n};\n\nexport const LanguageAndRegion = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n const browserTimezone = getBrowserTimezone();\n const currentTimezone = settings.region?.timezone || browserTimezone;\n const isUsingBrowserTimezone = currentTimezone === browserTimezone;\n\n // Get supported languages based on config\n const supportedLanguages = getSupportedLanguages(config?.language);\n\n const handleResetRegion = () => {\n updateSetting('region', { timezone: browserTimezone });\n };\n\n // State for current date/time\n const [currentDateTime, setCurrentDateTime] = useState<{ date: string; time: string }>(() => {\n const now = new Date();\n return {\n date: formatDate(now, currentTimezone, currentLanguage),\n time: formatTime(now, currentTimezone, currentLanguage),\n };\n });\n\n // Update date/time every second and when timezone/language changes\n useEffect(() => {\n const updateDateTime = () => {\n const now = new Date();\n setCurrentDateTime({\n date: formatDate(now, currentTimezone, currentLanguage),\n time: formatTime(now, currentTimezone, currentLanguage),\n });\n };\n\n // Update immediately when timezone or language changes\n updateDateTime();\n\n // Then update every second\n const interval = setInterval(updateDateTime, 1000);\n\n return () => clearInterval(interval);\n }, [currentTimezone, currentLanguage]);\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('languageAndRegion.language')}\n </label>\n <div className=\"mt-2\">\n <ButtonGroup>\n {supportedLanguages.map((lang) => {\n const isSelected = currentLanguage === lang.code;\n return (\n <Button\n key={lang.code}\n variant={isSelected ? 'default' : 'outline'}\n onClick={() => {\n updateSetting('language', { code: lang.code });\n }}\n className={cn(\n 'h-10 px-4 transition-all flex items-center gap-2',\n isSelected && ['shadow-md', 'font-semibold'],\n !isSelected && ['bg-background hover:bg-accent/50', 'text-muted-foreground'],\n )}\n aria-label={lang.nativeName}\n title={lang.nativeName}\n >\n <GlobeIcon />\n <span className=\"text-sm font-medium\">{lang.nativeName}</span>\n </Button>\n );\n })}\n </ButtonGroup>\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('languageAndRegion.region')}\n </label>\n {!isUsingBrowserTimezone && (\n <Button\n variant=\"ghost\"\n size=\"sm\"\n onClick={handleResetRegion}\n className=\"h-8 text-xs\"\n >\n {t('languageAndRegion.resetToBrowser')}\n </Button>\n )}\n </div>\n <div className=\"mt-2 space-y-3\">\n <Select\n value={currentTimezone}\n onChange={(e) => {\n updateSetting('region', { timezone: e.target.value });\n }}\n className=\"w-full\"\n >\n {TIMEZONE_GROUPS.map((group) => (\n <optgroup\n key={group.label}\n label={group.label}\n >\n {group.timezones.map((tz) => {\n const isBrowserTimezone = tz.value === browserTimezone;\n return (\n <option\n key={tz.value}\n value={tz.value}\n >\n {tz.label}\n {isBrowserTimezone ? ` (${t('languageAndRegion.defaultBrowser')})` : ''}\n </option>\n );\n })}\n </optgroup>\n ))}\n </Select>\n <div className=\"flex items-center gap-2 px-3 py-2 rounded-md bg-muted/60 border border-border/50\">\n <ClockIcon />\n <div className=\"flex items-baseline gap-2\">\n <span className=\"text-lg font-semibold tabular-nums\">{currentDateTime.time}</span>\n <span className=\"text-xs text-muted-foreground\">{currentDateTime.date}</span>\n </div>\n </div>\n <div className=\"text-xs text-muted-foreground flex items-center gap-1\">\n <span>{t('languageAndRegion.timezoneLabel')}:</span>\n <span className=\"font-medium\">\n {getTimezoneDisplayName(currentTimezone, currentLanguage)}\n </span>\n {isUsingBrowserTimezone && (\n <span className=\"ml-1\">({t('languageAndRegion.defaultBrowser')})</span>\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n","/* eslint-disable no-console */\nimport { Workbox } from 'workbox-window';\nimport { shellui, getLogger } from '@shellui/sdk';\n\nconst logger = getLogger('shellcore');\n\nlet wb: Workbox | null = null;\nlet updateAvailable = false;\nlet waitingServiceWorker: ServiceWorker | null = null;\nlet registrationPromise: Promise<void> | null = null;\nlet statusListeners: Array<(status: { registered: boolean; updateAvailable: boolean }) => void> =\n [];\nlet isInitialRegistration = false; // Track if this is the first registration (no reload needed)\nlet eventListenersAdded = false; // Track if event listeners have been added to prevent duplicates\nlet toastShownForServiceWorkerId: string | null = null; // Track which service worker we've shown toast for (prevents duplicates within same page load)\nlet isIntentionalUpdate = false; // Track if we're performing an intentional update (user clicked Install Now)\n// CRITICAL: Track registration state to prevent disabling during registration or immediately after page load\n// Initialize start time to page load time to provide grace period immediately after refresh\n// This prevents race conditions where error handlers fire before registration completes\nlet isRegistering = false; // Track if registration is currently in progress\nlet registrationStartTime = typeof window !== 'undefined' ? Date.now() : 0; // Track when registration started (initialize to page load time)\nconst REGISTRATION_GRACE_PERIOD = 5000; // Don't auto-disable within 5 seconds of page load/registration start\n\n// Store event handler references so we can remove them if needed\ntype EventHandler = (event?: unknown) => void;\nlet waitingHandler: EventHandler | null = null;\nlet activatedHandler: EventHandler | null = null;\nlet controllingHandler: EventHandler | null = null;\nlet registeredHandler: EventHandler | null = null;\nlet redundantHandler: EventHandler | null = null;\nlet serviceWorkerErrorHandler: EventHandler | null = null;\nlet messageErrorHandler: EventHandler | null = null;\n\n/** Global set by host or by us from config so Tauri can be forced (e.g. when __TAURI__ is not yet injected in dev). */\ndeclare global {\n interface Window {\n __SHELLUI_TAURI__?: boolean;\n }\n}\n\nfunction hasTauriOnWindow(w: Window | null): boolean {\n if (!w) return false;\n const o = w as Window & {\n __TAURI__?: unknown;\n __TAURI_INTERNALS__?: unknown;\n __SHELLUI_TAURI__?: boolean;\n };\n if (o.__SHELLUI_TAURI__ === true) return true;\n return !!(o.__TAURI__ ?? o.__TAURI_INTERNALS__);\n}\n\n/** True when the app is running inside Tauri (desktop). Service worker is disabled there; a different caching system is used. */\nexport function isTauri(): boolean {\n if (typeof window === 'undefined') return false;\n if (hasTauriOnWindow(window)) return true;\n try {\n if (window !== window.top && hasTauriOnWindow(window.top)) return true;\n if (window.parent && window.parent !== window && hasTauriOnWindow(window.parent)) return true;\n } catch {\n // Cross-origin: can't access top/parent\n }\n return false;\n}\n\n// Cache for service worker file existence check to avoid duplicate fetches\nlet swFileExistsCache: Promise<boolean> | null = null;\nlet swFileExistsCacheTime = 0;\nconst SW_FILE_EXISTS_CACHE_TTL = 5000; // Cache for 5 seconds\n\n// Notify all listeners of status changes\nasync function notifyStatusListeners() {\n const registered = await isServiceWorkerRegistered();\n const status = {\n registered,\n updateAvailable,\n };\n statusListeners.forEach((listener) => listener(status));\n}\n\nexport interface ServiceWorkerRegistrationOptions {\n enabled: boolean;\n onUpdateAvailable?: () => void;\n}\n\n/**\n * Disable caching automatically when errors occur\n * This helps prevent hard-to-debug issues\n */\nasync function disableCachingAutomatically(reason: string): Promise<void> {\n // CRITICAL: Don't disable if registration is in progress or just started\n // This prevents race conditions where errors fire during registration\n const timeSinceRegistrationStart = Date.now() - registrationStartTime;\n if (isRegistering || timeSinceRegistrationStart < REGISTRATION_GRACE_PERIOD) {\n console.warn(\n `[Service Worker] NOT disabling - registration in progress or within grace period. Reason: ${reason}, isRegistering: ${isRegistering}, timeSinceStart: ${timeSinceRegistrationStart}ms`,\n );\n logger.warn(\n `Not disabling service worker - registration in progress or within grace period: ${reason}`,\n );\n return;\n }\n\n logger.error(`Auto-disabling caching due to error: ${reason}`);\n\n try {\n // Unregister service worker first\n await unregisterServiceWorker();\n\n // Disable service worker in settings\n // We need to access settings through localStorage since we're in a module\n if (typeof window !== 'undefined') {\n const STORAGE_KEY = 'shellui:settings';\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const settings = JSON.parse(stored);\n // Only update if service worker is currently enabled to avoid unnecessary updates\n if (settings.serviceWorker?.enabled !== false) {\n settings.serviceWorker = { enabled: false };\n // Migrate legacy key so old cached shape is updated\n if (settings.caching !== undefined) {\n delete settings.caching;\n }\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));\n\n // Notify the app to reload settings via message system\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings },\n });\n\n // Also dispatch event for local listeners\n window.dispatchEvent(\n new CustomEvent('shellui:settings-updated', {\n detail: { settings },\n }),\n );\n\n // Show a toast notification\n shellui.toast({\n title: 'Service Worker Disabled',\n description: `The service worker has been automatically disabled due to an error: ${reason}`,\n type: 'error',\n duration: 10000,\n });\n }\n } else {\n // No settings stored, create default with service worker disabled\n const defaultSettings = {\n serviceWorker: { enabled: false },\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(defaultSettings));\n\n shellui.toast({\n title: 'Service Worker Disabled',\n description: `The service worker has been automatically disabled due to an error: ${reason}`,\n type: 'error',\n duration: 10000,\n });\n }\n } catch (error) {\n logger.error('Failed to disable service worker in settings:', { error });\n // Still show toast even if settings update fails\n shellui.toast({\n title: 'Service Worker Error',\n description: `Service worker error: ${reason}. Please disable it manually in settings.`,\n type: 'error',\n duration: 10000,\n });\n }\n }\n } catch (error) {\n logger.error('Failed to disable caching automatically:', { error });\n }\n}\n\n/**\n * Check if service worker file exists\n * Uses caching to prevent duplicate fetches when called concurrently\n */\nexport async function serviceWorkerFileExists(): Promise<boolean> {\n const now = Date.now();\n\n // Return cached promise if it's still valid and in progress\n if (swFileExistsCache && now - swFileExistsCacheTime < SW_FILE_EXISTS_CACHE_TTL) {\n return swFileExistsCache;\n }\n\n // Create a new fetch promise and cache it\n swFileExistsCache = (async () => {\n try {\n // Use a timestamp to prevent caching\n const response = await fetch(`/sw.js?t=${Date.now()}`, {\n method: 'GET',\n cache: 'no-store',\n headers: {\n 'Cache-Control': 'no-cache',\n Pragma: 'no-cache',\n },\n });\n\n // Handle 500 errors - server error, but don't disable caching immediately\n // This might be a transient server issue, just return false\n if (response.status >= 500) {\n console.warn(\n `[Service Worker] Server error (${response.status}) when fetching service worker - not disabling`,\n );\n logger.warn(\n `Server error (${response.status}) when fetching service worker - not disabling to avoid false positives`,\n );\n return false;\n }\n\n // If not ok or 404, file doesn't exist\n if (!response.ok || response.status === 404) {\n return false;\n }\n\n // Check content type - should be JavaScript\n const contentType = response.headers.get('content-type') || '';\n const isJavaScript =\n contentType.includes('javascript') ||\n contentType.includes('application/javascript') ||\n contentType.includes('text/javascript');\n\n // If content type is HTML, it's likely Vite's dev server returning index.html\n // which means the file doesn't exist\n if (contentType.includes('text/html')) {\n return false;\n }\n\n // Try to read a bit of the content to verify it's actually a service worker\n const text = await response.text();\n // Service worker files typically start with imports or have workbox/precache references\n const looksLikeServiceWorker =\n text.includes('workbox') ||\n text.includes('precache') ||\n text.includes('serviceWorker') ||\n text.includes('self.addEventListener');\n\n // If we got a response but it doesn't look like a service worker, log warning but don't disable\n // This could be a dev server issue or temporary problem\n if (!isJavaScript && !looksLikeServiceWorker) {\n console.warn('[Service Worker] File does not look like a service worker - not disabling');\n logger.warn(\n 'Service worker file appears to be invalid or corrupted - not disabling to avoid false positives',\n );\n return false;\n }\n\n return isJavaScript || looksLikeServiceWorker;\n } catch (error) {\n // Network errors - don't disable caching, might be offline or transient issue\n if (error instanceof TypeError && error.message.includes('Failed to fetch')) {\n // Don't disable on network errors - might be offline\n console.warn('[Service Worker] Network error when checking file existence - not disabling');\n return false;\n }\n // Other errors - log but don't disable, could be transient\n console.warn('[Service Worker] Error checking file existence - not disabling:', error);\n logger.warn(\n 'Network error checking service worker file - not disabling to avoid false positives',\n { error },\n );\n return false;\n }\n })();\n\n swFileExistsCacheTime = now;\n return swFileExistsCache;\n}\n\n/**\n * Register the service worker and handle updates\n */\nexport async function registerServiceWorker(\n options: ServiceWorkerRegistrationOptions = { enabled: true },\n): Promise<void> {\n if (!('serviceWorker' in navigator)) {\n return;\n }\n\n if (isTauri()) {\n await unregisterServiceWorker();\n wb = null;\n return;\n }\n\n if (!options.enabled) {\n // If disabled, unregister existing service worker\n await unregisterServiceWorker();\n wb = null;\n return;\n }\n\n // Check if service worker file exists (works in both dev and production)\n const swExists = await serviceWorkerFileExists();\n if (!swExists) {\n // In dev mode, the service worker might not be ready yet, try again after a short delay\n // Only retry once to avoid infinite loops\n if (!registrationPromise) {\n setTimeout(async () => {\n const retryExists = await serviceWorkerFileExists();\n if (retryExists && !registrationPromise) {\n // Retry registration if file becomes available\n registerServiceWorker(options);\n } else if (!retryExists) {\n logger.warn('Service worker file not found. Service workers may not be available.');\n }\n }, 1000);\n }\n return;\n }\n\n // If already registering, wait for that to complete\n if (registrationPromise) {\n return registrationPromise;\n }\n\n registrationPromise = (async () => {\n // CRITICAL: Mark that registration is starting to prevent auto-disable during registration\n isRegistering = true;\n registrationStartTime = Date.now();\n\n try {\n // Check if service worker is already registered\n const existingRegistration = await navigator.serviceWorker.getRegistration();\n\n // CRITICAL: If there's a waiting service worker on page load, automatically activate it\n // The user refreshed the page, so they want the new version - activate it automatically\n // This ensures the new version is used without requiring manual \"Install Now\" click\n if (existingRegistration?.waiting && !existingRegistration.installing) {\n // There's a waiting service worker from before the refresh\n // Since the user refreshed, they want the new version - activate it automatically\n console.info(\n '[Service Worker] Waiting service worker found on page load - automatically activating',\n );\n logger.info(\n 'Waiting service worker found on page load - automatically activating since user refreshed',\n );\n\n // Store reference to waiting service worker\n const waitingSW = existingRegistration.waiting;\n waitingServiceWorker = waitingSW;\n\n // CRITICAL: Mark that we're auto-activating so the controlling handler knows to reload\n // Store in sessionStorage so it survives if there's a reload\n if (typeof window !== 'undefined') {\n sessionStorage.setItem('shellui:service-worker:auto-activated', 'true');\n }\n\n // Automatically activate the waiting service worker\n // This is safe because the user already refreshed, so they want the new version\n // The controlling event handler will detect the auto-activation and reload the page\n try {\n waitingSW.postMessage({ type: 'SKIP_WAITING' });\n console.info(\n '[Service Worker] Sent SKIP_WAITING to waiting service worker - will reload when it takes control',\n );\n } catch (error) {\n logger.error('Failed to activate waiting service worker:', { error });\n // Clear the flag on error\n if (typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:auto-activated');\n }\n }\n }\n\n if (existingRegistration && wb) {\n // Already registered, just update\n isInitialRegistration = false; // This is an update check\n wb.update();\n return;\n }\n\n // Check if there's already a service worker controlling the page\n // If not, this is an initial registration (don't reload)\n isInitialRegistration = !navigator.serviceWorker.controller;\n\n // Register the service worker\n // Only create new Workbox instance if one doesn't exist\n const isNewWorkbox = !wb;\n if (!wb) {\n // Use updateViaCache: 'none' to ensure service worker file changes are always detected\n // This bypasses the browser cache when checking for updates to sw.js/sw-dev.js\n wb = new Workbox('/sw.js', {\n type: 'classic',\n updateViaCache: 'none', // Always check network for service worker updates\n });\n }\n\n // Remove old listeners if they exist (handles React Strict Mode double-mounting)\n // Always remove listeners if wb exists and we have handler references, regardless of flag\n // This ensures we clean up properly even if the flag was reset\n if (wb) {\n if (waitingHandler) {\n wb.removeEventListener('waiting', waitingHandler);\n waitingHandler = null;\n }\n if (activatedHandler) {\n wb.removeEventListener('activated', activatedHandler);\n activatedHandler = null;\n }\n if (controllingHandler) {\n wb.removeEventListener('controlling', controllingHandler);\n controllingHandler = null;\n }\n if (registeredHandler) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (wb as any).removeEventListener('registered', registeredHandler);\n registeredHandler = null;\n }\n if (redundantHandler) {\n wb.removeEventListener('redundant', redundantHandler);\n redundantHandler = null;\n }\n if (serviceWorkerErrorHandler) {\n navigator.serviceWorker.removeEventListener('error', serviceWorkerErrorHandler);\n serviceWorkerErrorHandler = null;\n }\n if (messageErrorHandler) {\n navigator.serviceWorker.removeEventListener('messageerror', messageErrorHandler);\n messageErrorHandler = null;\n }\n // Reset flag so we can add listeners again\n eventListenersAdded = false;\n }\n\n // Only add event listeners once (when creating a new Workbox instance or if they were removed)\n if (isNewWorkbox && !eventListenersAdded) {\n // Set flag IMMEDIATELY to prevent duplicate listener registration\n eventListenersAdded = true;\n\n // Handle service worker updates\n // CRITICAL: Use a consistent toast ID to prevent duplicate toasts\n // If the handler is called multiple times (event listener + manual call),\n // using the same ID will update the existing toast instead of creating a new one\n const UPDATE_AVAILABLE_TOAST_ID = 'shellui:update-available';\n\n waitingHandler = async () => {\n try {\n // CRITICAL: If we're auto-activating (user refreshed), don't show toast\n // The service worker will activate automatically and page will reload\n const isAutoActivating =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:auto-activated') === 'true';\n\n // Get the waiting service worker\n const registration = await navigator.serviceWorker.getRegistration();\n if (!registration || !registration.waiting) {\n return;\n }\n\n const currentWaitingSW = registration.waiting;\n const currentWaitingSWId = currentWaitingSW.scriptURL;\n\n // CRITICAL: If auto-activating, update state but skip toast\n if (isAutoActivating) {\n console.info(\n '[Service Worker] Waiting event fired during auto-activation - skipping toast',\n );\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n return;\n }\n\n // CRITICAL: Check flag BEFORE updating state to prevent race conditions\n // If we've already shown toast for this service worker in this page load, don't show again\n // This prevents duplicate toasts within the same page load, but allows showing after refresh\n if (toastShownForServiceWorkerId === currentWaitingSWId) {\n // Already shown, but ensure state is correct\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n return;\n }\n\n // CRITICAL: Mark that we've shown toast for this service worker IMMEDIATELY\n // This must happen BEFORE showing the toast to prevent race conditions\n // If the handler is called twice quickly, both might pass the check before the flag is set\n toastShownForServiceWorkerId = currentWaitingSWId;\n\n // Update state\n updateAvailable = true;\n waitingServiceWorker = currentWaitingSW;\n notifyStatusListeners();\n\n // Show toast notification about update\n if (options.onUpdateAvailable) {\n options.onUpdateAvailable();\n } else {\n // CRITICAL: Use consistent toast ID so duplicate calls update the same toast\n // This prevents multiple toasts from appearing if the handler is called multiple times\n // CRITICAL: Always create fresh action handlers that reference the current waitingServiceWorker\n // This ensures the action handler always has the correct service worker reference\n // even if the toast is updated later\n const actionHandler = () => {\n logger.info('Install Now clicked, updating service worker...');\n // CRITICAL: Get the current waitingServiceWorker at click time, not at toast creation time\n // This ensures it works even if the toast was created earlier and then updated\n if (waitingServiceWorker) {\n updateServiceWorker().catch((error) => {\n logger.error('Failed to update service worker:', { error });\n });\n } else {\n logger.warn('Install Now clicked but no waiting service worker found');\n // Try to get it from registration as fallback\n navigator.serviceWorker.getRegistration().then((swRegistration) => {\n if (swRegistration?.waiting) {\n waitingServiceWorker = swRegistration.waiting;\n updateServiceWorker().catch((error) => {\n logger.error('Failed to update service worker:', { error });\n });\n }\n });\n }\n };\n\n shellui.toast({\n id: UPDATE_AVAILABLE_TOAST_ID, // Use consistent ID to prevent duplicates\n title: 'New version available',\n description: 'A new version of the app is available. Install now or later?',\n type: 'info',\n duration: 0, // Don't auto-dismiss\n position: 'bottom-left',\n action: {\n label: 'Install Now',\n onClick: actionHandler, // Use the handler function\n },\n cancel: {\n label: 'Later',\n onClick: () => {\n // User chose to install later, toast will be dismissed\n },\n },\n });\n }\n } catch (error) {\n logger.error('Error in waiting handler:', { error });\n // On error, reset the flag so we can try again for this service worker\n toastShownForServiceWorkerId = null;\n }\n };\n wb.addEventListener('waiting', waitingHandler);\n\n // Handle service worker activated\n activatedHandler = (event?: unknown) => {\n const evt = (event ?? {}) as Record<string, unknown>;\n console.info('[Service Worker] Service worker activated:', {\n isUpdate: evt.isUpdate,\n isInitialRegistration,\n });\n notifyStatusListeners();\n // Reset flags when service worker is activated (update installed or new registration)\n updateAvailable = false;\n waitingServiceWorker = null;\n toastShownForServiceWorkerId = null; // Reset so we can show toast for the next update\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\")\n // Check both in-memory flag and sessionStorage to ensure we only reload when user explicitly requested it\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const shouldReload = isIntentionalUpdate || isIntentionalUpdatePersisted;\n\n // Clear intentional update flag after activation (update is complete)\n if (typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:intentional-update');\n }\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\")\n // Do NOT reload automatically when a new service worker is installed - wait for user action\n // Exception: If we auto-activated on page load, the new version is already active, no reload needed\n if (evt.isUpdate && !isInitialRegistration && shouldReload) {\n // User explicitly clicked \"Install Now\", so reload to use the new version\n console.info('[Service Worker] Reloading page after intentional update');\n window.location.reload();\n } else if (evt.isUpdate && !isInitialRegistration && !shouldReload) {\n // Auto-activated on page load - new version is now active, UI will update via notifyStatusListeners\n console.info(\n '[Service Worker] Service worker auto-activated on page load - new version is now active',\n );\n }\n // Reset flag after activation\n isInitialRegistration = false;\n };\n wb.addEventListener('activated', activatedHandler as (event: unknown) => void);\n\n // Handle service worker controlling\n controllingHandler = () => {\n notifyStatusListeners();\n\n // CRITICAL: Check if this is an auto-activation from page load refresh\n // If user refreshed and we auto-activated, we need to reload to get the new JavaScript\n const wasAutoActivated =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:auto-activated') === 'true';\n\n // CRITICAL: Only reload if this is an intentional update (user clicked \"Install Now\") OR auto-activation\n // The controlling event fires when a service worker takes control\n // Check both in-memory flag and sessionStorage to ensure we only reload when appropriate\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const shouldReload =\n isIntentionalUpdate || isIntentionalUpdatePersisted || wasAutoActivated;\n\n // Clear auto-activation flag if it was set\n if (wasAutoActivated && typeof window !== 'undefined') {\n sessionStorage.removeItem('shellui:service-worker:auto-activated');\n }\n\n // CRITICAL: Reload if this is an intentional update OR auto-activation from page refresh\n // After reload, the new version will be active and UI will show correct state\n if (!isInitialRegistration && shouldReload) {\n if (wasAutoActivated) {\n console.info(\n '[Service Worker] Auto-activated service worker took control - reloading to use new version',\n );\n } else {\n console.info(\n '[Service Worker] User clicked Install Now - reloading to use new version',\n );\n }\n // Reload to ensure new JavaScript is loaded\n window.location.reload();\n }\n // Reset flag after controlling\n isInitialRegistration = false;\n };\n wb.addEventListener('controlling', controllingHandler);\n\n // Handle service worker registered\n registeredHandler = () => {\n notifyStatusListeners();\n };\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (wb as any).addEventListener('registered', registeredHandler);\n\n // CRITICAL: Handle service worker 'redundant' event\n // This event fires when a service worker is replaced, which is NORMAL during updates\n // The 'redundant' event fires for the OLD service worker when a NEW one takes control\n // During intentional updates (user clicked \"Install Now\"), this is EXPECTED behavior\n // We MUST check for intentional updates BEFORE disabling, otherwise we'll disable the\n // service worker right after the user explicitly asked to install an update!\n redundantHandler = (event?: unknown) => {\n logger.info('Service worker became redundant:', event as Record<string, unknown>);\n\n // CRITICAL CHECK: Verify this is an intentional update BEFORE doing anything\n // Check sessionStorage FIRST (survives page reloads) - this is set BEFORE skip waiting\n // Then check in-memory flag as backup\n // This prevents race conditions where the flag might not be set yet\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n\n // CRITICAL: Also check if there's a waiting service worker - if there is, we're in update flow\n // This provides an additional safety check in case sessionStorage check fails\n // A waiting service worker means an update is in progress, so redundant is expected\n // We check synchronously first (waitingServiceWorker variable), then async if needed\n const hasWaitingServiceWorkerSync = !!waitingServiceWorker;\n\n // CRITICAL: If ANY of these indicate an intentional update, DO NOT disable\n // The combination of checks prevents false positives from disabling during updates\n // This is the KEY fix - we check multiple signals to be absolutely sure it's an update\n const isUpdateFlow =\n isIntentionalUpdate || isIntentionalUpdatePersisted || hasWaitingServiceWorkerSync;\n\n // CRITICAL: Only disable if this is NOT part of a normal update flow\n // Disabling during an update would break the user's explicit \"Install Now\" action\n // This bug has been seen many times - the redundant event fires during normal updates\n // and without these checks, it would disable the service worker right after install\n if (!isUpdateFlow) {\n // Double-check asynchronously in case the sync check missed it\n // CRITICAL: Be very defensive here - only disable if we're absolutely sure it's an error\n navigator.serviceWorker\n .getRegistration()\n .then((registration) => {\n const hasWaitingAsync = !!registration?.waiting;\n const hasInstallingAsync = !!registration?.installing;\n const hasActiveAsync = !!registration?.active;\n\n // CRITICAL: Only disable if there's NO waiting, NO installing, and NO active service worker\n // If any of these exist, it means an update is in progress and redundant is expected\n if (!hasWaitingAsync && !hasInstallingAsync && !hasActiveAsync) {\n // No service worker at all - this is truly unexpected and likely an error\n console.warn(\n '[Service Worker] Redundant event: No service workers found, disabling',\n );\n logger.warn(\n 'Service worker became redundant unexpectedly (no service workers found)',\n );\n disableCachingAutomatically(\n 'Service worker became redundant (no service workers found)',\n );\n } else {\n // Service workers exist - this is likely part of an update flow, don't disable\n console.info(\n '[Service Worker] Redundant event: Service workers exist, likely update in progress - ignoring',\n );\n logger.info(\n 'Service worker became redundant but other service workers exist - likely update in progress, ignoring',\n );\n }\n })\n .catch((error) => {\n // CRITICAL: If async check fails, DON'T disable - this could be a transient error\n // Log the error but don't disable the service worker\n console.warn(\n '[Service Worker] Redundant event: Async check failed, but NOT disabling:',\n error,\n );\n logger.warn(\n 'Service worker redundant event: Async check failed, but NOT disabling to avoid false positives',\n { error },\n );\n });\n } else {\n console.info(\n '[Service Worker] Redundant event: Intentional update detected - ignoring',\n );\n logger.info(\n 'Service worker became redundant as part of normal update - this is expected and safe',\n );\n // CRITICAL: Don't clear the sessionStorage flag immediately - wait until activation\n // Clearing it too early could cause issues if redundant fires multiple times\n // The activated handler will clear it when the update is complete\n }\n };\n wb.addEventListener('redundant', redundantHandler);\n\n // Handle external service worker errors\n // Only disable caching on critical errors, not during normal update operations\n serviceWorkerErrorHandler = (event?: unknown) => {\n logger.error('Service worker error event:', event as Record<string, unknown>);\n\n // Check if this is an intentional update (check both in-memory flag and sessionStorage)\n const isIntentionalUpdatePersisted =\n typeof window !== 'undefined' &&\n sessionStorage.getItem('shellui:service-worker:intentional-update') === 'true';\n const isUpdateFlow = isIntentionalUpdate || isIntentionalUpdatePersisted;\n\n // CRITICAL: Be very defensive - only disable on truly critical errors\n // Many service worker errors are non-fatal and don't require disabling\n if (!isUpdateFlow) {\n // Only disable on actual errors, not warnings or non-critical issues\n const evt = (event ?? {}) as Record<string, unknown>;\n const evtError = evt.error as Record<string, unknown> | undefined;\n const errorMessage = (evt.message as string) || (evtError?.message as string) || 'Unknown error';\n const errorName = (evtError?.name as string) || '';\n\n // CRITICAL: Only disable on critical errors, ignore common non-fatal errors\n // Many errors during service worker lifecycle are expected and don't require disabling\n const isCriticalError =\n !errorMessage.includes('update') &&\n !errorMessage.includes('activate') &&\n !errorMessage.includes('install') &&\n !errorName.includes('AbortError') &&\n !errorName.includes('NetworkError');\n\n if (isCriticalError) {\n disableCachingAutomatically(`Service worker error: ${errorMessage}`);\n } else {\n console.warn('[Service Worker] Non-critical error, ignoring:', errorMessage);\n logger.warn('Service worker non-critical error, not disabling:', {\n errorMessage,\n errorName,\n });\n }\n } else {\n console.info('[Service Worker] Error during update flow, ignoring');\n logger.info('Service worker error during update flow, ignoring');\n }\n };\n navigator.serviceWorker.addEventListener('error', serviceWorkerErrorHandler);\n\n // Handle message errors from service worker\n messageErrorHandler = (event?: unknown) => {\n logger.error('Service worker message error:', event as Record<string, unknown>);\n // Don't disable on message errors - they're usually not critical\n };\n navigator.serviceWorker.addEventListener('messageerror', messageErrorHandler);\n } // End of event listeners block\n\n // Register the service worker\n await wb.register();\n\n // Get the underlying registration to set updateViaCache\n // This ensures changes to sw.js/sw-dev.js are always detected (bypasses cache)\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration) {\n // Set updateViaCache to 'none' to ensure service worker file changes are always detected\n // This tells the browser to always check the network for sw.js/sw-dev.js updates\n // Note: This property is read-only in some browsers, but setting it helps where supported\n try {\n // Access the registration's update method to ensure cache-busting\n // The browser will check the service worker file with cache: 'reload' when update() is called\n } catch (_e) {\n // Ignore if updateViaCache can't be set (some browsers don't support it)\n }\n\n // Check if there's a waiting service worker after registration\n // If we already handled it above (auto-activation on page load), skip showing toast\n // Otherwise, show toast to let user know an update is available\n if (registration.waiting && waitingHandler) {\n const waitingSWId = registration.waiting.scriptURL;\n\n // Check if we already auto-activated this waiting service worker above\n // If so, don't show toast - it will activate automatically\n const wasAutoActivated =\n waitingServiceWorker === registration.waiting && updateAvailable === true;\n\n if (!wasAutoActivated) {\n // This is a new waiting service worker that appeared after registration\n // Show toast to notify user\n // CRITICAL: Check flag BEFORE calling handler to prevent duplicate toasts\n // The waiting event might have already fired and shown the toast\n if (toastShownForServiceWorkerId !== waitingSWId) {\n // Update state first\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n // Trigger the waiting handler to show toast\n // The handler will check the flag again and show toast if needed\n waitingHandler();\n } else {\n // Toast already shown, just update state\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n notifyStatusListeners();\n }\n } else {\n // Already auto-activated, just ensure state is correct\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n notifyStatusListeners();\n }\n }\n }\n\n notifyStatusListeners();\n\n // Check for updates periodically (including service worker file changes)\n // This ensures changes to sw.js/sw-dev.js are detected\n /* const _updateInterval = */ setInterval(\n () => {\n if (wb && options.enabled) {\n // wb.update() checks for updates to the service worker file itself\n // The browser will compare the byte-by-byte content of sw.js/sw-dev.js\n wb.update();\n }\n },\n 60 * 60 * 1000,\n ); // Check every hour\n\n // Also check for updates when the page becomes visible (user returns to tab)\n // This helps detect service worker file changes more quickly\n let visibilityHandler: (() => void) | null = null;\n if (typeof document !== 'undefined') {\n visibilityHandler = () => {\n if (!document.hidden && wb && options.enabled) {\n wb.update();\n }\n };\n document.addEventListener('visibilitychange', visibilityHandler);\n }\n\n // CRITICAL: Mark registration as complete only after everything is set up\n // This prevents error handlers from disabling during the registration process\n isRegistering = false;\n\n // Store interval and handler for cleanup (though cleanup is best-effort)\n // The interval will continue until page reload, which is acceptable\n } catch (error) {\n // Handle registration errors - be very selective about disabling\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : '';\n logger.error('Registration failed:', { error });\n\n // CRITICAL: Only disable on truly critical errors that indicate the service worker is broken\n // Many registration errors are transient or non-fatal\n const isCriticalError =\n (errorMessage.includes('Failed to register') &&\n !errorMessage.includes('already registered')) ||\n (errorMessage.includes('script error') && !errorMessage.includes('network')) ||\n errorMessage.includes('SyntaxError') ||\n (errorMessage.includes('TypeError') && !errorMessage.includes('fetch')) ||\n (error instanceof DOMException &&\n error.name !== 'SecurityError' &&\n error.name !== 'AbortError');\n\n if (isCriticalError) {\n await disableCachingAutomatically(`Registration failed: ${errorMessage}`);\n } else {\n console.warn(\n '[Service Worker] Non-critical registration error, NOT disabling:',\n errorMessage,\n );\n logger.warn('Non-critical registration error, not disabling:', { errorMessage, errorName });\n }\n } finally {\n // CRITICAL: Reset registration flag in finally block to ensure it's always reset\n // But keep a grace period to prevent immediate disable after registration completes\n // The grace period is handled in disableCachingAutomatically\n isRegistering = false;\n registrationPromise = null;\n }\n })();\n\n return registrationPromise;\n}\n\n/**\n * Update the service worker immediately\n * This will reload the page when the update is installed\n */\nexport async function updateServiceWorker(): Promise<void> {\n if (!wb || !waitingServiceWorker) {\n return;\n }\n\n try {\n // CRITICAL: Set intentional update flag FIRST, before any other operations\n // This flag MUST be set in sessionStorage BEFORE skip waiting is called\n // The 'redundant' event can fire very quickly after skip waiting, and if this flag\n // isn't set yet, the redundant handler will think it's an error and disable the SW\n // This is the ROOT CAUSE of the bug where service worker gets disabled on \"Install Now\"\n const INTENTIONAL_UPDATE_KEY = 'shellui:service-worker:intentional-update';\n if (typeof window !== 'undefined') {\n // CRITICAL: Set this IMMEDIATELY - don't wait for anything else\n sessionStorage.setItem(INTENTIONAL_UPDATE_KEY, 'true');\n }\n\n // CRITICAL: Also set in-memory flag immediately\n // This provides backup protection in case sessionStorage has issues\n isIntentionalUpdate = true;\n\n // CRITICAL: Ensure service worker setting is preserved and enabled before reload\n // This prevents the service worker from being disabled after refresh\n // The user explicitly clicked \"Install Now\", so we must keep the service worker enabled\n if (typeof window !== 'undefined') {\n const STORAGE_KEY = 'shellui:settings';\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const settings = JSON.parse(stored);\n // CRITICAL: Always ensure service worker is enabled when user clicks Install Now\n // This ensures it stays enabled after the page reloads\n // Without this, the service worker could be disabled after the reload\n settings.serviceWorker = { enabled: true };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(settings));\n\n // Notify the app about the settings update (in case it's listening)\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings },\n });\n } else {\n // No settings stored, create default with service worker enabled\n const defaultSettings = {\n serviceWorker: { enabled: true },\n };\n localStorage.setItem(STORAGE_KEY, JSON.stringify(defaultSettings));\n }\n } catch (error) {\n logger.warn('Failed to preserve settings before update:', { error });\n // CRITICAL: Even if settings update fails, the intentional update flag is already set\n // This prevents the redundant handler from disabling the service worker\n // The app.tsx will default to enabled anyway, so continue with the update\n }\n }\n\n // Mark that this is an update (not initial registration)\n isInitialRegistration = false;\n\n // Set up reload handler before sending skip waiting\n const reloadApp = () => {\n // Use shellUI refresh message if available, otherwise fallback to window.location.reload\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) {\n window.location.reload();\n }\n };\n\n // Add one-time listener for controlling event\n const updateControllingHandler = () => {\n reloadApp();\n wb?.removeEventListener('controlling', updateControllingHandler);\n // Reset flag after reload is triggered\n setTimeout(() => {\n isIntentionalUpdate = false;\n }, 1000);\n };\n wb.addEventListener('controlling', updateControllingHandler);\n\n // Send skip waiting message to the waiting service worker\n waitingServiceWorker.postMessage({ type: 'SKIP_WAITING' });\n\n // Fallback: if controlling event doesn't fire within 2 seconds, reload anyway\n setTimeout(() => {\n if (controllingHandler) wb?.removeEventListener('controlling', controllingHandler);\n // Check if service worker is now controlling\n if (navigator.serviceWorker.controller) {\n reloadApp();\n }\n // Reset flag if fallback is used\n setTimeout(() => {\n isIntentionalUpdate = false;\n }, 1000);\n }, 2000);\n } catch (error) {\n logger.error('Failed to update service worker:', { error });\n // Reset flag on error\n isIntentionalUpdate = false;\n }\n}\n\n/**\n * Unregister the service worker silently (no page reload)\n */\nexport async function unregisterServiceWorker(): Promise<void> {\n if (!('serviceWorker' in navigator)) {\n return;\n }\n\n try {\n // Set flag to prevent any reloads during unregistration\n isInitialRegistration = true;\n\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration) {\n await registration.unregister();\n\n // Clear all caches silently\n if ('caches' in window) {\n const cacheNames = await caches.keys();\n await Promise.all(cacheNames.map((name) => caches.delete(name)));\n }\n }\n\n // Clean up workbox instance and remove all event listeners\n if (wb) {\n // Remove all event listeners before cleaning up\n if (waitingHandler) wb.removeEventListener('waiting', waitingHandler);\n if (activatedHandler) wb.removeEventListener('activated', activatedHandler);\n if (controllingHandler) wb.removeEventListener('controlling', controllingHandler);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (registeredHandler) (wb as any).removeEventListener('registered', registeredHandler);\n if (redundantHandler) wb.removeEventListener('redundant', redundantHandler);\n if (serviceWorkerErrorHandler) {\n navigator.serviceWorker.removeEventListener('error', serviceWorkerErrorHandler);\n }\n if (messageErrorHandler) {\n navigator.serviceWorker.removeEventListener('messageerror', messageErrorHandler);\n }\n // Clear handler references\n waitingHandler = null;\n activatedHandler = null;\n controllingHandler = null;\n registeredHandler = null;\n redundantHandler = null;\n serviceWorkerErrorHandler = null;\n messageErrorHandler = null;\n // Remove workbox instance\n wb = null;\n }\n\n updateAvailable = false;\n waitingServiceWorker = null;\n isInitialRegistration = false;\n toastShownForServiceWorkerId = null; // Reset toast flag on unregister\n eventListenersAdded = false; // Reset event listeners flag on unregister\n isIntentionalUpdate = false; // Reset intentional update flag on unregister\n notifyStatusListeners();\n } catch (error) {\n logger.error('Failed to unregister service worker:', { error });\n isInitialRegistration = false;\n }\n}\n\n/**\n * Check if service worker is registered and active\n */\nexport async function isServiceWorkerRegistered(): Promise<boolean> {\n if (!('serviceWorker' in navigator)) {\n return false;\n }\n if (isTauri()) {\n return false;\n }\n\n // First check if service worker file exists (only in production)\n const swExists = await serviceWorkerFileExists();\n if (!swExists) {\n return false;\n }\n\n try {\n const registration = await navigator.serviceWorker.getRegistration();\n if (!registration) {\n return false;\n }\n\n // Check if service worker is active (either controlling or installed)\n // A service worker can be registered but not yet active\n if (registration.active) {\n return true;\n }\n\n // Also check if there's a waiting or installing service worker\n // This means registration is in progress or update is available\n if (registration.waiting || registration.installing) {\n return true;\n }\n\n // If navigator.serviceWorker.controller exists, the SW is controlling the page\n if (navigator.serviceWorker.controller) {\n return true;\n }\n\n return false;\n } catch (_error) {\n // Silently return false if there's an error checking registration\n return false;\n }\n}\n\n/**\n * Get service worker status\n */\nexport async function getServiceWorkerStatus(): Promise<{\n registered: boolean;\n updateAvailable: boolean;\n}> {\n const registered = await isServiceWorkerRegistered();\n\n // Actually check if there's a waiting service worker (more reliable than in-memory flag)\n // This ensures we get the correct state even after page reloads\n let actuallyUpdateAvailable = false;\n if (registered && !isTauri()) {\n try {\n const registration = await navigator.serviceWorker.getRegistration();\n if (registration?.waiting) {\n // There's a waiting service worker, so an update is available\n actuallyUpdateAvailable = true;\n // Sync the in-memory flag with the actual state\n updateAvailable = true;\n waitingServiceWorker = registration.waiting;\n } else {\n // No waiting service worker, so no update is available\n actuallyUpdateAvailable = false;\n // Sync the in-memory flag with the actual state\n updateAvailable = false;\n waitingServiceWorker = null;\n }\n } catch (error) {\n logger.error('Failed to check service worker registration:', { error });\n // Fall back to in-memory flag if check fails\n actuallyUpdateAvailable = updateAvailable;\n }\n } else {\n // Not registered or Tauri, so no update available\n actuallyUpdateAvailable = false;\n updateAvailable = false;\n waitingServiceWorker = null;\n }\n\n return {\n registered,\n updateAvailable: actuallyUpdateAvailable,\n };\n}\n\n/**\n * Manually trigger a check for service worker updates (browser only).\n * Resolves when the check is complete. Listen to addStatusListener for updateAvailable changes.\n */\nexport async function checkForServiceWorkerUpdate(): Promise<void> {\n if (isTauri() || !wb) return;\n await wb.update();\n}\n\n/**\n * Add a listener for service worker status changes\n */\nexport function addStatusListener(\n listener: (status: { registered: boolean; updateAvailable: boolean }) => void,\n): () => void {\n statusListeners.push(listener);\n // Don't call immediately - let the component do the initial check to avoid duplicate fetches\n\n // Return unsubscribe function\n return () => {\n statusListeners = statusListeners.filter((l) => l !== listener);\n };\n}\n","import { useTranslation } from 'react-i18next';\nimport { useConfig } from '@/features/config/useConfig';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport {\n isTauri,\n getServiceWorkerStatus,\n addStatusListener,\n checkForServiceWorkerUpdate,\n updateServiceWorker,\n} from '@/service-worker/register';\nimport { shellui, getLogger } from '@shellui/sdk';\nimport { CheckIcon } from '../SettingsIcons';\nimport { useState, useEffect } from 'react';\n\nconst logger = getLogger('shellcore');\n\nexport const UpdateApp = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings } = useSettings();\n const [updateAvailable, setUpdateAvailable] = useState(false);\n const [checking, setChecking] = useState(false);\n const [showUpToDateInButton, setShowUpToDateInButton] = useState(false);\n const [checkError, setCheckError] = useState(false);\n\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true;\n\n useEffect(() => {\n if (isTauri()) return;\n const load = async () => {\n const status = await getServiceWorkerStatus();\n setUpdateAvailable(status.updateAvailable);\n };\n load();\n const unsubscribe = addStatusListener((status) => {\n setUpdateAvailable(status.updateAvailable);\n // If an update becomes available, hide the \"You are up to date\" message and clear any errors\n if (status.updateAvailable) {\n setShowUpToDateInButton(false);\n setCheckError(false);\n }\n });\n return unsubscribe;\n }, []);\n\n const handleCheckForUpdate = async () => {\n if (isTauri()) return;\n setShowUpToDateInButton(false);\n setCheckError(false);\n setChecking(true);\n try {\n // Check current status before triggering update check\n const initialStatus = await getServiceWorkerStatus();\n\n // If update is already available, don't show \"You are up to date\"\n if (initialStatus.updateAvailable) {\n return;\n }\n\n // Trigger update check\n await checkForServiceWorkerUpdate();\n\n // Wait a bit for the update check to complete and status to update\n // The status listener will update updateAvailable if an update is found\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // Check status again after update check\n // Use the state value which may have been updated by the status listener\n // If updateAvailable is true, don't show \"You are up to date\"\n if (!updateAvailable) {\n // Double-check with API to be sure\n const finalStatus = await getServiceWorkerStatus();\n if (!finalStatus.updateAvailable) {\n setShowUpToDateInButton(true);\n window.setTimeout(() => setShowUpToDateInButton(false), 3000);\n }\n }\n } catch (error) {\n // Error occurred during update check - show error message in button\n setCheckError(true);\n logger.error('Failed to check for service worker update:', { error });\n } finally {\n setChecking(false);\n }\n };\n\n const version = config?.version ?? t('updateApp.versionUnknown');\n\n if (isTauri()) {\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.currentVersion')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{version}</p>\n </div>\n <div className=\"rounded-lg border border-border bg-muted/30 p-4\">\n <p className=\"text-sm text-muted-foreground\">{t('updateApp.tauriComingSoon')}</p>\n </div>\n </div>\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6\">\n <div className=\"space-y-4\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.currentVersion')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{version}</p>\n </div>\n {!serviceWorkerEnabled ? (\n <div className=\"space-y-3\">\n <p className=\"text-sm text-muted-foreground\">{t('updateApp.swDisabledMessage')}</p>\n <Button\n variant=\"outline\"\n onClick={() => {\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) window.location.reload();\n }}\n className=\"w-full sm:w-auto\"\n >\n {t('updateApp.refreshApp')}\n </Button>\n </div>\n ) : (\n <>\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('updateApp.status')}\n </label>\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n {updateAvailable ? (\n <span className=\"text-blue-600 dark:text-blue-400\">\n ● {t('updateApp.statusUpdateAvailable')}\n </span>\n ) : (\n <span className=\"text-green-600 dark:text-green-400\">\n ● {t('updateApp.statusUpToDate')}\n </span>\n )}\n </div>\n </div>\n <div className=\"flex items-center gap-2 flex-wrap\">\n {updateAvailable && (\n <Button\n variant=\"default\"\n onClick={async () => {\n await updateServiceWorker();\n }}\n className=\"w-full sm:w-auto\"\n >\n {t('updateApp.installNow')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n onClick={handleCheckForUpdate}\n disabled={checking || updateAvailable}\n className=\"w-full sm:w-auto\"\n >\n {checking ? (\n <>\n <span\n className=\"inline-block h-4 w-4 shrink-0 animate-spin rounded-full border-2 border-current border-t-transparent mr-2\"\n aria-hidden\n />\n {t('updateApp.checking')}\n </>\n ) : checkError ? (\n <span className=\"inline-flex items-center gap-2 text-red-600 dark:text-red-400\">\n {t('updateApp.checkError')}\n </span>\n ) : showUpToDateInButton && !updateAvailable ? (\n <span className=\"inline-flex items-center gap-2 text-green-600 dark:text-green-400\">\n <CheckIcon />\n {t('updateApp.youAreUpToDate')}\n </span>\n ) : (\n t('updateApp.checkForUpdate')\n )}\n </Button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n};\n","import { forwardRef, type InputHTMLAttributes, type ChangeEvent } from 'react';\nimport { cn } from '@/lib/utils';\n\nexport interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n checked?: boolean;\n onCheckedChange?: (checked: boolean) => void;\n}\n\nconst Switch = forwardRef<HTMLInputElement, SwitchProps>(\n ({ className, checked, onCheckedChange, ...props }, ref) => {\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n onCheckedChange?.(e.target.checked);\n };\n\n return (\n <label className=\"inline-flex items-center cursor-pointer\">\n <input\n type=\"checkbox\"\n ref={ref}\n checked={checked}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n <div\n className={cn(\n 'relative w-11 h-6 rounded-full border border-border transition-colors focus-within:outline-none focus-within:ring-2 focus-within:ring-ring',\n checked ? 'bg-primary' : 'bg-muted',\n className,\n )}\n >\n <div\n className={cn(\n 'absolute top-[1px] left-[1px] h-5 w-5 bg-background border border-border rounded-full transition-transform',\n checked ? 'translate-x-5' : 'translate-x-0',\n )}\n />\n </div>\n </label>\n );\n },\n);\nSwitch.displayName = 'Switch';\n\nexport { Switch };\n","import type { ShellUIConfig } from '../config/types';\n\nconst STORAGE_KEY = 'shellui:settings';\n\nfunction getConfig(): ShellUIConfig | undefined {\n if (typeof globalThis === 'undefined') return undefined;\n const g = globalThis as unknown as { __SHELLUI_CONFIG__?: string | ShellUIConfig };\n const raw = g.__SHELLUI_CONFIG__;\n if (raw === null || raw === undefined) return undefined;\n return typeof raw === 'string' ? (JSON.parse(raw) as ShellUIConfig) : raw;\n}\n\nfunction getStoredCookieConsent(): {\n acceptedHosts: string[];\n consentedCookieHosts: string[];\n} {\n if (typeof window === 'undefined') {\n return { acceptedHosts: [], consentedCookieHosts: [] };\n }\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (!stored) return { acceptedHosts: [], consentedCookieHosts: [] };\n const parsed = JSON.parse(stored) as {\n cookieConsent?: { acceptedHosts?: string[]; consentedCookieHosts?: string[] };\n };\n return {\n acceptedHosts: Array.isArray(parsed?.cookieConsent?.acceptedHosts)\n ? parsed.cookieConsent.acceptedHosts\n : [],\n consentedCookieHosts: Array.isArray(parsed?.cookieConsent?.consentedCookieHosts)\n ? parsed.cookieConsent.consentedCookieHosts\n : [],\n };\n } catch {\n return { acceptedHosts: [], consentedCookieHosts: [] };\n }\n}\n\n/**\n * Returns whether the given cookie host is accepted by the user.\n * Use this outside React (e.g. in initSentry) to gate features by cookie consent.\n * - If there is no cookieConsent config, returns true (no consent required).\n * - If the host is not in the config list, returns true (unknown cookie, don't block).\n * - Otherwise returns whether the host is in settings.cookieConsent.acceptedHosts.\n */\nexport function getCookieConsentAccepted(host: string): boolean {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return true;\n const knownHosts = new Set(config.cookieConsent.cookies.map((c) => c.host));\n if (!knownHosts.has(host)) return true;\n const { acceptedHosts } = getStoredCookieConsent();\n return acceptedHosts.includes(host);\n}\n\n/**\n * Returns whether the app should ask for consent again because new cookies were added to config.\n * True when current config has at least one host that is not in consentedCookieHosts (the list\n * stored when the user last gave consent). When re-prompting, pre-fill with acceptedHosts so\n * existing approvals are kept.\n */\nexport function getCookieConsentNeedsRenewal(): boolean {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return false;\n const { consentedCookieHosts } = getStoredCookieConsent();\n if (consentedCookieHosts.length === 0) return true; // Never consented\n const currentHosts = new Set(config.cookieConsent.cookies.map((c) => c.host));\n for (const host of currentHosts) {\n if (!consentedCookieHosts.includes(host)) return true;\n }\n return false;\n}\n\n/**\n * Returns the list of cookie hosts that are in the current config but were not in the list\n * when the user last gave consent. Use to show \"new\" badges or to know which cookies need\n * fresh approval while keeping existing acceptedHosts as pre-checked.\n */\nexport function getCookieConsentNewHosts(): string[] {\n const config = getConfig();\n if (!config?.cookieConsent?.cookies?.length) return [];\n const { consentedCookieHosts } = getStoredCookieConsent();\n const consentedSet = new Set(consentedCookieHosts);\n return config.cookieConsent.cookies.map((c) => c.host).filter((host) => !consentedSet.has(host));\n}\n","import { getCookieConsentAccepted } from '../cookieConsent/cookieConsent';\n\nconst SETTINGS_KEY = 'shellui:settings';\n\n/** True after @sentry/react has been lazy-loaded and init() was called. */\nlet sentryLoaded = false;\n\nfunction isErrorReportingEnabled(): boolean {\n if (typeof window === 'undefined') return true;\n // If cookie consent is configured with a cookie for sentry.io, only enable when user accepted it\n if (!getCookieConsentAccepted('sentry.io')) return false;\n try {\n const stored = localStorage.getItem(SETTINGS_KEY);\n if (!stored) return true;\n const parsed = JSON.parse(stored) as { errorReporting?: { enabled?: boolean } };\n return parsed?.errorReporting?.enabled !== false;\n } catch {\n return true;\n }\n}\n\ntype SentryGlobals = {\n __SHELLUI_SENTRY_DSN__?: string;\n __SHELLUI_SENTRY_ENVIRONMENT__?: string;\n __SHELLUI_SENTRY_RELEASE__?: string;\n};\n\n/**\n * Initialize error reporting only in production when configured and user has not disabled it.\n * Lazy-loads @sentry/react only when needed so the bundle is not loaded when Sentry is unused.\n * Reads DSN, environment, and release from __SHELLUI_SENTRY_DSN__, __SHELLUI_SENTRY_ENVIRONMENT__,\n * and __SHELLUI_SENTRY_RELEASE__ (injected at build time) and user preference from settings.\n * Exported so the settings UI can re-initialize when the user re-enables reporting.\n */\nexport function initSentry(): void {\n const isDev = (import.meta as unknown as { env?: { DEV?: boolean } }).env?.DEV;\n if (isDev) {\n return;\n }\n if (!isErrorReportingEnabled()) {\n return;\n }\n const g = globalThis as unknown as SentryGlobals;\n const dsn = g.__SHELLUI_SENTRY_DSN__;\n if (!dsn || typeof dsn !== 'string') {\n return;\n }\n void import('@sentry/react').then((Sentry) => {\n Sentry.init({\n dsn,\n environment: g.__SHELLUI_SENTRY_ENVIRONMENT__ ?? 'production',\n release: g.__SHELLUI_SENTRY_RELEASE__,\n });\n sentryLoaded = true;\n });\n}\n\n/**\n * Close Sentry when the user disables error reporting in settings.\n * Only loads @sentry/react if it was already initialized (avoids loading the chunk just to close).\n */\nexport function closeSentry(): void {\n if (!sentryLoaded) {\n return;\n }\n void import('@sentry/react').then((Sentry) => {\n Sentry.close();\n sentryLoaded = false;\n });\n}\n\ninitSentry();\n","import { useTranslation } from 'react-i18next';\nimport { Switch } from '@/components/ui/switch';\nimport { useConfig } from '@/features/config/useConfig';\nimport { closeSentry, initSentry } from '@/features/sentry/initSentry';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const Advanced = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings, updateSetting, resetAllData } = useSettings();\n const errorReportingConfigured = Boolean(config?.sentry?.dsn);\n\n const handleErrorReportingChange = (checked: boolean) => {\n updateSetting('errorReporting', { enabled: checked });\n if (checked) {\n initSentry();\n } else {\n closeSentry();\n }\n };\n\n const handleResetClick = () => {\n shellui.dialog({\n title: t('advanced.dangerZone.reset.toast.title'),\n description: t('advanced.dangerZone.reset.toast.description'),\n mode: 'delete',\n size: 'sm',\n okLabel: t('advanced.dangerZone.reset.toast.confirm'),\n cancelLabel: t('advanced.dangerZone.reset.toast.cancel'),\n onOk: () => {\n resetAllData();\n shellui.toast({\n title: t('advanced.dangerZone.reset.toast.success.title'),\n description: t('advanced.dangerZone.reset.toast.success.description'),\n type: 'success',\n });\n shellui.navigate('/');\n },\n onCancel: () => {\n // User cancelled, no action needed\n },\n });\n };\n\n return (\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <span\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.errorReporting.label')}\n </span>\n <p className=\"text-sm text-muted-foreground\">\n {errorReportingConfigured\n ? t('advanced.errorReporting.statusConfigured')\n : t('advanced.errorReporting.statusNotConfigured')}\n </p>\n </div>\n {errorReportingConfigured && (\n <Switch\n id=\"error-reporting\"\n checked={settings.errorReporting.enabled}\n onCheckedChange={handleErrorReportingChange}\n />\n )}\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"developer-features\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.developerFeatures.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('advanced.developerFeatures.description')}\n </p>\n </div>\n <Switch\n id=\"developer-features\"\n checked={settings.developerFeatures.enabled}\n onCheckedChange={(checked) => updateSetting('developerFeatures', { enabled: checked })}\n />\n </div>\n\n <div className=\"border-t pt-6 mt-6\">\n <div className=\"space-y-4\">\n <div className=\"space-y-0.5\">\n <h3\n className=\"text-sm font-semibold leading-none text-destructive\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.dangerZone.title')}\n </h3>\n <p className=\"text-sm text-muted-foreground\">{t('advanced.dangerZone.description')}</p>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('advanced.dangerZone.reset.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('advanced.dangerZone.reset.warning')}\n </p>\n </div>\n <Button\n variant=\"destructive\"\n onClick={handleResetClick}\n className=\"w-full sm:w-auto\"\n >\n {t('advanced.dangerZone.reset.button')}\n </Button>\n </div>\n </div>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const ToastTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.toastNotifications.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.success.title'),\n description: t('develop.testing.toastNotifications.messages.success.description'),\n type: 'success',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.success')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.error.title'),\n description: t('develop.testing.toastNotifications.messages.error.description'),\n type: 'error',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.error')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.warning.title'),\n description: t('develop.testing.toastNotifications.messages.warning.description'),\n type: 'warning',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.warning')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.info.title'),\n description: t('develop.testing.toastNotifications.messages.info.description'),\n type: 'info',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.info')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.default.title'),\n description: t('develop.testing.toastNotifications.messages.default.description'),\n type: 'default',\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.default')}\n </Button>\n <Button\n onClick={() => {\n const toastId = shellui.toast({\n title: t('develop.testing.toastNotifications.messages.processing.title'),\n description: t('develop.testing.toastNotifications.messages.processing.description'),\n type: 'loading',\n });\n\n // Simulate async operation and update toast\n if (typeof toastId === 'string') {\n setTimeout(() => {\n shellui.toast({\n id: toastId,\n type: 'success',\n title: t('develop.testing.toastNotifications.messages.uploadComplete.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.uploadComplete.description',\n ),\n });\n }, 2000);\n }\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.loadingSuccess')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.withAction.title'),\n description: t('develop.testing.toastNotifications.messages.withAction.description'),\n type: 'success',\n action: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.undo'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.undone.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.undone.description',\n ),\n type: 'info',\n });\n },\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.withAction')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.withAction.title'),\n description: t('develop.testing.toastNotifications.messages.withAction.description'),\n type: 'success',\n action: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.undo'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.undone.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.undone.description',\n ),\n type: 'info',\n });\n },\n },\n cancel: {\n label: t('develop.testing.toastNotifications.messages.actionLabels.cancel'),\n onClick: () => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.cancelled.title'),\n description: t(\n 'develop.testing.toastNotifications.messages.cancelled.description',\n ),\n type: 'info',\n });\n },\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.withActionAndCancel')}\n </Button>\n <Button\n onClick={() => {\n shellui.toast({\n title: t('develop.testing.toastNotifications.messages.persistent.title'),\n description: t('develop.testing.toastNotifications.messages.persistent.description'),\n type: 'info',\n duration: 10000,\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.toastNotifications.buttons.longDuration')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\n\nexport const DialogTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.dialogTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.ok.title'),\n description: t('develop.testing.dialogTesting.dialogs.ok.description'),\n mode: 'ok',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.okClicked'),\n type: 'success',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.okDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.okCancel.title'),\n description: t('develop.testing.dialogTesting.dialogs.okCancel.description'),\n mode: 'okCancel',\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.okClicked'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.cancelClicked'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.okCancelDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.delete.title'),\n description: t('develop.testing.dialogTesting.dialogs.delete.description'),\n mode: 'delete',\n okLabel: t('develop.testing.dialogTesting.dialogs.delete.okLabel'),\n cancelLabel: t('develop.testing.dialogTesting.dialogs.delete.cancelLabel'),\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.itemDeleted'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.deletionCancelled'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.deleteDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.confirm.title'),\n description: t('develop.testing.dialogTesting.dialogs.confirm.description'),\n mode: 'confirm',\n okLabel: t('develop.testing.dialogTesting.dialogs.confirm.okLabel'),\n cancelLabel: t('develop.testing.dialogTesting.dialogs.confirm.cancelLabel'),\n size: 'sm',\n onOk: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.actionConfirmed'),\n type: 'success',\n });\n },\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.actionCancelled'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.confirmDialog')}\n </Button>\n <Button\n onClick={() => {\n shellui.dialog({\n title: t('develop.testing.dialogTesting.dialogs.onlyCancel.title'),\n description: t('develop.testing.dialogTesting.dialogs.onlyCancel.description'),\n mode: 'onlyCancel',\n cancelLabel: t('develop.testing.dialogTesting.dialogs.onlyCancel.cancelLabel'),\n size: 'sm',\n onCancel: () => {\n shellui.toast({\n title: t('develop.testing.dialogTesting.toasts.dialogClosed'),\n type: 'info',\n });\n },\n });\n }}\n variant=\"outline\"\n >\n {t('develop.testing.dialogTesting.buttons.onlyCancelDialog')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\nimport urls from '@/constants/urls';\n\nexport const ModalTestButtons = () => {\n const { t } = useTranslation('settings');\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.modalTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => shellui.openModal(urls.settings)}\n variant=\"outline\"\n >\n {t('develop.testing.modalTesting.buttons.openModal')}\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground mt-2\">\n {t('develop.testing.modalTesting.description')}\n </p>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { Button } from '@/components/ui/button';\nimport { shellui, type OpenDrawerOptions } from '@shellui/sdk';\nimport urls from '@/constants/urls';\n\nexport const DrawerTestButtons = () => {\n const { t } = useTranslation('settings');\n\n const openDrawer = (options: OpenDrawerOptions) => {\n shellui.openDrawer({ url: urls.settings, ...options });\n };\n\n return (\n <div>\n <h4\n className=\"text-sm font-medium mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.drawerTesting.title')}\n </h4>\n <div className=\"flex flex-wrap gap-2\">\n <Button\n onClick={() => openDrawer({ position: 'right' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerRight')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'left' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerLeft')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'top' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerTop')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'bottom' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerBottom')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'right', size: '400px' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerRightNarrow')}\n </Button>\n <Button\n onClick={() => openDrawer({ position: 'bottom', size: '60vh' })}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.drawerBottomHalf')}\n </Button>\n <Button\n onClick={() => shellui.closeDrawer()}\n variant=\"outline\"\n >\n {t('develop.testing.drawerTesting.buttons.closeDrawer')}\n </Button>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '../../config/useConfig';\nimport { flattenNavigationItems, resolveLocalizedString } from '../../layouts/utils';\nimport { Switch } from '@/components/ui/switch';\nimport { Select } from '@/components/ui/select';\nimport { Button } from '@/components/ui/button';\nimport { ToastTestButtons } from './develop/ToastTestButtons';\nimport { DialogTestButtons } from './develop/DialogTestButtons';\nimport { ModalTestButtons } from './develop/ModalTestButtons';\nimport { DrawerTestButtons } from './develop/DrawerTestButtons';\nimport type { LayoutType } from '../../config/types';\n\nexport const Develop = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n const effectiveLayout: LayoutType = settings.layout ?? config?.layout ?? 'sidebar';\n const navItems = config?.navigation?.length\n ? flattenNavigationItems(config?.navigation ?? []).filter(\n (item, index, self) => index === self.findIndex((i) => i.path === item.path),\n )\n : [];\n\n return (\n <div className=\"space-y-6\">\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.title')}\n </h3>\n <div className=\"space-y-4\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"log-shellsdk\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.shellsdk.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('develop.logging.shellsdk.description')}\n </p>\n </div>\n <Switch\n id=\"log-shellsdk\"\n checked={settings.logging?.namespaces?.shellsdk || false}\n onCheckedChange={(checked) =>\n updateSetting('logging', {\n namespaces: {\n ...settings.logging?.namespaces,\n shellsdk: checked,\n },\n })\n }\n />\n </div>\n\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n htmlFor=\"log-shellcore\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.logging.shellcore.label')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('develop.logging.shellcore.description')}\n </p>\n </div>\n <Switch\n id=\"log-shellcore\"\n checked={settings.logging?.namespaces?.shellcore || false}\n onCheckedChange={(checked) =>\n updateSetting('logging', {\n namespaces: {\n ...settings.logging?.namespaces,\n shellcore: checked,\n },\n })\n }\n />\n </div>\n </div>\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.navigation.title')}\n </h3>\n {navItems.length ? (\n <div className=\"space-y-2\">\n <label\n htmlFor=\"develop-nav-select\"\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.navigation.selectLabel')}\n </label>\n <div className=\"mt-2\">\n <Select\n id=\"develop-nav-select\"\n defaultValue=\"\"\n onChange={(e) => {\n const path = e.target.value;\n if (path) {\n shellui.navigate(path.startsWith('/') ? path : `/${path}`);\n }\n }}\n >\n <option value=\"\">{t('develop.navigation.placeholder')}</option>\n {navItems.map((item) => (\n <option\n key={item.path}\n value={`/${item.path}`}\n >\n {resolveLocalizedString(item.label, currentLanguage) || item.path}\n </option>\n ))}\n </Select>\n </div>\n </div>\n ) : (\n <p className=\"text-sm text-muted-foreground\">{t('develop.navigation.empty')}</p>\n )}\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.layout.title')}\n </h3>\n <div className=\"flex flex-wrap gap-2\">\n {(['sidebar', 'windows'] as const).map((layoutMode) => (\n <Button\n key={layoutMode}\n variant={effectiveLayout === layoutMode ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => updateSetting('layout', layoutMode as LayoutType)}\n >\n {t(`develop.layout.${layoutMode}`)}\n </Button>\n ))}\n </div>\n </div>\n\n <div>\n <h3\n className=\"text-lg font-semibold mb-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('develop.testing.title')}\n </h3>\n <div className=\"space-y-4\">\n <ToastTestButtons />\n <DialogTestButtons />\n <ModalTestButtons />\n <DrawerTestButtons />\n </div>\n </div>\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { useConfig } from '@/features/config/useConfig';\nimport { Button } from '@/components/ui/button';\nimport { shellui } from '@shellui/sdk';\nimport urls from '@/constants/urls';\nimport { cn } from '@/lib/utils';\n\nexport const DataPrivacy = () => {\n const { t } = useTranslation('settings');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n\n const cookies = config?.cookieConsent?.cookies ?? [];\n const hasCookieConsent = cookies.length > 0;\n const hasConsented = Boolean(settings?.cookieConsent?.consentedCookieHosts?.length);\n\n // Determine consent status\n const acceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n const allHosts = cookies.map((c) => c.host);\n const strictNecessaryHosts = cookies\n .filter((c) => c.category === 'strict_necessary')\n .map((c) => c.host);\n\n const acceptedAll =\n hasConsented &&\n acceptedHosts.length === allHosts.length &&\n allHosts.every((h) => acceptedHosts.includes(h));\n // \"Rejected all\" means only strictly necessary cookies are accepted\n const rejectedAll =\n hasConsented &&\n acceptedHosts.length === strictNecessaryHosts.length &&\n strictNecessaryHosts.every((h) => acceptedHosts.includes(h)) &&\n !acceptedHosts.some((h) => !strictNecessaryHosts.includes(h));\n const isCustom = hasConsented && !acceptedAll && !rejectedAll;\n\n const handleResetCookieConsent = () => {\n updateSetting('cookieConsent', {\n acceptedHosts: [],\n consentedCookieHosts: [],\n });\n };\n\n return (\n <div className=\"space-y-6\">\n {!hasCookieConsent ? (\n <div className=\"rounded-lg border bg-card p-4 space-y-3\">\n <div className=\"space-y-1\">\n <h3\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('dataPrivacy.noCookiesConfigured.title')}\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n {t('dataPrivacy.noCookiesConfigured.description')}\n </p>\n </div>\n <div className=\"flex items-start gap-2 text-sm\">\n <span className=\"text-green-600 dark:text-green-400 mt-0.5\">✓</span>\n <span className=\"text-muted-foreground\">\n {t('dataPrivacy.noCookiesConfigured.info')}\n </span>\n </div>\n </div>\n ) : (\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('dataPrivacy.cookieConsent.title')}\n </label>\n <div className=\"mt-2 space-y-3\">\n <p className=\"text-sm text-muted-foreground\">\n {!hasConsented\n ? t('dataPrivacy.cookieConsent.descriptionNotConsented')\n : acceptedAll\n ? t('dataPrivacy.cookieConsent.statusAcceptedAll')\n : rejectedAll\n ? t('dataPrivacy.cookieConsent.statusRejectedAll')\n : t('dataPrivacy.cookieConsent.statusCustom')}\n </p>\n {hasConsented && (\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n acceptedAll\n ? 'bg-primary/10 text-primary border border-primary/20'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelAcceptedAll')}\n </span>\n <span className=\"text-muted-foreground/30\">|</span>\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n isCustom\n ? 'bg-muted text-muted-foreground border border-border'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelCustom')}\n </span>\n <span className=\"text-muted-foreground/30\">|</span>\n <span\n className={cn(\n 'px-2 py-1 rounded-md text-xs font-medium transition-colors',\n rejectedAll\n ? 'bg-muted text-muted-foreground border border-border'\n : 'text-muted-foreground',\n )}\n >\n {t('dataPrivacy.cookieConsent.labelRejectedAll')}\n </span>\n </div>\n )}\n <div className=\"flex flex-wrap gap-2\">\n <Button\n variant=\"outline\"\n onClick={() => shellui.openDrawer({ url: urls.cookiePreferences, size: '420px' })}\n className=\"w-full sm:w-auto\"\n >\n {t('dataPrivacy.cookieConsent.manageButton')}\n </Button>\n <Button\n variant=\"ghost\"\n onClick={handleResetCookieConsent}\n disabled={!hasConsented}\n className=\"w-full sm:w-auto\"\n >\n {t('dataPrivacy.cookieConsent.button')}\n </Button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { useSettings } from '../hooks/useSettings';\nimport { Button } from '@/components/ui/button';\nimport { Switch } from '@/components/ui/switch';\nimport {\n isServiceWorkerRegistered,\n updateServiceWorker,\n getServiceWorkerStatus,\n addStatusListener,\n serviceWorkerFileExists,\n} from '@/service-worker/register';\nimport { shellui } from '@shellui/sdk';\nimport { useState, useEffect } from 'react';\n\nexport const ServiceWorker = () => {\n const { t } = useTranslation('settings');\n const { settings, updateSetting } = useSettings();\n const [isRegistered, setIsRegistered] = useState(false);\n const [updateAvailable, setUpdateAvailable] = useState(false);\n const [isLoading, setIsLoading] = useState(true);\n const [swFileExists, setSwFileExists] = useState(true); // Track if service worker file exists\n\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true;\n\n useEffect(() => {\n // Don't check service worker status if disabled\n if (!serviceWorkerEnabled) {\n // Immediately clear all state and hide error messages\n setIsRegistered(false);\n setUpdateAvailable(false);\n setIsLoading(false);\n setSwFileExists(true); // Set to true to prevent error messages from showing\n return;\n }\n\n // Initial check with loading state\n const initialCheck = async () => {\n // Double-check service worker is still enabled before proceeding\n const stillEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!stillEnabled) {\n setIsLoading(false);\n return;\n }\n\n setIsLoading(true);\n\n // First check if service worker file exists\n const exists = await serviceWorkerFileExists();\n\n // Check again if service worker was disabled during the async operation\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabled) {\n setIsLoading(false);\n return;\n }\n\n setSwFileExists(exists);\n\n if (exists) {\n // Check service worker status only if file exists\n const status = await getServiceWorkerStatus();\n\n // Final check before updating state\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n }\n } else {\n // File doesn't exist, so service worker can't be registered\n // Only update if service worker is still enabled\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n }\n }\n\n setIsLoading(false);\n };\n\n // Background refresh without affecting loading state\n const refreshStatus = async () => {\n // Skip if service worker was disabled (check current setting value)\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabled) {\n return;\n }\n\n // Check if file exists first\n const exists = await serviceWorkerFileExists();\n\n // Check again if service worker was disabled during the async operation\n const currentEnabledAfter = settings?.serviceWorker?.enabled ?? true;\n if (!currentEnabledAfter) {\n return;\n }\n\n setSwFileExists(exists);\n\n if (exists) {\n // Check service worker status only if file exists\n const status = await getServiceWorkerStatus();\n\n // Final check before updating state\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n }\n } else {\n // File doesn't exist, so service worker can't be registered\n // Only update if service worker is still enabled\n const finalCheck = settings?.serviceWorker?.enabled ?? true;\n if (finalCheck) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n }\n }\n };\n\n // Initial check immediately\n initialCheck();\n\n // Listen for status changes\n const unsubscribe = addStatusListener((status) => {\n // Only update if service worker is still enabled (check current setting value)\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (currentEnabled) {\n setIsRegistered(status.registered);\n setUpdateAvailable(status.updateAvailable);\n setIsLoading(false);\n }\n });\n\n // Also check periodically as fallback (background refresh) - less frequent to avoid excessive fetches\n const interval = setInterval(refreshStatus, 30000); // Check every 30 seconds instead of 5\n\n return () => {\n unsubscribe();\n clearInterval(interval);\n };\n }, [serviceWorkerEnabled]);\n\n const handleToggleServiceWorker = async (enabled: boolean) => {\n // Immediately clear all state before updating setting to prevent error flashes\n if (!enabled) {\n setIsRegistered(false);\n setUpdateAvailable(false);\n setSwFileExists(true); // Set to true to hide error messages immediately\n setIsLoading(false);\n }\n\n updateSetting('serviceWorker', { enabled });\n\n if (!enabled) {\n // Already cleared above, just return\n return;\n }\n\n // Give it a moment to register/unregister\n setTimeout(async () => {\n // Double-check service worker is still enabled before updating state\n const currentEnabled = settings?.serviceWorker?.enabled ?? true;\n if (enabled && currentEnabled) {\n const registered = await isServiceWorkerRegistered();\n setIsRegistered(registered);\n }\n }, 1000);\n };\n\n const handleUpdateNow = async () => {\n try {\n await updateServiceWorker();\n // Don't show toast here - updateServiceWorker() will handle the reload\n // and the update process already provides feedback through the UI\n } catch (_error) {\n shellui.toast({\n title: t('caching.updateError.title'),\n description: t('caching.updateError.description'),\n type: 'error',\n });\n }\n };\n\n const handleResetToLatest = async () => {\n try {\n // Clear all caches and reload\n if ('caches' in window) {\n const cacheNames = await caches.keys();\n await Promise.all(cacheNames.map((name) => caches.delete(name)));\n }\n\n shellui.toast({\n title: t('caching.resetSuccess.title'),\n description: t('caching.resetSuccess.description'),\n type: 'success',\n });\n\n // Reload the app using shellUI refresh message (refreshes entire app, not just iframe)\n setTimeout(() => {\n const sent = shellui.sendMessageToParent({\n type: 'SHELLUI_REFRESH_PAGE',\n payload: {},\n });\n if (!sent) {\n // Fallback to window.location.reload if message can't be sent\n window.location.reload();\n }\n }, 1000);\n } catch (_error) {\n shellui.toast({\n title: t('caching.resetError.title'),\n description: t('caching.resetError.description'),\n type: 'error',\n });\n }\n };\n\n return (\n <div className=\"space-y-6\">\n {isLoading ? (\n <div className=\"text-sm text-muted-foreground\">{t('caching.loading')}</div>\n ) : null}\n\n {!isLoading && (\n <div className=\"space-y-6\">\n {/* Enable/Disable service worker */}\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.enabled.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {serviceWorkerEnabled\n ? t('caching.enabled.descriptionEnabled')\n : t('caching.enabled.descriptionDisabled')}\n </p>\n </div>\n <Switch\n checked={serviceWorkerEnabled}\n onCheckedChange={handleToggleServiceWorker}\n />\n </div>\n </div>\n\n {/* Status – always visible; shows Disabled when off */}\n <div className=\"space-y-2\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.status.title')}\n </label>\n <div className=\"flex items-center gap-2 text-sm mt-2\">\n {!serviceWorkerEnabled ? (\n <span className=\"text-muted-foreground\">○ {t('caching.status.disabled')}</span>\n ) : !swFileExists ? (\n <span className=\"text-red-600 dark:text-red-400\">\n ✗ {t('caching.status.fileNotFound')}\n </span>\n ) : (\n <>\n <span\n className={\n isRegistered\n ? 'text-green-600 dark:text-green-400'\n : 'text-orange-600 dark:text-orange-400'\n }\n >\n {isRegistered ? '●' : '○'}{' '}\n {isRegistered ? t('caching.status.registered') : t('caching.status.notRunning')}\n </span>\n {updateAvailable && (\n <>\n <span className=\"text-muted-foreground/50\">|</span>\n <span className=\"text-blue-600 dark:text-blue-400\">\n ● {t('caching.status.updateAvailable')}\n </span>\n </>\n )}\n </>\n )}\n </div>\n </div>\n\n {serviceWorkerEnabled && (\n <>\n {/* Error Message when file missing */}\n {!swFileExists && (\n <div className=\"rounded-lg border border-red-200 dark:border-red-800 bg-red-50 dark:bg-red-950/30 p-4 space-y-3\">\n <div className=\"space-y-1\">\n <h3\n className=\"text-sm font-medium leading-none text-red-600 dark:text-red-400\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.status.fileNotFound')}\n </h3>\n <p className=\"text-sm text-red-700 dark:text-red-300\">\n {t('caching.status.fileNotFoundDescription')}\n </p>\n </div>\n </div>\n )}\n\n {/* Update Available */}\n {updateAvailable && (\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.update.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">\n {t('caching.update.description')}\n </p>\n </div>\n <div className=\"mt-2\">\n <Button\n variant=\"outline\"\n onClick={handleUpdateNow}\n className=\"w-full sm:w-auto\"\n >\n {t('caching.update.button')}\n </Button>\n </div>\n </div>\n )}\n\n {/* Reset Cache */}\n <div className=\"space-y-2\">\n <div className=\"space-y-0.5\">\n <label\n className=\"text-sm font-medium leading-none\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('caching.reset.title')}\n </label>\n <p className=\"text-sm text-muted-foreground\">{t('caching.reset.description')}</p>\n </div>\n <div className=\"mt-2\">\n <Button\n variant=\"outline\"\n onClick={handleResetToLatest}\n className=\"w-full sm:w-auto\"\n >\n {t('caching.reset.button')}\n </Button>\n </div>\n </div>\n </>\n )}\n </div>\n )}\n </div>\n );\n};\n","import {\n PaintbrushIcon,\n GlobeIcon,\n SettingsIcon,\n CodeIcon,\n ShieldIcon,\n PackageIcon,\n RefreshDoubleIcon,\n} from './SettingsIcons';\nimport { Appearance } from './components/Appearance';\nimport { LanguageAndRegion } from './components/LanguageAndRegion';\nimport { UpdateApp } from './components/UpdateApp';\nimport { Advanced } from './components/Advanced';\nimport { Develop } from './components/Develop';\nimport { DataPrivacy } from './components/DataPrivacy';\nimport { ServiceWorker } from './components/ServiceWorker';\nimport { isTauri } from '../../service-worker/register';\n\nexport const createSettingsRoutes = (t: (key: string) => string) => [\n {\n name: t('routes.appearance'),\n icon: PaintbrushIcon,\n path: 'appearance',\n element: <Appearance />,\n },\n {\n name: t('routes.languageAndRegion'),\n icon: GlobeIcon,\n path: 'language-and-region',\n element: <LanguageAndRegion />,\n },\n {\n name: t('routes.updateApp'),\n icon: RefreshDoubleIcon,\n path: 'update-app',\n element: <UpdateApp />,\n },\n {\n name: t('routes.advanced'),\n icon: SettingsIcon,\n path: 'advanced',\n element: <Advanced />,\n },\n {\n name: t('routes.dataPrivacy'),\n icon: ShieldIcon,\n path: 'data-privacy',\n element: <DataPrivacy />,\n },\n {\n name: t('routes.develop'),\n icon: CodeIcon,\n path: 'developpers',\n element: <Develop />,\n },\n ...(isTauri()\n ? []\n : [\n {\n name: t('routes.serviceWorker'),\n icon: PackageIcon,\n path: 'service-worker',\n element: <ServiceWorker />,\n },\n ]),\n];\n","import { useState, useEffect, useMemo, useCallback } from 'react';\nimport {\n Breadcrumb,\n BreadcrumbItem,\n BreadcrumbList,\n BreadcrumbPage,\n BreadcrumbSeparator,\n} from '@/components/ui/breadcrumb';\nimport {\n Sidebar,\n SidebarContent,\n SidebarGroup,\n SidebarGroupContent,\n SidebarGroupLabel,\n SidebarMenu,\n SidebarMenuButton,\n SidebarMenuItem,\n SidebarProvider,\n} from '@/components/ui/sidebar';\nimport { Route, Routes, useLocation, useNavigate, Navigate } from 'react-router';\nimport { useTranslation } from 'react-i18next';\nimport urls from '@/constants/urls';\nimport { createSettingsRoutes } from './SettingsRoutes';\nimport { useSettings } from './hooks/useSettings';\nimport { useConfig } from '../config/useConfig';\nimport { isTauri } from '@/service-worker/register';\nimport { Button } from '@/components/ui/button';\nimport { ChevronRightIcon, ChevronLeftIcon } from './SettingsIcons';\n\nexport const SettingsView = () => {\n const location = useLocation();\n const navigate = useNavigate();\n const { settings } = useSettings();\n const { config } = useConfig();\n const { t } = useTranslation('settings');\n // Re-check isTauri after mount and after a short delay so we catch late-injected __TAURI__ in dev\n const [isTauriEnv, setIsTauriEnv] = useState(() => isTauri());\n\n useEffect(() => {\n setIsTauriEnv(isTauri());\n const tid = window.setTimeout(() => setIsTauriEnv(isTauri()), 200);\n return () => window.clearTimeout(tid);\n }, []);\n\n useEffect(() => {\n if (config?.title) {\n const settingsLabel = t('settings', { ns: 'common' });\n document.title = `${settingsLabel} | ${config.title}`;\n }\n }, [config?.title, t]);\n\n // Create routes with translations (service-worker route is already omitted in Tauri by createSettingsRoutes)\n const settingsRoutes = useMemo(() => createSettingsRoutes(t), [t]);\n\n // In Tauri, hide service worker route; use reactive isTauriEnv so we catch late injection (e.g. dev)\n const routesWithoutTauriSw = useMemo(() => {\n if (isTauriEnv) {\n return settingsRoutes.filter((route) => route.path !== 'service-worker');\n }\n return settingsRoutes;\n }, [settingsRoutes, isTauriEnv]);\n\n // Filter routes based on developer features setting\n const filteredRoutes = useMemo(() => {\n if (settings.developerFeatures.enabled) {\n return routesWithoutTauriSw;\n }\n return routesWithoutTauriSw.filter(\n (route) => route.path !== 'developpers' && route.path !== 'service-worker',\n );\n }, [settings.developerFeatures.enabled, routesWithoutTauriSw]);\n\n // Group routes by category\n const groupedRoutes = useMemo(() => {\n const developerOnlyPaths = ['developpers', 'service-worker'];\n const groups = [\n {\n title: t('categories.preferences'),\n routes: filteredRoutes.filter((route) =>\n ['appearance', 'language-and-region', 'data-privacy'].includes(route.path),\n ),\n },\n {\n title: t('categories.system'),\n routes: filteredRoutes.filter((route) => ['update-app', 'advanced'].includes(route.path)),\n },\n {\n title: t('categories.developer'),\n routes: filteredRoutes.filter((route) => developerOnlyPaths.includes(route.path)),\n },\n ];\n return groups.filter((group) => group.routes.length > 0);\n }, [filteredRoutes, t]);\n\n // Find matching nav item by checking if URL contains or ends with the item path\n const getSelectedItemFromUrl = useCallback(() => {\n const pathname = location.pathname;\n\n // Find matching nav item by checking if pathname contains the item path\n // This works regardless of the URL structure/prefix\n const matchedItem = filteredRoutes.find((item) => {\n // Normalize paths for comparison (remove leading/trailing slashes)\n const normalizedPathname = pathname.replace(/^\\/+|\\/+$/g, '');\n const normalizedItemPath = item.path.replace(/^\\/+|\\/+$/g, '');\n\n // Check if pathname ends with the item path, or contains it as a path segment\n return (\n normalizedPathname === normalizedItemPath ||\n normalizedPathname.endsWith(`/${normalizedItemPath}`) ||\n normalizedPathname.includes(`/${normalizedItemPath}/`)\n );\n });\n\n return matchedItem;\n }, [location.pathname, filteredRoutes]);\n\n const selectedItem = useMemo(() => getSelectedItemFromUrl(), [getSelectedItemFromUrl]);\n\n // Check if we're at the settings root (no specific route selected)\n const isSettingsRoot = useMemo(() => {\n const pathname = location.pathname;\n // Normalize the settings URL (remove leading/trailing slashes)\n const normalizedSettingsPath = urls.settings.replace(/^\\/+|\\/+$/g, '');\n // Normalize the current pathname (remove leading/trailing slashes)\n const normalizedPathname = pathname.replace(/^\\/+|\\/+$/g, '');\n\n // Check if we're exactly at the settings root\n // This handles both \"/__settings\" and \"/__settings/\" cases\n if (normalizedPathname === normalizedSettingsPath) {\n return true;\n }\n\n // If pathname starts with settings path followed by a slash, we're at a subpage\n // e.g., \"__settings/appearance\" means we're NOT at root\n const settingsPathWithSlash = `${normalizedSettingsPath}/`;\n if (normalizedPathname.startsWith(settingsPathWithSlash)) {\n return false;\n }\n\n // Pathname doesn't match settings path structure - not in settings\n return false;\n }, [location.pathname, filteredRoutes]);\n\n // Navigate back to settings root\n const handleBackToSettings = useCallback(() => {\n // Navigate to settings root, replacing current history entry\n navigate(urls.settings, { replace: true });\n }, [navigate]);\n\n return (\n <SidebarProvider>\n <div className=\"flex h-full w-full overflow-hidden items-start\">\n {/* Desktop Sidebar */}\n <Sidebar className=\"hidden md:flex\">\n <SidebarContent>\n {groupedRoutes.map((group) => (\n <SidebarGroup key={group.title}>\n <SidebarGroupLabel>{group.title}</SidebarGroupLabel>\n <SidebarGroupContent>\n <SidebarMenu>\n {group.routes.map((item) => (\n <SidebarMenuItem key={item.name}>\n <SidebarMenuButton\n asChild\n isActive={item.name === selectedItem?.name}\n >\n <button\n onClick={() => navigate(`${urls.settings}/${item.path}`)}\n className=\"cursor-pointer\"\n >\n <item.icon />\n <span>{item.name}</span>\n </button>\n </SidebarMenuButton>\n </SidebarMenuItem>\n ))}\n </SidebarMenu>\n </SidebarGroupContent>\n </SidebarGroup>\n ))}\n </SidebarContent>\n </Sidebar>\n\n {/* Mobile List View */}\n <div className=\"md:hidden flex h-full w-full flex-col overflow-hidden\">\n {isSettingsRoot ? (\n // Show list of settings pages\n <div className=\"flex flex-1 flex-col overflow-y-auto bg-background\">\n <header className=\"flex h-16 shrink-0 items-center justify-center px-4 border-b\">\n <h1 className=\"text-lg font-semibold\">{t('title')}</h1>\n </header>\n <div className=\"flex flex-1 flex-col p-4 gap-6\">\n {groupedRoutes.map((group) => (\n <div\n key={group.title}\n className=\"flex flex-col gap-2\"\n >\n <h2\n className=\"text-xs font-semibold text-foreground/60 uppercase tracking-wider px-2\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {group.title}\n </h2>\n <div className=\"flex flex-col bg-card rounded-lg overflow-hidden border border-border\">\n {group.routes.map((item, itemIndex) => {\n const Icon = item.icon;\n const isLast = itemIndex === group.routes.length - 1;\n return (\n <div\n key={item.name}\n className=\"relative\"\n >\n {!isLast && (\n <div className=\"absolute left-0 right-0 bottom-0 h-[1px] bg-border\" />\n )}\n <button\n onClick={() => navigate(`${urls.settings}/${item.path}`)}\n className=\"w-full flex items-center justify-between px-4 py-3 bg-transparent hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground transition-colors cursor-pointer rounded-none\"\n >\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n <div className=\"flex-shrink-0 text-foreground/70\">\n <Icon />\n </div>\n <span className=\"text-sm font-normal text-foreground\">\n {item.name}\n </span>\n </div>\n <div className=\"flex-shrink-0 ml-2 text-foreground/40\">\n <ChevronRightIcon />\n </div>\n </button>\n </div>\n );\n })}\n </div>\n </div>\n ))}\n </div>\n </div>\n ) : (\n // Show selected settings page with back button\n <div className=\"flex h-full flex-1 flex-col overflow-hidden\">\n <header className=\"flex h-16 shrink-0 items-center gap-2 px-4 border-b\">\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={handleBackToSettings}\n className=\"mr-2\"\n >\n <ChevronLeftIcon />\n </Button>\n <h1 className=\"text-lg font-semibold\">{selectedItem?.name}</h1>\n </header>\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-4\">\n <Routes>\n <Route\n index\n element={\n filteredRoutes.length > 0 ? (\n <Navigate\n to={`${urls.settings}/${filteredRoutes[0].path}`}\n replace\n />\n ) : null\n }\n />\n {filteredRoutes.map((item) => (\n <Route\n key={item.path}\n path={item.path}\n element={item.element}\n />\n ))}\n </Routes>\n </div>\n </div>\n )}\n </div>\n\n {/* Desktop Main Content */}\n <main className=\"hidden md:flex h-full flex-1 flex-col overflow-hidden\">\n {selectedItem && (\n <header className=\"flex h-16 shrink-0 items-center gap-2 transition-[width,height] ease-linear\">\n <div className=\"flex items-center gap-2 px-4\">\n <Breadcrumb>\n <BreadcrumbList>\n <BreadcrumbItem>{t('title')}</BreadcrumbItem>\n <BreadcrumbSeparator />\n <BreadcrumbItem>\n <BreadcrumbPage>{selectedItem.name}</BreadcrumbPage>\n </BreadcrumbItem>\n </BreadcrumbList>\n </Breadcrumb>\n </div>\n </header>\n )}\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4 pt-0\">\n <Routes>\n <Route\n index\n element={\n <div className=\"flex flex-1 flex-col items-center justify-center p-8 text-center\">\n <div className=\"max-w-md\">\n <h2 className=\"text-lg font-semibold mb-2\">{t('title')}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {t('selectCategory', {\n defaultValue: 'Select a category from the sidebar to get started.',\n })}\n </p>\n </div>\n </div>\n }\n />\n {filteredRoutes.map((item) => (\n <Route\n key={item.path}\n path={item.path}\n element={item.element}\n />\n ))}\n </Routes>\n </div>\n </main>\n </div>\n </SidebarProvider>\n );\n};\n","import { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { useLocation } from 'react-router';\nimport { shellui } from '@shellui/sdk';\nimport { Button } from '@/components/ui/button';\nimport { Switch } from '@/components/ui/switch';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { resolveLocalizedString } from '../layouts/utils';\nimport type { CookieConsentCategory, CookieDefinition } from '../config/types';\n\n/** Category display order and labels */\nconst CATEGORY_ORDER: CookieConsentCategory[] = [\n 'strict_necessary',\n 'functional_performance',\n 'targeting',\n 'social_media_embedded',\n];\n\n/** Format duration in human-readable format */\nfunction formatDuration(\n seconds: number,\n t: (key: string, options?: Record<string, unknown>) => string,\n): string {\n if (seconds < 60) return t('preferences.duration.seconds', { count: seconds });\n if (seconds < 3600) return t('preferences.duration.minutes', { count: Math.floor(seconds / 60) });\n if (seconds < 86400)\n return t('preferences.duration.hours', { count: Math.floor(seconds / 3600) });\n if (seconds < 31536000)\n return t('preferences.duration.days', { count: Math.floor(seconds / 86400) });\n return t('preferences.duration.years', { count: Math.floor(seconds / 31536000) });\n}\n\nexport function CookiePreferencesView() {\n const { t, i18n } = useTranslation('cookieConsent');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n const location = useLocation();\n const searchParams = new URLSearchParams(location.search);\n const isInitialConsent = searchParams.get('initial') === 'true';\n const currentLanguage = i18n.language || 'en';\n\n const cookies = config?.cookieConsent?.cookies ?? [];\n const allHosts = useMemo(() => cookies.map((c) => c.host), [cookies]);\n\n // Strictly necessary hosts are always enabled\n const strictNecessaryHosts = useMemo(\n () => cookies.filter((c) => c.category === 'strict_necessary').map((c) => c.host),\n [cookies],\n );\n\n const currentAcceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n\n // Local state for unsaved changes (always include strict necessary)\n const [localAcceptedHosts, setLocalAcceptedHosts] = useState<string[]>(() => [\n ...new Set([...currentAcceptedHosts, ...strictNecessaryHosts]),\n ]);\n\n // Track if save/accept/reject was clicked to avoid rejecting on intentional close\n const actionClickedRef = useRef(false);\n\n // Reset local state when drawer opens (when URL changes to include initial param)\n useEffect(() => {\n if (isInitialConsent) {\n // Always include strict necessary hosts\n setLocalAcceptedHosts([...new Set([...currentAcceptedHosts, ...strictNecessaryHosts])]);\n }\n }, [isInitialConsent, currentAcceptedHosts, strictNecessaryHosts]);\n\n // Handle drawer close without saving during initial consent\n useEffect(() => {\n if (!isInitialConsent) return;\n\n const handleDrawerClose = () => {\n // If closing without saving during initial consent, reject all except strict necessary\n // Check if user has never consented and no action was clicked\n const neverConsented = (settings?.cookieConsent?.consentedCookieHosts ?? []).length === 0;\n if (neverConsented && !actionClickedRef.current) {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }\n };\n\n const cleanup = shellui.addMessageListener('SHELLUI_CLOSE_DRAWER', handleDrawerClose);\n return cleanup;\n }, [isInitialConsent, strictNecessaryHosts, allHosts, updateSetting, settings]);\n\n // Cleanup on unmount: if initial consent and drawer closes without save, reject all\n useEffect(() => {\n return () => {\n if (isInitialConsent && !actionClickedRef.current) {\n // Check if user has never consented\n const neverConsented = (settings?.cookieConsent?.consentedCookieHosts ?? []).length === 0;\n if (neverConsented) {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }\n }\n };\n }, [isInitialConsent, strictNecessaryHosts, allHosts, updateSetting, settings]);\n\n // Group cookies by category\n const cookiesByCategory = useMemo(() => {\n const grouped = new Map<CookieConsentCategory, CookieDefinition[]>();\n for (const cookie of cookies) {\n const existing = grouped.get(cookie.category) ?? [];\n grouped.set(cookie.category, [...existing, cookie]);\n }\n return grouped;\n }, [cookies]);\n\n // Toggle individual cookie\n const toggleCookie = useCallback((host: string, enabled: boolean) => {\n setLocalAcceptedHosts((prev) => (enabled ? [...prev, host] : prev.filter((h) => h !== host)));\n }, []);\n\n // Toggle entire category\n const toggleCategory = useCallback(\n (category: CookieConsentCategory, enabled: boolean) => {\n const categoryHosts = cookiesByCategory.get(category)?.map((c) => c.host) ?? [];\n setLocalAcceptedHosts((prev) => {\n if (enabled) {\n return [...new Set([...prev, ...categoryHosts])];\n } else {\n const hostsSet = new Set(categoryHosts);\n return prev.filter((h) => !hostsSet.has(h));\n }\n });\n },\n [cookiesByCategory],\n );\n\n // Check if category is fully or partially enabled\n const getCategoryState = useCallback(\n (category: CookieConsentCategory): 'all' | 'some' | 'none' => {\n const categoryHosts = cookiesByCategory.get(category)?.map((c) => c.host) ?? [];\n if (categoryHosts.length === 0) return 'none';\n const enabledCount = categoryHosts.filter((h) => localAcceptedHosts.includes(h)).length;\n if (enabledCount === categoryHosts.length) return 'all';\n if (enabledCount > 0) return 'some';\n return 'none';\n },\n [cookiesByCategory, localAcceptedHosts],\n );\n\n // Accept all\n const handleAcceptAll = useCallback(() => {\n actionClickedRef.current = true;\n updateSetting('cookieConsent', {\n acceptedHosts: allHosts,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [allHosts, updateSetting]);\n\n // Reject all except strict necessary (which are always enabled)\n const handleRejectAll = useCallback(() => {\n actionClickedRef.current = true;\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [strictNecessaryHosts, allHosts, updateSetting]);\n\n // Save custom preferences (always include strict necessary)\n const handleSave = useCallback(() => {\n actionClickedRef.current = true;\n const hostsToSave = [...new Set([...localAcceptedHosts, ...strictNecessaryHosts])];\n updateSetting('cookieConsent', {\n acceptedHosts: hostsToSave,\n consentedCookieHosts: allHosts,\n });\n shellui.closeDrawer();\n }, [localAcceptedHosts, strictNecessaryHosts, allHosts, updateSetting]);\n\n // Check if preferences have changed\n const hasChanges = useMemo(() => {\n if (localAcceptedHosts.length !== currentAcceptedHosts.length) return true;\n const sortedLocal = [...localAcceptedHosts].sort();\n const sortedCurrent = [...currentAcceptedHosts].sort();\n return sortedLocal.some((h, i) => h !== sortedCurrent[i]);\n }, [localAcceptedHosts, currentAcceptedHosts]);\n\n if (cookies.length === 0) {\n return (\n <div className=\"flex items-center justify-center h-full p-6\">\n <p className=\"text-muted-foreground\">{t('preferences.noCookies')}</p>\n </div>\n );\n }\n\n return (\n <div className=\"flex flex-col h-full bg-background\">\n {/* Header */}\n <div className=\"flex flex-col space-y-2 border-b border-border/60 px-6 pt-5 pb-4\">\n <h2\n className=\"text-lg font-semibold leading-none tracking-tight\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t('preferences.title')}\n </h2>\n <p className=\"text-sm text-muted-foreground\">{t('preferences.description')}</p>\n </div>\n\n {/* Content */}\n <div className=\"flex-1 overflow-y-auto px-6 py-4\">\n {CATEGORY_ORDER.map((category) => {\n const categoryCookies = cookiesByCategory.get(category);\n if (!categoryCookies || categoryCookies.length === 0) return null;\n\n const categoryState = getCategoryState(category);\n const isStrictNecessary = category === 'strict_necessary';\n\n return (\n <div\n key={category}\n className=\"mb-6 last:mb-0\"\n >\n {/* Category header with toggle */}\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"flex-1 min-w-0\">\n <h3\n className=\"text-sm font-semibold\"\n style={{ fontFamily: 'var(--heading-font-family, inherit)' }}\n >\n {t(`preferences.categories.${category}.title`)}\n </h3>\n <p className=\"text-xs text-muted-foreground mt-0.5\">\n {t(`preferences.categories.${category}.description`)}\n </p>\n </div>\n <div className=\"ml-4 flex items-center gap-2\">\n {!isStrictNecessary && categoryState === 'some' && (\n <span className=\"text-xs text-muted-foreground\">\n {t('preferences.partial')}\n </span>\n )}\n {isStrictNecessary ? (\n <span className=\"text-xs text-muted-foreground\">\n {t('preferences.alwaysOn')}\n </span>\n ) : (\n <Switch\n checked={categoryState === 'all'}\n onCheckedChange={(checked) => toggleCategory(category, checked)}\n aria-label={t(`preferences.categories.${category}.title`)}\n />\n )}\n </div>\n </div>\n\n {/* Individual cookies - only show for non-strictly-necessary categories */}\n {!isStrictNecessary && (\n <div className=\"space-y-2 pl-2 border-l-2 border-border ml-1\">\n {categoryCookies.map((cookie) => {\n const isEnabled = localAcceptedHosts.includes(cookie.host);\n return (\n <div\n key={cookie.host}\n className=\"flex items-start justify-between gap-3 py-2 px-3 rounded-md bg-muted/30\"\n >\n <div className=\"flex-1 min-w-0\">\n <span className=\"text-sm font-medium truncate\">{cookie.name}</span>\n {cookie.description && (\n <p className=\"text-xs text-muted-foreground mt-0.5 line-clamp-2\">\n {resolveLocalizedString(cookie.description, currentLanguage)}\n </p>\n )}\n <div className=\"flex items-center gap-3 mt-1 text-[10px] text-muted-foreground/70\">\n <span>{cookie.host}</span>\n <span>•</span>\n <span>{formatDuration(cookie.durationSeconds, t)}</span>\n <span>•</span>\n <span className=\"capitalize\">{cookie.type.replace('_', ' ')}</span>\n </div>\n </div>\n <Switch\n checked={isEnabled}\n onCheckedChange={(checked) => toggleCookie(cookie.host, checked)}\n aria-label={cookie.name}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n );\n })}\n </div>\n\n {/* Footer */}\n <div className=\"mt-auto flex flex-col gap-2 border-t border-border px-6 py-4\">\n <div className=\"flex gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleRejectAll}\n className=\"flex-1\"\n >\n {t('preferences.rejectAll')}\n </Button>\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleAcceptAll}\n className=\"flex-1\"\n >\n {t('preferences.acceptAll')}\n </Button>\n </div>\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={!hasChanges && !isInitialConsent}\n className=\"w-full\"\n >\n {t('preferences.save')}\n </Button>\n </div>\n </div>\n );\n}\n","import { useMemo } from 'react';\nimport { Navigate, useLocation } from 'react-router';\nimport { ContentView } from './ContentView';\nimport type { NavigationItem } from '../features/config/types';\n\ninterface ViewRouteProps {\n navigation: NavigationItem[];\n}\n\nexport const ViewRoute = ({ navigation }: ViewRouteProps) => {\n const location = useLocation();\n const pathname = location.pathname;\n\n const navItem = useMemo(() => {\n return navigation.find((item) => {\n const pathPrefix = `/${item.path}`;\n return pathname === pathPrefix || pathname.startsWith(`${pathPrefix}/`);\n });\n }, [navigation, pathname]);\n\n if (!navItem) {\n return (\n <Navigate\n to=\"/\"\n replace\n />\n );\n }\n // Calculate the relative path from the navItem.path\n // e.g. if item.path is \"docs\" and pathname is \"/docs/intro\", subPath is \"intro\"\n const pathPrefix = `/${navItem.path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n\n // Construct the final URL for the iframe\n let finalUrl = navItem.url;\n if (subPath) {\n const baseUrl = navItem.url.endsWith('/') ? navItem.url : `${navItem.url}/`;\n finalUrl = `${baseUrl}${subPath}`;\n }\n return (\n <ContentView\n url={finalUrl}\n pathPrefix={navItem.path}\n navItem={navItem}\n />\n );\n};\n","import { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useConfig } from '@/features/config/useConfig';\nimport type { NavigationItem, NavigationGroup } from '@/features/config/types';\n\nconst flattenNavigationItems = (\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] => {\n if (navigation.length === 0) return [];\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) {\n return (item as NavigationGroup).items;\n }\n return item as NavigationItem;\n });\n};\n\nexport const NotFoundView = () => {\n const { config } = useConfig();\n const { i18n } = useTranslation();\n const currentLanguage = i18n.language || 'en';\n\n const resolveLocalizedString = (\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n ): string => {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n };\n\n const navItems =\n config?.navigation && config.navigation.length > 0\n ? flattenNavigationItems(config.navigation)\n .filter((item) => !item.hidden)\n .filter((item, index, self) => index === self.findIndex((i) => i.path === item.path))\n : [];\n\n const handleNavigate = (path: string) => {\n shellui.navigate(path.startsWith('/') ? path : `/${path}`);\n };\n\n return (\n <div className=\"flex flex-col min-h-full\">\n <div className=\"flex-1 flex flex-col items-center justify-center px-6 py-12 text-muted-foreground\">\n <span className=\"text-6xl font-light tracking-tighter text-foreground/80 select-none\">\n 404\n </span>\n <p className=\"mt-3 text-lg text-muted-foreground\">Page not found</p>\n </div>\n\n {navItems.length > 0 && (\n <footer className=\"border-t border-border py-4 px-6 mt-auto bg-muted/30\">\n <nav\n className=\"flex flex-row flex-wrap justify-center items-center gap-x-2 gap-y-1 text-sm text-muted-foreground\"\n aria-label=\"Available pages\"\n >\n {navItems.map((item, index) => (\n <span\n key={item.path}\n className=\"inline-flex items-center gap-x-2\"\n >\n {index > 0 && (\n <span\n className=\"text-border select-none\"\n aria-hidden\n >\n ·\n </span>\n )}\n <button\n type=\"button\"\n onClick={() => handleNavigate(`/${item.path}`)}\n className=\"text-muted-foreground hover:text-foreground hover:underline underline-offset-2 cursor-pointer bg-transparent border-0 p-0 font-normal\"\n >\n {resolveLocalizedString(item.label, currentLanguage)}\n </button>\n </span>\n ))}\n </nav>\n </footer>\n )}\n </div>\n );\n};\n","import { lazy, Suspense } from 'react';\nimport { Outlet, type RouteObject } from 'react-router';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { RouteErrorBoundary } from '../components/RouteErrorBoundary';\nimport { AppLayout } from '../features/layouts/AppLayout';\nimport { flattenNavigationItems } from '../features/layouts/utils';\nimport urls from '../constants/urls';\n\n// Lazy load route components\nconst HomeView = lazy(() =>\n import('../components/HomeView').then((m) => ({ default: m.HomeView })),\n);\nconst SettingsView = lazy(() =>\n import('../features/settings/SettingsView').then((m) => ({ default: m.SettingsView })),\n);\nconst CookiePreferencesView = lazy(() =>\n import('../features/cookieConsent/CookiePreferencesView').then((m) => ({\n default: m.CookiePreferencesView,\n })),\n);\nconst ViewRoute = lazy(() =>\n import('../components/ViewRoute').then((m) => ({ default: m.ViewRoute })),\n);\nconst NotFoundView = lazy(() =>\n import('../components/NotFoundView').then((m) => ({ default: m.NotFoundView })),\n);\n\nfunction RouteFallback() {\n return (\n <div\n className=\"min-h-screen bg-background\"\n aria-hidden\n />\n );\n}\n\nexport const createRoutes = (config: ShellUIConfig): RouteObject[] => {\n const routes: RouteObject[] = [\n {\n path: '/',\n element: <Outlet />,\n errorElement: <RouteErrorBoundary />,\n children: [\n {\n // Settings route (if configured)\n path: `${urls.settings.replace(/^\\//, '')}/*`,\n element: (\n <Suspense fallback={<RouteFallback />}>\n <SettingsView />\n </Suspense>\n ),\n },\n {\n // Cookie preferences route\n path: urls.cookiePreferences.replace(/^\\//, ''),\n element: (\n <Suspense fallback={<RouteFallback />}>\n <CookiePreferencesView />\n </Suspense>\n ),\n },\n {\n // Catch-all route\n path: '*',\n element: (\n <Suspense fallback={<RouteFallback />}>\n <NotFoundView />\n </Suspense>\n ),\n },\n ],\n },\n ];\n\n // Main layout route with nested routes\n const layoutRoute: RouteObject = {\n element: (\n <AppLayout\n layout={config.layout}\n title={config.title}\n appIcon={config.appIcon}\n logo={config.logo}\n navigation={config.navigation || []}\n />\n ),\n children: [\n {\n path: '/',\n element: (\n <Suspense fallback={<RouteFallback />}>\n <HomeView />\n </Suspense>\n ),\n },\n ],\n };\n\n // Add navigation routes\n if (config.navigation && config.navigation.length > 0) {\n const navigationItems = flattenNavigationItems(config.navigation);\n navigationItems.forEach((item) => {\n (layoutRoute.children as RouteObject[]).push({\n path: `/${item.path}/*`,\n element: (\n <Suspense fallback={<RouteFallback />}>\n <ViewRoute navigation={navigationItems} />\n </Suspense>\n ),\n });\n });\n }\n (routes[0].children as RouteObject[]).push(layoutRoute);\n\n return routes;\n};\n","import { createBrowserRouter } from 'react-router';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { createRoutes } from './routes';\n\nexport const createAppRouter = (config: ShellUIConfig) => {\n const routes = createRoutes(config);\n return createBrowserRouter(routes);\n};\n","import { useRef, useState, useEffect, useCallback, useMemo, type ReactNode } from 'react';\nimport {\n getLogger,\n shellui,\n type ShellUIMessage,\n type Settings,\n type SettingsNavigationItem,\n} from '@shellui/sdk';\nimport { SettingsContext } from './SettingsContext';\nimport { useConfig } from '../config/useConfig';\nimport { useTranslation } from 'react-i18next';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\n\nconst logger = getLogger('shellcore');\n\nfunction flattenNavigationItems(\n navigation: (NavigationItem | NavigationGroup)[],\n): NavigationItem[] {\n if (navigation.length === 0) return [];\n return navigation.flatMap((item) => {\n if ('title' in item && 'items' in item) return (item as NavigationGroup).items;\n return [item as NavigationItem];\n });\n}\n\nfunction resolveLabel(\n value: string | { en: string; fr: string; [key: string]: string },\n lang: string,\n): string {\n if (typeof value === 'string') return value;\n return value[lang] || value.en || value.fr || Object.values(value)[0] || '';\n}\n\nfunction buildSettingsWithNavigation(\n settings: Settings,\n navigation: (NavigationItem | NavigationGroup)[] | undefined,\n lang: string,\n): Settings {\n if (!navigation?.length) return settings;\n const items: SettingsNavigationItem[] = flattenNavigationItems(navigation).map((item) => ({\n path: item.path,\n url: item.url,\n label: resolveLabel(item.label, lang),\n }));\n return { ...settings, navigation: { items } };\n}\n\nconst STORAGE_KEY = 'shellui:settings';\n\n// Get browser's timezone as default\nconst getBrowserTimezone = (): string => {\n if (typeof window !== 'undefined' && Intl) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n};\n\nconst defaultSettings: Settings = {\n developerFeatures: {\n enabled: false,\n },\n errorReporting: {\n enabled: true,\n },\n logging: {\n namespaces: {\n shellsdk: false,\n shellcore: false,\n },\n },\n appearance: {\n theme: 'system',\n themeName: 'default',\n },\n language: {\n code: 'en',\n },\n region: {\n timezone: getBrowserTimezone(),\n },\n cookieConsent: {\n acceptedHosts: [],\n consentedCookieHosts: [],\n },\n serviceWorker: {\n enabled: true,\n },\n};\n\nexport function SettingsProvider({ children }: { children: ReactNode }) {\n const { config } = useConfig();\n const { i18n } = useTranslation();\n // Use a ref to always have current settings for message listeners (avoids closure issues)\n const settingsRef = useRef<Settings | null>(null);\n const [settings, setSettings] = useState<Settings>(() => {\n let initialSettings: Settings;\n\n if (shellui.initialSettings) {\n initialSettings = shellui.initialSettings;\n settingsRef.current = initialSettings;\n return initialSettings;\n }\n\n // Initialize from localStorage\n if (typeof window !== 'undefined') {\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n const parsed = JSON.parse(stored);\n // Deep merge with defaults to handle new settings\n initialSettings = {\n ...defaultSettings,\n ...parsed,\n errorReporting: {\n enabled: parsed.errorReporting?.enabled ?? defaultSettings.errorReporting.enabled,\n },\n logging: {\n namespaces: {\n ...defaultSettings.logging.namespaces,\n ...parsed.logging?.namespaces,\n },\n },\n appearance: {\n theme: parsed.appearance?.theme || defaultSettings.appearance.theme,\n themeName: parsed.appearance?.themeName || defaultSettings.appearance.themeName,\n },\n language: {\n code: parsed.language?.code || defaultSettings.language.code,\n },\n region: {\n // Only use stored timezone if it exists, otherwise use browser's current timezone\n timezone: parsed.region?.timezone || getBrowserTimezone(),\n },\n cookieConsent: {\n acceptedHosts: Array.isArray(parsed.cookieConsent?.acceptedHosts)\n ? parsed.cookieConsent.acceptedHosts\n : (defaultSettings.cookieConsent?.acceptedHosts ?? []),\n consentedCookieHosts: Array.isArray(parsed.cookieConsent?.consentedCookieHosts)\n ? parsed.cookieConsent.consentedCookieHosts\n : (defaultSettings.cookieConsent?.consentedCookieHosts ?? []),\n },\n serviceWorker: {\n // Migrate from legacy \"caching\" key if present\n enabled: parsed.serviceWorker?.enabled ?? parsed.caching?.enabled ?? true,\n },\n };\n settingsRef.current = initialSettings;\n return initialSettings;\n }\n } catch (error) {\n logger.error('Failed to load settings from localStorage:', { error });\n }\n }\n settingsRef.current = defaultSettings;\n return defaultSettings;\n });\n\n // Keep ref in sync with state for message listeners\n useEffect(() => {\n settingsRef.current = settings;\n }, [settings]);\n\n // Listen for settings updates from parent/other nodes\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n\n const cleanup = shellui.addMessageListener(\n 'SHELLUI_SETTINGS_UPDATED',\n (message: ShellUIMessage) => {\n const payload = message.payload as { settings: Settings };\n const newSettings = payload.settings;\n if (newSettings) {\n // Update localStorage with new settings value\n setSettings(newSettings);\n if (window.parent === window) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n // Confirm: root updated localStorage; re-inject navigation when propagating\n const settingsToPropagate = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n logger.info('Root Parent received settings update', { message });\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsToPropagate },\n });\n } catch (error) {\n logger.error('Failed to update settings from message:', { error });\n }\n }\n }\n },\n );\n\n const cleanupSettingsRequested = shellui.addMessageListener(\n 'SHELLUI_SETTINGS_REQUESTED',\n () => {\n // Use ref to always get current settings (avoids stale closure)\n const currentSettings = settingsRef.current ?? defaultSettings;\n const settingsWithNav = buildSettingsWithNavigation(\n currentSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsWithNav },\n });\n },\n );\n\n const cleanupSettings = shellui.addMessageListener(\n 'SHELLUI_SETTINGS',\n (data: ShellUIMessage) => {\n const message = data as ShellUIMessage;\n const payload = message.payload as { settings: Settings };\n const newSettings = payload.settings;\n if (newSettings) {\n setSettings(newSettings);\n }\n },\n );\n\n return () => {\n cleanup();\n cleanupSettings();\n cleanupSettingsRequested();\n };\n }, [settings, config?.navigation, i18n.language]);\n\n // ACTIONS\n const updateSettings = useCallback(\n (updates: Partial<Settings>) => {\n const newSettings = { ...settings, ...updates };\n\n // Update localStorage and propagate to children if we're in the root window\n if (typeof window !== 'undefined' && window.parent === window) {\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n setSettings(newSettings);\n // Propagate to child iframes (sendMessageToParent does nothing in root)\n const settingsWithNav = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsWithNav },\n });\n } catch (error) {\n logger.error('Failed to update settings in localStorage:', { error });\n }\n }\n\n // For child iframes, send to parent (parent will propagate to siblings)\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings: newSettings },\n });\n },\n [settings, config?.navigation, i18n.language],\n );\n\n const updateSetting = useCallback(\n <K extends keyof Settings>(key: K, updates: Partial<Settings[K]>) => {\n // Deep merge: preserve existing nested properties\n const currentValue = settings[key];\n const mergedValue =\n typeof currentValue === 'object' && currentValue !== null && !Array.isArray(currentValue)\n ? { ...currentValue, ...updates }\n : updates;\n updateSettings({ [key]: mergedValue } as Partial<Settings>);\n },\n [settings, updateSettings],\n );\n\n const resetAllData = useCallback(() => {\n // Clear all localStorage data\n if (typeof window !== 'undefined') {\n try {\n // Clear settings\n localStorage.removeItem(STORAGE_KEY);\n\n // Clear all other localStorage items that start with shellui:\n const keysToRemove: string[] = [];\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key && key.startsWith('shellui:')) {\n keysToRemove.push(key);\n }\n }\n keysToRemove.forEach((key) => localStorage.removeItem(key));\n\n // Reset settings to defaults\n const newSettings = defaultSettings;\n setSettings(newSettings);\n\n // If we're in the root window, update localStorage with defaults\n if (window.parent === window) {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(newSettings));\n const settingsToPropagate = buildSettingsWithNavigation(\n newSettings,\n config?.navigation,\n i18n.language || 'en',\n );\n shellui.propagateMessage({\n type: 'SHELLUI_SETTINGS',\n payload: { settings: settingsToPropagate },\n });\n }\n\n // Notify parent about reset\n shellui.sendMessageToParent({\n type: 'SHELLUI_SETTINGS_UPDATED',\n payload: { settings: newSettings },\n });\n\n logger.info('All app data has been reset');\n } catch (error) {\n logger.error('Failed to reset all data:', { error });\n }\n }\n }, [config?.navigation, i18n.language]);\n\n const value = useMemo(\n () => ({\n settings,\n updateSettings,\n updateSetting,\n resetAllData,\n }),\n [settings, updateSettings, updateSetting, resetAllData],\n );\n\n return <SettingsContext.Provider value={value}>{children}</SettingsContext.Provider>;\n}\n","/* eslint-disable no-console */\nimport { useLayoutEffect } from 'react';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { useConfig } from '../config/useConfig';\nimport { getTheme, registerTheme, applyTheme, type ThemeDefinition } from './themes';\n\n/**\n * Apply theme to document element\n */\nfunction applyThemeToDocument(isDark: boolean) {\n const root = document.documentElement;\n if (isDark) {\n root.classList.add('dark');\n } else {\n root.classList.remove('dark');\n }\n}\n\n/**\n * Hook to apply theme based on settings\n * Applies 'dark' class to document.documentElement based on:\n * - 'light': removes dark class\n * - 'dark': adds dark class\n * - 'system': follows prefers-color-scheme media query\n * Also applies theme colors based on themeName setting\n */\nexport function useTheme() {\n const { settings } = useSettings();\n const { config } = useConfig();\n const theme = settings.appearance?.theme || 'system';\n const themeName = settings.appearance?.themeName || 'default';\n\n // Apply theme immediately on mount (synchronously) to prevent empty colors\n // This ensures CSS variables are set before first render\n useLayoutEffect(() => {\n // Get the effective theme name (from settings or config)\n // Use themeName from settings first, then config defaultTheme, then 'default'\n const effectiveThemeName = themeName || config?.defaultTheme || 'default';\n\n if (config?.themes) {\n config.themes.forEach((themeDef: ThemeDefinition) => {\n registerTheme(themeDef);\n });\n }\n\n const themeDefinition = getTheme(effectiveThemeName) || getTheme('default');\n\n if (themeDefinition) {\n const determineIsDark = () => {\n if (theme === 'system') {\n const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');\n return mediaQuery.matches;\n }\n return theme === 'dark';\n };\n const isDark = determineIsDark();\n applyThemeToDocument(isDark);\n applyTheme(themeDefinition, isDark);\n } else {\n console.error('[Theme] No theme definition found, using fallback');\n // Fallback: at least set primary color from default theme\n const defaultTheme = getTheme('default');\n if (defaultTheme) {\n const isDark =\n theme === 'dark' ||\n (theme === 'system' && window.matchMedia('(prefers-color-scheme: dark)').matches);\n applyTheme(defaultTheme, isDark);\n }\n }\n }, [theme, themeName, config]); // Run when theme, themeName, or config changes\n}\n","import type { ReactNode } from 'react';\nimport { useTheme } from './useTheme';\n\nexport interface ThemeProviderProps {\n children: ReactNode;\n}\n\n/**\n * Provider that applies theme (light/dark/system and theme colors) from settings.\n * Must be rendered inside SettingsProvider so useTheme can read appearance settings.\n * Applies theme to document.documentElement and listens to system preference changes.\n */\nexport function ThemeProvider({ children }: ThemeProviderProps) {\n useTheme();\n return <>{children}</>;\n}\n","import { useEffect, type ReactNode } from 'react';\nimport { useSettings } from '../features/settings/hooks/useSettings';\nimport i18n, { initializeI18n } from './config';\nimport type { ShellUIConfig } from '../features/config/types';\nimport { useConfig } from '../features/config/useConfig';\n\ninterface I18nProviderProps {\n children: ReactNode;\n config?: ShellUIConfig;\n}\n\nexport function I18nProvider({ children }: I18nProviderProps) {\n const { settings } = useSettings();\n const { config } = useConfig();\n const currentLanguage = settings.language?.code || 'en';\n\n // Initialize i18n with enabled languages from config\n useEffect(() => {\n if (config?.language) {\n initializeI18n(config.language);\n }\n }, [config?.language]);\n\n // Sync i18n language with settings changes\n useEffect(() => {\n if (i18n.language !== currentLanguage) {\n i18n.changeLanguage(currentLanguage);\n }\n }, [currentLanguage]);\n\n return <>{children}</>;\n}\n","import {\n forwardRef,\n type ElementRef,\n type ComponentPropsWithoutRef,\n type HTMLAttributes,\n} from 'react';\nimport * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\nimport { Button, type ButtonProps } from '@/components/ui/button';\n\nconst AlertDialog = AlertDialogPrimitive.Root;\n\nconst AlertDialogTrigger = AlertDialogPrimitive.Trigger;\n\nconst AlertDialogPortal = AlertDialogPrimitive.Portal;\n\nconst AlertDialogOverlay = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Overlay>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Overlay>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Overlay\n ref={ref}\n data-dialog-overlay\n className={cn('fixed inset-0 bg-[hsl(var(--background)/0.8)] backdrop-blur-[1px]', className)}\n style={{ zIndex: Z_INDEX.ALERT_DIALOG_OVERLAY }}\n {...props}\n />\n));\nAlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName;\n\nconst alertDialogContentVariants = cva(\n 'fixed left-[50%] top-[50%] grid w-full min-w-0 max-w-[calc(100vw-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background py-6 shadow-lg box-border overflow-hidden sm:rounded-lg',\n {\n variants: {\n size: {\n default: 'max-w-lg',\n sm: 'max-w-sm',\n },\n },\n defaultVariants: {\n size: 'default',\n },\n },\n);\n\ninterface AlertDialogContentProps\n extends\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Content>,\n VariantProps<typeof alertDialogContentVariants> {}\n\nconst AlertDialogContent = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Content>,\n AlertDialogContentProps\n>(({ className, size = 'default', children, style, ...props }, ref) => (\n <AlertDialogPortal>\n <AlertDialogOverlay />\n <AlertDialogPrimitive.Content\n ref={ref}\n data-dialog-content\n className={cn(alertDialogContentVariants({ size }), 'group', className)}\n data-size={size}\n style={{ zIndex: Z_INDEX.ALERT_DIALOG_CONTENT, ...style }}\n {...props}\n >\n {children}\n </AlertDialogPrimitive.Content>\n </AlertDialogPortal>\n));\nAlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName;\n\nconst AlertDialogHeader = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex flex-col px-6 space-y-2 text-left group-data-[size=sm]:items-center group-data-[size=sm]:text-center',\n className,\n )}\n {...props}\n />\n);\nAlertDialogHeader.displayName = 'AlertDialogHeader';\n\nconst AlertDialogMedia = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex size-10 shrink-0 items-center justify-center rounded-lg mb-4 [&>svg]:size-5',\n className,\n )}\n {...props}\n />\n);\nAlertDialogMedia.displayName = 'AlertDialogMedia';\n\nconst AlertDialogFooter = ({ className, ...props }: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n 'flex w-full min-w-full flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n '-mb-6 mt-2 border-t border-border bg-muted/50 px-6 py-3 sm:rounded-b-lg',\n '[&_button]:h-8 [&_button]:text-xs [&_button]:px-3',\n 'group-data-[size=sm]:flex-row group-data-[size=sm]:gap-2',\n 'group-data-[size=sm]:[&>*:not(:only-child)]:min-w-0 group-data-[size=sm]:[&>*:not(:only-child)]:flex-1',\n className,\n )}\n {...props}\n />\n);\nAlertDialogFooter.displayName = 'AlertDialogFooter';\n\nconst AlertDialogTitle = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Title>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Title\n ref={ref}\n className={cn('text-lg font-semibold leading-none tracking-tight', className)}\n {...props}\n />\n));\nAlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName;\n\nconst AlertDialogDescription = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Description>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Description>\n>(({ className, ...props }, ref) => (\n <AlertDialogPrimitive.Description\n ref={ref}\n className={cn('text-sm text-muted-foreground', className)}\n {...props}\n />\n));\nAlertDialogDescription.displayName = AlertDialogPrimitive.Description.displayName;\n\nconst AlertDialogAction = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Action>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Action> &\n Pick<ButtonProps, 'variant' | 'size'>\n>(({ className, variant, size, ...props }, ref) => (\n <AlertDialogPrimitive.Action asChild>\n <Button\n ref={ref}\n variant={variant}\n size={size}\n className={className}\n {...props}\n />\n </AlertDialogPrimitive.Action>\n));\nAlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName;\n\nconst AlertDialogCancel = forwardRef<\n ElementRef<typeof AlertDialogPrimitive.Cancel>,\n ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Cancel> &\n Pick<ButtonProps, 'variant' | 'size'>\n>(({ className, variant, size, ...props }, ref) => (\n <AlertDialogPrimitive.Cancel asChild>\n <Button\n ref={ref}\n variant={variant}\n size={size}\n className={className}\n {...props}\n />\n </AlertDialogPrimitive.Cancel>\n));\nAlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName;\n\nexport {\n AlertDialog,\n AlertDialogPortal,\n AlertDialogOverlay,\n AlertDialogTrigger,\n AlertDialogContent,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogFooter,\n AlertDialogTitle,\n AlertDialogDescription,\n AlertDialogAction,\n AlertDialogCancel,\n};\n","import { shellui, type ShellUIMessage, type DialogOptions } from '@shellui/sdk';\nimport {\n createContext,\n useContext,\n useCallback,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { Button } from '@/components/ui/button';\nimport { Z_INDEX } from '@/lib/z-index';\n\n/** Match exit animation duration in index.css (overlay + content ~0.1s + buffer) */\nconst DIALOG_EXIT_ANIMATION_MS = 200;\nimport {\n AlertDialog,\n AlertDialogAction,\n AlertDialogCancel,\n AlertDialogContent,\n AlertDialogDescription,\n AlertDialogFooter,\n AlertDialogHeader,\n AlertDialogMedia,\n AlertDialogTitle,\n AlertDialogOverlay,\n AlertDialogPortal,\n} from '@/components/ui/alert-dialog';\nimport * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';\n\n/** Trash icon (matches lucide trash-2) */\nconst TrashIcon = () => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M3 6h18\" />\n <path d=\"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\" />\n <path d=\"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\" />\n <line\n x1=\"10\"\n x2=\"10\"\n y1=\"11\"\n y2=\"17\"\n />\n <line\n x1=\"14\"\n x2=\"14\"\n y1=\"11\"\n y2=\"17\"\n />\n </svg>\n);\n\n/** Cookie icon for cookie consent */\nconst CookieIcon = ({ className }: { className?: string }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 256 256\"\n fill=\"currentColor\"\n className={className}\n >\n <path d=\"M164.49 163.51a12 12 0 1 1-17 0a12 12 0 0 1 17 0m-81-8a12 12 0 1 0 17 0a12 12 0 0 0-16.98 0Zm9-39a12 12 0 1 0-17 0a12 12 0 0 0 17-.02Zm48-1a12 12 0 1 0 0 17a12 12 0 0 0 0-17M232 128A104 104 0 1 1 128 24a8 8 0 0 1 8 8a40 40 0 0 0 40 40a8 8 0 0 1 8 8a40 40 0 0 0 40 40a8 8 0 0 1 8 8m-16.31 7.39A56.13 56.13 0 0 1 168.5 87.5a56.13 56.13 0 0 1-47.89-47.19a88 88 0 1 0 95.08 95.08\" />\n </svg>\n);\n\ninterface DialogContextValue {\n dialog: (options: DialogOptions) => void;\n}\n\nconst DialogContext = createContext<DialogContextValue | undefined>(undefined);\n\nexport function useDialog() {\n const context = useContext(DialogContext);\n if (!context) {\n throw new Error('useDialog must be used within a DialogProvider');\n }\n return context;\n}\n\ninterface DialogProviderProps {\n children: ReactNode;\n}\n\ninterface DialogState extends Omit<DialogOptions, 'onOk' | 'onCancel' | 'icon'> {\n id: string;\n mode: DialogOptions['mode'];\n from?: string[];\n iconType?: 'cookie';\n}\n\nexport const DialogProvider = ({ children }: DialogProviderProps) => {\n const [dialogState, setDialogState] = useState<DialogState | null>(null);\n const [isOpen, setIsOpen] = useState(false);\n const unmountTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const scheduleUnmount = useCallback(() => {\n if (unmountTimeoutRef.current) clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = setTimeout(() => {\n unmountTimeoutRef.current = null;\n setDialogState(null);\n }, DIALOG_EXIT_ANIMATION_MS);\n }, []);\n\n const handleOpenChange = useCallback(\n (open: boolean) => {\n setIsOpen(open);\n if (!open && dialogState) {\n // If dialog was closed without clicking a button (X button or outside click),\n // trigger cancel callback if it exists\n if (dialogState.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_CANCEL',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerCancel(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n // Unmount after exit animation finishes\n scheduleUnmount();\n }\n },\n [dialogState, scheduleUnmount],\n );\n\n const handleOk = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_OK',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerAction(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const handleCancel = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_CANCEL',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerCancel(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const handleSecondary = useCallback(() => {\n if (dialogState?.from && dialogState.from.length > 0) {\n shellui.sendMessage({\n type: 'SHELLUI_DIALOG_SECONDARY',\n payload: { id: dialogState.id },\n to: dialogState.from,\n });\n } else if (dialogState?.id) {\n // Dialog opened from root window - trigger callback directly\n shellui.callbackRegistry.triggerSecondary(dialogState.id);\n shellui.callbackRegistry.clear(dialogState.id);\n }\n setIsOpen(false);\n scheduleUnmount();\n }, [dialogState, scheduleUnmount]);\n\n const dialog = useCallback((options: DialogOptions) => {\n // Only show dialog if window is root\n if (typeof window === 'undefined' || window.parent !== window) {\n return;\n }\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n\n const dialogId = options.id || `dialog-${Date.now()}-${Math.random()}`;\n\n // Register callbacks for direct calls (not from iframe)\n if (options.onOk || options.onCancel || options.secondaryButton?.onClick) {\n shellui.callbackRegistry.register(dialogId, {\n action: options.onOk,\n cancel: options.onCancel,\n secondary: options.secondaryButton?.onClick,\n });\n }\n\n setDialogState({\n id: dialogId,\n title: options.title,\n description: options.description,\n mode: options.mode || 'ok',\n okLabel: options.okLabel,\n cancelLabel: options.cancelLabel,\n size: options.size,\n position: options.position,\n secondaryButton: options.secondaryButton,\n iconType: options.icon === 'cookie' ? 'cookie' : undefined,\n });\n setIsOpen(true);\n }, []);\n\n // Listen for postMessage events from nested iframes\n useEffect(() => {\n // Only listen if window is root\n if (typeof window === 'undefined' || window.parent !== window) {\n return;\n }\n\n const cleanupDialog = shellui.addMessageListener('SHELLUI_DIALOG', (data: ShellUIMessage) => {\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n const payload = data.payload as DialogOptions & { id: string };\n setDialogState({\n id: payload.id,\n title: payload.title,\n description: payload.description,\n mode: payload.mode || 'ok',\n okLabel: payload.okLabel,\n cancelLabel: payload.cancelLabel,\n size: payload.size,\n position: payload.position,\n secondaryButton: payload.secondaryButton,\n iconType: payload.icon === 'cookie' ? 'cookie' : undefined,\n from: data.from,\n });\n setIsOpen(true);\n });\n\n const cleanupDialogUpdate = shellui.addMessageListener(\n 'SHELLUI_DIALOG_UPDATE',\n (data: ShellUIMessage) => {\n if (unmountTimeoutRef.current) {\n clearTimeout(unmountTimeoutRef.current);\n unmountTimeoutRef.current = null;\n }\n const payload = data.payload as DialogOptions & { id: string };\n setDialogState({\n id: payload.id,\n title: payload.title,\n description: payload.description,\n mode: payload.mode || 'ok',\n okLabel: payload.okLabel,\n cancelLabel: payload.cancelLabel,\n size: payload.size,\n position: payload.position,\n secondaryButton: payload.secondaryButton,\n iconType: payload.icon === 'cookie' ? 'cookie' : undefined,\n from: data.from,\n });\n setIsOpen(true);\n },\n );\n\n return () => {\n cleanupDialog();\n cleanupDialogUpdate();\n if (unmountTimeoutRef.current) clearTimeout(unmountTimeoutRef.current);\n };\n }, []);\n\n const renderButtons = () => {\n if (!dialogState) return null;\n\n const { mode, okLabel, cancelLabel, secondaryButton } = dialogState;\n\n // Cookie consent layout: secondary button on left, primary buttons on right\n if (secondaryButton && dialogState.position === 'bottom-left') {\n return (\n <>\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={handleSecondary}\n >\n {secondaryButton.label}\n </Button>\n <div className=\"flex gap-2\">\n {mode === 'okCancel' && (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </Button>\n )}\n <Button\n size=\"sm\"\n onClick={handleOk}\n >\n {okLabel || 'OK'}\n </Button>\n </div>\n </>\n );\n }\n\n switch (mode) {\n case 'ok':\n return <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>;\n\n case 'okCancel':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>\n </>\n );\n\n case 'delete':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction\n variant=\"destructive\"\n onClick={handleOk}\n >\n {okLabel || 'Delete'}\n </AlertDialogAction>\n </>\n );\n\n case 'confirm':\n return (\n <>\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n <AlertDialogAction onClick={handleOk}>{okLabel || 'Confirm'}</AlertDialogAction>\n </>\n );\n\n case 'onlyCancel':\n return (\n <AlertDialogCancel\n variant=\"outline\"\n onClick={handleCancel}\n >\n {cancelLabel || 'Cancel'}\n </AlertDialogCancel>\n );\n\n default:\n return <AlertDialogAction onClick={handleOk}>{okLabel || 'OK'}</AlertDialogAction>;\n }\n };\n\n // Render cookie consent dialog with custom layout\n const renderCookieConsentDialog = () => {\n if (!dialogState || dialogState.position !== 'bottom-left') return null;\n\n return (\n <AlertDialog\n open={isOpen}\n onOpenChange={handleOpenChange}\n >\n <AlertDialogPortal>\n <AlertDialogOverlay style={{ zIndex: Z_INDEX.COOKIE_CONSENT_OVERLAY }} />\n <AlertDialogPrimitive.Content\n className=\"fixed w-[calc(100%-32px)] max-w-[520px] rounded-xl border border-border bg-background text-foreground shadow-lg sm:w-full\"\n style={{\n bottom: 16,\n left: 16,\n zIndex: Z_INDEX.COOKIE_CONSENT_CONTENT,\n backgroundColor: 'hsl(var(--background))',\n top: 'auto',\n right: 'auto',\n transform: 'none',\n }}\n data-dialog-content\n data-cookie-consent\n >\n <div className=\"flex items-start gap-4 p-6 sm:gap-5 sm:p-7\">\n {dialogState.iconType === 'cookie' && (\n <div\n className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-primary/10\"\n aria-hidden\n >\n <CookieIcon className=\"h-5 w-5 text-primary\" />\n </div>\n )}\n <div className=\"flex-1 space-y-2\">\n <AlertDialogTitle className=\"text-base font-semibold leading-tight\">\n {dialogState.title}\n </AlertDialogTitle>\n {dialogState.description && (\n <AlertDialogDescription className=\"text-sm leading-relaxed\">\n {dialogState.description}\n </AlertDialogDescription>\n )}\n </div>\n </div>\n <div className=\"flex items-center justify-between rounded-b-xl border-t border-border bg-muted/50 px-6 py-4 sm:px-7\">\n {renderButtons()}\n </div>\n </AlertDialogPrimitive.Content>\n </AlertDialogPortal>\n </AlertDialog>\n );\n };\n\n return (\n <DialogContext.Provider value={{ dialog }}>\n {children}\n {dialogState && (\n <>\n {dialogState.position === 'bottom-left' ? (\n renderCookieConsentDialog()\n ) : (\n <AlertDialog\n open={isOpen}\n onOpenChange={handleOpenChange}\n >\n <AlertDialogContent size={dialogState.size ?? 'default'}>\n <AlertDialogHeader>\n {dialogState.mode === 'delete' && (\n <AlertDialogMedia className=\"bg-destructive/10 text-destructive dark:bg-destructive/20 dark:text-destructive\">\n <TrashIcon />\n </AlertDialogMedia>\n )}\n <AlertDialogTitle>{dialogState.title}</AlertDialogTitle>\n {dialogState.description && (\n <AlertDialogDescription>{dialogState.description}</AlertDialogDescription>\n )}\n </AlertDialogHeader>\n <AlertDialogFooter>{renderButtons()}</AlertDialogFooter>\n </AlertDialogContent>\n </AlertDialog>\n )}\n </>\n )}\n </DialogContext.Provider>\n );\n};\n","import { useRef, useCallback, useEffect } from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport { useDialog } from '../alertDialog/DialogContext';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport urls from '@/constants/urls';\n\n/**\n * Shows a friendly cookie consent modal on first visit (when user has not yet consented).\n * Accept all / Reject all only. Closing via Escape or overlay counts as Reject.\n */\nexport function CookieConsentModal() {\n const { t } = useTranslation('cookieConsent');\n const { config } = useConfig();\n const { settings, updateSetting } = useSettings();\n const { dialog: showDialog } = useDialog();\n const closedByChoiceRef = useRef(false);\n const dialogShownRef = useRef(false);\n\n const cookieConsent = config?.cookieConsent;\n const cookies = cookieConsent?.cookies ?? [];\n const consentedHosts = settings?.cookieConsent?.consentedCookieHosts ?? [];\n const allHosts = cookies.map((c) => c.host);\n const strictNecessaryHosts = cookies\n .filter((c) => c.category === 'strict_necessary')\n .map((c) => c.host);\n\n // Check if there are new cookies that weren't in the list when user last consented\n const hasNewCookies = allHosts.some((host) => !consentedHosts.includes(host));\n const neverConsented = consentedHosts.length === 0;\n const isRenewal = !neverConsented && hasNewCookies;\n\n // Only show in root window, not in sub-apps (iframes)\n const isRootWindow = typeof window !== 'undefined' && window.parent === window;\n // Show if: has cookies AND (never consented OR new cookies added)\n const shouldShow = isRootWindow && cookies.length > 0 && (neverConsented || hasNewCookies);\n\n // Use renewal text if showing due to cookie policy update\n const title = isRenewal ? t('titleRenewal') : t('title');\n const description = isRenewal ? t('descriptionRenewal') : t('description');\n\n const saveAccept = useCallback(() => {\n updateSetting('cookieConsent', {\n acceptedHosts: allHosts,\n consentedCookieHosts: allHosts,\n });\n }, [allHosts, updateSetting]);\n\n const saveReject = useCallback(() => {\n updateSetting('cookieConsent', {\n acceptedHosts: strictNecessaryHosts,\n consentedCookieHosts: allHosts,\n });\n }, [strictNecessaryHosts, allHosts, updateSetting]);\n\n const handleAccept = useCallback(() => {\n closedByChoiceRef.current = true;\n saveAccept();\n }, [saveAccept]);\n\n const handleReject = useCallback(() => {\n closedByChoiceRef.current = true;\n saveReject();\n }, [saveReject]);\n\n const handleSetPreferences = useCallback(() => {\n closedByChoiceRef.current = true;\n shellui.openDrawer({ url: `${urls.cookiePreferences}?initial=true`, size: '420px' });\n }, []);\n\n // Show/hide dialog based on shouldShow\n useEffect(() => {\n if (!shouldShow) {\n dialogShownRef.current = false;\n return;\n }\n\n // Prevent showing dialog multiple times\n if (dialogShownRef.current) {\n return;\n }\n\n // Mark as shown to prevent duplicate calls\n dialogShownRef.current = true;\n\n // Close any open modals/drawers when cookie consent is shown\n shellui.propagateMessage({ type: 'SHELLUI_CLOSE_MODAL', payload: {} });\n shellui.propagateMessage({ type: 'SHELLUI_CLOSE_DRAWER', payload: {} });\n\n // Reset choice ref when showing dialog\n closedByChoiceRef.current = false;\n\n // Show dialog using DialogContext directly (for root window)\n showDialog({\n title,\n description,\n mode: 'okCancel',\n okLabel: t('accept'),\n cancelLabel: t('reject'),\n position: 'bottom-left',\n icon: 'cookie',\n secondaryButton: {\n label: t('setPreferences'),\n onClick: handleSetPreferences,\n },\n onOk: handleAccept,\n onCancel: handleReject,\n });\n }, [\n shouldShow,\n title,\n description,\n t,\n handleAccept,\n handleReject,\n handleSetPreferences,\n showDialog,\n ]);\n\n return null;\n}\n","import { useMemo, useLayoutEffect, useState, useEffect } from 'react';\nimport { RouterProvider } from 'react-router';\nimport { shellui } from '@shellui/sdk';\nimport { useConfig } from './features/config/useConfig';\nimport { ConfigProvider } from './features/config/ConfigProvider';\nimport { createAppRouter } from './router/router';\nimport { SettingsProvider } from './features/settings/SettingsProvider';\nimport { ThemeProvider } from './features/theme/ThemeProvider';\nimport { I18nProvider } from './i18n/I18nProvider';\nimport { DialogProvider } from './features/alertDialog/DialogContext';\nimport { CookieConsentModal } from './features/cookieConsent/CookieConsentModal';\nimport './features/sentry/initSentry';\nimport './i18n/config'; // Initialize i18n\nimport './index.css';\nimport { registerServiceWorker, unregisterServiceWorker, isTauri } from './service-worker/register';\nimport { useSettings } from './features/settings/hooks/useSettings';\n\nconst AppContent = () => {\n const { config } = useConfig();\n const { settings } = useSettings();\n\n // Apply favicon from config when available (allows projects to override default)\n useEffect(() => {\n if (config?.favicon) {\n const link = document.querySelector<HTMLLinkElement>('link[rel=\"icon\"]');\n if (link) link.href = config.favicon;\n }\n }, [config?.favicon]);\n\n // Register or unregister service worker based on setting\n useEffect(() => {\n if (isTauri()) {\n unregisterServiceWorker();\n return;\n }\n const serviceWorkerEnabled = settings?.serviceWorker?.enabled ?? true; // Default to enabled\n\n // Don't register service worker if navigation is empty or undefined\n // This helps prevent issues in development or misconfigured apps\n if (!config?.navigation || config.navigation.length === 0) {\n if (serviceWorkerEnabled) {\n // eslint-disable-next-line no-console\n console.warn('[Service Worker] Disabled: No navigation items configured');\n unregisterServiceWorker();\n }\n return;\n }\n\n if (serviceWorkerEnabled) {\n registerServiceWorker({\n enabled: true,\n });\n } else {\n unregisterServiceWorker();\n }\n }, [settings?.serviceWorker?.enabled, config?.navigation]);\n\n // Create router from config using data mode\n const router = useMemo(() => {\n if (!config) {\n return null;\n }\n return createAppRouter(config);\n }, [config]);\n\n // If no navigation, show simple layout\n if (!config.navigation || config.navigation.length === 0) {\n return (\n <>\n <CookieConsentModal />\n <div style={{ fontFamily: 'system-ui, sans-serif', padding: '2rem' }}>\n <h1>{config.title || 'ShellUI'}</h1>\n <p>No navigation items configured.</p>\n </div>\n </>\n );\n }\n\n if (!router) {\n return null;\n }\n\n return (\n <>\n <CookieConsentModal />\n <RouterProvider router={router} />\n </>\n );\n};\n\nconst App = () => {\n const [isLoading, setIsLoading] = useState(true);\n // Initialize ShellUI SDK to support recursive nesting\n useLayoutEffect(() => {\n shellui.init().then(() => {\n setIsLoading(false);\n });\n }, []);\n\n if (isLoading) {\n return null;\n }\n\n return (\n <ConfigProvider>\n <SettingsProvider>\n <ThemeProvider>\n <I18nProvider>\n <DialogProvider>\n <AppContent />\n </DialogProvider>\n </I18nProvider>\n </ThemeProvider>\n </SettingsProvider>\n </ConfigProvider>\n );\n};\n\nexport default App;\n","import { useMemo } from 'react';\nimport { useConfig } from '../config/useConfig';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { getCookieConsentNeedsRenewal } from './cookieConsent';\n\n/**\n * Returns whether the given cookie host is accepted (feature may run) and whether\n * consent should be re-collected. Use to gate features in React components.\n *\n * - isAccepted: true if cookie consent is not configured, or the host is not in the config list,\n * or the user has accepted this host.\n * - needsConsent: true if cookie consent is configured and the user has not yet consented,\n * or new cookies were added since last consent (renewal); when showing the UI again, pre-fill\n * with settings.cookieConsent.acceptedHosts to keep existing approvals.\n */\nexport function useCookieConsent(host: string): { isAccepted: boolean; needsConsent: boolean } {\n const { config } = useConfig();\n const { settings } = useSettings();\n\n return useMemo(() => {\n const cookieConsent = config?.cookieConsent;\n const list = cookieConsent?.cookies ?? [];\n const acceptedHosts = settings?.cookieConsent?.acceptedHosts ?? [];\n\n if (!list.length) {\n return { isAccepted: true, needsConsent: false };\n }\n\n const knownHosts = new Set(list.map((c) => c.host));\n if (!knownHosts.has(host)) {\n return { isAccepted: true, needsConsent: false };\n }\n\n const isAccepted = acceptedHosts.includes(host);\n const needsConsent = acceptedHosts.length === 0 || getCookieConsentNeedsRenewal();\n\n return { isAccepted, needsConsent };\n }, [config?.cookieConsent, settings?.cookieConsent?.acceptedHosts, host]);\n}\n"],"names":["logger","getLogger","ConfigContext","createContext","configLogged","ConfigProvider","props","config","useState","configValue","parsedConfig","parseError","g","fallbackValue","err","value","createElement","useConfig","context","useContext","cn","inputs","twMerge","clsx","buttonVariants","cva","Button","forwardRef","className","variant","size","asChild","ref","jsx","Slot","isChunkLoadError","error","msg","getErrorMessage","isRouteErrorResponse","getErrorStack","getErrorDetailsText","message","stack","RouteErrorBoundary","useRouteError","t","useTranslation","isChunkError","detailsText","jsxs","shellui","SettingsContext","useSettings","Z_INDEX","SidebarContext","useSidebar","SidebarProvider","children","isCollapsed","setIsCollapsed","toggle","useCallback","prev","Sidebar","PanelLeftOpenIcon","PanelLeftCloseIcon","SidebarTrigger","SidebarHeader","SidebarContent","SidebarFooter","SidebarGroup","SidebarGroupLabel","SidebarGroupAction","SidebarGroupContent","sidebarMenuButtonVariants","SidebarMenuButton","isActive","SidebarMenu","SidebarMenuItem","SidebarMenuAction","SidebarMenuBadge","SidebarMenuSkeleton","showIcon","SidebarMenuSub","SidebarMenuSubButton","SidebarMenuSubItem","resolveLocalizedString","lang","flattenNavigationItems","navigation","item","filterNavigationByViewport","viewport","hideOnMobile","hideOnDesktop","group","visibleItems","navItem","filterNavigationForSidebar","splitNavigationByPosition","start","end","validateAndNormalizeUrl","url","urlObj","currentOrigin","normalizedPath","ModalContext","useModal","ModalProvider","isOpen","setIsOpen","modalUrl","setModalUrl","openModal","validatedUrl","closeModal","useEffect","cleanupOpenModal","data","payload","cleanupCloseModal","DEFAULT_DRAWER_POSITION","DrawerContext","useDrawer","DrawerProvider","drawerUrl","setDrawerUrl","position","setPosition","setSize","openDrawer","options","closeDrawer","cleanupOpen","cleanupClose","SonnerContext","SonnerProvider","toast","id","title","description","type","duration","action","cancel","onDismiss","onAutoClose","toastOptions","sonnerToast","cleanupToast","actionSent","cancelSent","cleanupToastUpdate","LayoutProviders","Dialog","DialogPrimitive","DialogPortal","DialogOverlay","DialogContent","onPointerDownOutside","hideCloseButton","hasContent","Children","handlePointerDownOutside","event","DialogTitle","DialogDescription","Drawer","open","onOpenChange","direction","VaulDrawer","DrawerTrigger","DrawerPortal","DrawerOverlay","drawerContentByDirection","DrawerContent","style","pos","isVertical","effectiveSize","sizeStyle","DrawerClose","DrawerTitle","DrawerDescription","Toaster","settings","Sonner","LoadingOverlay","ContentView","pathPrefix","ignoreMessages","navigate","useNavigate","iframeRef","useRef","isInternalNavigation","initialUrl","isLoading","setIsLoading","iframeId","addIframe","removeIframe","cleanup","pathname","search","hash","cleanPathname","newShellPath","urlParts","pathnamePart","queryHashPart","currentPath","newPathParts","normalizedNewPath","_data","timeoutId","iframe","handleLoad","iframeWindow","iframeDoc","script","originalWarn","args","OverlayShell","navigationItems","isDrawerOpen","drawerPosition","drawerSize","i18n","currentLanguage","rawUrl","Fragment","getExternalFaviconUrl","hostname","NavigationContent","location","useLocation","hasAnyIcons","useMemo","isGroup","renderNavItem","isOverlay","isExternal","itemLabel","faviconUrl","iconSrc","iconEl","content","ExternalLinkIcon","linkOrTrigger","Link","groupTitle","SidebarInner","logo","startNav","endItems","resolveLocalizedLabel","BOTTOM_NAV_SLOT_WIDTH","BOTTOM_NAV_GAP","BOTTOM_NAV_PX","BOTTOM_NAV_MAX_SLOTS","isAppIcon","src","BottomNavItem","label","applyIconTheme","baseClass","CaretUpIcon","CaretDownIcon","HomeIcon","MobileBottomNav","items","expanded","setExpanded","navRef","rowWidth","setRowWidth","useLayoutEffect","el","ro","entries","w","rowItems","overflowItems","hasMore","list","contentWidth","slotTotal","computedSlots","totalSlots","slotsForNav","maxInRow","row","rowPaths","i","overflow","renderItem","index","resolveNavLabel","e","DefaultLayoutContent","mobileNavItems","desktopNav","mobileNav","flat","mobileFlat","segment","Outlet","DefaultLayout","appIcon","FullscreenLayout","genId","MIN_WIDTH","MIN_HEIGHT","DEFAULT_WIDTH","DEFAULT_HEIGHT","TASKBAR_HEIGHT","getMaximizedBounds","buildFinalUrl","baseUrl","path","subPath","AppWindow","win","isFocused","onFocus","onClose","onBoundsChange","maxZIndex","zIndex","windowLabel","bounds","setBounds","isMaximized","setIsMaximized","boundsBeforeMaximizeRef","containerRef","dragRef","resizeRef","resizeRafRef","pendingResizeBoundsRef","onResize","onPointerMove","d","dx","dy","onPointerUp","finalBounds","handleTitlePointerDown","handleMaximizeToggle","onResizePointerMove","edge","startX","startY","startBounds","next","newW","newH","pending","onResizePointerUp","handleResizePointerDown","finalUrl","z","RestoreIcon","MaximizeIcon","CloseIcon","StartIcon","getBrowserTimezone","WindowsLayout","_appIcon","_logo","timeZone","startNavItems","endNavItems","windows","setWindows","frontWindowId","setFrontWindowId","startMenuOpen","setStartMenuOpen","now","setNow","startPanelRef","interval","openWindow","icon","closeWindow","current","focusWindow","updateWindowBounds","onDocClick","handleNavClick","n","o","LayoutFallback","AppLayout","layout","effectiveLayout","LayoutComponent","layoutProps","Suspense","HomeView","Breadcrumb","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbPage","BreadcrumbSeparator","PaintbrushIcon","GlobeIcon","CheckIcon","SettingsIcon","CodeIcon","ChevronRightIcon","ChevronLeftIcon","ShieldIcon","RefreshDoubleIcon","PackageIcon","ButtonGroup","child","isValidElement","isFirst","isLast","cloneElement","hexToHsl","hexString","hex","b","rNorm","gNorm","bNorm","max","min","h","s","hDeg","sPercent","lPercent","result","defaultTheme","blueTheme","warmYellowTheme","themeRegistry","registerTheme","theme","getTheme","name","getAllThemes","applyTheme","isDark","root","colors","primaryHsl","head","link","fontFile","fontName","bodyFont","headingFont","bodyShadow","match","rgba","values","opacity","actualPrimary","hslFormat","SunIcon","MoonIcon","MonitorIcon","ThemePreview","isSelected","Appearance","updateSetting","currentTheme","currentThemeName","availableThemes","setAvailableThemes","themeDef","isDarkForPreview","setIsDarkForPreview","updatePreview","mediaQuery","handleChange","modeThemes","Icon","allSupportedLanguages","resources","enCommon","enSettings","enCookieConsent","frCommon","frSettings","frCookieConsent","getInitialLanguage","enabledLanguages","stored","languageCode","isInitialized","initializeI18n","validLangs","supported","finalLangs","initialLang","initReactI18next","getSupportedLanguages","enabledLangs","Select","ClockIcon","TIMEZONE_GROUPS","formatDate","date","timezone","formatTime","getTimezoneDisplayName","timeZoneName","part","LanguageAndRegion","browserTimezone","currentTimezone","isUsingBrowserTimezone","supportedLanguages","handleResetRegion","currentDateTime","setCurrentDateTime","updateDateTime","tz","isBrowserTimezone","wb","updateAvailable","waitingServiceWorker","registrationPromise","statusListeners","isInitialRegistration","eventListenersAdded","toastShownForServiceWorkerId","isIntentionalUpdate","isRegistering","registrationStartTime","REGISTRATION_GRACE_PERIOD","waitingHandler","activatedHandler","controllingHandler","registeredHandler","redundantHandler","serviceWorkerErrorHandler","messageErrorHandler","hasTauriOnWindow","isTauri","swFileExistsCache","swFileExistsCacheTime","SW_FILE_EXISTS_CACHE_TTL","notifyStatusListeners","status","isServiceWorkerRegistered","listener","disableCachingAutomatically","reason","timeSinceRegistrationStart","unregisterServiceWorker","STORAGE_KEY","defaultSettings","serviceWorkerFileExists","response","contentType","isJavaScript","text","looksLikeServiceWorker","registerServiceWorker","retryExists","existingRegistration","waitingSW","isNewWorkbox","Workbox","UPDATE_AVAILABLE_TOAST_ID","isAutoActivating","registration","currentWaitingSW","currentWaitingSWId","actionHandler","updateServiceWorker","swRegistration","evt","isIntentionalUpdatePersisted","shouldReload","wasAutoActivated","hasWaitingAsync","hasInstallingAsync","hasActiveAsync","evtError","errorMessage","errorName","waitingSWId","visibilityHandler","reloadApp","updateControllingHandler","cacheNames","getServiceWorkerStatus","registered","actuallyUpdateAvailable","checkForServiceWorkerUpdate","addStatusListener","l","UpdateApp","setUpdateAvailable","checking","setChecking","showUpToDateInButton","setShowUpToDateInButton","checkError","setCheckError","serviceWorkerEnabled","handleCheckForUpdate","resolve","version","Switch","checked","onCheckedChange","getConfig","raw","getStoredCookieConsent","parsed","getCookieConsentAccepted","host","c","acceptedHosts","getCookieConsentNeedsRenewal","consentedCookieHosts","currentHosts","getCookieConsentNewHosts","consentedSet","SETTINGS_KEY","sentryLoaded","isErrorReportingEnabled","initSentry","dsn","Sentry","closeSentry","Advanced","resetAllData","errorReportingConfigured","handleErrorReportingChange","handleResetClick","ToastTestButtons","toastId","DialogTestButtons","ModalTestButtons","urls","DrawerTestButtons","Develop","navItems","self","layoutMode","DataPrivacy","cookies","hasCookieConsent","hasConsented","allHosts","strictNecessaryHosts","acceptedAll","rejectedAll","isCustom","handleResetCookieConsent","ServiceWorker","isRegistered","setIsRegistered","swFileExists","setSwFileExists","initialCheck","exists","refreshStatus","unsubscribe","handleToggleServiceWorker","enabled","currentEnabled","handleUpdateNow","handleResetToLatest","createSettingsRoutes","SettingsView","isTauriEnv","setIsTauriEnv","tid","settingsLabel","settingsRoutes","routesWithoutTauriSw","route","filteredRoutes","groupedRoutes","developerOnlyPaths","getSelectedItemFromUrl","normalizedPathname","normalizedItemPath","selectedItem","isSettingsRoot","normalizedSettingsPath","settingsPathWithSlash","handleBackToSettings","itemIndex","Routes","Route","Navigate","CATEGORY_ORDER","formatDuration","seconds","CookiePreferencesView","isInitialConsent","currentAcceptedHosts","localAcceptedHosts","setLocalAcceptedHosts","actionClickedRef","handleDrawerClose","cookiesByCategory","grouped","cookie","existing","toggleCookie","toggleCategory","category","categoryHosts","hostsSet","getCategoryState","enabledCount","handleAcceptAll","handleRejectAll","handleSave","hostsToSave","hasChanges","sortedLocal","sortedCurrent","categoryCookies","categoryState","isStrictNecessary","isEnabled","ViewRoute","NotFoundView","handleNavigate","RouteFallback","createRoutes","routes","layoutRoute","createAppRouter","createBrowserRouter","resolveLabel","buildSettingsWithNavigation","SettingsProvider","settingsRef","setSettings","initialSettings","newSettings","settingsToPropagate","cleanupSettingsRequested","currentSettings","settingsWithNav","cleanupSettings","updateSettings","updates","key","currentValue","mergedValue","keysToRemove","applyThemeToDocument","useTheme","themeName","effectiveThemeName","themeDefinition","ThemeProvider","I18nProvider","AlertDialog","AlertDialogPrimitive","AlertDialogPortal","AlertDialogOverlay","alertDialogContentVariants","AlertDialogContent","AlertDialogHeader","AlertDialogMedia","AlertDialogFooter","AlertDialogTitle","AlertDialogDescription","AlertDialogAction","AlertDialogCancel","DIALOG_EXIT_ANIMATION_MS","TrashIcon","CookieIcon","DialogContext","useDialog","DialogProvider","dialogState","setDialogState","unmountTimeoutRef","scheduleUnmount","handleOpenChange","handleOk","handleCancel","handleSecondary","dialog","dialogId","cleanupDialog","cleanupDialogUpdate","renderButtons","mode","okLabel","cancelLabel","secondaryButton","renderCookieConsentDialog","CookieConsentModal","showDialog","closedByChoiceRef","dialogShownRef","consentedHosts","hasNewCookies","neverConsented","isRenewal","shouldShow","saveAccept","saveReject","handleAccept","handleReject","handleSetPreferences","AppContent","router","RouterProvider","App","useCookieConsent","isAccepted","needsConsent"],"mappings":"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"}