{"version":3,"file":"ssrUtils-Ca211nnK.mjs","names":["getBrowserValue: () => T","fallbackValue: T | null","key: string","value: string","selector: string","element: Element | Window | Document | null","event: string","handler: EventListener","options?: AddEventListenerOptions","options?: EventListenerOptions","query: string","event: MediaQueryListEvent"],"sources":["../../src/utils/ssrUtils.ts"],"sourcesContent":["/**\n * SSR (Server-Side Rendering) Utilities\n *\n * Utilities for handling server-side rendering compatibility and hydration safety.\n * These utilities help prevent client-server mismatch errors and ensure components\n * work correctly in SSR environments like Next.js, Gatsby, and Remix.\n */\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Check if code is running in a browser environment\n */\nexport const isBrowser = (): boolean => {\n  return typeof window !== 'undefined' && typeof document !== 'undefined';\n};\n\n/**\n * Check if code is running on the server\n */\nexport const isServer = (): boolean => {\n  return !isBrowser();\n};\n\n/**\n * Safe access to window object\n */\nexport const safeWindow = (): Window | null => {\n  return isBrowser() ? window : null;\n};\n\n/**\n * Safe access to document object\n */\nexport const safeDocument = (): Document | null => {\n  return isBrowser() ? document : null;\n};\n\n/**\n * Hook to detect when component has hydrated on the client\n * This prevents hydration mismatches by ensuring client-only code\n * only runs after hydration is complete.\n */\nexport const useIsClient = (): boolean => {\n  const [isClient, setIsClient] = useState(false);\n\n  useEffect(() => {\n    setIsClient(true);\n  }, []);\n\n  return isClient;\n};\n\n/**\n * Hook to safely access browser APIs after hydration\n * Returns null during SSR and initial render, then the actual value after hydration\n */\nexport const useSafeBrowserAPI = <T>(\n  getBrowserValue: () => T,\n  fallbackValue: T | null = null\n): T | null => {\n  const isClient = useIsClient();\n  const [value, setValue] = useState<T | null>(fallbackValue);\n\n  useEffect(() => {\n    if (isClient) {\n      try {\n        setValue(getBrowserValue());\n      } catch (error) {\n        console.warn('Error accessing browser API:', error);\n        setValue(fallbackValue);\n      }\n    }\n  }, [isClient, getBrowserValue, fallbackValue]);\n\n  return isClient ? value : fallbackValue;\n};\n\n/**\n * SSR-safe localStorage access\n */\nexport const safeLocalStorage = {\n  getItem: (key: string): string | null => {\n    if (!isBrowser()) return null;\n    try {\n      return localStorage.getItem(key);\n    } catch (error) {\n      console.warn('Error accessing localStorage:', error);\n      return null;\n    }\n  },\n\n  setItem: (key: string, value: string): boolean => {\n    if (!isBrowser()) return false;\n    try {\n      localStorage.setItem(key, value);\n      return true;\n    } catch (error) {\n      console.warn('Error setting localStorage:', error);\n      return false;\n    }\n  },\n\n  removeItem: (key: string): boolean => {\n    if (!isBrowser()) return false;\n    try {\n      localStorage.removeItem(key);\n      return true;\n    } catch (error) {\n      console.warn('Error removing from localStorage:', error);\n      return false;\n    }\n  }\n};\n\n/**\n * SSR-safe sessionStorage access\n */\nexport const safeSessionStorage = {\n  getItem: (key: string): string | null => {\n    if (!isBrowser()) return null;\n    try {\n      return sessionStorage.getItem(key);\n    } catch (error) {\n      console.warn('Error accessing sessionStorage:', error);\n      return null;\n    }\n  },\n\n  setItem: (key: string, value: string): boolean => {\n    if (!isBrowser()) return false;\n    try {\n      sessionStorage.setItem(key, value);\n      return true;\n    } catch (error) {\n      console.warn('Error setting sessionStorage:', error);\n      return false;\n    }\n  },\n\n  removeItem: (key: string): boolean => {\n    if (!isBrowser()) return false;\n    try {\n      sessionStorage.removeItem(key);\n      return true;\n    } catch (error) {\n      console.warn('Error removing from sessionStorage:', error);\n      return false;\n    }\n  }\n};\n\n/**\n * SSR-safe DOM query selector\n */\nexport const safeQuerySelector = (selector: string): Element | null => {\n  if (!isBrowser()) return null;\n  try {\n    return document.querySelector(selector);\n  } catch (error) {\n    console.warn('Error querying DOM:', error);\n    return null;\n  }\n};\n\n/**\n * SSR-safe DOM query selector all\n */\nexport const safeQuerySelectorAll = (selector: string): NodeListOf<Element> | null => {\n  if (!isBrowser()) return null;\n  try {\n    return document.querySelectorAll(selector);\n  } catch (error) {\n    console.warn('Error querying DOM:', error);\n    return null;\n  }\n};\n\n/**\n * SSR-safe event listener management\n */\nexport const safeEventListener = {\n  add: (\n    element: Element | Window | Document | null,\n    event: string,\n    handler: EventListener,\n    options?: AddEventListenerOptions\n  ): boolean => {\n    if (!isBrowser() || !element) return false;\n    try {\n      element.addEventListener(event, handler, options);\n      return true;\n    } catch (error) {\n      console.warn('Error adding event listener:', error);\n      return false;\n    }\n  },\n\n  remove: (\n    element: Element | Window | Document | null,\n    event: string,\n    handler: EventListener,\n    options?: EventListenerOptions\n  ): boolean => {\n    if (!isBrowser() || !element) return false;\n    try {\n      element.removeEventListener(event, handler, options);\n      return true;\n    } catch (error) {\n      console.warn('Error removing event listener:', error);\n      return false;\n    }\n  }\n};\n\n/**\n * SSR-safe viewport dimensions\n */\nexport const useViewportDimensions = () => {\n  const [dimensions, setDimensions] = useState({\n    width: 1024, // Default fallback values\n    height: 768\n  });\n\n  useEffect(() => {\n    if (!isBrowser()) return;\n\n    const updateDimensions = () => {\n      setDimensions({\n        width: window.innerWidth,\n        height: window.innerHeight\n      });\n    };\n\n    // Set initial dimensions\n    updateDimensions();\n\n    // Listen for resize events\n    window.addEventListener('resize', updateDimensions);\n\n    return () => {\n      window.removeEventListener('resize', updateDimensions);\n    };\n  }, []);\n\n  return dimensions;\n};\n\n/**\n * SSR-safe media query hook\n */\nexport const useMediaQuery = (query: string): boolean => {\n  const [matches, setMatches] = useState(false);\n\n  useEffect(() => {\n    if (!isBrowser()) return;\n\n    const mediaQuery = window.matchMedia(query);\n    setMatches(mediaQuery.matches);\n\n    const handler = (event: MediaQueryListEvent) => {\n      setMatches(event.matches);\n    };\n\n    mediaQuery.addEventListener('change', handler);\n\n    return () => {\n      mediaQuery.removeEventListener('change', handler);\n    };\n  }, [query]);\n\n  return matches;\n};\n\n/**\n * SSR-safe user agent detection\n */\nexport const useUserAgent = () => {\n  const [userAgent, setUserAgent] = useState('');\n\n  useEffect(() => {\n    if (isBrowser()) {\n      setUserAgent(navigator.userAgent);\n    }\n  }, []);\n\n  return userAgent;\n};\n\n/**\n * Detect mobile devices\n */\nexport const useIsMobile = (): boolean => {\n  const userAgent = useUserAgent();\n  const isSmallScreen = useMediaQuery('(max-width: 768px)');\n\n  const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);\n\n  return isMobileUA || isSmallScreen;\n};\n\n/**\n * Detect touch support\n */\nexport const useHasTouchSupport = (): boolean => {\n  const [hasTouch, setHasTouch] = useState(false);\n\n  useEffect(() => {\n    if (isBrowser()) {\n      setHasTouch(\n        'ontouchstart' in window ||\n        navigator.maxTouchPoints > 0 ||\n        // @ts-ignore - for older browsers\n        navigator.msMaxTouchPoints > 0\n      );\n    }\n  }, []);\n\n  return hasTouch;\n};\n"],"mappings":";;;;;;;AAaA,MAAa,YAAY,MAAe;AACtC,eAAc,WAAW,sBAAsB,aAAa;AAC7D;;;;AAKD,MAAa,WAAW,MAAe;AACrC,SAAQ,WAAW;AACpB;;;;AAKD,MAAa,aAAa,MAAqB;AAC7C,QAAO,WAAW,GAAG,SAAS;AAC/B;;;;AAKD,MAAa,eAAe,MAAuB;AACjD,QAAO,WAAW,GAAG,WAAW;AACjC;;;;;;AAOD,MAAa,cAAc,MAAe;CACxC,MAAM,CAAC,UAAU,YAAY,GAAG,SAAS,MAAM;AAE/C,WAAU,MAAM;AACd,cAAY,KAAK;CAClB,GAAE,CAAE,EAAC;AAEN,QAAO;AACR;;;;;AAMD,MAAa,oBAAoB,CAC/BA,iBACAC,gBAA0B,SACb;CACb,MAAM,WAAW,aAAa;CAC9B,MAAM,CAAC,OAAO,SAAS,GAAG,SAAmB,cAAc;AAE3D,WAAU,MAAM;AACd,MAAI,SACF,KAAI;AACF,YAAS,iBAAiB,CAAC;EAC5B,SAAQ,OAAO;AACd,WAAQ,KAAK,gCAAgC,MAAM;AACnD,YAAS,cAAc;EACxB;CAEJ,GAAE;EAAC;EAAU;EAAiB;CAAc,EAAC;AAE9C,QAAO,WAAW,QAAQ;AAC3B;;;;AAKD,MAAa,mBAAmB;CAC9B,SAAS,CAACC,QAA+B;AACvC,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,UAAO,aAAa,QAAQ,IAAI;EACjC,SAAQ,OAAO;AACd,WAAQ,KAAK,iCAAiC,MAAM;AACpD,UAAO;EACR;CACF;CAED,SAAS,CAACA,KAAaC,UAA2B;AAChD,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,gBAAa,QAAQ,KAAK,MAAM;AAChC,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,+BAA+B,MAAM;AAClD,UAAO;EACR;CACF;CAED,YAAY,CAACD,QAAyB;AACpC,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,gBAAa,WAAW,IAAI;AAC5B,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,qCAAqC,MAAM;AACxD,UAAO;EACR;CACF;AACF;;;;AAKD,MAAa,qBAAqB;CAChC,SAAS,CAACA,QAA+B;AACvC,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,UAAO,eAAe,QAAQ,IAAI;EACnC,SAAQ,OAAO;AACd,WAAQ,KAAK,mCAAmC,MAAM;AACtD,UAAO;EACR;CACF;CAED,SAAS,CAACA,KAAaC,UAA2B;AAChD,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,kBAAe,QAAQ,KAAK,MAAM;AAClC,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,iCAAiC,MAAM;AACpD,UAAO;EACR;CACF;CAED,YAAY,CAACD,QAAyB;AACpC,OAAK,WAAW,CAAE,QAAO;AACzB,MAAI;AACF,kBAAe,WAAW,IAAI;AAC9B,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,uCAAuC,MAAM;AAC1D,UAAO;EACR;CACF;AACF;;;;AAKD,MAAa,oBAAoB,CAACE,aAAqC;AACrE,MAAK,WAAW,CAAE,QAAO;AACzB,KAAI;AACF,SAAO,SAAS,cAAc,SAAS;CACxC,SAAQ,OAAO;AACd,UAAQ,KAAK,uBAAuB,MAAM;AAC1C,SAAO;CACR;AACF;;;;AAKD,MAAa,uBAAuB,CAACA,aAAiD;AACpF,MAAK,WAAW,CAAE,QAAO;AACzB,KAAI;AACF,SAAO,SAAS,iBAAiB,SAAS;CAC3C,SAAQ,OAAO;AACd,UAAQ,KAAK,uBAAuB,MAAM;AAC1C,SAAO;CACR;AACF;;;;AAKD,MAAa,oBAAoB;CAC/B,KAAK,CACHC,SACAC,OACAC,SACAC,YACY;AACZ,OAAK,WAAW,KAAK,QAAS,QAAO;AACrC,MAAI;AACF,WAAQ,iBAAiB,OAAO,SAAS,QAAQ;AACjD,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,gCAAgC,MAAM;AACnD,UAAO;EACR;CACF;CAED,QAAQ,CACNH,SACAC,OACAC,SACAE,YACY;AACZ,OAAK,WAAW,KAAK,QAAS,QAAO;AACrC,MAAI;AACF,WAAQ,oBAAoB,OAAO,SAAS,QAAQ;AACpD,UAAO;EACR,SAAQ,OAAO;AACd,WAAQ,KAAK,kCAAkC,MAAM;AACrD,UAAO;EACR;CACF;AACF;;;;AAKD,MAAa,wBAAwB,MAAM;CACzC,MAAM,CAAC,YAAY,cAAc,GAAG,SAAS;EAC3C,OAAO;EACP,QAAQ;CACT,EAAC;AAEF,WAAU,MAAM;AACd,OAAK,WAAW,CAAE;EAElB,MAAM,mBAAmB,MAAM;AAC7B,iBAAc;IACZ,OAAO,OAAO;IACd,QAAQ,OAAO;GAChB,EAAC;EACH;AAGD,oBAAkB;AAGlB,SAAO,iBAAiB,UAAU,iBAAiB;AAEnD,SAAO,MAAM;AACX,UAAO,oBAAoB,UAAU,iBAAiB;EACvD;CACF,GAAE,CAAE,EAAC;AAEN,QAAO;AACR;;;;AAKD,MAAa,gBAAgB,CAACC,UAA2B;CACvD,MAAM,CAAC,SAAS,WAAW,GAAG,SAAS,MAAM;AAE7C,WAAU,MAAM;AACd,OAAK,WAAW,CAAE;EAElB,MAAM,aAAa,OAAO,WAAW,MAAM;AAC3C,aAAW,WAAW,QAAQ;EAE9B,MAAM,UAAU,CAACC,UAA+B;AAC9C,cAAW,MAAM,QAAQ;EAC1B;AAED,aAAW,iBAAiB,UAAU,QAAQ;AAE9C,SAAO,MAAM;AACX,cAAW,oBAAoB,UAAU,QAAQ;EAClD;CACF,GAAE,CAAC,KAAM,EAAC;AAEX,QAAO;AACR;;;;AAKD,MAAa,eAAe,MAAM;CAChC,MAAM,CAAC,WAAW,aAAa,GAAG,SAAS,GAAG;AAE9C,WAAU,MAAM;AACd,MAAI,WAAW,CACb,cAAa,UAAU,UAAU;CAEpC,GAAE,CAAE,EAAC;AAEN,QAAO;AACR;;;;AAKD,MAAa,cAAc,MAAe;CACxC,MAAM,YAAY,cAAc;CAChC,MAAM,gBAAgB,cAAc,qBAAqB;CAEzD,MAAM,aAAa,iEAAiE,KAAK,UAAU;AAEnG,QAAO,cAAc;AACtB;;;;AAKD,MAAa,qBAAqB,MAAe;CAC/C,MAAM,CAAC,UAAU,YAAY,GAAG,SAAS,MAAM;AAE/C,WAAU,MAAM;AACd,MAAI,WAAW,CACb,aACE,kBAAkB,UAClB,UAAU,iBAAiB,KAE3B,UAAU,mBAAmB,EAC9B;CAEJ,GAAE,CAAE,EAAC;AAEN,QAAO;AACR"}