{"version":3,"sources":["../../src/components/AccountAvatar.tsx","../../src/components/AccountSwitcherProvider.tsx","../../src/lib/message-protocol.ts","../../src/lib/actions.ts","../../src/lib/message-utils.ts","../../src/lib/client.ts","../../src/lib/dialogs.ts","../../src/hooks/useSession.ts","../../src/components/AccountSwitcher.tsx","../../src/components/HandoffArrivalToast.tsx","../../src/hooks/useHandoffArrival.ts"],"sourcesContent":["'use client';\n\nimport { useState, useEffect, useRef, useCallback, useId } from 'react';\nimport { useSession } from '../hooks/useSession';\nimport type { User } from '../lib/types';\n\nexport interface AccountAvatarProps {\n  /** Avatar diameter in pixels (default: 40) */\n  size?: number;\n  /** Additional CSS classes */\n  className?: string;\n  /** Custom inline styles */\n  style?: React.CSSProperties;\n  /** ID of element to toggle visibility on click (e.g., IFRAME container) */\n  targetId?: string;\n  /** Custom click handler */\n  onClick?: () => void;\n  /** Callback when avatar is clicked with current user data */\n  onAvatarClick?: (user: User | null) => void;\n}\n\n/**\n * AccountAvatar Component\n *\n * A compact, clickable avatar component for NAV bars that displays the current user's avatar\n * and synchronizes with the AccountSwitcher session.\n *\n * Features:\n * - Displays user avatar (image or initials) when logged in\n * - Shows generic profile icon when logged out\n * - Automatically syncs with session changes via AccountSwitcherProvider\n * - Toggles target element visibility (typically IFRAME container)\n * - Outside click and ESC key support for closing popup\n * - Smooth hover and active animations\n *\n * @example\n * ```tsx\n * // Basic usage\n * <AccountAvatar />\n *\n * // With IFRAME toggle\n * <AccountAvatar targetId=\"account-switcher-dropdown\" size={40} />\n *\n * // In NAV with dropdown\n * <nav>\n *   <AccountAvatar targetId=\"switcher-popup\" />\n * </nav>\n * <div id=\"switcher-popup\" style={{ display: 'none' }}>\n *   <AccountSwitcher />\n * </div>\n * ```\n */\nexport function AccountAvatar({\n  size = 40,\n  className = '',\n  style = {},\n  targetId,\n  onClick,\n  onAvatarClick,\n}: AccountAvatarProps) {\n  const { currentUser, isAuthenticated } = useSession();\n  const [isOpen, setIsOpen] = useState(false);\n  const avatarRef = useRef<HTMLDivElement>(null);\n  const uniqueId = useId();\n  const avatarClass = `account-avatar-${uniqueId.replace(/:/g, '-')}`;\n\n  /**\n   * Get initials from name (same logic as IFRAME)\n   */\n  const getInitials = useCallback((name: string): string => {\n    if (!name) return '??';\n    return name\n      .split(' ')\n      .map((n) => n[0])\n      .join('')\n      .toUpperCase()\n      .slice(0, 2);\n  }, []);\n\n  /**\n   * Handle avatar image error (fallback to initials)\n   */\n  const [imageError, setImageError] = useState(false);\n  const handleImageError = useCallback(() => {\n    setImageError(true);\n  }, []);\n\n  /**\n   * Reset image error when user changes\n   */\n  useEffect(() => {\n    setImageError(false);\n  }, [currentUser?.uuid]);\n\n  /**\n   * Render avatar content (image or initials)\n   */\n  const renderAvatarContent = useCallback(() => {\n    if (!isAuthenticated || !currentUser) {\n      return null;\n    }\n\n    // If avatar exists and hasn't errored, show image\n    if (currentUser.avatar && !imageError) {\n      const src = currentUser.avatar.startsWith('http')\n        ? currentUser.avatar\n        : `/storage/${currentUser.avatar}`;\n\n      return (\n        <img\n          src={src}\n          alt={currentUser.name}\n          onError={handleImageError}\n          style={{\n            width: '100%',\n            height: '100%',\n            objectFit: 'cover',\n            borderRadius: 'inherit',\n          }}\n        />\n      );\n    }\n\n    // Fallback to initials\n    return getInitials(currentUser.name);\n  }, [isAuthenticated, currentUser, imageError, getInitials, handleImageError]);\n\n  /**\n   * Handle click events\n   */\n  const handleClick = useCallback(() => {\n    // Call onAvatarClick callback with user data\n    onAvatarClick?.(currentUser);\n\n    // Toggle target element if specified\n    if (targetId) {\n      const target = document.getElementById(targetId);\n      if (target) {\n        const willOpen = !isOpen;\n        target.style.display = willOpen ? 'block' : 'none';\n        setIsOpen(willOpen);\n      }\n    }\n\n    // Call custom onClick if provided\n    onClick?.();\n  }, [currentUser, targetId, isOpen, onAvatarClick, onClick]);\n\n  /**\n   * Setup outside click and ESC key handlers when popup is open\n   */\n  useEffect(() => {\n    if (!isOpen || !targetId || typeof window === 'undefined') return;\n\n    const handleClickOutside = (event: MouseEvent) => {\n      const target = document.getElementById(targetId);\n      if (!target) return;\n\n      const clickedInside = target.contains(event.target as Node);\n      const clickedAvatar = avatarRef.current?.contains(event.target as Node);\n\n      if (!clickedInside && !clickedAvatar) {\n        target.style.display = 'none';\n        setIsOpen(false);\n      }\n    };\n\n    const handleEscape = (event: KeyboardEvent) => {\n      if (event.key === 'Escape') {\n        const target = document.getElementById(targetId);\n        if (target) {\n          target.style.display = 'none';\n          setIsOpen(false);\n        }\n      }\n    };\n\n    // Delay adding listener to prevent immediate closure from same click\n    const timeoutId = setTimeout(() => {\n      document.addEventListener('click', handleClickOutside);\n      document.addEventListener('keydown', handleEscape);\n    }, 0);\n\n    return () => {\n      clearTimeout(timeoutId);\n      document.removeEventListener('click', handleClickOutside);\n      document.removeEventListener('keydown', handleEscape);\n    };\n  }, [isOpen, targetId]);\n\n  /**\n   * Inject hover and active styles\n   */\n  useEffect(() => {\n    if (typeof window === 'undefined') return;\n\n    const styleId = `account-avatar-styles-${avatarClass}`;\n\n    // Check if styles already exist\n    if (document.getElementById(styleId)) return;\n\n    const styleElement = document.createElement('style');\n    styleElement.id = styleId;\n    styleElement.textContent = `\n      .${avatarClass}:hover {\n        transform: scale(1.05);\n        box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);\n      }\n\n      .${avatarClass}:active {\n        transform: scale(0.98);\n      }\n    `;\n\n    document.head.appendChild(styleElement);\n\n    return () => {\n      const existingStyle = document.getElementById(styleId);\n      if (existingStyle) {\n        document.head.removeChild(existingStyle);\n      }\n    };\n  }, [avatarClass]);\n\n  // Container styles\n  const containerStyle: React.CSSProperties = {\n    width: `${size}px`,\n    height: `${size}px`,\n    borderRadius: '50%',\n    background: isAuthenticated && currentUser ? 'transparent' : '#e5e7eb',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n    cursor: 'pointer',\n    transition: 'all 0.2s ease',\n    overflow: 'hidden',\n    position: 'relative',\n    flexShrink: 0,\n    ...style,\n  };\n\n  // Icon styles (shown when logged out)\n  const iconStyle: React.CSSProperties = {\n    transition: 'opacity 0.2s ease',\n    display: isAuthenticated && currentUser ? 'none' : 'block',\n  };\n\n  // Content styles (shown when logged in)\n  const contentStyle: React.CSSProperties = {\n    position: 'absolute',\n    top: 0,\n    left: 0,\n    width: '100%',\n    height: '100%',\n    display: isAuthenticated && currentUser ? 'flex' : 'none',\n    alignItems: 'center',\n    justifyContent: 'center',\n    background:\n      currentUser?.avatar && !imageError\n        ? 'transparent'\n        : 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',\n    color: 'white',\n    fontSize: `${size * 0.4}px`,\n    fontWeight: 500,\n    fontFamily: '-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif',\n  };\n\n  return (\n    <div\n      ref={avatarRef}\n      className={`${avatarClass} ${className}`}\n      style={containerStyle}\n      onClick={handleClick}\n      role=\"button\"\n      tabIndex={0}\n      onKeyDown={(e) => {\n        if (e.key === 'Enter' || e.key === ' ') {\n          e.preventDefault();\n          handleClick();\n        }\n      }}\n      aria-label={\n        currentUser\n          ? `Account menu for ${currentUser.name}`\n          : 'Account menu'\n      }\n    >\n      {/* Generic profile icon (default state) */}\n      <svg\n        width={size * 0.6}\n        height={size * 0.6}\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"#9ca3af\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        style={iconStyle}\n      >\n        <path d=\"M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2\"></path>\n        <circle cx=\"12\" cy=\"7\" r=\"4\"></circle>\n      </svg>\n\n      {/* Avatar content (shown when logged in) */}\n      <div style={contentStyle}>{renderAvatarContent()}</div>\n    </div>\n  );\n}\n","'use client';\r\n\r\nimport React, { createContext, useContext, useState, useEffect, useCallback, useRef } from 'react';\r\nimport type {\r\n  Session,\r\n  AccountSwitcherConfig,\r\n  AccountSwitcherContextValue,\r\n  ConfirmPayload,\r\n  PromptPayload,\r\n  AlertPayload,\r\n  UrlRedirectPayload,\r\n} from '../lib/types';\r\nimport { PostMessageClient } from '../lib/client';\r\nimport { MESSAGE_TYPES } from '../lib/message-protocol';\r\nimport { DialogManager } from '../lib/dialogs';\r\n\r\n// Cross-bundle singleton context.\r\n//\r\n// tsup builds this package as multiple entry points (index, components, hooks,\r\n// sharing) with `splitting: false`, which DUPLICATES this module — and its\r\n// `createContext()` call — into every entry bundle. That yields distinct\r\n// Context objects, so a Provider imported from one entry (e.g. the root) and a\r\n// consumer imported from another (e.g. `/sharing`'s HandoffLanding) never\r\n// match, and the consumer reads `null`. Anchoring the Context on `globalThis`\r\n// behind a stable `Symbol.for()` key guarantees exactly ONE shared Context\r\n// object across all bundles at runtime. See tsup.config.ts.\r\nconst CONTEXT_KEY = Symbol.for('@benbraide/auth-service-nextjs/AccountSwitcherContext');\r\ntype AccountSwitcherReactContext = React.Context<AccountSwitcherContextValue | null>;\r\nconst contextRegistry = globalThis as unknown as Record<symbol, AccountSwitcherReactContext | undefined>;\r\nconst AccountSwitcherContext: AccountSwitcherReactContext =\r\n  contextRegistry[CONTEXT_KEY] ??\r\n  (contextRegistry[CONTEXT_KEY] = createContext<AccountSwitcherContextValue | null>(null));\r\n\r\nexport interface AccountSwitcherProviderProps extends AccountSwitcherConfig {\r\n  children: React.ReactNode;\r\n}\r\n\r\n/**\r\n * Provider component for account switcher functionality\r\n * Wraps your app to provide session state and switcher methods\r\n */\r\nexport function AccountSwitcherProvider({\r\n  children,\r\n  backendUrl,\r\n  authServiceUrl,\r\n  serviceApiKey,\r\n  onSessionChange,\r\n  onAccountChange,\r\n  onError,\r\n  debug = false,\r\n  dialogs,\r\n  onConfirmRequest,\r\n  onPromptRequest,\r\n  onAlertRequest,\r\n  autoResize = true,\r\n  minHeight = 200,\r\n  maxHeight = null,\r\n  onResize,\r\n  onNavigate,\r\n  onNavigateToAddAccount,\r\n  onNavigateToManageAccount,\r\n  onNavigateToAvatarUpdate,\r\n}: AccountSwitcherProviderProps) {\r\n  const [session, setSession] = useState<Session>({\r\n    isAuthenticated: false,\r\n    currentUser: null,\r\n    accounts: [],\r\n  });\r\n  const [isLoading, setIsLoading] = useState(false);\r\n  const [error, setError] = useState<Error | null>(null);\r\n  // State mirror of clientRef so the context value updates (and consumers such\r\n  // as HandoffLanding re-render) once the PostMessage client is initialized in\r\n  // the mount effect below.\r\n  const [activeClient, setActiveClient] = useState<PostMessageClient | null>(null);\r\n  const clientRef = useRef<PostMessageClient | null>(null);\r\n  const dialogManagerRef = useRef<DialogManager | null>(null);\r\n\r\n  // Use refs for callbacks to avoid recreating PostMessageClient on every prop change\r\n  const debugRef = useRef(debug);\r\n  const onSessionChangeRef = useRef(onSessionChange);\r\n  const onAccountChangeRef = useRef(onAccountChange);\r\n  const onErrorRef = useRef(onError);\r\n  const onConfirmRequestRef = useRef(onConfirmRequest);\r\n  const onPromptRequestRef = useRef(onPromptRequest);\r\n  const onAlertRequestRef = useRef(onAlertRequest);\r\n  const onNavigateRef = useRef(onNavigate);\r\n  const onNavigateToAddAccountRef = useRef(onNavigateToAddAccount);\r\n  const onNavigateToManageAccountRef = useRef(onNavigateToManageAccount);\r\n  const onNavigateToAvatarUpdateRef = useRef(onNavigateToAvatarUpdate);\r\n\r\n  // Update refs whenever callbacks change\r\n  useEffect(() => {\r\n    debugRef.current = debug;\r\n    onSessionChangeRef.current = onSessionChange;\r\n    onAccountChangeRef.current = onAccountChange;\r\n    onErrorRef.current = onError;\r\n    onConfirmRequestRef.current = onConfirmRequest;\r\n    onPromptRequestRef.current = onPromptRequest;\r\n    onAlertRequestRef.current = onAlertRequest;\r\n    onNavigateRef.current = onNavigate;\r\n    onNavigateToAddAccountRef.current = onNavigateToAddAccount;\r\n    onNavigateToManageAccountRef.current = onNavigateToManageAccount;\r\n    onNavigateToAvatarUpdateRef.current = onNavigateToAvatarUpdate;\r\n  });\r\n\r\n  // Initialize PostMessage client\r\n  useEffect(() => {\r\n    if (typeof window === 'undefined') return;\r\n\r\n    // Initialize dialog manager if dialogs are enabled\r\n    if (dialogs?.enabled !== false) {\r\n      const dialogManager = new DialogManager(dialogs || {});\r\n      dialogManager.injectDialogStyles();\r\n      dialogManagerRef.current = dialogManager;\r\n    }\r\n\r\n    const config: AccountSwitcherConfig = {\r\n      backendUrl,\r\n      authServiceUrl,\r\n      serviceApiKey,\r\n      onSessionChange,\r\n      onAccountChange,\r\n      onError,\r\n      debug,\r\n      dialogs,\r\n      onConfirmRequest,\r\n      onPromptRequest,\r\n      onAlertRequest,\r\n      autoResize,\r\n      minHeight,\r\n      maxHeight,\r\n      onResize,\r\n    };\r\n\r\n    const client = new PostMessageClient(config);\r\n    clientRef.current = client;\r\n    // Publish into state so the context value exposes a live `client` to\r\n    // consumers (e.g. the cross-product handoff) once it's ready.\r\n    setActiveClient(client);\r\n\r\n    // Set up session change listener\r\n    client.on(MESSAGE_TYPES.SESSION_CHANGED, (data: any) => {\r\n      const sessionData = data.payload || data;\r\n      const newSession: Session = {\r\n        isAuthenticated: sessionData.isAuthenticated || false,\r\n        currentUser: sessionData.currentUser || null,\r\n        accounts: sessionData.accounts || [],\r\n      };\r\n\r\n      setSession(newSession);\r\n      onSessionChangeRef.current?.(newSession);\r\n    });\r\n\r\n    // Set up account change listener\r\n    client.on(MESSAGE_TYPES.ACCOUNT_SWITCHED, (data: any) => {\r\n      const payload = data.payload || data;\r\n\r\n      // ACCOUNT_SWITCHED only sends { user_uuid }, not the full user object\r\n      // Find the full user object from the accounts array\r\n      setSession((prevSession) => {\r\n        const switchedUser = prevSession.accounts.find(\r\n          (account) => account.uuid === payload.user_uuid\r\n        );\r\n\r\n        if (switchedUser) {\r\n          // Update current user with the full user object from accounts\r\n          const newSession = {\r\n            ...prevSession,\r\n            currentUser: switchedUser,\r\n          };\r\n\r\n          // Call the callback with the full user object\r\n          onAccountChangeRef.current?.(switchedUser);\r\n\r\n          return newSession;\r\n        }\r\n\r\n        // If user not found in accounts, keep previous session\r\n        if (debug) {\r\n          console.warn('[AccountSwitcher] Switched user not found in accounts:', payload.user_uuid);\r\n        }\r\n        return prevSession;\r\n      });\r\n    });\r\n\r\n    // Set up error listener\r\n    client.on(MESSAGE_TYPES.ERROR, (data: any) => {\r\n      const err = data.payload || data;\r\n      const error = new Error(err.message || 'Unknown error');\r\n      setError(error);\r\n      onErrorRef.current?.(error);\r\n    });\r\n\r\n    // NOTE: SIZE_CHANGED is now handled directly in AccountSwitcher component\r\n    // using direct DOM manipulation to avoid re-renders. If you need resize notifications,\r\n    // use the onHeightChange prop on the AccountSwitcher component instead.\r\n\r\n    // Set up navigation handlers\r\n    client.on(MESSAGE_TYPES.ADD_ACCOUNT, (data: any) => {\r\n      const payload = data.payload || data;\r\n      if (payload.landing_url) {\r\n        if (onNavigateToAddAccountRef.current) {\r\n          onNavigateToAddAccountRef.current(payload.landing_url);\r\n        } else {\r\n          window.location.href = payload.landing_url;\r\n        }\r\n      }\r\n    });\r\n\r\n    client.on(MESSAGE_TYPES.MANAGE_ACCOUNT, (data: any) => {\r\n      const payload = data.payload || data;\r\n      if (payload.management_url) {\r\n        if (onNavigateToManageAccountRef.current) {\r\n          onNavigateToManageAccountRef.current(payload.management_url);\r\n        } else {\r\n          window.location.href = payload.management_url;\r\n        }\r\n      }\r\n    });\r\n\r\n    client.on(MESSAGE_TYPES.UPDATE_AVATAR, (data: any) => {\r\n      const payload = data.payload || data;\r\n      if (payload.avatar_url) {\r\n        if (onNavigateToAvatarUpdateRef.current) {\r\n          onNavigateToAvatarUpdateRef.current(payload.avatar_url);\r\n        } else {\r\n          window.location.href = payload.avatar_url;\r\n        }\r\n      }\r\n    });\r\n\r\n    // Set up unified URL redirect handler (Unified Action Protocol)\r\n    client.on(MESSAGE_TYPES.URL_REDIRECT, (data: any) => {\r\n      const payload = data.payload || data;\r\n      const redirectPayload: UrlRedirectPayload = {\r\n        url: payload.url,\r\n        reason: payload.reason,\r\n        openInNewTab: payload.openInNewTab || false,\r\n      };\r\n\r\n      if (onNavigateRef.current) {\r\n        // Use new unified navigation handler\r\n        onNavigateRef.current(redirectPayload);\r\n      } else {\r\n        // Fallback to legacy handlers or default behavior\r\n        const { url, reason, openInNewTab } = redirectPayload;\r\n\r\n        // Try legacy handlers first based on reason\r\n        if (reason === 'add-account' && onNavigateToAddAccountRef.current) {\r\n          onNavigateToAddAccountRef.current(url);\r\n        } else if (reason === 'manage-account' && onNavigateToManageAccountRef.current) {\r\n          onNavigateToManageAccountRef.current(url);\r\n        } else if (reason === 'update-avatar' && onNavigateToAvatarUpdateRef.current) {\r\n          onNavigateToAvatarUpdateRef.current(url);\r\n        } else {\r\n          // Default navigation behavior\r\n          if (openInNewTab) {\r\n            window.open(url, '_blank');\r\n          } else {\r\n            window.location.href = url;\r\n          }\r\n        }\r\n      }\r\n    });\r\n\r\n    // Set up dialog handlers\r\n    if (dialogs?.enabled !== false) {\r\n      // Confirm dialog\r\n      client.on(MESSAGE_TYPES.CONFIRM_REQUEST, async (data: any) => {\r\n        if (debug) {\r\n          console.log('[AccountSwitcher] CONFIRM_REQUEST received:', data);\r\n        }\r\n        const { requestId, payload } = data;\r\n\r\n        try {\r\n          let result: boolean;\r\n\r\n          if (onConfirmRequestRef.current) {\r\n            // Use custom handler if provided\r\n            result = await onConfirmRequestRef.current(payload as ConfirmPayload);\r\n          } else if (dialogManagerRef.current) {\r\n            // Use custom dialog manager\r\n            result = await dialogManagerRef.current.showConfirm(payload as ConfirmPayload);\r\n          } else {\r\n            // Fallback to browser confirm\r\n            result = window.confirm(payload.message);\r\n          }\r\n\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            confirmed: result,\r\n          });\r\n        } catch (err) {\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            confirmed: false,\r\n          });\r\n        }\r\n      });\r\n\r\n      // Prompt dialog\r\n      client.on(MESSAGE_TYPES.PROMPT_REQUEST, async (data: any) => {\r\n        const { requestId, payload } = data;\r\n\r\n        try {\r\n          let value: string | null = null;\r\n          let cancelled = true;\r\n\r\n          if (onPromptRequestRef.current) {\r\n            // Use custom handler if provided\r\n            const customResult = await onPromptRequestRef.current(payload as PromptPayload);\r\n            value = customResult;\r\n            cancelled = customResult === null;\r\n          } else if (dialogManagerRef.current) {\r\n            // Use custom dialog manager\r\n            const result = await dialogManagerRef.current.showPrompt(payload as PromptPayload);\r\n            value = result.value;\r\n            cancelled = result.cancelled;\r\n          } else {\r\n            // Fallback to browser prompt\r\n            const browserResult = window.prompt(payload.message, payload.defaultValue || '');\r\n            value = browserResult;\r\n            cancelled = browserResult === null;\r\n          }\r\n\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            value,\r\n            cancelled,\r\n          });\r\n        } catch (err) {\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            value: null,\r\n            cancelled: true,\r\n          });\r\n        }\r\n      });\r\n\r\n      // Alert dialog\r\n      client.on(MESSAGE_TYPES.ALERT_REQUEST, async (data: any) => {\r\n        const { requestId, payload } = data;\r\n\r\n        try {\r\n          if (onAlertRequestRef.current) {\r\n            // Use custom handler if provided\r\n            await onAlertRequestRef.current(payload as AlertPayload);\r\n          } else if (dialogManagerRef.current) {\r\n            // Use custom dialog manager\r\n            await dialogManagerRef.current.showAlert(payload as AlertPayload);\r\n          } else {\r\n            // Fallback to browser alert\r\n            window.alert(payload.message);\r\n          }\r\n\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            acknowledged: true,\r\n          });\r\n        } catch (err) {\r\n          client.sendDialogResponse(MESSAGE_TYPES.REQUEST_RESPONSE, requestId, {\r\n            acknowledged: false,\r\n          });\r\n        }\r\n      });\r\n    }\r\n\r\n    return () => {\r\n      client.destroy();\r\n      clientRef.current = null;\r\n      setActiveClient(null);\r\n    };\r\n  }, []);\r\n\r\n  const switchAccount = useCallback(async (userUuid: string) => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    setIsLoading(true);\r\n    setError(null);\r\n\r\n    try {\r\n      await clientRef.current.switchAccount(userUuid);\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    } finally {\r\n      setIsLoading(false);\r\n    }\r\n  }, []);\r\n\r\n  const addAccount = useCallback(async () => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    try {\r\n      await clientRef.current.addAccount();\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    }\r\n  }, []);\r\n\r\n  const manageAccount = useCallback(async () => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    try {\r\n      await clientRef.current.manageAccount();\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    }\r\n  }, []);\r\n\r\n  const updateAvatar = useCallback(async () => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    try {\r\n      await clientRef.current.updateAvatar();\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    }\r\n  }, []);\r\n\r\n  const logoutAccount = useCallback(async (userUuid: string) => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    setIsLoading(true);\r\n    setError(null);\r\n\r\n    try {\r\n      await clientRef.current.logoutAccount(userUuid);\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    } finally {\r\n      setIsLoading(false);\r\n    }\r\n  }, []);\r\n\r\n  const logoutAll = useCallback(async () => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    setIsLoading(true);\r\n    setError(null);\r\n\r\n    try {\r\n      await clientRef.current.logoutAll();\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    } finally {\r\n      setIsLoading(false);\r\n    }\r\n  }, []);\r\n\r\n  const refresh = useCallback(async () => {\r\n    if (!clientRef.current) throw new Error('Client not initialized');\r\n\r\n    setIsLoading(true);\r\n    setError(null);\r\n\r\n    try {\r\n      const sessionData = await clientRef.current.getSession();\r\n      setSession(sessionData);\r\n    } catch (err) {\r\n      const error = err as Error;\r\n      setError(error);\r\n      throw error;\r\n    } finally {\r\n      setIsLoading(false);\r\n    }\r\n  }, []);\r\n\r\n  const registerIframe = useCallback((iframe: HTMLIFrameElement, origin: string) => {\r\n    if (!clientRef.current) {\r\n      console.warn('[AccountSwitcherProvider] Client not initialized, cannot register iframe');\r\n      return;\r\n    }\r\n\r\n    clientRef.current.setIframe(iframe, origin);\r\n\r\n    // Fetch initial session after iframe is registered\r\n    // Wait a bit for the iframe to be ready and handshake to complete\r\n    setTimeout(async () => {\r\n      try {\r\n        setIsLoading(true);\r\n        const sessionData = await clientRef.current!.getSession();\r\n        setSession(sessionData);\r\n      } catch (err) {\r\n        if (debugRef.current) {\r\n          console.error('[AccountSwitcherProvider] Failed to fetch initial session:', err);\r\n        }\r\n      } finally {\r\n        setIsLoading(false);\r\n      }\r\n    }, 1000); // Give the iframe time to complete handshake\r\n  }, []); // No dependencies - uses only refs and setState\r\n\r\n  const sendMessage = useCallback((type: string, payload?: unknown) => {\r\n    if (!clientRef.current) {\r\n      console.warn('[AccountSwitcherProvider] Client not initialized, cannot send message:', type);\r\n      return;\r\n    }\r\n    clientRef.current.send(type, payload);\r\n  }, []);\r\n\r\n  const value: AccountSwitcherContextValue = {\r\n    session,\r\n    isLoading,\r\n    error,\r\n    switchAccount,\r\n    addAccount,\r\n    manageAccount,\r\n    updateAvatar,\r\n    logoutAccount,\r\n    logoutAll,\r\n    refresh,\r\n    registerIframe,\r\n    client: activeClient,\r\n    sendMessage,\r\n  };\r\n\r\n  return (\r\n    <AccountSwitcherContext.Provider value={value}>\r\n      {children}\r\n    </AccountSwitcherContext.Provider>\r\n  );\r\n}\r\n\r\n/**\r\n * Hook to access the account switcher context\r\n * @throws Error if used outside of AccountSwitcherProvider\r\n */\r\nexport function useAccountSwitcherContext() {\r\n  const context = useContext(AccountSwitcherContext);\r\n\r\n  if (!context) {\r\n    throw new Error(\r\n      'useAccountSwitcherContext must be used within AccountSwitcherProvider'\r\n    );\r\n  }\r\n\r\n  return context;\r\n}\r\n","/**\r\n * Message types for PostMessage communication between iframe and parent window\r\n */\r\nexport const MESSAGE_TYPES = {\r\n  // Handshake messages\r\n  READY: 'READY',                          // iframe → host: Iframe loaded and ready\r\n  HANDSHAKE: 'HANDSHAKE',                  // host → iframe: Host origin identification\r\n  HANDSHAKE_ACK: 'HANDSHAKE_ACK',          // iframe → host: Origin validated, connection established\r\n\r\n  // Unified Action Protocol (new)\r\n  ACTION_REQUEST: 'ACTION_REQUEST',        // host → iframe: Unified action request\r\n  URL_REDIRECT: 'URL_REDIRECT',            // iframe → host: Unified navigation request\r\n\r\n  // Account query messages (legacy - kept for backward compatibility)\r\n  GET_ACCOUNTS: 'GET_ACCOUNTS',            // host → iframe: Request account list\r\n  ACCOUNTS_DATA: 'ACCOUNTS_DATA',          // iframe → host: Send account data\r\n\r\n  // Account action messages (legacy - kept for backward compatibility)\r\n  SWITCH_ACCOUNT: 'SWITCH_ACCOUNT',        // host → iframe: Request account switch\r\n  ACCOUNT_SWITCHED: 'ACCOUNT_SWITCHED',    // iframe → host: Account switch completed\r\n  ADD_ACCOUNT: 'ADD_ACCOUNT',              // host → iframe: Request add account flow\r\n  ACCOUNT_ADDED: 'ACCOUNT_ADDED',          // iframe → host: Account added successfully\r\n\r\n  // Cross-product handoff (Sharing protocol — F3/F4/A6)\r\n  // Values MUST be SCREAMING_SNAKE to match the auth-service iframe's own\r\n  // MESSAGE_TYPES registry (resources/js/widgets/message-protocol.js). The\r\n  // iframe's isValidMessage() whitelists by value, so a kebab-case slug is\r\n  // silently dropped and the handoff never completes.\r\n  ADD_ACCOUNT_WITH_TOKEN: 'ADD_ACCOUNT_WITH_TOKEN',                  // host → iframe: push a pre-authenticated account\r\n  ADD_ACCOUNT_WITH_TOKEN_OK: 'ADD_ACCOUNT_WITH_TOKEN_OK',            // iframe → host: cookie written, account appended\r\n  ADD_ACCOUNT_WITH_TOKEN_FAILED: 'ADD_ACCOUNT_WITH_TOKEN_FAILED',    // iframe → host: backend rejected the session token\r\n\r\n  // Prep–Sign–Promote pattern (v1.4 sharing/prep/*)\r\n  PREP_SIGNED:      'prep-signed',         // peer iframe → host: signature captured, prep flipped to 'signed'\r\n  PREP_SIGN_FAILED: 'prep-sign-failed',    // peer iframe → host: signature rejected by intent handler\r\n\r\n  MANAGE_ACCOUNT: 'MANAGE_ACCOUNT',        // iframe → host: Request account management flow\r\n  UPDATE_AVATAR: 'UPDATE_AVATAR',          // iframe → host: Request avatar update flow\r\n  LOGOUT_ACCOUNT: 'LOGOUT_ACCOUNT',        // host → iframe: Request logout specific account\r\n  ACCOUNT_LOGGED_OUT: 'ACCOUNT_LOGGED_OUT', // iframe → host: Account logged out\r\n  LOGOUT_ALL: 'LOGOUT_ALL',                // host → iframe: Request logout all accounts\r\n  ALL_LOGGED_OUT: 'ALL_LOGGED_OUT',        // iframe → host: All accounts logged out\r\n\r\n  // Interactive request messages (iframe → host)\r\n  CONFIRM_REQUEST: 'CONFIRM_REQUEST',      // iframe → host: Request user confirmation\r\n  PROMPT_REQUEST: 'PROMPT_REQUEST',        // iframe → host: Request user text input\r\n  ALERT_REQUEST: 'ALERT_REQUEST',          // iframe → host: Request user acknowledgment\r\n  REQUEST_RESPONSE: 'REQUEST_RESPONSE',    // host → iframe: Response to interactive request\r\n\r\n  // Event notifications\r\n  SESSION_CHANGED: 'SESSION_CHANGED',      // iframe → host: Session state changed\r\n  TOKEN_REFRESHED: 'TOKEN_REFRESHED',      // iframe → host: Auth token refreshed\r\n  SIZE_CHANGED: 'SIZE_CHANGED',            // iframe → host: Content height changed\r\n\r\n  // External session management\r\n  SET_SESSION: 'SET_SESSION',              // host → iframe: Set session from external login\r\n  SESSION_SET: 'SESSION_SET',              // iframe → host: Confirm session was set\r\n\r\n  // Page context messages\r\n  SET_PAGE_URL: 'SET_PAGE_URL',            // host → iframe: Update current page URL\r\n\r\n  // Error messages\r\n  ERROR: 'ERROR',                          // both ways: Error notification\r\n  UNAUTHORIZED: 'UNAUTHORIZED',            // iframe → host: Origin not authorized\r\n} as const;\r\n\r\n/**\r\n * PostMessage message structure\r\n */\r\nexport interface PostMessageData {\r\n  type: string;\r\n  payload?: any;\r\n  requestId?: string;\r\n  timestamp?: number;\r\n  version?: string;\r\n}\r\n\r\n/**\r\n * Session change event payload\r\n */\r\nexport interface SessionChangedPayload {\r\n  isAuthenticated: boolean;\r\n  currentUser: any;\r\n  accounts: any[];\r\n}\r\n\r\n/**\r\n * Account switched event payload\r\n */\r\nexport interface AccountSwitchedPayload {\r\n  uuid: string;\r\n  name: string;\r\n  email: string;\r\n  avatar_url?: string;\r\n}\r\n\r\n/**\r\n * Error event payload\r\n */\r\nexport interface ErrorPayload {\r\n  message: string;\r\n  code?: string;\r\n  details?: any;\r\n}\r\n\r\n/**\r\n * Resize event payload\r\n */\r\nexport interface ResizePayload {\r\n  height: number;\r\n}\r\n\r\n/**\r\n * Action request payload (Unified Action Protocol)\r\n */\r\nexport interface ActionRequestPayload {\r\n  action: string;\r\n  params: Record<string, any>;\r\n}\r\n\r\n/**\r\n * URL redirect payload (Unified Action Protocol)\r\n */\r\nexport interface UrlRedirectPayload {\r\n  url: string;\r\n  reason?: string;\r\n  openInNewTab?: boolean;\r\n}\r\n\r\n/**\r\n * Sharing protocol — request payload sent by `multiAccountAutoAdd` (F4) to the\r\n * auth-service iframe (A6). The iframe redeems the session token at its own\r\n * backend, writes the destination-scoped session cookie, and acks with\r\n * ADD_ACCOUNT_WITH_TOKEN_OK (or ..._FAILED).\r\n */\r\nexport interface AddAccountWithTokenPayload {\r\n  /** UUID of the user being added — must match the user the session token was issued for. */\r\n  accountUuid: string;\r\n  /** Short-lived session token returned by the handoff exchange (F1). */\r\n  sessionToken: string;\r\n}\r\n\r\n/**\r\n * Sharing protocol — iframe → host: cookie written and account appended.\r\n */\r\nexport interface AddAccountWithTokenOkPayload {\r\n  accountUuid: string;\r\n}\r\n\r\n/**\r\n * Sharing protocol — iframe → host: redemption failed.\r\n *\r\n * `reason` is one of:\r\n * - `http_401` — session token invalid / expired (auth-service rejected)\r\n * - `http_4xx` / `http_5xx` — generic upstream error\r\n * - `network` — fetch to iframe's own backend failed\r\n * - `mismatch` — session token's user didn't match `accountUuid`\r\n */\r\nexport interface AddAccountWithTokenFailedPayload {\r\n  reason: string;\r\n  message?: string;\r\n}\r\n\r\n/**\r\n * Prep–Sign–Promote (v1.4) — iframe → host: signature captured.\r\n * Fires from the peer's /sharing/embed/{slug}/{prep_id} surface after a\r\n * successful POST to .../submit. The orchestrator's <PrepEmbed> listens\r\n * for this to chain into Sharing::shareUser + Sharing::promote.\r\n */\r\nexport interface PrepSignedPayload {\r\n  prep_id: string;\r\n}\r\n\r\n/**\r\n * Prep–Sign–Promote (v1.4) — iframe → host: signature rejected.\r\n * `error` mirrors the JSON body's `error` field from /submit (e.g.\r\n * `handler_rejected`, `invalid_state`, `not_found`).\r\n */\r\nexport interface PrepSignFailedPayload {\r\n  prep_id: string;\r\n  error: string;\r\n  message?: string;\r\n}\r\n","/**\r\n * Action types for Unified Action Protocol\r\n * These constants define all available actions that can be sent via ACTION_REQUEST\r\n */\r\nexport const ACTIONS = {\r\n  // Account management actions\r\n  GET_ACCOUNTS: 'get-accounts',\r\n  SWITCH_ACCOUNT: 'switch-account',\r\n  ADD_ACCOUNT: 'add-account',\r\n  REMOVE_ACCOUNT: 'remove-account',\r\n\r\n  // Authentication actions\r\n  LOGOUT_ACCOUNT: 'logout-account',\r\n  LOGOUT_ALL: 'logout-all',\r\n\r\n  // Profile management actions\r\n  MANAGE_ACCOUNT: 'manage-account',\r\n  UPDATE_AVATAR: 'update-avatar',\r\n\r\n  // Session management actions\r\n  SET_SESSION: 'set-session',  // Set session data from host (external login)\r\n} as const;\r\n\r\n/**\r\n * Action type - union of all possible action values\r\n */\r\nexport type Action = typeof ACTIONS[keyof typeof ACTIONS];\r\n","import type { PostMessageData } from './message-protocol';\nimport { MESSAGE_TYPES } from './message-protocol';\nimport type { Action } from './actions';\n\n/**\n * Protocol version for Unified Action Protocol\n */\nexport const PROTOCOL_VERSION = '1.0';\n\n/**\n * Generate a unique request ID\n */\nexport function generateRequestId(): string {\n  return `${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Create a PostMessage message with standard structure\n */\nexport function createMessage<T = any>(\n  type: string,\n  payload?: T,\n  requestId?: string\n): PostMessageData {\n  return {\n    type,\n    payload,\n    requestId: requestId || generateRequestId(),\n    timestamp: Date.now(),\n    version: PROTOCOL_VERSION,\n  };\n}\n\n/**\n * Create an ACTION_REQUEST message\n */\nexport function createActionRequest(\n  action: Action,\n  params: Record<string, any> = {},\n  requestId?: string\n): PostMessageData {\n  return createMessage(\n    MESSAGE_TYPES.ACTION_REQUEST,\n    {\n      action,\n      params,\n    },\n    requestId\n  );\n}\n","import type { Session, AccountSwitcherConfig, SetSessionPayload } from './types';\r\nimport { MESSAGE_TYPES, type PostMessageData } from './message-protocol';\r\nimport { ACTIONS } from './actions';\r\nimport { PROTOCOL_VERSION, generateRequestId } from './message-utils';\r\n\r\ninterface PendingRequest {\r\n  resolve: (value: any) => void;\r\n  reject: (error: Error) => void;\r\n  timeout: ReturnType<typeof setTimeout>;\r\n}\r\n\r\n/**\r\n * PostMessage client for communicating with the auth service iframe\r\n */\r\nexport class PostMessageClient {\r\n  private iframe: HTMLIFrameElement | null = null;\r\n  private iframeOrigin: string;\r\n  private isConnected = false;\r\n  private eventHandlers = new Map<string, Set<Function>>();\r\n  private pendingRequests = new Map<string, PendingRequest>();\r\n  private debug: boolean;\r\n  private serviceApiKey: string | undefined;\r\n\r\n  constructor(config: AccountSwitcherConfig) {\r\n    // Use config for potential future enhancements\r\n    const { authServiceUrl, debug: debugMode, serviceApiKey } = config;\r\n\r\n    this.iframeOrigin = authServiceUrl\r\n      ? new URL(authServiceUrl).origin\r\n      : '';\r\n    this.debug = debugMode || false;\r\n    this.serviceApiKey = serviceApiKey;\r\n    this.handleMessage = this.handleMessage.bind(this);\r\n\r\n    if (typeof window !== 'undefined') {\r\n      window.addEventListener('message', this.handleMessage);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Set the iframe reference\r\n   */\r\n  setIframe(iframe: HTMLIFrameElement, origin: string) {\r\n    this.iframe = iframe;\r\n    this.iframeOrigin = origin;\r\n\r\n    if (this.debug) {\r\n      console.log('[AccountSwitcher] Iframe set:', { origin });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Handle incoming PostMessage events\r\n   */\r\n  private handleMessage(event: MessageEvent) {\r\n    // Verify origin if we have one set\r\n    if (this.iframeOrigin && event.origin !== this.iframeOrigin) {\r\n      return;\r\n    }\r\n\r\n    const message = event.data as PostMessageData;\r\n    if (!message || !message.type) {\r\n      return;\r\n    }\r\n\r\n    if (this.debug) {\r\n      console.log('[AccountSwitcher] Received message:', message);\r\n    }\r\n\r\n    // Handle pending request responses\r\n    if (message.requestId && this.pendingRequests.has(message.requestId)) {\r\n      const pending = this.pendingRequests.get(message.requestId)!;\r\n      clearTimeout(pending.timeout);\r\n      this.pendingRequests.delete(message.requestId);\r\n\r\n      if (message.type === MESSAGE_TYPES.ERROR) {\r\n        pending.reject(new Error(message.payload?.message || 'Unknown error'));\r\n      } else {\r\n        pending.resolve(message.payload);\r\n      }\r\n      return;\r\n    }\r\n\r\n    // Handle connection handshake\r\n    if (message.type === MESSAGE_TYPES.READY) {\r\n      this.handleReady();\r\n      return;\r\n    }\r\n\r\n    if (message.type === MESSAGE_TYPES.HANDSHAKE_ACK) {\r\n      this.isConnected = true;\r\n      if (this.debug) {\r\n        console.log('[AccountSwitcher] Connection established', { isConnected: this.isConnected });\r\n      }\r\n      return;\r\n    }\r\n\r\n    // Emit events to registered handlers\r\n    // Pass the full message data including requestId for dialog handlers\r\n    this.emit(message.type, { requestId: message.requestId, payload: message.payload });\r\n  }\r\n\r\n  /**\r\n   * Handle READY message from iframe\r\n   */\r\n  private handleReady() {\r\n    if (this.debug) {\r\n      console.log('[AccountSwitcher] Iframe ready, sending handshake');\r\n    }\r\n\r\n    // Send handshake with service API key and requestId for proper protocol format\r\n    const requestId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n    const payload = {\r\n      apiKey: this.serviceApiKey,\r\n    };\r\n\r\n    this.sendMessage(MESSAGE_TYPES.HANDSHAKE, payload, requestId);\r\n  }\r\n\r\n  /**\r\n   * Register an event handler\r\n   */\r\n  on(eventType: string, handler: Function) {\r\n    if (!this.eventHandlers.has(eventType)) {\r\n      this.eventHandlers.set(eventType, new Set());\r\n    }\r\n    this.eventHandlers.get(eventType)!.add(handler);\r\n  }\r\n\r\n  /**\r\n   * Unregister an event handler\r\n   */\r\n  off(eventType: string, handler: Function) {\r\n    const handlers = this.eventHandlers.get(eventType);\r\n    if (handlers) {\r\n      handlers.delete(handler);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Emit an event to all registered handlers\r\n   */\r\n  private emit(eventType: string, payload: any) {\r\n    const handlers = this.eventHandlers.get(eventType);\r\n    if (handlers) {\r\n      handlers.forEach((handler) => {\r\n        try {\r\n          handler(payload);\r\n        } catch (error) {\r\n          console.error('[AccountSwitcher] Error in event handler:', error);\r\n        }\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Send a message to the iframe\r\n   */\r\n  private sendMessage(type: string, payload?: any, requestId?: string) {\r\n    if (!this.iframe?.contentWindow) {\r\n      if (this.debug) {\r\n        console.warn('[AccountSwitcher] Cannot send message: iframe not ready');\r\n      }\r\n      return;\r\n    }\r\n\r\n    const message: PostMessageData = {\r\n      type,\r\n      payload,\r\n      // The auth-service iframe bridge rejects any message without a string\r\n      // requestId (see isValidMessage), so always carry one — generating a\r\n      // fresh id for fire-and-forget sends that don't supply their own.\r\n      requestId: requestId || generateRequestId(),\r\n      timestamp: Date.now(),\r\n      version: PROTOCOL_VERSION,\r\n    };\r\n\r\n    if (this.debug) {\r\n      console.log('[AccountSwitcher] Sending message:', message);\r\n    }\r\n\r\n    this.iframe.contentWindow.postMessage(message, this.iframeOrigin);\r\n  }\r\n\r\n  /**\r\n   * Send a request and wait for response\r\n   */\r\n  private async request(type: string, payload?: any, timeout = 30000): Promise<any> {\r\n    return new Promise((resolve, reject) => {\r\n      const requestId = `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\r\n\r\n      const timeoutHandle = setTimeout(() => {\r\n        this.pendingRequests.delete(requestId);\r\n        reject(new Error(`Request timeout: ${type}`));\r\n      }, timeout);\r\n\r\n      this.pendingRequests.set(requestId, {\r\n        resolve,\r\n        reject,\r\n        timeout: timeoutHandle,\r\n      });\r\n\r\n      this.sendMessage(type, payload, requestId);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Switch to a different account\r\n   */\r\n  async switchAccount(userUuid: string): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.SWITCH_ACCOUNT,\r\n      params: { user_uuid: userUuid },\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Add a new account\r\n   */\r\n  async addAccount(): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.ADD_ACCOUNT,\r\n      params: {},\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Manage account (navigate to account management page)\r\n   */\r\n  async manageAccount(): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.MANAGE_ACCOUNT,\r\n      params: {},\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Update avatar (navigate to avatar update page)\r\n   */\r\n  async updateAvatar(): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.UPDATE_AVATAR,\r\n      params: {},\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Logout a specific account\r\n   */\r\n  async logoutAccount(userUuid: string): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.LOGOUT_ACCOUNT,\r\n      params: { user_uuid: userUuid },\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Logout all accounts\r\n   */\r\n  async logoutAll(): Promise<void> {\r\n    await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.LOGOUT_ALL,\r\n      params: {},\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Get current session state\r\n   */\r\n  async getSession(): Promise<Session> {\r\n    return await this.request(MESSAGE_TYPES.ACTION_REQUEST, {\r\n      action: ACTIONS.GET_ACCOUNTS,\r\n      params: {},\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Set session from external login (e.g., host application's login flow)\r\n   */\r\n  async setSession(sessionData: SetSessionPayload): Promise<void> {\r\n    return this.request(MESSAGE_TYPES.SET_SESSION, sessionData);\r\n  }\r\n\r\n  /**\r\n   * Send dialog response\r\n   */\r\n  sendDialogResponse(type: string, requestId: string, payload: any) {\r\n    this.sendMessage(type, payload, requestId);\r\n  }\r\n\r\n  /**\r\n   * Public: post a fully-enveloped, fire-and-forget message at the iframe.\r\n   *\r\n   * Unlike `request()`, this does not await a response. A requestId, timestamp\r\n   * and protocol version are attached automatically so the auth-service iframe's\r\n   * isValidMessage() accepts the message. Used by the cross-product handoff\r\n   * (sharing/multiAccountAutoAdd) via the provider context's `sendMessage`.\r\n   */\r\n  send(type: string, payload?: any): void {\r\n    this.sendMessage(type, payload);\r\n  }\r\n\r\n  /**\r\n   * Public: whether the client can actually deliver a message to the iframe —\r\n   * i.e. an iframe is registered AND the handshake has completed. The iframe's\r\n   * bridge drops any non-HANDSHAKE message received before its own handshake,\r\n   * so callers that fire one-shot messages (e.g. the handoff auto-add) should\r\n   * wait for this before sending.\r\n   */\r\n  isReady(): boolean {\r\n    return !!this.iframe?.contentWindow && this.isConnected;\r\n  }\r\n\r\n  /**\r\n   * Clean up resources\r\n   */\r\n  destroy() {\r\n    if (typeof window !== 'undefined') {\r\n      window.removeEventListener('message', this.handleMessage);\r\n    }\r\n\r\n    // Clear all pending requests\r\n    this.pendingRequests.forEach((pending) => {\r\n      clearTimeout(pending.timeout);\r\n      pending.reject(new Error('Client destroyed'));\r\n    });\r\n\r\n    this.pendingRequests.clear();\r\n    this.eventHandlers.clear();\r\n    this.iframe = null;\r\n    this.isConnected = false;\r\n  }\r\n}\r\n","import type { ConfirmPayload, PromptPayload, AlertPayload, DialogConfig } from './types';\n\n/**\n * Dialog Manager for Account Switcher\n *\n * Provides custom styled dialogs for confirm, prompt, and alert interactions.\n * Ported from the Laravel account-switcher-client.js implementation.\n */\nexport class DialogManager {\n  private activeDialog: HTMLElement | null = null;\n  private previousFocus: HTMLElement | null = null;\n  private dialogStylesInjected = false;\n  private config: DialogConfig;\n\n  constructor(config: DialogConfig = {}) {\n    this.config = {\n      enabled: config.enabled !== false,\n      closeOnOverlayClick: config.closeOnOverlayClick !== false,\n      closeOnEscape: config.closeOnEscape !== false,\n    };\n  }\n\n  /**\n   * Show a confirm dialog\n   */\n  async showConfirm(payload: ConfirmPayload): Promise<boolean> {\n    if (this.activeDialog) {\n      throw new Error('Another dialog is already open');\n    }\n\n    return new Promise((resolve) => {\n      const overlay = this.createDialogOverlay();\n      const dialog = this.createConfirmDialog(payload);\n\n      const handleConfirm = () => {\n        this.destroyDialog(overlay);\n        resolve(true);\n      };\n\n      const handleCancel = () => {\n        this.destroyDialog(overlay);\n        resolve(false);\n      };\n\n      // Attach button listeners\n      dialog.querySelector('.asc-dialog-btn-confirm')?.addEventListener('click', handleConfirm);\n      dialog.querySelector('.asc-dialog-btn-cancel')?.addEventListener('click', handleCancel);\n\n      // ESC key handler\n      const handleKeyDown = (e: KeyboardEvent) => {\n        if (e.key === 'Escape' && this.config.closeOnEscape) {\n          document.removeEventListener('keydown', handleKeyDown);\n          handleCancel();\n        }\n        if (e.key === 'Enter') {\n          e.preventDefault();\n          document.removeEventListener('keydown', handleKeyDown);\n          handleConfirm();\n        }\n      };\n      document.addEventListener('keydown', handleKeyDown);\n\n      // Overlay click handler\n      if (this.config.closeOnOverlayClick) {\n        overlay.addEventListener('click', (e) => {\n          if (e.target === overlay) {\n            document.removeEventListener('keydown', handleKeyDown);\n            handleCancel();\n          }\n        });\n      }\n\n      // Show dialog\n      this.previousFocus = document.activeElement as HTMLElement;\n      overlay.appendChild(dialog);\n      document.body.appendChild(overlay);\n      this.activeDialog = overlay;\n\n      // Set up focus trap and focus first button\n      this.trapFocus(dialog);\n      (dialog.querySelector('.asc-dialog-btn-confirm') as HTMLElement)?.focus();\n    });\n  }\n\n  /**\n   * Show a prompt dialog\n   */\n  async showPrompt(payload: PromptPayload): Promise<{ value: string | null; cancelled: boolean }> {\n    if (this.activeDialog) {\n      throw new Error('Another dialog is already open');\n    }\n\n    return new Promise((resolve) => {\n      const overlay = this.createDialogOverlay();\n      const dialog = this.createPromptDialog(payload);\n      const input = dialog.querySelector('.asc-dialog-input') as HTMLInputElement;\n\n      const handleSubmit = () => {\n        const value = input.value;\n        this.destroyDialog(overlay);\n        resolve({ value, cancelled: false });\n      };\n\n      const handleCancel = () => {\n        this.destroyDialog(overlay);\n        resolve({ value: null, cancelled: true });\n      };\n\n      // Attach button listeners\n      dialog.querySelector('.asc-dialog-btn-confirm')?.addEventListener('click', handleSubmit);\n      dialog.querySelector('.asc-dialog-btn-cancel')?.addEventListener('click', handleCancel);\n\n      // Input Enter key handler\n      input.addEventListener('keydown', (e) => {\n        if (e.key === 'Enter') {\n          e.preventDefault();\n          handleSubmit();\n        }\n      });\n\n      // ESC key handler\n      const handleKeyDown = (e: KeyboardEvent) => {\n        if (e.key === 'Escape' && this.config.closeOnEscape) {\n          document.removeEventListener('keydown', handleKeyDown);\n          handleCancel();\n        }\n      };\n      document.addEventListener('keydown', handleKeyDown);\n\n      // Overlay click handler\n      if (this.config.closeOnOverlayClick) {\n        overlay.addEventListener('click', (e) => {\n          if (e.target === overlay) {\n            document.removeEventListener('keydown', handleKeyDown);\n            handleCancel();\n          }\n        });\n      }\n\n      // Show dialog\n      this.previousFocus = document.activeElement as HTMLElement;\n      overlay.appendChild(dialog);\n      document.body.appendChild(overlay);\n      this.activeDialog = overlay;\n\n      // Set up focus trap and focus input\n      this.trapFocus(dialog);\n      input.focus();\n      input.select();\n    });\n  }\n\n  /**\n   * Show an alert dialog\n   */\n  async showAlert(payload: AlertPayload): Promise<void> {\n    if (this.activeDialog) {\n      throw new Error('Another dialog is already open');\n    }\n\n    return new Promise((resolve) => {\n      const overlay = this.createDialogOverlay();\n      const dialog = this.createAlertDialog(payload);\n\n      const handleOk = () => {\n        this.destroyDialog(overlay);\n        resolve();\n      };\n\n      // Attach button listener\n      dialog.querySelector('.asc-dialog-btn-confirm')?.addEventListener('click', handleOk);\n\n      // ESC and Enter key handlers\n      const handleKeyDown = (e: KeyboardEvent) => {\n        if ((e.key === 'Escape' && this.config.closeOnEscape) || e.key === 'Enter') {\n          e.preventDefault();\n          document.removeEventListener('keydown', handleKeyDown);\n          handleOk();\n        }\n      };\n      document.addEventListener('keydown', handleKeyDown);\n\n      // Overlay click handler\n      if (this.config.closeOnOverlayClick) {\n        overlay.addEventListener('click', (e) => {\n          if (e.target === overlay) {\n            document.removeEventListener('keydown', handleKeyDown);\n            handleOk();\n          }\n        });\n      }\n\n      // Show dialog\n      this.previousFocus = document.activeElement as HTMLElement;\n      overlay.appendChild(dialog);\n      document.body.appendChild(overlay);\n      this.activeDialog = overlay;\n\n      // Set up focus trap and focus button\n      this.trapFocus(dialog);\n      (dialog.querySelector('.asc-dialog-btn-confirm') as HTMLElement)?.focus();\n    });\n  }\n\n  /**\n   * Create dialog overlay backdrop\n   */\n  private createDialogOverlay(): HTMLElement {\n    const overlay = document.createElement('div');\n    overlay.className = 'asc-dialog-overlay';\n    overlay.setAttribute('role', 'presentation');\n    return overlay;\n  }\n\n  /**\n   * Create confirm dialog element\n   */\n  private createConfirmDialog(payload: ConfirmPayload): HTMLElement {\n    const dialog = document.createElement('div');\n    dialog.className = 'asc-dialog asc-dialog-confirm';\n    dialog.setAttribute('role', 'dialog');\n    dialog.setAttribute('aria-labelledby', 'asc-dialog-title');\n    dialog.setAttribute('aria-modal', 'true');\n\n    const variant = payload.variant || 'info';\n    const title = payload.title || 'Confirm';\n    const message = payload.message || '';\n    const confirmText = payload.confirmText || 'OK';\n    const cancelText = payload.cancelText || 'Cancel';\n\n    dialog.innerHTML = `\n      <div class=\"asc-dialog-header\">\n        <h3 id=\"asc-dialog-title\" class=\"asc-dialog-title\"></h3>\n      </div>\n      <div class=\"asc-dialog-body\">\n        <p class=\"asc-dialog-message\"></p>\n      </div>\n      <div class=\"asc-dialog-footer\">\n        <button class=\"asc-dialog-btn asc-dialog-btn-cancel\" type=\"button\"></button>\n        <button class=\"asc-dialog-btn asc-dialog-btn-confirm asc-dialog-btn-${variant}\" type=\"button\"></button>\n      </div>\n    `;\n\n    // Set text content safely (XSS protection)\n    dialog.querySelector('#asc-dialog-title')!.textContent = title;\n    dialog.querySelector('.asc-dialog-message')!.textContent = message;\n    dialog.querySelector('.asc-dialog-btn-cancel')!.textContent = cancelText;\n    dialog.querySelector('.asc-dialog-btn-confirm')!.textContent = confirmText;\n\n    return dialog;\n  }\n\n  /**\n   * Create prompt dialog element\n   */\n  private createPromptDialog(payload: PromptPayload): HTMLElement {\n    const dialog = document.createElement('div');\n    dialog.className = 'asc-dialog asc-dialog-prompt';\n    dialog.setAttribute('role', 'dialog');\n    dialog.setAttribute('aria-labelledby', 'asc-dialog-title');\n    dialog.setAttribute('aria-modal', 'true');\n\n    const title = payload.title || 'Input Required';\n    const message = payload.message || '';\n    const defaultValue = payload.defaultValue || '';\n    const placeholder = payload.placeholder || '';\n\n    dialog.innerHTML = `\n      <div class=\"asc-dialog-header\">\n        <h3 id=\"asc-dialog-title\" class=\"asc-dialog-title\"></h3>\n      </div>\n      <div class=\"asc-dialog-body\">\n        <p class=\"asc-dialog-message\"></p>\n        <input type=\"text\" class=\"asc-dialog-input\" value=\"\" placeholder=\"\">\n      </div>\n      <div class=\"asc-dialog-footer\">\n        <button class=\"asc-dialog-btn asc-dialog-btn-cancel\" type=\"button\">Cancel</button>\n        <button class=\"asc-dialog-btn asc-dialog-btn-confirm\" type=\"button\">Submit</button>\n      </div>\n    `;\n\n    // Set text content safely (XSS protection)\n    dialog.querySelector('#asc-dialog-title')!.textContent = title;\n    dialog.querySelector('.asc-dialog-message')!.textContent = message;\n    (dialog.querySelector('.asc-dialog-input') as HTMLInputElement).value = defaultValue;\n    (dialog.querySelector('.asc-dialog-input') as HTMLInputElement).placeholder = placeholder;\n\n    return dialog;\n  }\n\n  /**\n   * Create alert dialog element\n   */\n  private createAlertDialog(payload: AlertPayload): HTMLElement {\n    const dialog = document.createElement('div');\n    dialog.className = 'asc-dialog asc-dialog-alert';\n    dialog.setAttribute('role', 'alertdialog');\n    dialog.setAttribute('aria-labelledby', 'asc-dialog-title');\n    dialog.setAttribute('aria-modal', 'true');\n\n    const variant = payload.variant || 'info';\n    const title = payload.title || 'Alert';\n    const message = payload.message || '';\n\n    dialog.innerHTML = `\n      <div class=\"asc-dialog-header\">\n        <h3 id=\"asc-dialog-title\" class=\"asc-dialog-title\"></h3>\n      </div>\n      <div class=\"asc-dialog-body\">\n        <p class=\"asc-dialog-message\"></p>\n      </div>\n      <div class=\"asc-dialog-footer\">\n        <button class=\"asc-dialog-btn asc-dialog-btn-confirm asc-dialog-btn-${variant}\" type=\"button\">OK</button>\n      </div>\n    `;\n\n    // Set text content safely (XSS protection)\n    dialog.querySelector('#asc-dialog-title')!.textContent = title;\n    dialog.querySelector('.asc-dialog-message')!.textContent = message;\n\n    return dialog;\n  }\n\n  /**\n   * Destroy and remove a dialog\n   */\n  private destroyDialog(overlay: HTMLElement): void {\n    if (!overlay || !overlay.parentNode) return;\n\n    // Restore focus\n    if (this.previousFocus && typeof this.previousFocus.focus === 'function') {\n      try {\n        this.previousFocus.focus();\n      } catch (e) {\n        // Element may no longer be focusable\n      }\n    }\n\n    // Remove from DOM\n    overlay.parentNode.removeChild(overlay);\n    this.activeDialog = null;\n    this.previousFocus = null;\n  }\n\n  /**\n   * Trap focus within dialog for accessibility\n   */\n  private trapFocus(dialog: HTMLElement): void {\n    const focusableSelectors = [\n      'button:not([disabled])',\n      'input:not([disabled])',\n      'textarea:not([disabled])',\n      'select:not([disabled])',\n      '[tabindex]:not([tabindex=\"-1\"])',\n    ].join(',');\n\n    const focusableElements = dialog.querySelectorAll(focusableSelectors);\n    if (focusableElements.length === 0) return;\n\n    const firstFocusable = focusableElements[0] as HTMLElement;\n    const lastFocusable = focusableElements[focusableElements.length - 1] as HTMLElement;\n\n    const handleTabKey = (e: KeyboardEvent) => {\n      if (e.key !== 'Tab') return;\n\n      if (e.shiftKey) {\n        // Shift + Tab\n        if (document.activeElement === firstFocusable) {\n          e.preventDefault();\n          lastFocusable.focus();\n        }\n      } else {\n        // Tab\n        if (document.activeElement === lastFocusable) {\n          e.preventDefault();\n          firstFocusable.focus();\n        }\n      }\n    };\n\n    dialog.addEventListener('keydown', handleTabKey);\n  }\n\n  /**\n   * Inject dialog CSS styles into the document\n   */\n  injectDialogStyles(): void {\n    if (this.dialogStylesInjected) return;\n\n    const style = document.createElement('style');\n    style.id = 'asc-dialog-styles';\n    style.textContent = `\n/* Account Switcher Client Dialog Styles */\n.asc-dialog-overlay {\n  position: fixed;\n  top: 0;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  background: rgba(0, 0, 0, 0.5);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  z-index: 9999;\n  animation: asc-fade-in 200ms ease-out;\n  padding: 16px;\n}\n\n.asc-dialog {\n  background: #ffffff;\n  border-radius: 12px;\n  box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);\n  max-width: 400px;\n  width: 100%;\n  max-height: calc(100vh - 32px);\n  overflow: hidden;\n  display: flex;\n  flex-direction: column;\n  animation: asc-scale-in 250ms ease-out;\n}\n\n.asc-dialog-header {\n  padding: 24px 24px 16px;\n  border-bottom: 1px solid #e5e7eb;\n}\n\n.asc-dialog-title {\n  margin: 0;\n  font-size: 18px;\n  font-weight: 600;\n  color: #1f2937;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n\n.asc-dialog-body {\n  padding: 24px;\n  overflow-y: auto;\n  flex: 1;\n}\n\n.asc-dialog-message {\n  margin: 0 0 16px 0;\n  color: #4b5563;\n  line-height: 1.6;\n  font-size: 14px;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n\n.asc-dialog-input {\n  width: 100%;\n  padding: 12px 16px;\n  border: 1px solid #d1d5db;\n  border-radius: 8px;\n  font-size: 14px;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n  transition: border-color 150ms, box-shadow 150ms;\n  box-sizing: border-box;\n}\n\n.asc-dialog-input:focus {\n  outline: none;\n  border-color: #3b82f6;\n  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);\n}\n\n.asc-dialog-footer {\n  padding: 16px 24px 24px;\n  display: flex;\n  gap: 12px;\n  justify-content: flex-end;\n}\n\n.asc-dialog-btn {\n  padding: 0 24px;\n  height: 40px;\n  border-radius: 8px;\n  border: none;\n  font-size: 14px;\n  font-weight: 500;\n  cursor: pointer;\n  transition: all 150ms;\n  white-space: nowrap;\n  font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n}\n\n.asc-dialog-btn:focus {\n  outline: 2px solid;\n  outline-offset: 2px;\n}\n\n.asc-dialog-btn-cancel {\n  background: #f3f4f6;\n  color: #374151;\n}\n\n.asc-dialog-btn-cancel:hover {\n  background: #e5e7eb;\n}\n\n.asc-dialog-btn-cancel:focus {\n  outline-color: #9ca3af;\n}\n\n.asc-dialog-btn-confirm {\n  background: #3b82f6;\n  color: white;\n}\n\n.asc-dialog-btn-confirm:hover {\n  background: #2563eb;\n}\n\n.asc-dialog-btn-confirm:focus {\n  outline-color: #3b82f6;\n}\n\n.asc-dialog-btn-info { background: #3b82f6; }\n.asc-dialog-btn-info:hover { background: #2563eb; }\n.asc-dialog-btn-info:focus { outline-color: #3b82f6; }\n\n.asc-dialog-btn-warning { background: #f59e0b; }\n.asc-dialog-btn-warning:hover { background: #d97706; }\n.asc-dialog-btn-warning:focus { outline-color: #f59e0b; }\n\n.asc-dialog-btn-danger { background: #ef4444; }\n.asc-dialog-btn-danger:hover { background: #dc2626; }\n.asc-dialog-btn-danger:focus { outline-color: #ef4444; }\n\n.asc-dialog-btn-error { background: #ef4444; }\n.asc-dialog-btn-error:hover { background: #dc2626; }\n.asc-dialog-btn-error:focus { outline-color: #ef4444; }\n\n.asc-dialog-btn-success { background: #10b981; }\n.asc-dialog-btn-success:hover { background: #059669; }\n.asc-dialog-btn-success:focus { outline-color: #10b981; }\n\n@keyframes asc-fade-in {\n  from { opacity: 0; }\n  to { opacity: 1; }\n}\n\n@keyframes asc-scale-in {\n  from {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n  to {\n    opacity: 1;\n    transform: scale(1);\n  }\n}\n\n@media (max-width: 480px) {\n  .asc-dialog-footer {\n    flex-direction: column-reverse;\n  }\n  .asc-dialog-btn {\n    width: 100%;\n  }\n}\n    `;\n    document.head.appendChild(style);\n    this.dialogStylesInjected = true;\n  }\n}\n","import { useAccountSwitcherContext } from '../components/AccountSwitcherProvider';\n\n/**\n * Hook to access session state\n * Returns current session information including authentication status, user, and accounts\n */\nexport function useSession() {\n  const { session, isLoading, error } = useAccountSwitcherContext();\n\n  return {\n    ...session,\n    isLoading,\n    error,\n  };\n}\n","'use client';\r\n\r\nimport { useEffect, useRef, useState } from 'react';\r\nimport { useAccountSwitcherContext } from './AccountSwitcherProvider';\r\n\r\nexport interface AccountSwitcherProps {\r\n  className?: string;\r\n  position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\r\n  width?: number;\r\n  height?: number;\r\n  /** Callback when iframe height changes (auto-resize) */\r\n  onHeightChange?: (height: number) => void;\r\n}\r\n\r\n/**\r\n * AccountSwitcher iframe component\r\n * Displays the account switcher widget in an iframe\r\n */\r\nexport function AccountSwitcher({\r\n  className = '',\r\n  width = 320,\r\n  height: initialHeight = 400,\r\n  onHeightChange,\r\n}: AccountSwitcherProps) {\r\n  const containerRef = useRef<HTMLDivElement>(null);\r\n  const iframeRef = useRef<HTMLIFrameElement>(null);\r\n  const [isLoading, setIsLoading] = useState(true);\r\n  const [error, setError] = useState<Error | null>(null);\r\n  const [embedUrl, setEmbedUrl] = useState<string | null>(null);\r\n  const { registerIframe } = useAccountSwitcherContext();\r\n\r\n  // Fetch widget token from backend (backend should implement this endpoint)\r\n  useEffect(() => {\r\n    if (typeof window === 'undefined') return;\r\n\r\n    const fetchToken = async () => {\r\n      try {\r\n        // This endpoint should be implemented in the Next.js app\r\n        // It calls the backend API to get the widget token\r\n        const response = await fetch('/api/account-switcher/token');\r\n\r\n        if (!response.ok) {\r\n          throw new Error(`HTTP ${response.status}`);\r\n        }\r\n\r\n        const data = await response.json();\r\n\r\n        if (!data.embed_url) {\r\n          throw new Error('No embed_url in response');\r\n        }\r\n\r\n        setEmbedUrl(data.embed_url);\r\n        setIsLoading(false);\r\n      } catch (err) {\r\n        setError(err as Error);\r\n        setIsLoading(false);\r\n      }\r\n    };\r\n\r\n    fetchToken();\r\n  }, []);\r\n\r\n  // Register iframe with PostMessageClient when it loads\r\n  useEffect(() => {\r\n    if (!iframeRef.current || !embedUrl) return;\r\n\r\n    const iframe = iframeRef.current;\r\n\r\n    // Extract origin from embed URL\r\n    const url = new URL(embedUrl);\r\n    const origin = url.origin;\r\n\r\n    // Register iframe after it loads\r\n    const handleLoad = () => {\r\n      registerIframe(iframe, origin);\r\n    };\r\n\r\n    iframe.addEventListener('load', handleLoad);\r\n\r\n    return () => {\r\n      iframe.removeEventListener('load', handleLoad);\r\n    };\r\n  }, [embedUrl, registerIframe]);\r\n\r\n  // Listen for resize messages from iframe\r\n  useEffect(() => {\r\n    if (typeof window === 'undefined') return;\r\n\r\n    const handleMessage = (event: MessageEvent) => {\r\n      // Check if message is from our iframe\r\n      if (!embedUrl) return;\r\n\r\n      const url = new URL(embedUrl);\r\n      if (event.origin !== url.origin) return;\r\n\r\n      const message = event.data;\r\n      if (!message || message.type !== 'SIZE_CHANGED') return;\r\n\r\n      const payload = message.payload || message;\r\n      if (payload.height && iframeRef.current) {\r\n        // Use direct DOM manipulation instead of state update to avoid re-render\r\n        iframeRef.current.style.height = `${payload.height}px`;\r\n        onHeightChange?.(payload.height);\r\n      }\r\n    };\r\n\r\n    window.addEventListener('message', handleMessage);\r\n\r\n    return () => {\r\n      window.removeEventListener('message', handleMessage);\r\n    };\r\n  }, [embedUrl, onHeightChange]);\r\n\r\n  if (isLoading) {\r\n    return (\r\n      <div\r\n        className={`${className} flex items-center justify-center`}\r\n        style={{ width, height: initialHeight }}\r\n      >\r\n        <div className=\"animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900\"></div>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  if (error) {\r\n    return (\r\n      <div\r\n        className={`${className} flex items-center justify-center text-red-500`}\r\n        style={{ width, height: initialHeight }}\r\n      >\r\n        <p>Failed to load account switcher</p>\r\n      </div>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <div ref={containerRef} className={`${className} relative`}>\r\n      <iframe\r\n        ref={iframeRef}\r\n        src={embedUrl || ''}\r\n        style={{ width, height: initialHeight }}\r\n        className=\"border-0 rounded-lg shadow-lg\"\r\n        title=\"Account Switcher\"\r\n        sandbox=\"allow-same-origin allow-scripts allow-forms\"\r\n      />\r\n    </div>\r\n  );\r\n}\r\n","'use client';\r\nimport { useEffect } from 'react';\r\nimport { useHandoffArrival } from '../hooks/useHandoffArrival';\r\n\r\nexport interface HandoffArrivalToastProps {\r\n  /** Auto-dismiss after this many ms. Default 5000. Pass 0 to disable. */\r\n  autoDismissMs?: number;\r\n}\r\n\r\n/**\r\n * Drop-in arrival banner — pair with the F2 → F5 handoff flow. Renders nothing\r\n * when there's no `?_toast=` to show.\r\n */\r\nexport function HandoffArrivalToast({ autoDismissMs = 5_000 }: HandoffArrivalToastProps) {\r\n  const { toast, dismiss } = useHandoffArrival();\r\n\r\n  useEffect(() => {\r\n    if (!toast || autoDismissMs <= 0) return;\r\n    const t = setTimeout(dismiss, autoDismissMs);\r\n    return () => clearTimeout(t);\r\n  }, [toast, autoDismissMs, dismiss]);\r\n\r\n  if (!toast) return null;\r\n\r\n  return (\r\n    <div\r\n      role=\"status\"\r\n      aria-live=\"polite\"\r\n      style={{\r\n        position: 'fixed',\r\n        top: 16,\r\n        left: '50%',\r\n        transform: 'translateX(-50%)',\r\n        zIndex: 9999,\r\n        background: '#111',\r\n        color: '#fff',\r\n        padding: '10px 16px',\r\n        borderRadius: 8,\r\n        boxShadow: '0 4px 14px rgba(0,0,0,0.2)',\r\n        fontFamily: 'system-ui, sans-serif',\r\n        fontSize: 14,\r\n        display: 'flex',\r\n        alignItems: 'center',\r\n        gap: 12,\r\n      }}\r\n    >\r\n      <span>{toast}</span>\r\n      <button\r\n        type=\"button\"\r\n        onClick={dismiss}\r\n        aria-label=\"Dismiss\"\r\n        style={{\r\n          background: 'transparent',\r\n          border: 'none',\r\n          color: '#fff',\r\n          cursor: 'pointer',\r\n          fontSize: 16,\r\n          lineHeight: 1,\r\n        }}\r\n      >\r\n        ×\r\n      </button>\r\n    </div>\r\n  );\r\n}\r\n","'use client';\r\nimport { useCallback, useEffect, useRef, useState } from 'react';\r\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation';\r\n\r\nconst PARAM = '_toast';\r\n\r\nexport interface HandoffArrival {\r\n  toast: string | null;\r\n  dismiss: () => void;\r\n}\r\n\r\n/**\r\n * Reads the `?_toast=…` query param once on mount, scrubs it from the URL via\r\n * `router.replace`, and returns the decoded message. Intended to be mounted in\r\n * a top-level layout so any page the user lands on after a cross-product\r\n * handoff (F2 → F5) can render the arrival banner.\r\n */\r\nexport function useHandoffArrival(): HandoffArrival {\r\n  const router = useRouter();\r\n  const pathname = usePathname();\r\n  const params = useSearchParams();\r\n  const fired = useRef(false);\r\n  const [toast, setToast] = useState<string | null>(null);\r\n\r\n  useEffect(() => {\r\n    if (fired.current) return;\r\n    fired.current = true;\r\n\r\n    const raw = params?.get(PARAM);\r\n    if (!raw) return;\r\n\r\n    setToast(raw);\r\n\r\n    const remaining = new URLSearchParams(params?.toString() ?? '');\r\n    remaining.delete(PARAM);\r\n    const qs = remaining.toString();\r\n    router.replace(qs ? `${pathname}?${qs}` : pathname);\r\n  }, [params, pathname, router]);\r\n\r\n  const dismiss = useCallback(() => setToast(null), []);\r\n\r\n  return { toast, dismiss };\r\n}\r\n"],"mappings":"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","names":["useState","useEffect","useRef","useCallback","error","value","jsx","useState","useRef","useCallback","useEffect","useEffect","useRef","useState","jsx","useRef","useState","useEffect","useEffect","useCallback","useEffect","useRef","useState","jsx","jsxs","useEffect"]}