{"version":3,"file":"index.mjs","names":["handle: number | null","rejectPromise: ((reason?: unknown) => void) | null","subscribe","getSnapshot","getServerSnapshot","subscribe","subscribe","getSnapshot","id: number | null","getServerSnapshot","SAFE_AREA_INSET_TEST_ELEMENT: HTMLDivElement | null"],"sources":["../src/hooks/useAbortController.ts","../src/utils/waitForRepaint.ts","../src/hooks/useIsomorphicLayoutEffect.ts","../src/hooks/useMediaQuery.ts","../src/hooks/useCollapsable.ts","../src/hooks/useCurrentTime.tsx","../src/hooks/useInlineCSS.ts","../src/hooks/useInterval.ts","../src/hooks/useIsOnline.ts","../src/hooks/useKonamiCode.ts","../src/hooks/storage.ts","../src/utils/mergeRefs.ts","../src/hooks/useMergedRefs.ts","../src/hooks/usePageVisibility.ts","../src/utils/listeners.ts","../src/utils/css.ts","../src/utils/rafThrottle.ts","../src/hooks/useRafThrottle.ts","../src/hooks/useRect.ts","../src/hooks/usePopup.ts","../src/hooks/usePrevious.ts","../src/hooks/useStableIdentity.ts","../src/hooks/useTimeZone.tsx","../src/hooks/useUpdatingRef.ts","../src/components/ShowWhen/index.tsx","../src/utils/getSafeAreaInsets.ts","../src/utils/getTextWidth.ts","../src/utils/getViewportDimensions.ts","../src/utils/isInViewport.ts","../src/utils/isPwa.ts","../src/utils/measureCSSProperty.ts","../src/utils/svg.ts","../src/utils/createTestIds.ts"],"sourcesContent":["import * as React from \"react\";\n\n/**\n * Custom hook which manages a series of `AbortController`s, aborting the previous when requesting\n * the `next`, and aborting the final controller on unmount\n *\n * e.g.\n *\n * ```typescript\n * const { next } = useAbortController();\n * const onClick = useCallback(() => {\n *   const controller = next();\n *   // all but the latest fetch is aborted, and is also aborted if the component unmounts\n *   fetch(url, { signal: controller.signal }).then(transformAndCheckStatus).then((data) => {\n *     if (controller.signal.aborted) return;\n *     setState(data);\n *   });\n * }, [next]);\n * ```\n */\nexport default function useAbortController() {\n  const ref = React.useRef<AbortController>(undefined);\n\n  React.useEffect(\n    () => () => {\n      ref.current?.abort();\n    },\n    [],\n  );\n\n  const next = React.useCallback(() => {\n    ref.current?.abort();\n    ref.current = new AbortController();\n    return ref.current;\n  }, []);\n\n  return {\n    next,\n    ref,\n  };\n}\n","/**\n * Returns a cancellable promise which resolves after a layout reflow/repaint\n * @param options.signal\n */\nexport default function waitForRepaint({\n  signal,\n}: { signal?: AbortSignal } = {}) {\n  let handle: number | null = null;\n  let rejectPromise: ((reason?: unknown) => void) | null = null;\n\n  const onAbort = () => {\n    if (handle) window.cancelAnimationFrame(handle);\n    rejectPromise?.(new Error(\"Aborted\"));\n    rejectPromise = null;\n  };\n  signal?.addEventListener(\"abort\", onAbort);\n\n  const cancel = () => {\n    if (handle) window.cancelAnimationFrame(handle);\n    rejectPromise?.(new Error(\"waitForRepaint was cancelled\"));\n    rejectPromise = null;\n    signal?.removeEventListener(\"abort\", onAbort);\n  };\n\n  return Object.assign(\n    new Promise<void>((resolve, reject) => {\n      rejectPromise = reject;\n\n      handle = window.requestAnimationFrame(() => {\n        handle = window.requestAnimationFrame(() => {\n          handle = null;\n          rejectPromise = null;\n          resolve();\n        });\n      });\n    }),\n    { cancel },\n  );\n}\n","import * as React from \"react\";\n\n/**\n * Please avoid using this unless it is absolutely required. Most of the time, what you actually want is just\n * `React.useEffect()`, or may be accomplished more correctly with\n * `React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)`.\n *\n * Most of the time `React.useEffect()` should be used if what you need doesn't need to happen before the render is\n * ready for the user, e.g. making a network call.\n *\n * Sometimes, however, you don't want a brief intermediate state shown to the user if the result is available\n * immediately on the client and this is where `React.useLayoutEffect()` is useful. For hydration from SSR, this\n * actually makes no difference (and hence the reason why React recommends you just use `React.useEffect()`), since the\n * intermediate state would be shown anyway before React finishes hydrating.\n *\n * But when moving between pages client side, you want to avoid an intermediate flash which could result after a change\n * in `React.useEffect()`, but not `React.useLayoutEffect()` (which is called synchronously after render). It may also\n * be worth checking whether `React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)` is a better fit\n * for your use case, and would avoid a double render.\n */\nconst useIsomorphicLayoutEffect =\n  typeof window === \"undefined\"\n    ? /* istanbul ignore next */ React.useEffect\n    : React.useLayoutEffect;\n\nexport default useIsomorphicLayoutEffect;\n","import { noop } from \"lodash\";\nimport * as React from \"react\";\n\nexport interface UseMediaQueryOptions {\n  /**\n   * Default for SSR\n   * @default false\n   */\n  defaultMatches?: boolean;\n}\n\n/**\n * Custom hook which returns the result of the provided media `query`, watching for changes\n * @param query `query` passed to `window.matchMedia(query)`\n * @param options\n */\nexport default function useMediaQuery(\n  query: string,\n  { defaultMatches = false }: UseMediaQueryOptions = {},\n): boolean {\n  const subscribe = React.useCallback(\n    (callback: () => void) => {\n      // This branch should only occur in tests\n      if (\n        typeof window === \"undefined\" ||\n        typeof window.matchMedia !== \"function\"\n      ) {\n        return noop;\n      }\n\n      // This is necessary due to a bug in Safari where unsubscribing from a MediaQueryList does not work\n      const controller = new AbortController();\n\n      const onUpdate = () => {\n        /* istanbul ignore if */\n        if (controller.signal.aborted) return;\n        callback();\n      };\n\n      const list = window.matchMedia(query);\n\n      // NOTE: using `addListener` (deprecated) instead of `addEventListener` for Safari <14 support\n      list.addListener(onUpdate);\n\n      return () => {\n        list.removeListener(onUpdate);\n        controller.abort();\n      };\n    },\n    [query],\n  );\n\n  const getSnapshot = React.useCallback(() => {\n    // In React 16 & 17, the `useSyncExternalStore` shim always uses `getSnapshot()`, even on the server\n    if (\n      typeof window === \"undefined\" ||\n      typeof window.matchMedia !== \"function\"\n    ) {\n      return defaultMatches;\n    }\n\n    return window.matchMedia(query).matches;\n  }, [defaultMatches, query]);\n\n  const getServerSnapshot = React.useCallback(\n    () => defaultMatches,\n    [defaultMatches],\n  );\n\n  return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import { timeout } from \"@kablamo/kerosene\";\nimport { noop } from \"lodash\";\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\nimport waitForRepaint from \"../utils/waitForRepaint\";\nimport useIsomorphicLayoutEffect from \"./useIsomorphicLayoutEffect\";\nimport useMediaQuery from \"./useMediaQuery\";\n\nexport interface UseCollapsableReturn {\n  ref: React.RefObject<HTMLElement | null>;\n  /**\n   * Until `HTMLElement.inert` has widespread support, this flag can be used to determine whether to render child elements\n   * of the collapsable container so that they are excluded from the accessibility tree and are not interactable via\n   * keyboard.\n   */\n  render: boolean;\n  /**\n   * Styles to be applied to the collapsable element including:\n   * - `maxHeight`\n   * - `overflow`\n   * - `transitionDuration`\n   * - `transitionProperty`\n   * - `transitionTimingFunction`\n   */\n  style: React.CSSProperties;\n}\n\n/**\n * Custom hook which manages height transitions on the element that `ref` is applied to using `maxHeight`\n * @param open\n * @param options\n */\nexport default function useCollapsable(\n  open: boolean,\n  {\n    immediate = false,\n    transitionDuration: animatedTransitionDuration = 250,\n    transitionTimingFunction = \"ease-in-out\",\n  }: {\n    immediate?: boolean;\n    transitionDuration?: number;\n    transitionTimingFunction?: React.CSSProperties[\"transitionTimingFunction\"];\n  } = {},\n): UseCollapsableReturn {\n  const [render, setRender] = React.useState(open);\n  const [transitionDuration, setTransitionDuration] = React.useState(\n    animatedTransitionDuration,\n  );\n  const [maxHeight, setMaxHeight] = React.useState<number | \"none\">(\n    open ? \"none\" : 0,\n  );\n\n  const ref = React.useRef<HTMLElement>(null);\n\n  const prefersReducedMotion = useMediaQuery(\n    \"(prefers-reduced-motion: reduce)\",\n  );\n  const immediateRef = React.useRef(immediate || prefersReducedMotion);\n  const transitionDurationRef = React.useRef(animatedTransitionDuration);\n  useIsomorphicLayoutEffect(() => {\n    immediateRef.current = immediate || prefersReducedMotion;\n    transitionDurationRef.current = animatedTransitionDuration;\n  }, [animatedTransitionDuration, immediate, prefersReducedMotion]);\n\n  const hasRun = React.useRef(false);\n  useIsomorphicLayoutEffect(() => {\n    const controller = new AbortController();\n\n    if (immediateRef.current || !hasRun.current) {\n      hasRun.current = true;\n      if (open) {\n        setRender(true);\n        setMaxHeight(\"none\");\n      } else {\n        setRender(false);\n        setMaxHeight(0);\n      }\n    } else if (open) {\n      setTransitionDuration(0);\n\n      waitForRepaint({ signal: controller.signal })\n        .then(() =>\n          // NOTE: `ReactDOM.unstable_batchedUpdates(callback)` is required here to ensure async updates are flushed at\n          // the same time as part of the same update.\n          // From React 18, this is no longer required as updates are batched automatically and\n          // `ReactDOM.flushSync(callback)` is opt-in\n          ReactDOM.unstable_batchedUpdates(() => {\n            setTransitionDuration(transitionDurationRef.current);\n            setMaxHeight(0);\n            setRender(true);\n          }),\n        )\n        .then(() => waitForRepaint({ signal: controller.signal }))\n        .then(() => {\n          setMaxHeight(ref.current!.scrollHeight);\n        })\n        .then(() =>\n          timeout(transitionDurationRef.current, { signal: controller.signal }),\n        )\n        .then(() => {\n          setMaxHeight(\"none\");\n        })\n        .catch(noop);\n    } else {\n      setMaxHeight(ref.current!.scrollHeight);\n      setTransitionDuration(transitionDurationRef.current);\n\n      waitForRepaint({ signal: controller.signal })\n        .then(() => {\n          setMaxHeight(0);\n        })\n        .then(() =>\n          timeout(transitionDurationRef.current, { signal: controller.signal }),\n        )\n        .then(() => {\n          setRender(false);\n        })\n        .catch(noop);\n    }\n\n    return controller.abort.bind(controller);\n  }, [open]);\n\n  const style = React.useMemo(\n    () => ({\n      maxHeight,\n      overflow: \"hidden\",\n      transitionProperty: \"max-height\",\n      transitionDuration: `${\n        immediate || prefersReducedMotion ? 0 : transitionDuration\n      }ms`,\n      transitionTimingFunction,\n    }),\n    [\n      immediate,\n      maxHeight,\n      prefersReducedMotion,\n      transitionDuration,\n      transitionTimingFunction,\n    ],\n  );\n\n  return { ref, render, style };\n}\n","import { MINUTE } from \"@kablamo/kerosene\";\nimport * as React from \"react\";\n\ninterface CurrentTimeSubscription {\n  lastUpdatedAt: number;\n  listener: () => void;\n  period: number;\n}\n\nclass CurrentTimeEmitter {\n  private currentTime: number;\n\n  /**\n   * Stores the handler returned by `setInterval`\n   */\n  private interval?: number;\n\n  /**\n   * Stores the current interval period. Set to `Infinity` when no interval is active\n   */\n  private period = Infinity;\n\n  private subscribers: readonly CurrentTimeSubscription[] = [];\n\n  constructor(\n    /**\n     * Stores the time of initial render for SSR. The default here is probably not useful for SSR, so it is strongly\n     * recommended to use `<CurrentTimeProvider />` with an `ssrTime` when using SSR and hydration. But having a default\n     * means that use of the `useCurrentTime()` hook will not crash when using SSR.\n     */\n    private ssrTime = new Date(\"2000-01-01T00:00:00.000Z\").getTime(),\n    /**\n     * Stores the default interval period which will be used if none is specified\n     */\n    private defaultPeriod = MINUTE,\n  ) {\n    this.currentTime = ssrTime;\n  }\n\n  /**\n   * `getSnapshot()` function used by `React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)`\n   */\n  public readonly getCurrentTime = () => this.currentTime;\n\n  /**\n   * `getServerSnapshot()` function used by `React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot)`\n   */\n  public readonly getSsrTime = () => this.ssrTime;\n\n  /**\n   * Updates `this.currentTime` and calls all subscribers which need an update\n   */\n  private update = () => {\n    this.currentTime = Date.now();\n    this.subscribers\n      .filter(\n        ({ period, lastUpdatedAt }) =>\n          // Include subscribers which are within half their interval period of needing an update\n          this.currentTime >= lastUpdatedAt + period / 2,\n      )\n      .forEach((s) => {\n        // eslint-disable-next-line no-param-reassign\n        s.lastUpdatedAt = this.currentTime;\n        s.listener();\n      });\n  };\n\n  /**\n   * Mark all subscribers as requiring an update as soon as the next call to `this.update()`\n   */\n  private markAllForUpdate = () => {\n    // eslint-disable-next-line no-param-reassign\n    this.subscribers.forEach((s) => (s.lastUpdatedAt = 0));\n  };\n\n  /**\n   * Handles `document` `\"visibilitychange\"` events by disabling the interval whilst the document is hidden, and\n   * re-running updates when the page is resumed.\n   */\n  private onVisibilityChange = () => {\n    const { hidden = false } = document;\n\n    if (hidden) {\n      window.clearInterval(this.interval);\n      delete this.interval;\n    } else if (this.subscribers.length) {\n      this.period = Math.min(...this.subscribers.map((s) => s.period))!;\n      this.interval = window.setInterval(this.update, this.period);\n    }\n\n    this.markAllForUpdate();\n    this.update();\n  };\n\n  public readonly subscribe = (\n    listener: () => void,\n    period = this.defaultPeriod,\n  ) => {\n    if (!this.subscribers.length) {\n      // If there were previously no subscribers, start listening to the `\"visibilitychange\"` event\n      document.addEventListener(\"visibilitychange\", this.onVisibilityChange);\n    }\n\n    // If the new period is less than the period of the currently operating interval\n    if (period < this.period) {\n      // Clear the existing interval\n      window.clearInterval(this.interval);\n      // Update to the more frequent period of this subscriber\n      this.period = period;\n      // Create a new interval with the updated period\n      this.interval = window.setInterval(this.update, this.period);\n    }\n\n    // Add the new subscriber\n    this.subscribers = [\n      ...this.subscribers,\n      { listener, period, lastUpdatedAt: 0 },\n    ];\n\n    this.update();\n\n    // Return a function which removes this subscription\n    return () => {\n      // Remove this subscription\n      this.subscribers = this.subscribers.filter(\n        (s) => s.listener !== listener,\n      );\n\n      // If there are no more subscribers after removing this one, we need to cleanup\n      if (!this.subscribers.length) {\n        // Clear the existing interval\n        window.clearInterval(this.interval);\n        delete this.interval;\n\n        // Set the period to indicate that there is no interval\n        this.period = Infinity;\n\n        // Remove the `\"visibilitychange\"` listener\n        document.removeEventListener(\n          \"visibilitychange\",\n          this.onVisibilityChange,\n        );\n      } else {\n        // Find the minimum period of the remaining listeners\n        const newPeriod = Math.min(...this.subscribers.map((s) => s.period));\n\n        // If the interval period needs updating\n        if (newPeriod !== this.period) {\n          // Clear the existing interval\n          window.clearInterval(this.interval);\n          this.period = newPeriod;\n\n          // Create a new interval with the updated period\n          this.interval = window.setInterval(this.update, this.period);\n\n          // Force an update soon, just in case the last interval was about to fire before it was cleared\n          this.markAllForUpdate();\n          // eslint-disable-next-line @typescript-eslint/no-floating-promises\n          Promise.resolve().then(() => this.update());\n        }\n      }\n    };\n  };\n}\n\n// Set up the context with a default `CurrentTimeEmitter` singleton so that the `useCurrentTime()` hook may be used\n// ergonimically without `<CurrentTimeProvider />` when there is no server side rendering\nconst CurrentTimeEmitterContext = React.createContext(new CurrentTimeEmitter());\n\n/**\n * Custom hook which uses a shared `CurrentTimeEmitter` class to listen for time updates in a performant way.\n * Will update at least once every `period` milliseconds whilst the page is visible. Uses only a single interval to\n * avoid overloading the browser when there are a large number of components listening to the time. Whilst this hook\n * will attempt to updates components only as-required, it is not recommended to use this hook for extremely frequent\n * updates (sub 1-second) and for such specific cases, `requestAnimationFrame` should be used instead.\n * @param period Interval period\n * @returns `currentTime`\n */\nexport default function useCurrentTime(period?: number): number {\n  const emitter = React.useContext(CurrentTimeEmitterContext);\n\n  const subscribe = React.useCallback(\n    (callback: () => void) => {\n      return emitter.subscribe(callback, period);\n    },\n    [emitter, period],\n  );\n\n  return React.useSyncExternalStore(\n    subscribe,\n    emitter.getCurrentTime,\n    emitter.getSsrTime,\n  );\n}\n\nexport interface CurrentTimeProviderProps {\n  children?: React.ReactNode;\n  defaultPeriod?: number;\n  ssrTime?: number;\n}\n\n/**\n * Context Provider for the CurrentTimeEmitter used internally by the `useCurrentTime` hook.\n * Recommended for use when using SSR so that on initial render and hydration a consistent and correct time will be used.\n * @param props.children\n * @param props.defaultPeriod\n * @param props.ssrTime Unix epoch milliseconds for initial SSR render\n */\nexport const CurrentTimeProvider = ({\n  children,\n  defaultPeriod,\n  ssrTime,\n}: CurrentTimeProviderProps) => (\n  <CurrentTimeEmitterContext.Provider\n    value={React.useMemo(\n      () => new CurrentTimeEmitter(ssrTime, defaultPeriod),\n      [ssrTime, defaultPeriod],\n    )}\n  >\n    {children}\n  </CurrentTimeEmitterContext.Provider>\n);\n","import type { KeysWhere } from \"@kablamo/kerosene\";\nimport { noop } from \"lodash\";\nimport * as React from \"react\";\nimport useIsomorphicLayoutEffect from \"./useIsomorphicLayoutEffect\";\n\nexport type CSSStylePropertyKey =\n  | KeysWhere<Omit<CSSStyleDeclaration, number>, string>\n  | `--${string}`;\n\nexport interface UseInlineCSSOptions<PropertyKey extends CSSStylePropertyKey> {\n  property: PropertyKey;\n  value?:\n    | (PropertyKey extends keyof React.CSSProperties\n        ? Extract<React.CSSProperties[PropertyKey], string>\n        : string)\n    | null;\n  priority?: \"important\" | \"\";\n}\n\nfunction applyProperty<PropertyKey extends CSSStylePropertyKey>(\n  el: HTMLElement | SVGElement | null,\n  { property, value, priority }: UseInlineCSSOptions<PropertyKey>,\n): () => void {\n  el?.style.setProperty(property, value ?? null, priority);\n\n  return () => {\n    el?.style.removeProperty(property);\n  };\n}\n\n// Silence warnings about potential hydration mismatch when using `useInsertionEffect` on the server as we're only using\n// `useInsertionEffect` when applying inline styles above the hydration root.\nconst useInsertionEffect =\n  typeof window === \"undefined\" ? React.useEffect : React.useInsertionEffect;\n\n/**\n * Custom hook which applies a CSS `property` `value` with `priority` to the element provided in `refOrSelector`\n * @param options.property\n * @param options.value\n * @param options.priority\n * @param refOrSelector\n */\nexport default function useInlineCSS<\n  PropertyKey extends CSSStylePropertyKey,\n  T extends HTMLElement | SVGElement,\n>(\n  { property, value, priority }: UseInlineCSSOptions<PropertyKey>,\n  refOrSelector: React.RefObject<T | null> | \"html\" | \"body\" = \"html\",\n) {\n  // If we're using a selector, we can apply the styles immediately, before rendering\n  useInsertionEffect(() => {\n    if (typeof refOrSelector !== \"string\") return noop;\n\n    return applyProperty(document.querySelector(refOrSelector), {\n      property,\n      value,\n      priority,\n    });\n  }, [priority, property, refOrSelector, value]);\n\n  // If we're using a ref, we apply the styles synchronously, after rendering\n  useIsomorphicLayoutEffect(() => {\n    if (typeof refOrSelector === \"string\") return noop;\n\n    return applyProperty(refOrSelector.current, { property, value, priority });\n  }, [priority, property, refOrSelector, value]);\n}\n","import { noop } from \"lodash\";\nimport * as React from \"react\";\n\n/**\n * Custom React Hook that makes `setInterval` work declaratively with hooks\n * @see https://overreacted.io/making-setinterval-declarative-with-react-hooks/\n *\n * @param callback\n * @param delay\n */\nexport default function useInterval(\n  callback: () => void,\n  delay: number | null,\n) {\n  const savedCallback = React.useRef(callback);\n\n  // Remember the latest callback.\n  React.useEffect(() => {\n    savedCallback.current = callback;\n  });\n\n  // Set up the interval.\n  React.useEffect(() => {\n    const tick = () => {\n      savedCallback.current();\n    };\n\n    if (delay !== null) {\n      const id = setInterval(tick, delay);\n      return () => clearInterval(id);\n    }\n\n    return noop;\n  }, [delay]);\n}\n","import * as React from \"react\";\n\nfunction getSnapshot() {\n  return navigator.onLine;\n}\n\nfunction getServerSnapshot() {\n  return true;\n}\n\nfunction subscribe(callback: () => void) {\n  window.addEventListener(\"online\", callback);\n  window.addEventListener(\"offline\", callback);\n  return () => {\n    window.removeEventListener(\"online\", callback);\n    window.removeEventListener(\"offline\", callback);\n  };\n}\n\n/**\n * Custom hook which returns the current value of `navigator.onLine`, watching for changes via the\n * `\"online\"` and `\"offline\"` events\n */\nexport default function useIsOnline() {\n  return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n","import { isEqual } from \"lodash\";\nimport * as React from \"react\";\n\n/**\n * Creates a hook that will call the callback when the `code` is entered\n *\n * Note: If the `code` only contains basic keys it can be supplied as a string. For keys that do not have a single\n * character representation, `KeyboardEvent#key` values may be specified in an array\n * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values\n *\n * @param code\n * @param callback\n */\nexport default function useKonamiCode(\n  code: string | readonly string[],\n  callback: () => void,\n) {\n  const pressed = React.useRef([] as string[]);\n\n  React.useEffect(() => {\n    const onKeyDown = (e: KeyboardEvent) => {\n      pressed.current.push(e.key);\n      while (pressed.current.length > code.length) pressed.current.shift();\n      if (isEqual(pressed.current, [...code])) callback();\n    };\n\n    window.addEventListener(\"keydown\", onKeyDown, false);\n\n    return () => window.removeEventListener(\"keydown\", onKeyDown, false);\n  }, [code, callback]);\n}\n","import { isEqual } from \"lodash\";\nimport * as React from \"react\";\nimport { useSyncExternalStoreWithSelector } from \"use-sync-external-store/shim/with-selector\";\n\nconst CUSTOM_STORAGE_EVENT_NAME = \"@kablamo/kerosene-ui/storage\";\n\nexport interface CustomStorageEventInit {\n  readonly key: string | null;\n  readonly newValue: string | null;\n  readonly oldValue: string | null;\n  readonly storageArea: Storage | null;\n  readonly url: string;\n}\n\ndeclare global {\n  interface WindowEventMap {\n    [CUSTOM_STORAGE_EVENT_NAME]: CustomEvent<CustomStorageEventInit>;\n  }\n}\n\nconst getServerSnapshot = () => null;\n\nfunction createUseStorage(storageArea: \"localStorage\" | \"sessionStorage\") {\n  return <T>(\n    key: string,\n    defaultValue: T,\n    isT: (value: unknown) => value is T,\n  ) => {\n    const subscribe = React.useCallback(\n      (callback: () => void) => {\n        const onCustomStorageEvent = (\n          e: CustomEvent<CustomStorageEventInit>,\n        ) => {\n          if (\n            e.detail.storageArea !== window[storageArea] ||\n            e.detail.key !== key\n          )\n            return;\n          callback();\n        };\n\n        const onStorageEvent = (e: StorageEvent) => {\n          if (e.storageArea !== window[storageArea] || e.key !== key) return;\n          callback();\n        };\n\n        window.addEventListener(\n          CUSTOM_STORAGE_EVENT_NAME,\n          onCustomStorageEvent,\n        );\n        window.addEventListener(\"storage\", onStorageEvent);\n        return () => {\n          window.removeEventListener(\n            CUSTOM_STORAGE_EVENT_NAME,\n            onCustomStorageEvent,\n          );\n          window.removeEventListener(\"storage\", onStorageEvent);\n        };\n      },\n      [key],\n    );\n\n    const getSnapshot = React.useCallback(() => {\n      // In React 16 & 17, the `useSyncExternalStore` shim always uses `getSnapshot()`, even on the server\n      if (\n        typeof window === \"undefined\" ||\n        typeof window[storageArea] === \"undefined\"\n      ) {\n        return null;\n      }\n\n      return window[storageArea].getItem(key);\n    }, [key]);\n\n    const selector = React.useCallback(\n      (stored: string | null) => {\n        try {\n          const parsed = stored\n            ? (JSON.parse(stored) as unknown)\n            : defaultValue;\n          return isT(parsed) ? parsed : defaultValue;\n        } catch {\n          return defaultValue;\n        }\n      },\n      [defaultValue, isT],\n    );\n\n    const state = useSyncExternalStoreWithSelector(\n      subscribe,\n      getSnapshot,\n      getServerSnapshot,\n      selector,\n      isEqual,\n    );\n\n    const setValue = React.useCallback(\n      (value: React.SetStateAction<T>) => {\n        const oldValue = getSnapshot();\n        const newValue = JSON.stringify(\n          // @ts-expect-error TS2349 because TS doesn't curently have a way to indicate type T cannot be a function\n          typeof value === \"function\" ? value(selector(oldValue)) : value,\n        );\n\n        window[storageArea].setItem(key, newValue);\n        window.dispatchEvent(\n          new CustomEvent<CustomStorageEventInit>(CUSTOM_STORAGE_EVENT_NAME, {\n            cancelable: false,\n            detail: {\n              key,\n              newValue,\n              oldValue,\n              storageArea: window[storageArea],\n              url: window.location.href,\n            },\n          }),\n        );\n      },\n      [getSnapshot, key, selector],\n    );\n\n    return [state, setValue] as const;\n  };\n}\n\n/**\n * Custom hook which allows reading/writing of `localStorage` in a manner similar to `React.useState`\n * @param key localStorage key\n * @param defaultValue Value used when `localStorage` contains an empty or invalid value\n * @param isT Type guard function which checks that the parsed value from `localStorage` is of type `T`\n */\nexport const useLocalStorage = createUseStorage(\"localStorage\");\n\n/**\n * Custom hook which allows reading/writing of `sessionStorage` in a manner similar to `React.useState`\n * @param key sessionStorage key\n * @param defaultValue Value used when `sessionStorage` contains an empty or invalid value\n * @param isT Type guard function which checks that the parsed value from `sessionStorage` is of type `T`\n */\nexport const useSessionStorage = createUseStorage(\"sessionStorage\");\n","import type { Mutable } from \"@kablamo/kerosene\";\n\n/**\n * Returns a new callback ref that effectively merges all provided `refs`\n *\n * Note: React 19 callback refs with cleanup are not supported as this is impossible without library support.\n * @see https://github.com/facebook/react/issues/29757\n *\n * @param refs\n */\nexport default function mergeRefs<T>(\n  ...refs: Array<React.Ref<T> | undefined>\n): React.RefCallback<T> {\n  return (instance: T | null) => {\n    refs.forEach((ref) => {\n      if (typeof ref === \"function\") {\n        const result = ref(instance);\n\n        if (typeof result === \"function\") {\n          throw new Error(\n            \"mergeRefs() does not support callback refs with cleanup. See https://github.com/facebook/react/issues/29757\",\n          );\n        }\n      } else if (ref) {\n        // eslint-disable-next-line no-param-reassign\n        (ref as Mutable<typeof ref>).current = instance;\n      }\n    });\n  };\n}\n","import * as React from \"react\";\nimport mergeRefs from \"../utils/mergeRefs\";\n\n/**\n * Custom hook which creates a new callback ref that effectively merges all provided `refs`.\n *\n * Note: React 19 callback refs with cleanup are not supported as this is impossible without library support.\n * @see https://github.com/facebook/react/issues/29757\n *\n * @param refs\n */\nexport default function useMergedRefs<T>(\n  ...refs: Array<React.Ref<T> | undefined>\n): React.RefCallback<T> {\n  // eslint-disable-next-line react-hooks/exhaustive-deps\n  return React.useCallback(mergeRefs(...refs), refs);\n}\n","import * as React from \"react\";\n\nconst getServerSnapshot = () => true;\n\nexport default function usePageVisibility(\n  useState?: true,\n): [boolean, React.RefObject<boolean>];\n\nexport default function usePageVisibility(\n  useState: false,\n): React.RefObject<boolean>;\n\n/**\n * Custom React Hook which listens to the page visibility API and provides a ref\n * @param [useState] Whether or not to use state (default) or ref for the current visibility\n * @returns If `useState` is `true` (or not set) a 2-tuple containing a boolean and a ref, otherwise just a ref\n */\nexport default function usePageVisibility(\n  useState = true,\n): [boolean, React.RefObject<boolean>] | React.RefObject<boolean> {\n  const visibility = React.useRef(true);\n\n  const subscribe = React.useCallback((callback: () => void) => {\n    document.addEventListener(\"visibilitychange\", callback);\n\n    return () => document.removeEventListener(\"visibilitychange\", callback);\n  }, []);\n\n  const getSnapshot = React.useCallback(() => {\n    // In React 16 & 17, the `useSyncExternalStore` shim always uses `getSnapshot()`, even on the server\n    /* istanbul ignore if */\n    if (typeof document === \"undefined\") return true;\n\n    const { hidden = false } = document;\n\n    visibility.current = !hidden;\n    // Always returning true when not using state to prevent component updates\n    return useState ? visibility.current : true;\n  }, [useState]);\n\n  const visible = React.useSyncExternalStore(\n    subscribe,\n    getSnapshot,\n    getServerSnapshot,\n  );\n\n  return useState ? [visible, visibility] : visibility;\n}\n","import { noop } from \"lodash\";\n\n/**\n * @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support\n */\nlet isPassiveSupported = false;\nlet isCapturePassiveSupported = false;\n\ntry {\n  const options = {\n    get passive() {\n      isPassiveSupported = true;\n      return true;\n    },\n  };\n  window.addEventListener(\"test\", noop, options);\n  window.removeEventListener(\"test\", noop, {});\n} catch /* istanbul ignore next */ {\n  isPassiveSupported = false;\n}\n\ntry {\n  const options = {\n    get capture() {\n      isCapturePassiveSupported = isPassiveSupported;\n      return true;\n    },\n    passive: true,\n  };\n  window.addEventListener(\"test\", noop, options);\n  window.removeEventListener(\"test\", noop, { capture: true });\n} catch /* istanbul ignore next */ {\n  isCapturePassiveSupported = false;\n}\n\nexport const ADD_EVENT_LISTENER_PASSIVE_OPTIONS = isPassiveSupported\n  ? ({ passive: true } as const)\n  : /* istanbul ignore next */ false;\nexport const REMOVE_EVENT_LISTENER_PASSIVE_OPTIONS = isPassiveSupported\n  ? ({} as const)\n  : /* istanbul ignore next */ false;\n\nexport const ADD_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS =\n  isCapturePassiveSupported\n    ? ({\n        capture: true,\n        passive: true,\n      } as const)\n    : /* istanbul ignore next */ true;\nexport const REMOVE_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS =\n  isCapturePassiveSupported\n    ? ({\n        capture: true,\n      } as const)\n    : /* istanbul ignore next */ true;\n","/* eslint-disable import/prefer-default-export */\n\nexport const SIDES = [\"top\", \"right\", \"bottom\", \"left\"] as const;\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * Throttles the provided `callback` with `window.requestAnimationFrame`\n * @param callback\n */\nexport default function rafThrottle<T extends any[]>(\n  callback: (...args: T) => void,\n) {\n  let id: number | null = null;\n\n  const deferred =\n    (...args: T) =>\n    () => {\n      id = null;\n      callback(...args);\n    };\n\n  return Object.assign(\n    (...args: T) => {\n      if (!id) {\n        id = window.requestAnimationFrame(deferred(...args));\n      }\n    },\n    {\n      cancel: () => {\n        if (id) {\n          window.cancelAnimationFrame(id);\n          id = null;\n        }\n      },\n    },\n  );\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport * as React from \"react\";\nimport rafThrottle from \"../utils/rafThrottle\";\n\n/**\n * Custom hook for throttling a callback with `requestAnimationFrame`.\n * `cancelAnimationFrame` will automatically be called on component unmount.\n *\n * @param callback\n */\nexport default function useRafThrottle<T extends any[]>(\n  callback: (...args: T) => void,\n) {\n  const cb = React.useRef(callback);\n\n  React.useEffect(() => {\n    cb.current = callback;\n  }, [callback]);\n\n  const throttled = React.useMemo(\n    () => rafThrottle((...args: T) => cb.current(...args)),\n    [],\n  );\n\n  React.useEffect(() => () => throttled.cancel(), [throttled]);\n\n  return throttled;\n}\n","import type { ElementType } from \"@kablamo/kerosene\";\nimport { isEqual, pick } from \"lodash\";\nimport * as React from \"react\";\nimport { SIDES } from \"../utils/css\";\nimport {\n  ADD_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS,\n  REMOVE_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS,\n} from \"../utils/listeners\";\nimport useIsomorphicLayoutEffect from \"./useIsomorphicLayoutEffect\";\nimport useRafThrottle from \"./useRafThrottle\";\n\ntype Rect = { [side in ElementType<typeof SIDES>]: number };\n\ntype ScrollPosition = {\n  scrollX: number;\n  scrollY: number;\n};\n\nconst DEFAULT_RECT: Rect = {\n  top: 0,\n  right: 0,\n  bottom: 0,\n  left: 0,\n};\n\n/**\n * Custom React Hook for reading bounding rect of a DOM Element\n * @param disable When set to `true`, updating the rect will be disabled\n * @param eventList Listens for specified event types and triggers update\n */\nexport default function useRect(\n  disable = false,\n  eventList: ReadonlyArray<keyof WindowEventMap> = [],\n): [React.RefObject<Element | null>, Rect, ScrollPosition] {\n  const ref = React.useRef<Element | null>(null);\n  const [rect, setRect] = React.useState(DEFAULT_RECT);\n  const [scroll, setScroll] = React.useState<ScrollPosition>({\n    scrollX: 0,\n    scrollY: 0,\n  });\n  const events = React.useMemo<ReadonlyArray<keyof WindowEventMap>>(\n    () => [\"scroll\", ...eventList],\n    [eventList],\n  );\n\n  const update = useRafThrottle(() => {\n    const newRect = ref.current\n      ? pick(ref.current.getBoundingClientRect(), SIDES)\n      : DEFAULT_RECT;\n    if (!isEqual(rect, newRect)) setRect(newRect);\n\n    const newScroll = {\n      scrollX: window.pageXOffset,\n      scrollY: window.pageYOffset,\n    };\n    if (!isEqual(scroll, newScroll)) setScroll(newScroll);\n  });\n\n  useIsomorphicLayoutEffect(() => {\n    if (!disable) update();\n  });\n\n  React.useEffect(() => {\n    if (!disable) {\n      window.addEventListener(\"resize\", update);\n      events.forEach((event) =>\n        window.addEventListener(\n          event,\n          update,\n          ADD_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS,\n        ),\n      );\n    }\n\n    return () => {\n      window.removeEventListener(\"resize\", update);\n      events.forEach((event) =>\n        window.removeEventListener(\n          event,\n          update,\n          REMOVE_EVENT_LISTENER_CAPTURE_PASSIVE_OPTIONS,\n        ),\n      );\n    };\n  }, [disable, update, events]);\n\n  return [ref, rect, scroll];\n}\n","import type { Mutable } from \"@kablamo/kerosene\";\nimport * as React from \"react\";\nimport {\n  ADD_EVENT_LISTENER_PASSIVE_OPTIONS,\n  REMOVE_EVENT_LISTENER_PASSIVE_OPTIONS,\n} from \"../utils/listeners\";\nimport useIsomorphicLayoutEffect from \"./useIsomorphicLayoutEffect\";\nimport useRect from \"./useRect\";\n\n/**\n * Custom Hook for a popup portal\n * @param zIndex\n * @param inside List of refs that are considered _inside_ the popup - useful for portals\n */\nexport default function usePopup(\n  zIndex: string | null = null,\n  inside: readonly React.RefObject<HTMLElement>[] = [],\n) {\n  const [open, setOpen] = React.useState(false);\n\n  const [ref, rect, scroll] = useRect(!open);\n\n  const portalEl = React.useRef<HTMLDivElement>(null);\n  useIsomorphicLayoutEffect(() => {\n    const el = document.createElement(\"div\");\n    Object.assign(el.style, {\n      position: \"absolute\",\n      top: \"0px\",\n      left: \"0px\",\n      bottom: \"0px\",\n      right: \"0px\",\n      overflow: \"visible\",\n      pointerEvents: \"none\",\n      zIndex,\n    });\n    document.body.appendChild(el);\n    (portalEl as Mutable<typeof portalEl>).current = el;\n\n    return () => el.remove();\n  }, [zIndex]);\n\n  React.useEffect(() => {\n    const onClickOutside = (e: MouseEvent) => {\n      const { target } = e;\n      const isInside =\n        target instanceof Node &&\n        [portalEl, ref, ...inside].some(\n          (elRef) => !!elRef.current && elRef.current.contains(target),\n        );\n\n      if (!isInside && open) {\n        setOpen(false);\n      }\n    };\n    window.addEventListener(\n      \"click\",\n      onClickOutside,\n      ADD_EVENT_LISTENER_PASSIVE_OPTIONS,\n    );\n    return () =>\n      window.removeEventListener(\n        \"click\",\n        onClickOutside,\n        REMOVE_EVENT_LISTENER_PASSIVE_OPTIONS,\n      );\n  });\n\n  return {\n    open,\n    setOpen,\n    ref,\n    rect,\n    portalEl,\n    ...scroll,\n  };\n}\n","import * as React from \"react\";\n\nexport default function usePrevious<T>(\n  value: T,\n  initialValue?: undefined,\n): T | undefined;\n\nexport default function usePrevious<T, U>(value: T, initialValue: U): T | U;\n\n/**\n * Custom hook which remembers the value from the previous render\n *\n * @deprecated Violates rules of hooks by reading from a ref during render\n *\n * @param value\n * @param initialValue\n */\nexport default function usePrevious<T, U>(value: T, initialValue: U): T | U {\n  const ref = React.useRef<T | U>(initialValue);\n  React.useEffect(() => {\n    ref.current = value;\n  }, [value]);\n  return ref.current;\n}\n","import { isEqual as _isEqual } from \"lodash\";\nimport * as React from \"react\";\n\n/**\n * Custom hook which provides a stable identity between renders for `value` which is equal to the previous value\n * according to the `isEqual` function\n * @param value\n * @param isEqual\n */\nexport default function useStableIdentity<T>(\n  value: T,\n  isEqual: (value: T, other: T) => boolean = _isEqual,\n): T {\n  // Using the initializer function so that `value` can itself be a function\n  const [reference, setReference] = React.useState(() => value);\n\n  // First perform a shallow check with `Object.is()` for performance, then use custom `isEqual`\n  if (!Object.is(value, reference) && !isEqual(value, reference)) {\n    // Conditionally dispatching a state update as part of a render will cause the component to re-render synchronously\n    // NOTE: Using the updater function variant so that `value` itself can be a function\n    setReference(() => value);\n\n    // Allow the new value to be used immediately as part of this render\n    return value;\n  }\n\n  // Use the previous reference to a value so that its identity remains the same\n  return reference;\n}\n","import * as React from \"react\";\n\ndeclare global {\n  interface WindowEventHandlersEventMap {\n    timezonechange: Event;\n  }\n\n  interface WindowEventHandlers {\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    ontimezonechange?: ((this: Window, ev: Event) => any) | null;\n  }\n}\n\nfunction subscribe(callback: () => void): () => void {\n  // @see https://github.com/whatwg/html/pull/3047\n  if (\"ontimezonechange\" in window) {\n    window.addEventListener(\"timezonechange\", callback);\n    return () => {\n      window.removeEventListener(\"timezonechange\", callback);\n    };\n  }\n\n  // If the \"timezonechange\" event is not supported, use \"visibilitychange\" as a proxy\n  document.addEventListener(\"visibilitychange\", callback);\n  return () => document.removeEventListener(\"visibilitychange\", callback);\n}\n\nfunction getSnapshot() {\n  return new Intl.DateTimeFormat().resolvedOptions().timeZone;\n}\n\nconst SSRTimeZoneContext = React.createContext(\"Etc/UTC\");\n\n/**\n * Custom hook which returns the current `timeZone`.\n *\n * Defaults to `\"Etc/UTC\"` during SSR and hydration, but this may be overriden with a provider\n * `<TimeZoneProvider ssrTimeZone={timeZone}>`. Ensure that the value used during SSR and hydration is the same.\n * @returns IANA tz database identifier\n * @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones\n */\nexport default function useTimeZone() {\n  const ssrTimeZone = React.useContext(SSRTimeZoneContext);\n  const getServerSnapshot = React.useCallback(() => ssrTimeZone, [ssrTimeZone]);\n\n  return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\nexport interface TimeZoneProviderProps {\n  children?: React.ReactNode;\n  /** IANA tz database identifier */\n  ssrTimeZone: string;\n}\n\n/**\n * Context Provider for the `useTimeZone` hook. May be used to override the default `\"Etc/UTC\"` `timeZone` value during\n * SSR and hydration.\n * @param props.children\n * @param props.ssrTimeZone IANA tz database identifier\n */\nexport const TimeZoneProvider = ({\n  children,\n  ssrTimeZone,\n}: TimeZoneProviderProps) => (\n  <SSRTimeZoneContext.Provider value={ssrTimeZone}>\n    {children}\n  </SSRTimeZoneContext.Provider>\n);\n","import * as React from \"react\";\nimport useIsomorphicLayoutEffect from \"./useIsomorphicLayoutEffect\";\n\n/**\n * Custom hook which creates a ref to the `value` which is kept up-to-date after each render in `useLayoutEffect`\n * @param value\n */\nexport default function useUpdatingRef<T>(value: T) {\n  const ref = React.useRef(value);\n\n  // NOTE: This must occur in an effect, as writing to a ref during the render phase can lead to unexpected consequences\n  // during concurrent rendering. Writing _and reading_ to a ref during render is banned, except during initialization.\n  useIsomorphicLayoutEffect(() => {\n    ref.current = value;\n  }, [value]);\n\n  return ref;\n}\n","import { PureComponent, type ReactNode } from \"react\";\n\ninterface ShowWhenProps {\n  when: boolean;\n  children: ReactNode;\n}\n\nexport default class ShowWhen extends PureComponent<ShowWhenProps> {\n  public override render() {\n    const { children, when } = this.props;\n    return when ? children : null;\n  }\n}\n","import type { ElementType } from \"@kablamo/kerosene\";\nimport { SIDES } from \"./css\";\n\nlet SAFE_AREA_INSET_TEST_ELEMENT: HTMLDivElement | null = null;\n\nexport type SafeAreaInsets = { [side in ElementType<typeof SIDES>]: number };\n\n/**\n * Return the safe area insets\n */\nexport default function getSafeAreaInsets(): SafeAreaInsets {\n  if (!SAFE_AREA_INSET_TEST_ELEMENT) {\n    SAFE_AREA_INSET_TEST_ELEMENT = document.createElement(\"div\");\n    SAFE_AREA_INSET_TEST_ELEMENT.style.pointerEvents = \"none\";\n    SIDES.forEach((side) => {\n      SAFE_AREA_INSET_TEST_ELEMENT!.style[side] =\n        `env(safe-area-inset-${side}, 0px)`;\n    });\n    document.body.appendChild(SAFE_AREA_INSET_TEST_ELEMENT);\n  }\n  const computed = window.getComputedStyle(SAFE_AREA_INSET_TEST_ELEMENT);\n  return SIDES.reduce(\n    (acc, side) => ({\n      ...acc,\n      [side]: (computed[side] && parseInt(computed[side], 10)) || 0,\n    }),\n    {} as Partial<SafeAreaInsets> as SafeAreaInsets,\n  );\n}\n","import { identity } from \"lodash\";\n\nexport interface FontDetails {\n  family: string;\n  size: string;\n  style?: string;\n  weight?: string;\n}\n\nlet TEST_CANVAS: HTMLCanvasElement | null = null;\n\n/**\n * Calculates the width of the provided text with 2D Canvas\n * @param text\n * @param font Font Details\n */\nexport default function getTextWidth(text: string, font: FontDetails) {\n  if (!TEST_CANVAS) {\n    TEST_CANVAS = document.createElement(\"canvas\");\n  }\n\n  const context = TEST_CANVAS.getContext(\"2d\", { alpha: false });\n\n  if (!context) return text.length * parseInt(font.size, 10);\n\n  context.font = (\n    [font.style, font.weight, font.size, font.family].filter(\n      identity,\n    ) as string[]\n  ).join(\" \");\n  return Math.ceil(context.measureText(text).width);\n}\n","export interface ViewportDimensions {\n  height: number;\n  width: number;\n}\n\nconst MOBILE_SAFARI_REGEX = /mobile\\/\\w+\\ssafari/i;\n\n/**\n * Returns the viewport dimensions\n *\n * iOS PWAs with no browser chrome (standalone mode) report `window.innerHeight` and `window.innerWidth` incorrectly\n * as a square with sides equal to the minimum of the height and width when the device is rotated.\n *\n * Instead, `screen.height` and `screen.width` may be used to measure the device height/width in its default\n * orientation (portrait) in tandem with media query to detect the current orientation so that the correct dimensions\n * are used. This cannot be used in regular Safari as the screen dimensions do not match the actual size of the viewport.\n */\nexport default function getViewportDimensions(): ViewportDimensions {\n  // This will be true for an iOS PWA with no browser chrome\n  if (\n    MOBILE_SAFARI_REGEX.test(navigator.userAgent) &&\n    (navigator as Navigator & { standalone?: boolean }).standalone\n  ) {\n    const max = Math.max(window.screen.height, window.screen.width);\n    const min = Math.min(window.screen.height, window.screen.width);\n    const isPortrait = window.matchMedia(\"(orientation: portrait)\").matches;\n    return { height: isPortrait ? max : min, width: isPortrait ? min : max };\n  }\n\n  return { height: window.innerHeight, width: window.innerWidth };\n}\n","import getViewportDimensions from \"./getViewportDimensions\";\n\n/**\n * Returns whether or not a given `element` is within the current viewport\n * @param element\n */\nexport default function isInViewport(element: Element): boolean {\n  const { top, left, bottom, right } = element.getBoundingClientRect();\n  const { height, width } = getViewportDimensions();\n\n  return bottom >= 0 && right >= 0 && top <= height && left <= width;\n}\n","/**\n * Returns whether the current page is a PWA\n */\nexport default function isPwa(): boolean {\n  return (\n    window.matchMedia(\"(display-mode: standalone)\").matches ||\n    !!(navigator as Navigator & { standalone?: boolean }).standalone\n  );\n}\n","/**\n * Measures a CSS `property` at the provided `element` by injecting a `<noscript />` element and setting the style\n * `property` to `value` and measuring with `window.getComputedStyle`.\n *\n * Useful for measuring CSS Custom Properties that contain calc expressions, e.g.\n *\n * ```css\n * :root {\n *   --header-height: 48px;\n * }\n *\n * @media only screen and (min-width: 768px) {\n *   :root {\n *     --header-height: 72px;\n *   }\n * }\n * ```\n *\n * ```typescript\n * const headerHeight = measureCSSProperty(document.body, \"paddingTop\", \"var(--header-height, 0px)\");\n * ```\n *\n * @param element\n * @param property\n * @param value\n */\nexport default function measureCSSProperty<P extends keyof CSSStyleDeclaration>(\n  element: Element,\n  property: P,\n  value: CSSStyleDeclaration[P],\n): CSSStyleDeclaration[P] {\n  const noscript = document.createElement(\"noscript\");\n  noscript.style[property] = value;\n  element.appendChild(noscript);\n  const computed = window.getComputedStyle(noscript)[property];\n  element.removeChild(noscript);\n  return computed;\n}\n","import type { AngleDegrees, AngleRadians, MarkType } from \"@kablamo/kerosene\";\n\nexport type Point2D = MarkType<readonly [x: number, y: number], \"Point2D\">;\n\nexport type Delta2D = MarkType<readonly [dx: number, dy: number], \"Delta2D\">;\n\nexport type PolarVector2D = MarkType<\n  readonly [r: number, theta: AngleRadians],\n  \"PolarVector2D\"\n>;\n\n/**\n * Collection of SVG path d utils\n */\nexport const d = {\n  /**\n   *\n   * @param rx\n   * @param ry\n   * @param angle Angle in degrees (not radians)\n   * @param largeArc\n   * @param clockwise\n   * @param delta\n   */\n  arcBy(\n    rx: number,\n    ry: number,\n    angle: AngleDegrees,\n    largeArc: boolean,\n    clockwise: boolean,\n    [dx, dy]: Delta2D,\n  ): string {\n    return `a ${rx} ${ry} ${angle} ${largeArc ? 1 : 0} ${\n      clockwise ? 1 : 0\n    } ${dx},${dy}`;\n  },\n  /**\n   *\n   * @param rx\n   * @param ry\n   * @param angle Angle in degrees (not radians)\n   * @param largeArc\n   * @param clockwise\n   * @param point\n   */\n  arcTo(\n    rx: number,\n    ry: number,\n    angle: AngleDegrees,\n    largeArc: boolean,\n    clockwise: boolean,\n    [x, y]: Point2D,\n  ): string {\n    return `A ${rx} ${ry} ${angle} ${largeArc ? 1 : 0} ${\n      clockwise ? 1 : 0\n    } ${x},${y}`;\n  },\n  closePath() {\n    return \"z\";\n  },\n  cubicBezierBy(\n    [dx1, dy1]: Delta2D,\n    [dx2, dy2]: Delta2D,\n    [dx, dy]: Delta2D,\n  ): string {\n    return `c ${dx1},${dy1},${dx2},${dy2},${dx},${dy}`;\n  },\n  cubicBezierTo([x1, y1]: Point2D, [x2, y2]: Point2D, [x, y]: Point2D): string {\n    return `C ${x1},${y1},${x2},${y2},${x},${y}`;\n  },\n  lineBy([dx, dy]: Delta2D): string {\n    return `l ${dx},${dy}`;\n  },\n  lineTo([x, y]: Point2D): string {\n    return `L ${x},${y}`;\n  },\n  moveBy([dx, dy]: Delta2D): string {\n    return `m ${dx},${dy}`;\n  },\n  moveTo([x, y]: Point2D): string {\n    return `M ${x},${y}`;\n  },\n  quadraticBezierBy([dx1, dy1]: Delta2D, [dx, dy]: Delta2D): string {\n    return `q ${dx1},${dy1},${dx},${dy}`;\n  },\n  quadraticBezierTo([x1, y1]: Point2D, [x, y]: Point2D): string {\n    return `Q ${x1},${y1},${x},${y}`;\n  },\n  smoothCubicBezierBy([dx2, dy2]: Delta2D, [dx, dy]: Delta2D): string {\n    return `s ${dx2},${dy2},${dx},${dy}`;\n  },\n  smoothCubicBezierTo([x2, y2]: Point2D, [x, y]: Point2D): string {\n    return `S ${x2},${y2},${x},${y}`;\n  },\n  smoothQuadraticBezierBy([dx, dy]: Delta2D): string {\n    return `t ${dx},${dy}`;\n  },\n  smoothQuadraticBezierTo([x, y]: Point2D): string {\n    return `T ${x},${y}`;\n  },\n};\n\n/**\n * Adds the vector `[r, theta]` to Point2D `[x, y]`\n * @param x Point2D cartesian x-coordinate\n * @param y Point2D cartesian y-coordinate\n * @param r Polar vector length\n * @param theta Polar vector angle in radians\n */\nexport function point2DPlusPolarVector(\n  [x, y]: Point2D,\n  [r, theta]: PolarVector2D,\n): Point2D {\n  return [x + Math.sin(theta) * r, y + Math.cos(theta) * r];\n}\n","export default function createTestIds<N extends string>(\n  name: string,\n  components: readonly N[],\n): { [key in N]: string } {\n  return components.reduce(\n    (acc, component) => ({\n      ...acc,\n      [component]: `${name}#${component}`,\n    }),\n    {} as { [key in N]: string },\n  );\n}\n"],"mappings":"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"}