@smoregg/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/cjs/components/DirectionPad.cjs +68 -0
  2. package/dist/cjs/components/DirectionPad.cjs.map +1 -0
  3. package/dist/cjs/components/DirectionPad.module.css.cjs +12 -0
  4. package/dist/cjs/components/DirectionPad.module.css.cjs.map +1 -0
  5. package/dist/cjs/components/HoldButton.cjs +57 -0
  6. package/dist/cjs/components/HoldButton.cjs.map +1 -0
  7. package/dist/cjs/components/HoldButton.module.css.cjs +12 -0
  8. package/dist/cjs/components/HoldButton.module.css.cjs.map +1 -0
  9. package/dist/cjs/components/SwipeArea.cjs +58 -0
  10. package/dist/cjs/components/SwipeArea.cjs.map +1 -0
  11. package/dist/cjs/components/SwipeArea.module.css.cjs +12 -0
  12. package/dist/cjs/components/SwipeArea.module.css.cjs.map +1 -0
  13. package/dist/cjs/components/TapButton.cjs +58 -0
  14. package/dist/cjs/components/TapButton.cjs.map +1 -0
  15. package/dist/cjs/components/TapButton.module.css.cjs +12 -0
  16. package/dist/cjs/components/TapButton.module.css.cjs.map +1 -0
  17. package/dist/cjs/context/RoomProvider.cjs +118 -0
  18. package/dist/cjs/context/RoomProvider.cjs.map +1 -0
  19. package/dist/cjs/hooks/useExternalGames.cjs +49 -0
  20. package/dist/cjs/hooks/useExternalGames.cjs.map +1 -0
  21. package/dist/cjs/hooks/useGameHost.cjs +135 -0
  22. package/dist/cjs/hooks/useGameHost.cjs.map +1 -0
  23. package/dist/cjs/hooks/useGamePlayer.cjs +75 -0
  24. package/dist/cjs/hooks/useGamePlayer.cjs.map +1 -0
  25. package/dist/cjs/iframe/index.cjs +508 -0
  26. package/dist/cjs/iframe/index.cjs.map +1 -0
  27. package/dist/cjs/index.cjs +32 -0
  28. package/dist/cjs/index.cjs.map +1 -0
  29. package/dist/cjs/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.cjs +33 -0
  30. package/dist/cjs/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.cjs.map +1 -0
  31. package/dist/cjs/server/index.cjs +45 -0
  32. package/dist/cjs/server/index.cjs.map +1 -0
  33. package/dist/cjs/transport/DirectTransport.cjs +23 -0
  34. package/dist/cjs/transport/DirectTransport.cjs.map +1 -0
  35. package/dist/cjs/transport/PostMessageTransport.cjs +72 -0
  36. package/dist/cjs/transport/PostMessageTransport.cjs.map +1 -0
  37. package/dist/cjs/transport/protocol.cjs +10 -0
  38. package/dist/cjs/transport/protocol.cjs.map +1 -0
  39. package/dist/esm/components/DirectionPad.js +66 -0
  40. package/dist/esm/components/DirectionPad.js.map +1 -0
  41. package/dist/esm/components/DirectionPad.module.css.js +8 -0
  42. package/dist/esm/components/DirectionPad.module.css.js.map +1 -0
  43. package/dist/esm/components/HoldButton.js +55 -0
  44. package/dist/esm/components/HoldButton.js.map +1 -0
  45. package/dist/esm/components/HoldButton.module.css.js +8 -0
  46. package/dist/esm/components/HoldButton.module.css.js.map +1 -0
  47. package/dist/esm/components/SwipeArea.js +56 -0
  48. package/dist/esm/components/SwipeArea.js.map +1 -0
  49. package/dist/esm/components/SwipeArea.module.css.js +8 -0
  50. package/dist/esm/components/SwipeArea.module.css.js.map +1 -0
  51. package/dist/esm/components/TapButton.js +56 -0
  52. package/dist/esm/components/TapButton.js.map +1 -0
  53. package/dist/esm/components/TapButton.module.css.js +8 -0
  54. package/dist/esm/components/TapButton.module.css.js.map +1 -0
  55. package/dist/esm/context/RoomProvider.js +109 -0
  56. package/dist/esm/context/RoomProvider.js.map +1 -0
  57. package/dist/esm/hooks/useExternalGames.js +47 -0
  58. package/dist/esm/hooks/useExternalGames.js.map +1 -0
  59. package/dist/esm/hooks/useGameHost.js +133 -0
  60. package/dist/esm/hooks/useGameHost.js.map +1 -0
  61. package/dist/esm/hooks/useGamePlayer.js +73 -0
  62. package/dist/esm/hooks/useGamePlayer.js.map +1 -0
  63. package/dist/esm/iframe/index.js +502 -0
  64. package/dist/esm/iframe/index.js.map +1 -0
  65. package/dist/esm/index.js +11 -0
  66. package/dist/esm/index.js.map +1 -0
  67. package/dist/esm/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js +29 -0
  68. package/dist/esm/node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js.map +1 -0
  69. package/dist/esm/server/index.js +43 -0
  70. package/dist/esm/server/index.js.map +1 -0
  71. package/dist/esm/transport/DirectTransport.js +21 -0
  72. package/dist/esm/transport/DirectTransport.js.map +1 -0
  73. package/dist/esm/transport/PostMessageTransport.js +70 -0
  74. package/dist/esm/transport/PostMessageTransport.js.map +1 -0
  75. package/dist/esm/transport/protocol.js +7 -0
  76. package/dist/esm/transport/protocol.js.map +1 -0
  77. package/dist/types/components/DirectionPad.d.ts +21 -0
  78. package/dist/types/components/DirectionPad.d.ts.map +1 -0
  79. package/dist/types/components/HoldButton.d.ts +22 -0
  80. package/dist/types/components/HoldButton.d.ts.map +1 -0
  81. package/dist/types/components/IframeGameBridge.d.ts +40 -0
  82. package/dist/types/components/IframeGameBridge.d.ts.map +1 -0
  83. package/dist/types/components/SwipeArea.d.ts +19 -0
  84. package/dist/types/components/SwipeArea.d.ts.map +1 -0
  85. package/dist/types/components/TapButton.d.ts +19 -0
  86. package/dist/types/components/TapButton.d.ts.map +1 -0
  87. package/dist/types/components/index.d.ts +8 -0
  88. package/dist/types/components/index.d.ts.map +1 -0
  89. package/dist/types/context/RoomProvider.d.ts +69 -0
  90. package/dist/types/context/RoomProvider.d.ts.map +1 -0
  91. package/dist/types/context/index.d.ts +3 -0
  92. package/dist/types/context/index.d.ts.map +1 -0
  93. package/dist/types/dev/DevSimulator.d.ts +31 -0
  94. package/dist/types/dev/DevSimulator.d.ts.map +1 -0
  95. package/dist/types/dev/index.d.ts +2 -0
  96. package/dist/types/dev/index.d.ts.map +1 -0
  97. package/dist/types/hooks/index.d.ts +4 -0
  98. package/dist/types/hooks/index.d.ts.map +1 -0
  99. package/dist/types/hooks/useExternalGames.d.ts +32 -0
  100. package/dist/types/hooks/useExternalGames.d.ts.map +1 -0
  101. package/dist/types/hooks/useGameHost.d.ts +40 -0
  102. package/dist/types/hooks/useGameHost.d.ts.map +1 -0
  103. package/dist/types/hooks/useGamePlayer.d.ts +17 -0
  104. package/dist/types/hooks/useGamePlayer.d.ts.map +1 -0
  105. package/dist/types/iframe/IframeRoomProvider.d.ts +31 -0
  106. package/dist/types/iframe/IframeRoomProvider.d.ts.map +1 -0
  107. package/dist/types/iframe/index.d.ts +18 -0
  108. package/dist/types/iframe/index.d.ts.map +1 -0
  109. package/dist/types/iframe/vanilla.d.ts +40 -0
  110. package/dist/types/iframe/vanilla.d.ts.map +1 -0
  111. package/dist/types/index.d.ts +34 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/types/server/createGameRelay.d.ts +26 -0
  114. package/dist/types/server/createGameRelay.d.ts.map +1 -0
  115. package/dist/types/server/index.d.ts +3 -0
  116. package/dist/types/server/index.d.ts.map +1 -0
  117. package/dist/types/transport/DirectTransport.d.ts +14 -0
  118. package/dist/types/transport/DirectTransport.d.ts.map +1 -0
  119. package/dist/types/transport/PostMessageTransport.d.ts +20 -0
  120. package/dist/types/transport/PostMessageTransport.d.ts.map +1 -0
  121. package/dist/types/transport/index.d.ts +6 -0
  122. package/dist/types/transport/index.d.ts.map +1 -0
  123. package/dist/types/transport/protocol.d.ts +50 -0
  124. package/dist/types/transport/protocol.d.ts.map +1 -0
  125. package/dist/types/transport/types.d.ts +14 -0
  126. package/dist/types/transport/types.d.ts.map +1 -0
  127. package/dist/types/types.d.ts +33 -0
  128. package/dist/types/types.d.ts.map +1 -0
  129. package/dist/umd/smore-sdk-iframe.umd.js +511 -0
  130. package/dist/umd/smore-sdk-iframe.umd.js.map +1 -0
  131. package/dist/umd/smore-sdk-iframe.umd.min.js +2 -0
  132. package/dist/umd/smore-sdk-iframe.umd.min.js.map +1 -0
  133. package/dist/umd/smore-sdk.umd.js +709 -0
  134. package/dist/umd/smore-sdk.umd.js.map +1 -0
  135. package/dist/umd/smore-sdk.umd.min.js +2 -0
  136. package/dist/umd/smore-sdk.umd.min.js.map +1 -0
  137. package/package.json +87 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smore-sdk.umd.js","sources":["../../../../node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js","../../src/components/TapButton.tsx","../../src/components/HoldButton.tsx","../../src/components/DirectionPad.tsx","../../src/components/SwipeArea.tsx","../../src/transport/DirectTransport.ts","../../src/context/RoomProvider.tsx","../../src/transport/protocol.ts","../../src/transport/PostMessageTransport.ts","../../src/hooks/useGameHost.ts","../../src/hooks/useGamePlayer.ts","../../src/hooks/useExternalGames.ts"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","/**\n * S'MORE Game SDK - TapButton Component\n *\n * Optimized touch button with haptic feedback\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { TapButtonProps } from '../types';\nimport styles from './TapButton.module.css';\n\n/**\n * TapButton - Optimized for mobile touch input\n *\n * @example\n * ```tsx\n * <TapButton onTap={() => send('tap')}>\n * TAP!\n * </TapButton>\n * ```\n */\nexport function TapButton({\n onTap,\n children,\n className,\n disabled = false,\n}: TapButtonProps) {\n const isPressed = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n if (disabled) return;\n e.preventDefault();\n isPressed.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onTap();\n }, [onTap, disabled]);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n isPressed.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n }, []);\n\n const handleMouseDown = useCallback(() => {\n if (disabled) return;\n isPressed.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n onTap();\n }, [onTap, disabled]);\n\n const handleMouseUp = useCallback(() => {\n isPressed.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n }, []);\n\n return (\n <button\n ref={buttonRef}\n className={`${styles.tapButton} ${className || ''} ${disabled ? styles.disabled : ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={handleTouchEnd}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\nexport default TapButton;\n","/**\n * S'MORE Game SDK - HoldButton Component\n *\n * Button that detects hold start/end events\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { HoldButtonProps } from '../types';\nimport styles from './HoldButton.module.css';\n\n/**\n * HoldButton - For hold/release input patterns\n *\n * @example\n * ```tsx\n * <HoldButton\n * onHoldStart={() => send('charge', { type: 'start' })}\n * onHoldEnd={() => send('charge', { type: 'end' })}\n * >\n * HOLD\n * </HoldButton>\n * ```\n */\nexport function HoldButton({\n onHoldStart,\n onHoldEnd,\n children,\n className,\n disabled = false,\n}: HoldButtonProps) {\n const isHolding = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const startHold = useCallback(() => {\n if (disabled || isHolding.current) return;\n isHolding.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onHoldStart();\n }, [onHoldStart, disabled]);\n\n const endHold = useCallback(() => {\n if (!isHolding.current) return;\n isHolding.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n onHoldEnd();\n }, [onHoldEnd]);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n startHold();\n }, [startHold]);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n endHold();\n }, [endHold]);\n\n return (\n <button\n ref={buttonRef}\n className={`${styles.holdButton} ${className || ''} ${disabled ? styles.disabled : ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={handleTouchEnd}\n onMouseDown={startHold}\n onMouseUp={endHold}\n onMouseLeave={endHold}\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\nexport default HoldButton;\n","/**\n * S'MORE Game SDK - DirectionPad Component\n *\n * 4-direction or 2-direction control pad\n */\n\nimport { useCallback, useRef } from 'react';\nimport type { DirectionPadProps } from '../types';\nimport styles from './DirectionPad.module.css';\n\n/**\n * DirectionPad - For directional input\n *\n * @example\n * ```tsx\n * // 4 directions\n * <DirectionPad onDirection={(dir) => send('move', { direction: dir })} />\n *\n * // Left/Right only\n * <DirectionPad leftRightOnly onDirection={(dir) => send('move', { direction: dir })} />\n * ```\n */\nexport function DirectionPad({\n onDirection,\n leftRightOnly = false,\n upDownOnly = false,\n className,\n}: DirectionPadProps) {\n const pressedRef = useRef<Set<string>>(new Set());\n\n const handlePress = useCallback((direction: 'up' | 'down' | 'left' | 'right') => {\n if (pressedRef.current.has(direction)) return;\n pressedRef.current.add(direction);\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onDirection(direction);\n }, [onDirection]);\n\n const handleRelease = useCallback((direction: string) => {\n pressedRef.current.delete(direction);\n }, []);\n\n const createButton = (direction: 'up' | 'down' | 'left' | 'right', label: string) => (\n <button\n key={direction}\n className={`${styles.dirButton} ${styles[direction]}`}\n onTouchStart={(e) => {\n e.preventDefault();\n handlePress(direction);\n }}\n onTouchEnd={(e) => {\n e.preventDefault();\n handleRelease(direction);\n }}\n onTouchCancel={() => handleRelease(direction)}\n onMouseDown={() => handlePress(direction)}\n onMouseUp={() => handleRelease(direction)}\n onMouseLeave={() => handleRelease(direction)}\n >\n {label}\n </button>\n );\n\n if (leftRightOnly) {\n return (\n <div className={`${styles.padContainer} ${styles.horizontal} ${className || ''}`}>\n {createButton('left', '◀')}\n {createButton('right', '▶')}\n </div>\n );\n }\n\n if (upDownOnly) {\n return (\n <div className={`${styles.padContainer} ${styles.vertical} ${className || ''}`}>\n {createButton('up', '▲')}\n {createButton('down', '▼')}\n </div>\n );\n }\n\n return (\n <div className={`${styles.padContainer} ${styles.full} ${className || ''}`}>\n <div className={styles.row}>\n {createButton('up', '▲')}\n </div>\n <div className={styles.row}>\n {createButton('left', '◀')}\n {createButton('right', '▶')}\n </div>\n <div className={styles.row}>\n {createButton('down', '▼')}\n </div>\n </div>\n );\n}\n\nexport default DirectionPad;\n","/**\n * S'MORE Game SDK - SwipeArea Component\n *\n * Detects swipe gestures\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { SwipeAreaProps } from '../types';\nimport styles from './SwipeArea.module.css';\n\n/**\n * SwipeArea - For swipe gesture input\n *\n * @example\n * ```tsx\n * <SwipeArea onSwipe={(dir) => send('swipe', { direction: dir })}>\n * <div>Swipe here!</div>\n * </SwipeArea>\n * ```\n */\nexport function SwipeArea({\n onSwipe,\n threshold = 50,\n children,\n className,\n}: SwipeAreaProps) {\n const touchStart = useRef<{ x: number; y: number } | null>(null);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n const touch = e.touches[0];\n if (!touch) return;\n touchStart.current = { x: touch.clientX, y: touch.clientY };\n }, []);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n if (!touchStart.current) return;\n\n const touch = e.changedTouches[0];\n if (!touch) return;\n const deltaX = touch.clientX - touchStart.current.x;\n const deltaY = touch.clientY - touchStart.current.y;\n\n const absX = Math.abs(deltaX);\n const absY = Math.abs(deltaY);\n\n // Check if swipe exceeds threshold\n if (absX < threshold && absY < threshold) {\n touchStart.current = null;\n return;\n }\n\n // Determine direction\n let direction: 'up' | 'down' | 'left' | 'right';\n if (absX > absY) {\n direction = deltaX > 0 ? 'right' : 'left';\n } else {\n direction = deltaY > 0 ? 'down' : 'up';\n }\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(15);\n }\n\n onSwipe(direction);\n touchStart.current = null;\n }, [onSwipe, threshold]);\n\n return (\n <div\n className={`${styles.swipeArea} ${className || ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={() => { touchStart.current = null; }}\n >\n {children}\n </div>\n );\n}\n\nexport default SwipeArea;\n","/**\n * DirectTransport - Wraps a Socket.IO socket as a Transport.\n * Used by bundled (internal) games. Behaviour is identical to using socket directly.\n */\n\nimport type { Socket } from 'socket.io-client';\nimport type { Transport, TransportEventHandler } from './types';\n\nexport class DirectTransport implements Transport {\n constructor(private socket: Socket) {}\n\n emit(event: string, ...args: any[]): void {\n this.socket.emit(event, ...args);\n }\n\n on(event: string, handler: TransportEventHandler): void {\n this.socket.on(event, handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (handler) {\n this.socket.off(event, handler);\n } else {\n this.socket.off(event);\n }\n }\n}\n","/**\n * RoomProvider - SDK Room Context\n *\n * Foundation context that all other SDK hooks depend on.\n * Provides room state (players, roomCode, leaderId) for both host and player sides.\n *\n * Also provides a Transport abstraction via TransportContext.\n * - HostRoomProvider / PlayerRoomProvider create a DirectTransport from the socket.\n * - IframeRoomProvider (external) provides a PostMessageTransport.\n *\n * Usage:\n * - Host: <HostRoomProvider roomCode={...} players={...} leaderId={...} socket={...}>\n * - Player: <PlayerRoomProvider roomCode={...} players={...} leaderId={...} mySessionId={...} isLeader={...} socket={...} isConnected={...}>\n */\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { Player } from '@smore/shared';\nimport type { Socket } from 'socket.io-client';\nimport type { Transport } from '../transport/types';\nimport { DirectTransport } from '../transport/DirectTransport';\n\n// ===== Transport Context =====\n\nconst TransportContext = createContext<Transport | null>(null);\n\nexport function useTransport(): Transport {\n const transport = useContext(TransportContext);\n if (!transport) {\n throw new Error('useTransport must be used within a RoomProvider that supplies a Transport');\n }\n return transport;\n}\n\nexport { TransportContext };\n\n// ===== State Types =====\n\nexport interface RoomState {\n roomCode: string;\n players: Player[];\n connectedPlayers: Player[];\n leaderId: string | null;\n}\n\nexport interface HostRoomState extends RoomState {\n socket: Socket;\n}\n\nexport interface PlayerRoomState extends RoomState {\n mySessionId: string;\n isLeader: boolean;\n socket: Socket;\n isConnected: boolean;\n}\n\nexport interface RoomContextValue {\n roomCode: string;\n players: Player[];\n connectedPlayers: Player[];\n leaderId: string | null;\n side: 'host' | 'player';\n host: HostRoomState | null;\n player: PlayerRoomState | null;\n}\n\n// ===== Context =====\n\nexport const RoomContext = createContext<RoomContextValue | null>(null);\n\n// ===== Host Provider =====\n\ninterface HostRoomProviderProps {\n roomCode: string;\n players: Player[];\n leaderId: string | null;\n socket: Socket;\n children: React.ReactNode;\n}\n\nexport const HostRoomProvider: React.FC<HostRoomProviderProps> = ({\n roomCode,\n players,\n leaderId,\n socket,\n children,\n}) => {\n const connectedPlayers = useMemo(\n () => players.filter((p) => p.connected !== false),\n [players]\n );\n\n const hostState: HostRoomState = useMemo(\n () => ({ roomCode, players, connectedPlayers, leaderId, socket }),\n [roomCode, players, connectedPlayers, leaderId, socket]\n );\n\n const value: RoomContextValue = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n side: 'host' as const,\n host: hostState,\n player: null,\n }),\n [roomCode, players, connectedPlayers, leaderId, hostState]\n );\n\n const transport = useMemo(() => new DirectTransport(socket), [socket]);\n\n return (\n <TransportContext.Provider value={transport}>\n <RoomContext.Provider value={value}>{children}</RoomContext.Provider>\n </TransportContext.Provider>\n );\n};\n\n// ===== Player Provider =====\n\ninterface PlayerRoomProviderProps {\n roomCode: string;\n players: Player[];\n leaderId: string | null;\n mySessionId: string;\n isLeader: boolean;\n socket: Socket;\n isConnected: boolean;\n children: React.ReactNode;\n}\n\nexport const PlayerRoomProvider: React.FC<PlayerRoomProviderProps> = ({\n roomCode,\n players,\n leaderId,\n mySessionId,\n isLeader,\n socket,\n isConnected,\n children,\n}) => {\n const connectedPlayers = useMemo(\n () => players.filter((p) => p.connected !== false),\n [players]\n );\n\n const playerState: PlayerRoomState = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n mySessionId,\n isLeader,\n socket,\n isConnected,\n }),\n [roomCode, players, connectedPlayers, leaderId, mySessionId, isLeader, socket, isConnected]\n );\n\n const value: RoomContextValue = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n side: 'player' as const,\n host: null,\n player: playerState,\n }),\n [roomCode, players, connectedPlayers, leaderId, playerState]\n );\n\n const transport = useMemo(() => new DirectTransport(socket), [socket]);\n\n return (\n <TransportContext.Provider value={transport}>\n <RoomContext.Provider value={value}>{children}</RoomContext.Provider>\n </TransportContext.Provider>\n );\n};\n\n// ===== Hooks =====\n\nexport function useRoom(): RoomContextValue {\n const context = useContext(RoomContext);\n if (!context) {\n throw new Error('useRoom must be used within HostRoomProvider or PlayerRoomProvider');\n }\n return context;\n}\n\nexport function useHostRoom(): HostRoomState {\n const context = useRoom();\n if (context.side !== 'host' || !context.host) {\n throw new Error('useHostRoom must be used within HostRoomProvider');\n }\n return context.host;\n}\n\nexport function usePlayerRoom(): PlayerRoomState {\n const context = useRoom();\n if (context.side !== 'player' || !context.player) {\n throw new Error('usePlayerRoom must be used within PlayerRoomProvider');\n }\n return context.player;\n}\n","/**\n * postMessage protocol types for iframe ↔ parent communication.\n */\n\nexport const SMORE_MSG_PREFIX = 'smore:' as const;\n\nexport interface SmoreReadyMessage {\n type: 'smore:ready';\n}\n\nexport interface SmoreInitMessage {\n type: 'smore:init';\n payload: {\n side: 'host' | 'player';\n roomCode: string;\n players: any[];\n leaderId: string | null;\n mySessionId?: string;\n isLeader?: boolean;\n };\n}\n\nexport interface SmoreEmitMessage {\n type: 'smore:emit';\n payload: {\n event: string;\n data?: any;\n ackId?: string;\n };\n}\n\nexport interface SmoreEventMessage {\n type: 'smore:event';\n payload: {\n event: string;\n data?: any;\n };\n}\n\nexport interface SmoreAckMessage {\n type: 'smore:ack';\n payload: {\n ackId: string;\n data?: any;\n };\n}\n\nexport interface SmoreUpdateMessage {\n type: 'smore:update';\n payload: {\n players?: any[];\n leaderId?: string | null;\n };\n}\n\nexport type SmoreMessage =\n | SmoreReadyMessage\n | SmoreInitMessage\n | SmoreEmitMessage\n | SmoreEventMessage\n | SmoreAckMessage\n | SmoreUpdateMessage;\n\nexport function isSmoreMessage(data: any): data is SmoreMessage {\n return data && typeof data === 'object' && typeof data.type === 'string' && data.type.startsWith(SMORE_MSG_PREFIX);\n}\n","/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `smore:emit` to parent and listens for `smore:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { SmoreEventMessage, SmoreAckMessage } from './protocol';\nimport { isSmoreMessage } from './protocol';\n\nexport class PostMessageTransport implements Transport {\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: any[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: any[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: any = args[0];\n let ackId: string | undefined;\n\n if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args.length === 2 ? args[0] : args[0];\n const callback = args[args.length - 1];\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n }\n\n window.parent.postMessage(\n { type: 'smore:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isSmoreMessage(msg)) return;\n\n if (msg.type === 'smore:event') {\n const { event, data } = (msg as SmoreEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n } else if (msg.type === 'smore:ack') {\n const { ackId, data } = (msg as SmoreAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n","/**\n * useGameHost - Host-side game hook for the S'MORE SDK\n *\n * Provides host game developers with:\n * - Automatic room state access (via useHostRoom context)\n * - Input listening (dedicated socket events)\n * - Broadcasting to all/specific players\n * - Game over emission\n * - Player lifecycle callbacks\n *\n * Internally uses Transport abstraction so the same API works over\n * Socket.IO (bundled games) or postMessage (iframe games).\n */\nimport { useEffect, useCallback, useRef } from 'react';\nimport { useHostRoom } from '../context/RoomProvider';\nimport { useTransport } from '../context/RoomProvider';\nimport type { HostRoomState } from '../context/RoomProvider';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype InputHandler = (playerId: string, data?: any) => void;\n\nexport interface UseGameHostConfig {\n /** Unique game identifier (e.g. 'fibbage', 'wasd') */\n gameId: string;\n\n /**\n * Map of action names to handler functions.\n * Listens directly on socket for `{gameId}:{key}` events.\n */\n onInput?: Record<string, InputHandler>;\n\n /**\n * Called when a player requests game state (e.g. after returning from background).\n * Return the current game state object to send back to that player.\n */\n onStateRequest?: (playerId: string) => Record<string, any>;\n\n /** Called when a player leaves the room. */\n onPlayerLeave?: (playerId: string) => void;\n\n /** Called when a player disconnects (may reconnect). */\n onPlayerDisconnect?: (playerId: string) => void;\n\n /** Called when a previously disconnected player reconnects. */\n onPlayerReconnect?: (playerId: string) => void;\n\n /**\n * Generic socket event listeners (for server broadcasts the host needs to receive).\n * Keys are full event names, values are handler functions.\n */\n listeners?: Record<string, (data: any) => void>;\n}\n\nexport interface UseGameHostReturn {\n /** Current room state from HostRoomProvider context. */\n room: HostRoomState;\n\n /** Broadcast an event to all players via the host socket. */\n broadcast: (event: string, data: any) => void;\n\n /** Send state/event to a specific player by sessionId. */\n sendToPlayer: (sessionId: string, event: string, data: any) => void;\n\n /** Emit game-over with optional results payload. */\n emitGameOver: (results?: any) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useGameHost(config: UseGameHostConfig): UseGameHostReturn {\n const { gameId, onInput, onStateRequest, onPlayerLeave, onPlayerDisconnect, onPlayerReconnect, listeners } = config;\n\n const hostRoom = useHostRoom();\n const transport = useTransport();\n\n // Stable refs to avoid stale closures in listeners\n const onInputRef = useRef(onInput);\n const onStateRequestRef = useRef(onStateRequest);\n const onPlayerLeaveRef = useRef(onPlayerLeave);\n const onPlayerDisconnectRef = useRef(onPlayerDisconnect);\n const onPlayerReconnectRef = useRef(onPlayerReconnect);\n\n useEffect(() => { onInputRef.current = onInput; }, [onInput]);\n useEffect(() => { onStateRequestRef.current = onStateRequest; }, [onStateRequest]);\n useEffect(() => { onPlayerLeaveRef.current = onPlayerLeave; }, [onPlayerLeave]);\n useEffect(() => { onPlayerDisconnectRef.current = onPlayerDisconnect; }, [onPlayerDisconnect]);\n useEffect(() => { onPlayerReconnectRef.current = onPlayerReconnect; }, [onPlayerReconnect]);\n\n // -------------------------------------------------------------------------\n // Dedicated input listeners (transport events)\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport || !onInputRef.current) return;\n\n const registeredEvents: Array<{ event: string; handler: (...args: any[]) => void }> = [];\n\n // For each handler key, listen on transport for \"{gameId}:{key}\"\n const inputMap = onInputRef.current;\n for (const key of Object.keys(inputMap)) {\n const eventName = `${gameId}:${key}`;\n const handler = (data: any) => {\n const currentHandler = onInputRef.current?.[key];\n if (currentHandler) {\n currentHandler(data?.sessionId ?? data?.playerId, data);\n }\n };\n transport.on(eventName, handler);\n registeredEvents.push({ event: eventName, handler });\n }\n\n return () => {\n for (const { event, handler } of registeredEvents) {\n transport.off(event, handler);\n }\n };\n }, [gameId, transport]);\n\n // -------------------------------------------------------------------------\n // State request handler\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport) return;\n\n const handler = (data: { requesterId: string }) => {\n const stateFn = onStateRequestRef.current;\n if (!stateFn) return;\n\n const gameState = stateFn(data.requesterId);\n transport.emit('game:state-response', {\n targetSessionId: data.requesterId,\n gameState: {\n gameId,\n ...gameState,\n },\n });\n };\n\n transport.on('game:state-request', handler);\n return () => {\n transport.off('game:state-request', handler);\n };\n }, [transport, gameId]);\n\n // -------------------------------------------------------------------------\n // Player lifecycle listeners\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport) return;\n\n const onLeft = (data: any) => {\n onPlayerLeaveRef.current?.(data?.sessionId ?? data?.playerId);\n };\n const onDisconnected = (data: any) => {\n onPlayerDisconnectRef.current?.(data?.sessionId ?? data?.playerId);\n };\n const onReconnected = (data: any) => {\n onPlayerReconnectRef.current?.(data?.sessionId ?? data?.playerId);\n };\n\n transport.on('room:player-left', onLeft);\n transport.on('room:player-disconnected', onDisconnected);\n transport.on('room:player-reconnected', onReconnected);\n\n return () => {\n transport.off('room:player-left', onLeft);\n transport.off('room:player-disconnected', onDisconnected);\n transport.off('room:player-reconnected', onReconnected);\n };\n }, [transport]);\n\n // -------------------------------------------------------------------------\n // Generic listeners\n // -------------------------------------------------------------------------\n const listenersRef = useRef(listeners);\n listenersRef.current = listeners;\n\n useEffect(() => {\n if (!transport || !listenersRef.current) return;\n const entries = Object.entries(listenersRef.current);\n const handlers = entries.map(([event, handler]) => {\n transport.on(event, handler);\n return () => { transport.off(event, handler); };\n });\n return () => handlers.forEach(fn => fn());\n }, [transport, listeners]);\n\n // -------------------------------------------------------------------------\n // Actions\n // -------------------------------------------------------------------------\n\n const broadcast = useCallback(\n (event: string, data: any) => {\n transport?.emit(event, data);\n },\n [transport],\n );\n\n const sendToPlayer = useCallback(\n (sessionId: string, event: string, data: any) => {\n transport?.emit('game:state-to-player', {\n targetSessionId: sessionId,\n gameId,\n event,\n state: data,\n });\n },\n [transport, gameId],\n );\n\n const emitGameOver = useCallback(\n (results?: any) => {\n transport?.emit('room:game-over', { gameId, results });\n },\n [transport, gameId],\n );\n\n return {\n room: hostRoom,\n broadcast,\n sendToPlayer,\n emitGameOver,\n };\n}\n","import { useEffect, useCallback, useState, useRef } from 'react';\nimport { usePlayerRoom } from '../context/RoomProvider';\nimport { useTransport } from '../context/RoomProvider';\nimport type { PlayerRoomState } from '../context/RoomProvider';\n\nexport interface UseGamePlayerConfig {\n gameId: string;\n listeners?: Record<string, (data: any) => void>;\n}\n\nexport interface UseGamePlayerReturn {\n room: PlayerRoomState;\n emit: (event: string, data?: any, callback?: (response: any) => void) => void;\n /** Emit a tap input: sends `{gameId}:{action}` event */\n sendTapInput: (action: string) => void;\n /** Emit a hold input: sends `{gameId}:{action}:{type}` event */\n sendHoldInput: (action: string, type: 'START' | 'END') => void;\n isConnected: boolean;\n gameState: Record<string, any> | null;\n}\n\nexport function useGamePlayer(config: UseGamePlayerConfig): UseGamePlayerReturn {\n const room = usePlayerRoom();\n const transport = useTransport();\n const { isConnected } = room;\n const { gameId, listeners } = config;\n const [gameState, setGameState] = useState<Record<string, any> | null>(null);\n const listenersRef = useRef(listeners);\n listenersRef.current = listeners;\n\n // Transport listeners\n useEffect(() => {\n if (!transport || !listenersRef.current) return;\n const cleanups: (() => void)[] = [];\n Object.entries(listenersRef.current).forEach(([event, handler]) => {\n transport.on(event, handler);\n cleanups.push(() => transport.off(event, handler));\n });\n return () => cleanups.forEach(fn => fn());\n }, [transport, listeners]);\n\n // Reconnection: game:state-response\n useEffect(() => {\n if (!transport) return;\n const handler = (state: any) => {\n if (state.gameId !== gameId) return;\n setGameState(state);\n };\n transport.on('game:state-response', handler);\n return () => { transport.off('game:state-response', handler); };\n }, [transport, gameId]);\n\n // game:state-to-player (Host push)\n useEffect(() => {\n if (!transport) return;\n const handler = (data: { gameId: string; state: any }) => {\n if (data.gameId !== gameId) return;\n setGameState(data.state);\n };\n transport.on('game:state-to-player', handler);\n return () => { transport.off('game:state-to-player', handler); };\n }, [transport, gameId]);\n\n // Visibility change\n useEffect(() => {\n if (!transport) return;\n const handler = () => {\n if (!document.hidden) {\n transport.emit('game:request-state', { gameId });\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, [transport, gameId]);\n\n // API\n const emit = useCallback((event: string, data?: any, callback?: (response: any) => void) => {\n if (!transport) return;\n if (callback) {\n transport.emit(event, data, callback);\n } else {\n transport.emit(event, data);\n }\n }, [transport]);\n\n const sendTapInput = useCallback((action: string) => {\n if (!transport) return;\n transport.emit(`${gameId}:${action}`);\n }, [transport, gameId]);\n\n const sendHoldInput = useCallback((action: string, type: 'START' | 'END') => {\n if (!transport) return;\n transport.emit(`${gameId}:${action}:${type}`);\n }, [transport, gameId]);\n\n return { room, emit, sendTapInput, sendHoldInput, isConnected, gameState };\n}\n","/**\n * useExternalGames - Fetches external games from the server API.\n *\n * Returns a list of GameMetadata-compatible objects for external (iframe) games.\n * Consumers merge this with their local GAMES array.\n */\n\nimport { useState, useEffect } from 'react';\n\nexport interface ExternalGameMetadata {\n id: string;\n title: string;\n description: string;\n minPlayers: number;\n maxPlayers: number;\n thumbnail: string;\n categories: string[];\n type: 'external';\n hostUrl: string | null;\n playerUrl: string | null;\n available: boolean;\n rating: number;\n heroRequired: boolean;\n}\n\nexport interface UseExternalGamesConfig {\n serverUrl: string;\n enabled?: boolean;\n}\n\nexport function useExternalGames(config: UseExternalGamesConfig): {\n games: ExternalGameMetadata[];\n loading: boolean;\n error: string | null;\n refresh: () => void;\n} {\n const { serverUrl, enabled = true } = config;\n const [games, setGames] = useState<ExternalGameMetadata[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [refreshKey, setRefreshKey] = useState(0);\n\n useEffect(() => {\n if (!enabled) return;\n\n let cancelled = false;\n setLoading(true);\n\n fetch(`${serverUrl}/api/games`)\n .then((res) => res.json())\n .then((data) => {\n if (cancelled) return;\n const external: ExternalGameMetadata[] = (data.games || []).map((g: any) => ({\n id: g.id,\n title: g.title,\n description: g.description || '',\n minPlayers: g.minPlayers || 2,\n maxPlayers: g.maxPlayers || 8,\n thumbnail: g.thumbnail || '/thumbnails/g8.jpeg',\n categories: g.categories || ['party'],\n type: 'external' as const,\n hostUrl: g.hostUrl,\n playerUrl: g.playerUrl,\n available: !!(g.hostUrl && g.playerUrl),\n rating: 4.0,\n heroRequired: false,\n }));\n setGames(external);\n setError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setError(err.message);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => { cancelled = true; };\n }, [serverUrl, enabled, refreshKey]);\n\n const refresh = () => setRefreshKey((k) => k + 1);\n\n return { games, loading, error, refresh };\n}\n"],"names":["useRef","useCallback","styles","jsx","jsxs","createContext","useContext","useMemo","useEffect","useState"],"mappings":";;;;;;EAAA,SAAS,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE;EAC/B,EAAE,KAAK,GAAG,KAAK,MAAM,GAAG,GAAG,GAAG,EAAE;EAChC,EAAE,IAAI,QAAQ,GAAG,GAAG,CAAC,QAAQ;;EAE7B,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,EAAE,OAAO,CAAC;;EAEzD,EAAE,IAAI,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;EACtE,EAAE,IAAI,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC;EAC7C,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU;;EAEzB,EAAE,IAAI,QAAQ,KAAK,KAAK,EAAE;EAC1B,IAAI,IAAI,IAAI,CAAC,UAAU,EAAE;EACzB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC;EAC/C,IAAI,CAAC,MAAM;EACX,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;EAC7B,IAAI;EACJ,EAAE,CAAC,MAAM;EACT,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;EAC3B,EAAE;;EAEF,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE;EACxB,IAAI,KAAK,CAAC,UAAU,CAAC,OAAO,GAAG,GAAG;EAClC,EAAE,CAAC,MAAM;EACT,IAAI,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;EACnD,EAAE;EACF;;;;;;ECJO,SAAS,SAAA,CAAU;EAAA,EACxB,KAAA;EAAA,EACA,QAAA;EAAA,EACA,SAAA;EAAA,EACA,QAAA,GAAW;EACb,CAAA,EAAmB;EACjB,EAAA,MAAM,SAAA,GAAYA,aAAO,KAAK,CAAA;EAC9B,EAAA,MAAM,SAAA,GAAYA,aAA0B,IAAI,CAAA;EAEhD,EAAA,MAAM,gBAAA,GAAmBC,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC5D,IAAA,IAAI,QAAA,EAAU;EACd,IAAA,CAAA,CAAE,cAAA,EAAe;EACjB,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,GAAA,CAAIC,QAAA,CAAO,OAAa,CAAA;EAGrD,IAAA,IAAI,UAAU,OAAA,EAAS;EACrB,MAAA,SAAA,CAAU,QAAQ,EAAE,CAAA;EAAA,IACtB;EAEA,IAAA,KAAA,EAAM;EAAA,EACR,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;EAEpB,EAAA,MAAM,cAAA,GAAiBD,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC1D,IAAA,CAAA,CAAE,cAAA,EAAe;EACjB,IAAA,SAAA,CAAU,OAAA,GAAU,KAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,MAAA,CAAOC,QAAA,CAAO,OAAa,CAAA;EAAA,EAC1D,CAAA,EAAG,EAAE,CAAA;EAEL,EAAA,MAAM,eAAA,GAAkBD,kBAAY,MAAM;EACxC,IAAA,IAAI,QAAA,EAAU;EACd,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,GAAA,CAAIC,QAAA,CAAO,OAAa,CAAA;EACrD,IAAA,KAAA,EAAM;EAAA,EACR,CAAA,EAAG,CAAC,KAAA,EAAO,QAAQ,CAAC,CAAA;EAEpB,EAAA,MAAM,aAAA,GAAgBD,kBAAY,MAAM;EACtC,IAAA,SAAA,CAAU,OAAA,GAAU,KAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,MAAA,CAAOC,QAAA,CAAO,OAAa,CAAA;EAAA,EAC1D,CAAA,EAAG,EAAE,CAAA;EAEL,EAAA,uBACEC,cAAA;EAAA,IAAC,QAAA;EAAA,IAAA;EAAA,MACC,GAAA,EAAK,SAAA;EAAA,MACL,SAAA,EAAW,CAAA,EAAGD,QAAA,CAAO,SAAS,CAAA,CAAA,EAAI,SAAA,IAAa,EAAE,CAAA,CAAA,EAAI,QAAA,GAAWA,QAAA,CAAO,QAAA,GAAW,EAAE,CAAA,CAAA;EAAA,MACpF,YAAA,EAAc,gBAAA;EAAA,MACd,UAAA,EAAY,cAAA;EAAA,MACZ,aAAA,EAAe,cAAA;EAAA,MACf,WAAA,EAAa,eAAA;EAAA,MACb,SAAA,EAAW,aAAA;EAAA,MACX,YAAA,EAAc,aAAA;EAAA,MACd,QAAA;EAAA,MAEC;EAAA;EAAA,GACH;EAEJ;;;;;;ECrDO,SAAS,UAAA,CAAW;EAAA,EACzB,WAAA;EAAA,EACA,SAAA;EAAA,EACA,QAAA;EAAA,EACA,SAAA;EAAA,EACA,QAAA,GAAW;EACb,CAAA,EAAoB;EAClB,EAAA,MAAM,SAAA,GAAYF,aAAO,KAAK,CAAA;EAC9B,EAAA,MAAM,SAAA,GAAYA,aAA0B,IAAI,CAAA;EAEhD,EAAA,MAAM,SAAA,GAAYC,kBAAY,MAAM;EAClC,IAAA,IAAI,QAAA,IAAY,UAAU,OAAA,EAAS;EACnC,IAAA,SAAA,CAAU,OAAA,GAAU,IAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,GAAA,CAAIC,QAAA,CAAO,OAAa,CAAA;EAGrD,IAAA,IAAI,UAAU,OAAA,EAAS;EACrB,MAAA,SAAA,CAAU,QAAQ,EAAE,CAAA;EAAA,IACtB;EAEA,IAAA,WAAA,EAAY;EAAA,EACd,CAAA,EAAG,CAAC,WAAA,EAAa,QAAQ,CAAC,CAAA;EAE1B,EAAA,MAAM,OAAA,GAAUD,kBAAY,MAAM;EAChC,IAAA,IAAI,CAAC,UAAU,OAAA,EAAS;EACxB,IAAA,SAAA,CAAU,OAAA,GAAU,KAAA;EACpB,IAAA,SAAA,CAAU,OAAA,EAAS,SAAA,CAAU,MAAA,CAAOC,QAAA,CAAO,OAAa,CAAA;EACxD,IAAA,SAAA,EAAU;EAAA,EACZ,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;EAEd,EAAA,MAAM,gBAAA,GAAmBD,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC5D,IAAA,CAAA,CAAE,cAAA,EAAe;EACjB,IAAA,SAAA,EAAU;EAAA,EACZ,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;EAEd,EAAA,MAAM,cAAA,GAAiBA,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC1D,IAAA,CAAA,CAAE,cAAA,EAAe;EACjB,IAAA,OAAA,EAAQ;EAAA,EACV,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;EAEZ,EAAA,uBACEE,cAAA;EAAA,IAAC,QAAA;EAAA,IAAA;EAAA,MACC,GAAA,EAAK,SAAA;EAAA,MACL,SAAA,EAAW,CAAA,EAAGD,QAAA,CAAO,UAAU,CAAA,CAAA,EAAI,SAAA,IAAa,EAAE,CAAA,CAAA,EAAI,QAAA,GAAWA,QAAA,CAAO,QAAA,GAAW,EAAE,CAAA,CAAA;EAAA,MACrF,YAAA,EAAc,gBAAA;EAAA,MACd,UAAA,EAAY,cAAA;EAAA,MACZ,aAAA,EAAe,cAAA;EAAA,MACf,WAAA,EAAa,SAAA;EAAA,MACb,SAAA,EAAW,OAAA;EAAA,MACX,YAAA,EAAc,OAAA;EAAA,MACd,QAAA;EAAA,MAEC;EAAA;EAAA,GACH;EAEJ;;;;;;ECzDO,SAAS,YAAA,CAAa;EAAA,EAC3B,WAAA;EAAA,EACA,aAAA,GAAgB,KAAA;EAAA,EAChB,UAAA,GAAa,KAAA;EAAA,EACb;EACF,CAAA,EAAsB;EACpB,EAAA,MAAM,UAAA,GAAaF,YAAA,iBAAoB,IAAI,GAAA,EAAK,CAAA;EAEhD,EAAA,MAAM,WAAA,GAAcC,iBAAA,CAAY,CAAC,SAAA,KAAgD;EAC/E,IAAA,IAAI,UAAA,CAAW,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA,EAAG;EACvC,IAAA,UAAA,CAAW,OAAA,CAAQ,IAAI,SAAS,CAAA;EAGhC,IAAA,IAAI,UAAU,OAAA,EAAS;EACrB,MAAA,SAAA,CAAU,QAAQ,EAAE,CAAA;EAAA,IACtB;EAEA,IAAA,WAAA,CAAY,SAAS,CAAA;EAAA,EACvB,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;EAEhB,EAAA,MAAM,aAAA,GAAgBA,iBAAA,CAAY,CAAC,SAAA,KAAsB;EACvD,IAAA,UAAA,CAAW,OAAA,CAAQ,OAAO,SAAS,CAAA;EAAA,EACrC,CAAA,EAAG,EAAE,CAAA;EAEL,EAAA,MAAM,YAAA,GAAe,CAAC,SAAA,EAA6C,KAAA,qBACjEE,cAAA;EAAA,IAAC,QAAA;EAAA,IAAA;EAAA,MAEC,WAAW,CAAA,EAAGD,QAAA,CAAO,SAAS,CAAA,CAAA,EAAIA,QAAA,CAAO,SAAS,CAAC,CAAA,CAAA;EAAA,MACnD,YAAA,EAAc,CAAC,CAAA,KAAM;EACnB,QAAA,CAAA,CAAE,cAAA,EAAe;EACjB,QAAA,WAAA,CAAY,SAAS,CAAA;EAAA,MACvB,CAAA;EAAA,MACA,UAAA,EAAY,CAAC,CAAA,KAAM;EACjB,QAAA,CAAA,CAAE,cAAA,EAAe;EACjB,QAAA,aAAA,CAAc,SAAS,CAAA;EAAA,MACzB,CAAA;EAAA,MACA,aAAA,EAAe,MAAM,aAAA,CAAc,SAAS,CAAA;EAAA,MAC5C,WAAA,EAAa,MAAM,WAAA,CAAY,SAAS,CAAA;EAAA,MACxC,SAAA,EAAW,MAAM,aAAA,CAAc,SAAS,CAAA;EAAA,MACxC,YAAA,EAAc,MAAM,aAAA,CAAc,SAAS,CAAA;EAAA,MAE1C,QAAA,EAAA;EAAA,KAAA;EAAA,IAfI;EAAA,GAgBP;EAGF,EAAA,IAAI,aAAA,EAAe;EACjB,IAAA,uBACEE,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,EAAGF,QAAA,CAAO,YAAY,CAAA,CAAA,EAAIA,QAAA,CAAO,UAAU,CAAA,CAAA,EAAI,SAAA,IAAa,EAAE,CAAA,CAAA,EAC3E,QAAA,EAAA;EAAA,MAAA,YAAA,CAAa,QAAQ,QAAG,CAAA;EAAA,MACxB,YAAA,CAAa,SAAS,QAAG;EAAA,KAAA,EAC5B,CAAA;EAAA,EAEJ;EAEA,EAAA,IAAI,UAAA,EAAY;EACd,IAAA,uBACEE,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,EAAGF,QAAA,CAAO,YAAY,CAAA,CAAA,EAAIA,QAAA,CAAO,QAAQ,CAAA,CAAA,EAAI,SAAA,IAAa,EAAE,CAAA,CAAA,EACzE,QAAA,EAAA;EAAA,MAAA,YAAA,CAAa,MAAM,QAAG,CAAA;EAAA,MACtB,YAAA,CAAa,QAAQ,QAAG;EAAA,KAAA,EAC3B,CAAA;EAAA,EAEJ;EAEA,EAAA,uBACEE,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAW,CAAA,EAAGF,QAAA,CAAO,YAAY,CAAA,CAAA,EAAIA,QAAA,CAAO,IAAI,CAAA,CAAA,EAAI,SAAA,IAAa,EAAE,CAAA,CAAA,EACtE,QAAA,EAAA;EAAA,oBAAAC,cAAA,CAAC,SAAI,SAAA,EAAWD,QAAA,CAAO,KACpB,QAAA,EAAA,YAAA,CAAa,IAAA,EAAM,QAAG,CAAA,EACzB,CAAA;EAAA,oBACAE,eAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAWF,QAAA,CAAO,GAAA,EACpB,QAAA,EAAA;EAAA,MAAA,YAAA,CAAa,QAAQ,QAAG,CAAA;EAAA,MACxB,YAAA,CAAa,SAAS,QAAG;EAAA,KAAA,EAC5B,CAAA;EAAA,oBACAC,cAAA,CAAC,SAAI,SAAA,EAAWD,QAAA,CAAO,KACpB,QAAA,EAAA,YAAA,CAAa,MAAA,EAAQ,QAAG,CAAA,EAC3B;EAAA,GAAA,EACF,CAAA;EAEJ;;;;;;EC9EO,SAAS,SAAA,CAAU;EAAA,EACxB,OAAA;EAAA,EACA,SAAA,GAAY,EAAA;EAAA,EACZ,QAAA;EAAA,EACA;EACF,CAAA,EAAmB;EACjB,EAAA,MAAM,UAAA,GAAaF,aAAwC,IAAI,CAAA;EAE/D,EAAA,MAAM,gBAAA,GAAmBC,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC5D,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAA;EACzB,IAAA,IAAI,CAAC,KAAA,EAAO;EACZ,IAAA,UAAA,CAAW,UAAU,EAAE,CAAA,EAAG,MAAM,OAAA,EAAS,CAAA,EAAG,MAAM,OAAA,EAAQ;EAAA,EAC5D,CAAA,EAAG,EAAE,CAAA;EAEL,EAAA,MAAM,cAAA,GAAiBA,iBAAA,CAAY,CAAC,CAAA,KAAwB;EAC1D,IAAA,IAAI,CAAC,WAAW,OAAA,EAAS;EAEzB,IAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,cAAA,CAAe,CAAC,CAAA;EAChC,IAAA,IAAI,CAAC,KAAA,EAAO;EACZ,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,UAAA,CAAW,OAAA,CAAQ,CAAA;EAClD,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,GAAU,UAAA,CAAW,OAAA,CAAQ,CAAA;EAElD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;EAC5B,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,MAAM,CAAA;EAG5B,IAAA,IAAI,IAAA,GAAO,SAAA,IAAa,IAAA,GAAO,SAAA,EAAW;EACxC,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;EACrB,MAAA;EAAA,IACF;EAGA,IAAA,IAAI,SAAA;EACJ,IAAA,IAAI,OAAO,IAAA,EAAM;EACf,MAAA,SAAA,GAAY,MAAA,GAAS,IAAI,OAAA,GAAU,MAAA;EAAA,IACrC,CAAA,MAAO;EACL,MAAA,SAAA,GAAY,MAAA,GAAS,IAAI,MAAA,GAAS,IAAA;EAAA,IACpC;EAGA,IAAA,IAAI,UAAU,OAAA,EAAS;EACrB,MAAA,SAAA,CAAU,QAAQ,EAAE,CAAA;EAAA,IACtB;EAEA,IAAA,OAAA,CAAQ,SAAS,CAAA;EACjB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAA;EAAA,EACvB,CAAA,EAAG,CAAC,OAAA,EAAS,SAAS,CAAC,CAAA;EAEvB,EAAA,uBACEE,cAAA;EAAA,IAAC,KAAA;EAAA,IAAA;EAAA,MACC,WAAW,CAAA,EAAG,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,aAAa,EAAE,CAAA,CAAA;EAAA,MACjD,YAAA,EAAc,gBAAA;EAAA,MACd,UAAA,EAAY,cAAA;EAAA,MACZ,eAAe,MAAM;EAAE,QAAA,UAAA,CAAW,OAAA,GAAU,IAAA;EAAA,MAAM,CAAA;EAAA,MAEjD;EAAA;EAAA,GACH;EAEJ;;ECvEO,MAAM,eAAA,CAAqC;EAAA,EAChD,YAAoB,MAAA,EAAgB;EAAhB,IAAA,IAAA,CAAA,MAAA,GAAA,MAAA;EAAA,EAAiB;EAAA,EAErC,IAAA,CAAK,UAAkB,IAAA,EAAmB;EACxC,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,GAAG,IAAI,CAAA;EAAA,EACjC;EAAA,EAEA,EAAA,CAAG,OAAe,OAAA,EAAsC;EACtD,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,OAAO,CAAA;EAAA,EAC/B;EAAA,EAEA,GAAA,CAAI,OAAe,OAAA,EAAuC;EACxD,IAAA,IAAI,OAAA,EAAS;EACX,MAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,OAAO,CAAA;EAAA,IAChC,CAAA,MAAO;EACL,MAAA,IAAA,CAAK,MAAA,CAAO,IAAI,KAAK,CAAA;EAAA,IACvB;EAAA,EACF;EACF;;ACHA,QAAM,gBAAA,GAAmBE,oBAAgC,IAAI;EAEtD,SAAS,YAAA,GAA0B;EACxC,EAAA,MAAM,SAAA,GAAYC,iBAAW,gBAAgB,CAAA;EAC7C,EAAA,IAAI,CAAC,SAAA,EAAW;EACd,IAAA,MAAM,IAAI,MAAM,2EAA2E,CAAA;EAAA,EAC7F;EACA,EAAA,OAAO,SAAA;EACT;EAoCO,MAAM,WAAA,GAAcD,oBAAuC,IAAI,CAAA;AAY/D,QAAM,mBAAoD,CAAC;EAAA,EAChE,QAAA;EAAA,EACA,OAAA;EAAA,EACA,QAAA;EAAA,EACA,MAAA;EAAA,EACA;EACF,CAAA,KAAM;EACJ,EAAA,MAAM,gBAAA,GAAmBE,aAAA;EAAA,IACvB,MAAM,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,KAAK,CAAA;EAAA,IACjD,CAAC,OAAO;EAAA,GACV;EAEA,EAAA,MAAM,SAAA,GAA2BA,aAAA;EAAA,IAC/B,OAAO,EAAE,QAAA,EAAU,OAAA,EAAS,gBAAA,EAAkB,UAAU,MAAA,EAAO,CAAA;EAAA,IAC/D,CAAC,QAAA,EAAU,OAAA,EAAS,gBAAA,EAAkB,UAAU,MAAM;EAAA,GACxD;EAEA,EAAA,MAAM,KAAA,GAA0BA,aAAA;EAAA,IAC9B,OAAO;EAAA,MACL,QAAA;EAAA,MACA,OAAA;EAAA,MACA,gBAAA;EAAA,MACA,QAAA;EAAA,MACA,IAAA,EAAM,MAAA;EAAA,MACN,IAAA,EAAM,SAAA;EAAA,MACN,MAAA,EAAQ;EAAA,KACV,CAAA;EAAA,IACA,CAAC,QAAA,EAAU,OAAA,EAAS,gBAAA,EAAkB,UAAU,SAAS;EAAA,GAC3D;EAEA,EAAA,MAAM,SAAA,GAAYA,cAAQ,MAAM,IAAI,gBAAgB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;EAErE,EAAA,uBACEJ,cAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,SAAA,EAChC,QAAA,kBAAAA,cAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAe,QAAA,EAAS,CAAA,EAChD,CAAA;EAEJ;AAeO,QAAM,qBAAwD,CAAC;EAAA,EACpE,QAAA;EAAA,EACA,OAAA;EAAA,EACA,QAAA;EAAA,EACA,WAAA;EAAA,EACA,QAAA;EAAA,EACA,MAAA;EAAA,EACA,WAAA;EAAA,EACA;EACF,CAAA,KAAM;EACJ,EAAA,MAAM,gBAAA,GAAmBI,aAAA;EAAA,IACvB,MAAM,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,cAAc,KAAK,CAAA;EAAA,IACjD,CAAC,OAAO;EAAA,GACV;EAEA,EAAA,MAAM,WAAA,GAA+BA,aAAA;EAAA,IACnC,OAAO;EAAA,MACL,QAAA;EAAA,MACA,OAAA;EAAA,MACA,gBAAA;EAAA,MACA,QAAA;EAAA,MACA,WAAA;EAAA,MACA,QAAA;EAAA,MACA,MAAA;EAAA,MACA;EAAA,KACF,CAAA;EAAA,IACA,CAAC,UAAU,OAAA,EAAS,gBAAA,EAAkB,UAAU,WAAA,EAAa,QAAA,EAAU,QAAQ,WAAW;EAAA,GAC5F;EAEA,EAAA,MAAM,KAAA,GAA0BA,aAAA;EAAA,IAC9B,OAAO;EAAA,MACL,QAAA;EAAA,MACA,OAAA;EAAA,MACA,gBAAA;EAAA,MACA,QAAA;EAAA,MACA,IAAA,EAAM,QAAA;EAAA,MACN,IAAA,EAAM,IAAA;EAAA,MACN,MAAA,EAAQ;EAAA,KACV,CAAA;EAAA,IACA,CAAC,QAAA,EAAU,OAAA,EAAS,gBAAA,EAAkB,UAAU,WAAW;EAAA,GAC7D;EAEA,EAAA,MAAM,SAAA,GAAYA,cAAQ,MAAM,IAAI,gBAAgB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;EAErE,EAAA,uBACEJ,cAAA,CAAC,gBAAA,CAAiB,QAAA,EAAjB,EAA0B,KAAA,EAAO,SAAA,EAChC,QAAA,kBAAAA,cAAA,CAAC,WAAA,CAAY,QAAA,EAAZ,EAAqB,KAAA,EAAe,QAAA,EAAS,CAAA,EAChD,CAAA;EAEJ;EAIO,SAAS,OAAA,GAA4B;EAC1C,EAAA,MAAM,OAAA,GAAUG,iBAAW,WAAW,CAAA;EACtC,EAAA,IAAI,CAAC,OAAA,EAAS;EACZ,IAAA,MAAM,IAAI,MAAM,oEAAoE,CAAA;EAAA,EACtF;EACA,EAAA,OAAO,OAAA;EACT;EAEO,SAAS,WAAA,GAA6B;EAC3C,EAAA,MAAM,UAAU,OAAA,EAAQ;EACxB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,IAAU,CAAC,QAAQ,IAAA,EAAM;EAC5C,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;EAAA,EACpE;EACA,EAAA,OAAO,OAAA,CAAQ,IAAA;EACjB;EAEO,SAAS,aAAA,GAAiC;EAC/C,EAAA,MAAM,UAAU,OAAA,EAAQ;EACxB,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,QAAA,IAAY,CAAC,QAAQ,MAAA,EAAQ;EAChD,IAAA,MAAM,IAAI,MAAM,sDAAsD,CAAA;EAAA,EACxE;EACA,EAAA,OAAO,OAAA,CAAQ,MAAA;EACjB;;EC1MO,MAAM,gBAAA,GAAmB,QAAA;EA2DzB,SAAS,eAAe,IAAA,EAAiC;EAC9D,EAAA,OAAO,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,IAAA,CAAK,IAAA,KAAS,QAAA,IAAY,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,gBAAgB,CAAA;EACnH;;ECvDO,MAAM,oBAAA,CAA0C;EAAA,EAC7C,QAAA,uBAAe,GAAA,EAAwC;EAAA,EACvD,YAAA,uBAAmB,GAAA,EAAsC;EAAA,EACzD,UAAA,GAAa,CAAA;EAAA,EACb,YAAA;EAAA,EACA,mBAAA;EAAA,EAER,WAAA,CAAY,eAAuB,GAAA,EAAK;EACtC,IAAA,IAAA,CAAK,YAAA,GAAe,YAAA;EACpB,IAAA,IAAA,CAAK,mBAAA,GAAsB,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,IAAI,CAAA;EACvD,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,mBAAmB,CAAA;EAAA,EAC7D;EAAA,EAEA,IAAA,CAAK,UAAkB,IAAA,EAAmB;EAExC,IAAA,IAAI,IAAA,GAAY,KAAK,CAAC,CAAA;EACtB,IAAA,IAAI,KAAA;EAEJ,IAAA,IAAI,IAAA,CAAK,UAAU,CAAA,IAAK,OAAO,KAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA,KAAM,UAAA,EAAY;EACnE,MAAA,IAAA,GAAO,KAAK,MAAA,KAAW,CAAA,GAAI,KAAK,CAAC,CAAA,GAAI,KAAK,CAAC,CAAA;EAC3C,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;EACrC,MAAA,KAAA,GAAQ,CAAA,IAAA,EAAO,EAAE,IAAA,CAAK,UAAU,CAAA,CAAA;EAChC,MAAA,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;EAAA,IACvC;EAEA,IAAA,MAAA,CAAO,MAAA,CAAO,WAAA;EAAA,MACZ,EAAE,MAAM,YAAA,EAAc,OAAA,EAAS,EAAE,KAAA,EAAO,IAAA,EAAM,OAAM,EAAE;EAAA,MACtD,IAAA,CAAK;EAAA,KACP;EAAA,EACF;EAAA,EAEA,EAAA,CAAG,OAAe,OAAA,EAAsC;EACtD,IAAA,IAAI,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;EACjC,IAAA,IAAI,CAAC,GAAA,EAAK;EACR,MAAA,GAAA,uBAAU,GAAA,EAAI;EACd,MAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;EAAA,IAC9B;EACA,IAAA,GAAA,CAAI,IAAI,OAAO,CAAA;EAAA,EACjB;EAAA,EAEA,GAAA,CAAI,OAAe,OAAA,EAAuC;EACxD,IAAA,IAAI,CAAC,OAAA,EAAS;EACZ,MAAA,IAAA,CAAK,QAAA,CAAS,OAAO,KAAK,CAAA;EAC1B,MAAA;EAAA,IACF;EACA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,OAAO,CAAA;EAAA,EAC1C;EAAA,EAEA,OAAA,GAAgB;EACd,IAAA,MAAA,CAAO,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,mBAAmB,CAAA;EAC9D,IAAA,IAAA,CAAK,SAAS,KAAA,EAAM;EACpB,IAAA,IAAA,CAAK,aAAa,KAAA,EAAM;EAAA,EAC1B;EAAA,EAEQ,cAAc,CAAA,EAAuB;EAE3C,IAAA,IAAI,KAAK,YAAA,KAAiB,GAAA,IAAO,CAAA,CAAE,MAAA,KAAW,KAAK,YAAA,EAAc;EAEjE,IAAA,MAAM,MAAM,CAAA,CAAE,IAAA;EACd,IAAA,IAAI,CAAC,cAAA,CAAe,GAAG,CAAA,EAAG;EAE1B,IAAA,IAAI,GAAA,CAAI,SAAS,aAAA,EAAe;EAC9B,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAK,GAAA,CAA0B,OAAA;EACnD,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,KAAK,CAAA;EACnC,MAAA,IAAI,GAAA,EAAK;EACP,QAAA,GAAA,CAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,OAAA,CAAQ,IAAI,CAAC,CAAA;EAAA,MACxC;EAAA,IACF,CAAA,MAAA,IAAW,GAAA,CAAI,IAAA,KAAS,WAAA,EAAa;EACnC,MAAA,MAAM,EAAE,KAAA,EAAO,IAAA,EAAK,GAAK,GAAA,CAAwB,OAAA;EACjD,MAAA,MAAM,EAAA,GAAK,IAAA,CAAK,YAAA,CAAa,GAAA,CAAI,KAAK,CAAA;EACtC,MAAA,IAAI,EAAA,EAAI;EACN,QAAA,IAAA,CAAK,YAAA,CAAa,OAAO,KAAK,CAAA;EAC9B,QAAA,EAAA,CAAG,IAAI,CAAA;EAAA,MACT;EAAA,IACF;EAAA,EACF;EACF;;ECZO,SAAS,YAAY,MAAA,EAA8C;EACxE,EAAA,MAAM,EAAE,QAAQ,OAAA,EAAS,cAAA,EAAgB,eAAe,kBAAA,EAAoB,iBAAA,EAAmB,WAAU,GAAI,MAAA;EAE7G,EAAA,MAAM,WAAW,WAAA,EAAY;EAC7B,EAAA,MAAM,YAAY,YAAA,EAAa;EAG/B,EAAA,MAAM,UAAA,GAAaN,aAAO,OAAO,CAAA;EACjC,EAAA,MAAM,iBAAA,GAAoBA,aAAO,cAAc,CAAA;EAC/C,EAAA,MAAM,gBAAA,GAAmBA,aAAO,aAAa,CAAA;EAC7C,EAAA,MAAM,qBAAA,GAAwBA,aAAO,kBAAkB,CAAA;EACvD,EAAA,MAAM,oBAAA,GAAuBA,aAAO,iBAAiB,CAAA;EAErD,EAAAQ,eAAA,CAAU,MAAM;EAAE,IAAA,UAAA,CAAW,OAAA,GAAU,OAAA;EAAA,EAAS,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;EAC5D,EAAAA,eAAA,CAAU,MAAM;EAAE,IAAA,iBAAA,CAAkB,OAAA,GAAU,cAAA;EAAA,EAAgB,CAAA,EAAG,CAAC,cAAc,CAAC,CAAA;EACjF,EAAAA,eAAA,CAAU,MAAM;EAAE,IAAA,gBAAA,CAAiB,OAAA,GAAU,aAAA;EAAA,EAAe,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;EAC9E,EAAAA,eAAA,CAAU,MAAM;EAAE,IAAA,qBAAA,CAAsB,OAAA,GAAU,kBAAA;EAAA,EAAoB,CAAA,EAAG,CAAC,kBAAkB,CAAC,CAAA;EAC7F,EAAAA,eAAA,CAAU,MAAM;EAAE,IAAA,oBAAA,CAAqB,OAAA,GAAU,iBAAA;EAAA,EAAmB,CAAA,EAAG,CAAC,iBAAiB,CAAC,CAAA;EAK1F,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,UAAA,CAAW,OAAA,EAAS;EAEvC,IAAA,MAAM,mBAAgF,EAAC;EAGvF,IAAA,MAAM,WAAW,UAAA,CAAW,OAAA;EAC5B,IAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,EAAG;EACvC,MAAA,MAAM,SAAA,GAAY,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA;EAClC,MAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAc;EAC7B,QAAA,MAAM,cAAA,GAAiB,UAAA,CAAW,OAAA,GAAU,GAAG,CAAA;EAC/C,QAAA,IAAI,cAAA,EAAgB;EAClB,UAAA,cAAA,CAAe,IAAA,EAAM,SAAA,IAAa,IAAA,EAAM,QAAA,EAAU,IAAI,CAAA;EAAA,QACxD;EAAA,MACF,CAAA;EACA,MAAA,SAAA,CAAU,EAAA,CAAG,WAAW,OAAO,CAAA;EAC/B,MAAA,gBAAA,CAAiB,IAAA,CAAK,EAAE,KAAA,EAAO,SAAA,EAAW,SAAS,CAAA;EAAA,IACrD;EAEA,IAAA,OAAO,MAAM;EACX,MAAA,KAAA,MAAW,EAAE,KAAA,EAAO,OAAA,EAAQ,IAAK,gBAAA,EAAkB;EACjD,QAAA,SAAA,CAAU,GAAA,CAAI,OAAO,OAAO,CAAA;EAAA,MAC9B;EAAA,IACF,CAAA;EAAA,EACF,CAAA,EAAG,CAAC,MAAA,EAAQ,SAAS,CAAC,CAAA;EAKtB,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,EAAW;EAEhB,IAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAkC;EACjD,MAAA,MAAM,UAAU,iBAAA,CAAkB,OAAA;EAClC,MAAA,IAAI,CAAC,OAAA,EAAS;EAEd,MAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,IAAA,CAAK,WAAW,CAAA;EAC1C,MAAA,SAAA,CAAU,KAAK,qBAAA,EAAuB;EAAA,QACpC,iBAAiB,IAAA,CAAK,WAAA;EAAA,QACtB,SAAA,EAAW;EAAA,UACT,MAAA;EAAA,UACA,GAAG;EAAA;EACL,OACD,CAAA;EAAA,IACH,CAAA;EAEA,IAAA,SAAA,CAAU,EAAA,CAAG,sBAAsB,OAAO,CAAA;EAC1C,IAAA,OAAO,MAAM;EACX,MAAA,SAAA,CAAU,GAAA,CAAI,sBAAsB,OAAO,CAAA;EAAA,IAC7C,CAAA;EAAA,EACF,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAKtB,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,EAAW;EAEhB,IAAA,MAAM,MAAA,GAAS,CAAC,IAAA,KAAc;EAC5B,MAAA,gBAAA,CAAiB,OAAA,GAAU,IAAA,EAAM,SAAA,IAAa,IAAA,EAAM,QAAQ,CAAA;EAAA,IAC9D,CAAA;EACA,IAAA,MAAM,cAAA,GAAiB,CAAC,IAAA,KAAc;EACpC,MAAA,qBAAA,CAAsB,OAAA,GAAU,IAAA,EAAM,SAAA,IAAa,IAAA,EAAM,QAAQ,CAAA;EAAA,IACnE,CAAA;EACA,IAAA,MAAM,aAAA,GAAgB,CAAC,IAAA,KAAc;EACnC,MAAA,oBAAA,CAAqB,OAAA,GAAU,IAAA,EAAM,SAAA,IAAa,IAAA,EAAM,QAAQ,CAAA;EAAA,IAClE,CAAA;EAEA,IAAA,SAAA,CAAU,EAAA,CAAG,oBAAoB,MAAM,CAAA;EACvC,IAAA,SAAA,CAAU,EAAA,CAAG,4BAA4B,cAAc,CAAA;EACvD,IAAA,SAAA,CAAU,EAAA,CAAG,2BAA2B,aAAa,CAAA;EAErD,IAAA,OAAO,MAAM;EACX,MAAA,SAAA,CAAU,GAAA,CAAI,oBAAoB,MAAM,CAAA;EACxC,MAAA,SAAA,CAAU,GAAA,CAAI,4BAA4B,cAAc,CAAA;EACxD,MAAA,SAAA,CAAU,GAAA,CAAI,2BAA2B,aAAa,CAAA;EAAA,IACxD,CAAA;EAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;EAKd,EAAA,MAAM,YAAA,GAAeR,aAAO,SAAS,CAAA;EACrC,EAAA,YAAA,CAAa,OAAA,GAAU,SAAA;EAEvB,EAAAQ,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,YAAA,CAAa,OAAA,EAAS;EACzC,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,YAAA,CAAa,OAAO,CAAA;EACnD,IAAA,MAAM,WAAW,OAAA,CAAQ,GAAA,CAAI,CAAC,CAAC,KAAA,EAAO,OAAO,CAAA,KAAM;EACjD,MAAA,SAAA,CAAU,EAAA,CAAG,OAAO,OAAO,CAAA;EAC3B,MAAA,OAAO,MAAM;EAAE,QAAA,SAAA,CAAU,GAAA,CAAI,OAAO,OAAO,CAAA;EAAA,MAAG,CAAA;EAAA,IAChD,CAAC,CAAA;EACD,IAAA,OAAO,MAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,EAAA,KAAM,IAAI,CAAA;EAAA,EAC1C,CAAA,EAAG,CAAC,SAAA,EAAW,SAAS,CAAC,CAAA;EAMzB,EAAA,MAAM,SAAA,GAAYP,iBAAA;EAAA,IAChB,CAAC,OAAe,IAAA,KAAc;EAC5B,MAAA,SAAA,EAAW,IAAA,CAAK,OAAO,IAAI,CAAA;EAAA,IAC7B,CAAA;EAAA,IACA,CAAC,SAAS;EAAA,GACZ;EAEA,EAAA,MAAM,YAAA,GAAeA,iBAAA;EAAA,IACnB,CAAC,SAAA,EAAmB,KAAA,EAAe,IAAA,KAAc;EAC/C,MAAA,SAAA,EAAW,KAAK,sBAAA,EAAwB;EAAA,QACtC,eAAA,EAAiB,SAAA;EAAA,QACjB,MAAA;EAAA,QACA,KAAA;EAAA,QACA,KAAA,EAAO;EAAA,OACR,CAAA;EAAA,IACH,CAAA;EAAA,IACA,CAAC,WAAW,MAAM;EAAA,GACpB;EAEA,EAAA,MAAM,YAAA,GAAeA,iBAAA;EAAA,IACnB,CAAC,OAAA,KAAkB;EACjB,MAAA,SAAA,EAAW,IAAA,CAAK,gBAAA,EAAkB,EAAE,MAAA,EAAQ,SAAS,CAAA;EAAA,IACvD,CAAA;EAAA,IACA,CAAC,WAAW,MAAM;EAAA,GACpB;EAEA,EAAA,OAAO;EAAA,IACL,IAAA,EAAM,QAAA;EAAA,IACN,SAAA;EAAA,IACA,YAAA;EAAA,IACA;EAAA,GACF;EACF;;EC9MO,SAAS,cAAc,MAAA,EAAkD;EAC9E,EAAA,MAAM,OAAO,aAAA,EAAc;EAC3B,EAAA,MAAM,YAAY,YAAA,EAAa;EAC/B,EAAA,MAAM,EAAE,aAAY,GAAI,IAAA;EACxB,EAAA,MAAM,EAAE,MAAA,EAAQ,SAAA,EAAU,GAAI,MAAA;EAC9B,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAIQ,eAAqC,IAAI,CAAA;EAC3E,EAAA,MAAM,YAAA,GAAeT,aAAO,SAAS,CAAA;EACrC,EAAA,YAAA,CAAa,OAAA,GAAU,SAAA;EAGvB,EAAAQ,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,IAAa,CAAC,YAAA,CAAa,OAAA,EAAS;EACzC,IAAA,MAAM,WAA2B,EAAC;EAClC,IAAA,MAAA,CAAO,OAAA,CAAQ,aAAa,OAAO,CAAA,CAAE,QAAQ,CAAC,CAAC,KAAA,EAAO,OAAO,CAAA,KAAM;EACjE,MAAA,SAAA,CAAU,EAAA,CAAG,OAAO,OAAO,CAAA;EAC3B,MAAA,QAAA,CAAS,KAAK,MAAM,SAAA,CAAU,GAAA,CAAI,KAAA,EAAO,OAAO,CAAC,CAAA;EAAA,IACnD,CAAC,CAAA;EACD,IAAA,OAAO,MAAM,QAAA,CAAS,OAAA,CAAQ,CAAA,EAAA,KAAM,IAAI,CAAA;EAAA,EAC1C,CAAA,EAAG,CAAC,SAAA,EAAW,SAAS,CAAC,CAAA;EAGzB,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,MAAM,OAAA,GAAU,CAAC,KAAA,KAAe;EAC9B,MAAA,IAAI,KAAA,CAAM,WAAW,MAAA,EAAQ;EAC7B,MAAA,YAAA,CAAa,KAAK,CAAA;EAAA,IACpB,CAAA;EACA,IAAA,SAAA,CAAU,EAAA,CAAG,uBAAuB,OAAO,CAAA;EAC3C,IAAA,OAAO,MAAM;EAAE,MAAA,SAAA,CAAU,GAAA,CAAI,uBAAuB,OAAO,CAAA;EAAA,IAAG,CAAA;EAAA,EAChE,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAGtB,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,MAAM,OAAA,GAAU,CAAC,IAAA,KAAyC;EACxD,MAAA,IAAI,IAAA,CAAK,WAAW,MAAA,EAAQ;EAC5B,MAAA,YAAA,CAAa,KAAK,KAAK,CAAA;EAAA,IACzB,CAAA;EACA,IAAA,SAAA,CAAU,EAAA,CAAG,wBAAwB,OAAO,CAAA;EAC5C,IAAA,OAAO,MAAM;EAAE,MAAA,SAAA,CAAU,GAAA,CAAI,wBAAwB,OAAO,CAAA;EAAA,IAAG,CAAA;EAAA,EACjE,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAGtB,EAAAA,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,MAAM,UAAU,MAAM;EACpB,MAAA,IAAI,CAAC,SAAS,MAAA,EAAQ;EACpB,QAAA,SAAA,CAAU,IAAA,CAAK,oBAAA,EAAsB,EAAE,MAAA,EAAQ,CAAA;EAAA,MACjD;EAAA,IACF,CAAA;EACA,IAAA,QAAA,CAAS,gBAAA,CAAiB,oBAAoB,OAAO,CAAA;EACrD,IAAA,OAAO,MAAM,QAAA,CAAS,mBAAA,CAAoB,kBAAA,EAAoB,OAAO,CAAA;EAAA,EACvE,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAGtB,EAAA,MAAM,IAAA,GAAOP,iBAAA,CAAY,CAAC,KAAA,EAAe,MAAY,QAAA,KAAuC;EAC1F,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,IAAI,QAAA,EAAU;EACZ,MAAA,SAAA,CAAU,IAAA,CAAK,KAAA,EAAO,IAAA,EAAM,QAAQ,CAAA;EAAA,IACtC,CAAA,MAAO;EACL,MAAA,SAAA,CAAU,IAAA,CAAK,OAAO,IAAI,CAAA;EAAA,IAC5B;EAAA,EACF,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;EAEd,EAAA,MAAM,YAAA,GAAeA,iBAAA,CAAY,CAAC,MAAA,KAAmB;EACnD,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,SAAA,CAAU,IAAA,CAAK,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;EAAA,EACtC,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAEtB,EAAA,MAAM,aAAA,GAAgBA,iBAAA,CAAY,CAAC,MAAA,EAAgB,IAAA,KAA0B;EAC3E,IAAA,IAAI,CAAC,SAAA,EAAW;EAChB,IAAA,SAAA,CAAU,KAAK,CAAA,EAAG,MAAM,IAAI,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,CAAE,CAAA;EAAA,EAC9C,CAAA,EAAG,CAAC,SAAA,EAAW,MAAM,CAAC,CAAA;EAEtB,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAM,YAAA,EAAc,aAAA,EAAe,aAAa,SAAA,EAAU;EAC3E;;EClEO,SAAS,iBAAiB,MAAA,EAK/B;EACA,EAAA,MAAM,EAAE,SAAA,EAAW,OAAA,GAAU,IAAA,EAAK,GAAI,MAAA;EACtC,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIQ,cAAA,CAAiC,EAAE,CAAA;EAC7D,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;EAC5C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIA,eAAwB,IAAI,CAAA;EACtD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,CAAC,CAAA;EAE9C,EAAAD,eAAA,CAAU,MAAM;EACd,IAAA,IAAI,CAAC,OAAA,EAAS;EAEd,IAAA,IAAI,SAAA,GAAY,KAAA;EAChB,IAAA,UAAA,CAAW,IAAI,CAAA;EAEf,IAAA,KAAA,CAAM,CAAA,EAAG,SAAS,CAAA,UAAA,CAAY,CAAA,CAC3B,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,CAAI,IAAA,EAAM,CAAA,CACxB,IAAA,CAAK,CAAC,IAAA,KAAS;EACd,MAAA,IAAI,SAAA,EAAW;EACf,MAAA,MAAM,YAAoC,IAAA,CAAK,KAAA,IAAS,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,MAAY;EAAA,QAC3E,IAAI,CAAA,CAAE,EAAA;EAAA,QACN,OAAO,CAAA,CAAE,KAAA;EAAA,QACT,WAAA,EAAa,EAAE,WAAA,IAAe,EAAA;EAAA,QAC9B,UAAA,EAAY,EAAE,UAAA,IAAc,CAAA;EAAA,QAC5B,UAAA,EAAY,EAAE,UAAA,IAAc,CAAA;EAAA,QAC5B,SAAA,EAAW,EAAE,SAAA,IAAa,qBAAA;EAAA,QAC1B,UAAA,EAAY,CAAA,CAAE,UAAA,IAAc,CAAC,OAAO,CAAA;EAAA,QACpC,IAAA,EAAM,UAAA;EAAA,QACN,SAAS,CAAA,CAAE,OAAA;EAAA,QACX,WAAW,CAAA,CAAE,SAAA;EAAA,QACb,SAAA,EAAW,CAAC,EAAE,CAAA,CAAE,WAAW,CAAA,CAAE,SAAA,CAAA;EAAA,QAC7B,MAAA,EAAQ,CAAA;EAAA,QACR,YAAA,EAAc;EAAA,OAChB,CAAE,CAAA;EACF,MAAA,QAAA,CAAS,QAAQ,CAAA;EACjB,MAAA,QAAA,CAAS,IAAI,CAAA;EAAA,IACf,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;EACd,MAAA,IAAI,SAAA,EAAW;EACf,MAAA,QAAA,CAAS,IAAI,OAAO,CAAA;EAAA,IACtB,CAAC,CAAA,CACA,OAAA,CAAQ,MAAM;EACb,MAAA,IAAI,CAAC,SAAA,EAAW,UAAA,CAAW,KAAK,CAAA;EAAA,IAClC,CAAC,CAAA;EAEH,IAAA,OAAO,MAAM;EAAE,MAAA,SAAA,GAAY,IAAA;EAAA,IAAM,CAAA;EAAA,EACnC,CAAA,EAAG,CAAC,SAAA,EAAW,OAAA,EAAS,UAAU,CAAC,CAAA;EAEnC,EAAA,MAAM,UAAU,MAAM,aAAA,CAAc,CAAC,CAAA,KAAM,IAAI,CAAC,CAAA;EAEhD,EAAA,OAAO,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAO,OAAA,EAAQ;EAC1C;;;;;;;;;;;;;;;;;;;;;;;","x_google_ignoreList":[0]}
@@ -0,0 +1,2 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react/jsx-runtime"),require("react")):"function"==typeof define&&define.amd?define(["exports","react/jsx-runtime","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).SmoreSDK={},e.ReactJSXRuntime,e.React)}(this,function(e,t,r){"use strict";function n(e,t){void 0===t&&(t={});var r=t.insertAt;if(e&&"undefined"!=typeof document){var n=document.head||document.getElementsByTagName("head")[0],o=document.createElement("style");o.type="text/css","top"===r&&n.firstChild?n.insertBefore(o,n.firstChild):n.appendChild(o),o.styleSheet?o.styleSheet.cssText=e:o.appendChild(document.createTextNode(e))}}var o="TapButton-module_tapButton__dqJr9",a="TapButton-module_pressed__Z2nfR",s="TapButton-module_disabled__3bR6q";n(".TapButton-module_tapButton__dqJr9{-webkit-tap-highlight-color:transparent;align-items:center;background:var(--color-primary,#6366f1);border:none;border-radius:16px;color:#fff;cursor:pointer;display:flex;font-size:18px;font-weight:700;justify-content:center;min-height:80px;min-width:80px;padding:16px 24px;touch-action:manipulation;transition:transform .1s ease,background .1s ease;user-select:none;-webkit-user-select:none}.TapButton-module_pressed__Z2nfR,.TapButton-module_tapButton__dqJr9:active{background:var(--color-primary-dark,#4f46e5);transform:scale(.95)}.TapButton-module_disabled__3bR6q{cursor:not-allowed;opacity:.5}.TapButton-module_disabled__3bR6q.TapButton-module_pressed__Z2nfR,.TapButton-module_disabled__3bR6q:active{background:var(--color-primary,#6366f1);transform:none}");var i="HoldButton-module_holdButton__tu4mi",l="HoldButton-module_pressed__JWIRG",c="HoldButton-module_disabled__4QwwT";n(".HoldButton-module_holdButton__tu4mi{-webkit-tap-highlight-color:transparent;align-items:center;background:var(--color-secondary,#f59e0b);border:none;border-radius:16px;color:#fff;cursor:pointer;display:flex;font-size:18px;font-weight:700;justify-content:center;min-height:80px;min-width:80px;padding:16px 24px;touch-action:manipulation;transition:transform .1s ease,background .1s ease;user-select:none;-webkit-user-select:none}.HoldButton-module_holdButton__tu4mi:active,.HoldButton-module_pressed__JWIRG{background:var(--color-secondary-dark,#d97706);transform:scale(.95)}.HoldButton-module_disabled__4QwwT{cursor:not-allowed;opacity:.5}.HoldButton-module_disabled__4QwwT.HoldButton-module_pressed__JWIRG,.HoldButton-module_disabled__4QwwT:active{background:var(--color-secondary,#f59e0b);transform:none}");var u={padContainer:"DirectionPad-module_padContainer__iL-rh",horizontal:"DirectionPad-module_horizontal__kI4j7",vertical:"DirectionPad-module_vertical__b8Xec",row:"DirectionPad-module_row__mzuUr",dirButton:"DirectionPad-module_dirButton__QCCHz"};n(".DirectionPad-module_padContainer__iL-rh{align-items:center;display:flex;flex-direction:column;gap:8px;user-select:none;-webkit-user-select:none}.DirectionPad-module_horizontal__kI4j7{flex-direction:row;gap:16px}.DirectionPad-module_vertical__b8Xec{flex-direction:column;gap:16px}.DirectionPad-module_row__mzuUr{display:flex;gap:8px}.DirectionPad-module_dirButton__QCCHz{-webkit-tap-highlight-color:transparent;align-items:center;background:var(--color-surface,#374151);border:none;border-radius:12px;color:#fff;cursor:pointer;display:flex;font-size:24px;height:70px;justify-content:center;touch-action:manipulation;transition:transform .1s ease,background .1s ease;width:70px}.DirectionPad-module_dirButton__QCCHz:active{background:var(--color-primary,#6366f1);transform:scale(.9)}.DirectionPad-module_horizontal__kI4j7 .DirectionPad-module_dirButton__QCCHz,.DirectionPad-module_vertical__b8Xec .DirectionPad-module_dirButton__QCCHz{font-size:32px;height:100px;width:100px}");var d="SwipeArea-module_swipeArea__yob7L";n(".SwipeArea-module_swipeArea__yob7L{height:100%;touch-action:none;user-select:none;-webkit-user-select:none;width:100%}");class m{constructor(e){this.socket=e}emit(e,...t){this.socket.emit(e,...t)}on(e,t){this.socket.on(e,t)}off(e,t){t?this.socket.off(e,t):this.socket.off(e)}}const f=r.createContext(null);function p(){const e=r.useContext(f);if(!e)throw new Error("useTransport must be used within a RoomProvider that supplies a Transport");return e}const h=r.createContext(null);function _(){const e=r.useContext(h);if(!e)throw new Error("useRoom must be used within HostRoomProvider or PlayerRoomProvider");return e}function g(){const e=_();if("host"!==e.side||!e.host)throw new Error("useHostRoom must be used within HostRoomProvider");return e.host}function b(){const e=_();if("player"!==e.side||!e.player)throw new Error("usePlayerRoom must be used within PlayerRoomProvider");return e.player}e.DirectTransport=m,e.DirectionPad=function({onDirection:e,leftRightOnly:n=!1,upDownOnly:o=!1,className:a}){const s=r.useRef(new Set),i=r.useCallback(t=>{s.current.has(t)||(s.current.add(t),navigator.vibrate&&navigator.vibrate(10),e(t))},[e]),l=r.useCallback(e=>{s.current.delete(e)},[]),c=(e,r)=>t.jsx("button",{className:`${u.dirButton} ${u[e]}`,onTouchStart:t=>{t.preventDefault(),i(e)},onTouchEnd:t=>{t.preventDefault(),l(e)},onTouchCancel:()=>l(e),onMouseDown:()=>i(e),onMouseUp:()=>l(e),onMouseLeave:()=>l(e),children:r},e);return n?t.jsxs("div",{className:`${u.padContainer} ${u.horizontal} ${a||""}`,children:[c("left","◀"),c("right","▶")]}):o?t.jsxs("div",{className:`${u.padContainer} ${u.vertical} ${a||""}`,children:[c("up","▲"),c("down","▼")]}):t.jsxs("div",{className:`${u.padContainer} ${u.full} ${a||""}`,children:[t.jsx("div",{className:u.row,children:c("up","▲")}),t.jsxs("div",{className:u.row,children:[c("left","◀"),c("right","▶")]}),t.jsx("div",{className:u.row,children:c("down","▼")})]})},e.HoldButton=function({onHoldStart:e,onHoldEnd:n,children:o,className:a,disabled:s=!1}){const u=r.useRef(!1),d=r.useRef(null),m=r.useCallback(()=>{s||u.current||(u.current=!0,d.current?.classList.add(l),navigator.vibrate&&navigator.vibrate(10),e())},[e,s]),f=r.useCallback(()=>{u.current&&(u.current=!1,d.current?.classList.remove(l),n())},[n]),p=r.useCallback(e=>{e.preventDefault(),m()},[m]),h=r.useCallback(e=>{e.preventDefault(),f()},[f]);return t.jsx("button",{ref:d,className:`${i} ${a||""} ${s?c:""}`,onTouchStart:p,onTouchEnd:h,onTouchCancel:h,onMouseDown:m,onMouseUp:f,onMouseLeave:f,disabled:s,children:o})},e.HostRoomProvider=({roomCode:e,players:n,leaderId:o,socket:a,children:s})=>{const i=r.useMemo(()=>n.filter(e=>!1!==e.connected),[n]),l=r.useMemo(()=>({roomCode:e,players:n,connectedPlayers:i,leaderId:o,socket:a}),[e,n,i,o,a]),c=r.useMemo(()=>({roomCode:e,players:n,connectedPlayers:i,leaderId:o,side:"host",host:l,player:null}),[e,n,i,o,l]),u=r.useMemo(()=>new m(a),[a]);return t.jsx(f.Provider,{value:u,children:t.jsx(h.Provider,{value:c,children:s})})},e.PlayerRoomProvider=({roomCode:e,players:n,leaderId:o,mySessionId:a,isLeader:s,socket:i,isConnected:l,children:c})=>{const u=r.useMemo(()=>n.filter(e=>!1!==e.connected),[n]),d=r.useMemo(()=>({roomCode:e,players:n,connectedPlayers:u,leaderId:o,mySessionId:a,isLeader:s,socket:i,isConnected:l}),[e,n,u,o,a,s,i,l]),p=r.useMemo(()=>({roomCode:e,players:n,connectedPlayers:u,leaderId:o,side:"player",host:null,player:d}),[e,n,u,o,d]),_=r.useMemo(()=>new m(i),[i]);return t.jsx(f.Provider,{value:_,children:t.jsx(h.Provider,{value:p,children:c})})},e.PostMessageTransport=class{handlers=new Map;ackCallbacks=new Map;ackCounter=0;parentOrigin;boundMessageHandler;constructor(e="*"){this.parentOrigin=e,this.boundMessageHandler=this.handleMessage.bind(this),window.addEventListener("message",this.boundMessageHandler)}emit(e,...t){let r,n=t[0];if(t.length>=2&&"function"==typeof t[t.length-1]){t.length,n=t[0];const e=t[t.length-1];r="ack_"+ ++this.ackCounter,this.ackCallbacks.set(r,e)}window.parent.postMessage({type:"smore:emit",payload:{event:e,data:n,ackId:r}},this.parentOrigin)}on(e,t){let r=this.handlers.get(e);r||(r=new Set,this.handlers.set(e,r)),r.add(t)}off(e,t){t?this.handlers.get(e)?.delete(t):this.handlers.delete(e)}destroy(){window.removeEventListener("message",this.boundMessageHandler),this.handlers.clear(),this.ackCallbacks.clear()}handleMessage(e){if("*"!==this.parentOrigin&&e.origin!==this.parentOrigin)return;const t=e.data;var r;if((r=t)&&"object"==typeof r&&"string"==typeof r.type&&r.type.startsWith("smore:"))if("smore:event"===t.type){const{event:e,data:r}=t.payload,n=this.handlers.get(e);n&&n.forEach(e=>e(r))}else if("smore:ack"===t.type){const{ackId:e,data:r}=t.payload,n=this.ackCallbacks.get(e);n&&(this.ackCallbacks.delete(e),n(r))}}},e.SwipeArea=function({onSwipe:e,threshold:n=50,children:o,className:a}){const s=r.useRef(null),i=r.useCallback(e=>{const t=e.touches[0];t&&(s.current={x:t.clientX,y:t.clientY})},[]),l=r.useCallback(t=>{if(!s.current)return;const r=t.changedTouches[0];if(!r)return;const o=r.clientX-s.current.x,a=r.clientY-s.current.y,i=Math.abs(o),l=Math.abs(a);if(i<n&&l<n)return void(s.current=null);let c;c=i>l?o>0?"right":"left":a>0?"down":"up",navigator.vibrate&&navigator.vibrate(15),e(c),s.current=null},[e,n]);return t.jsx("div",{className:`${d} ${a||""}`,onTouchStart:i,onTouchEnd:l,onTouchCancel:()=>{s.current=null},children:o})},e.TapButton=function({onTap:e,children:n,className:i,disabled:l=!1}){const c=r.useRef(!1),u=r.useRef(null),d=r.useCallback(t=>{l||(t.preventDefault(),c.current=!0,u.current?.classList.add(a),navigator.vibrate&&navigator.vibrate(10),e())},[e,l]),m=r.useCallback(e=>{e.preventDefault(),c.current=!1,u.current?.classList.remove(a)},[]),f=r.useCallback(()=>{l||(c.current=!0,u.current?.classList.add(a),e())},[e,l]),p=r.useCallback(()=>{c.current=!1,u.current?.classList.remove(a)},[]);return t.jsx("button",{ref:u,className:`${o} ${i||""} ${l?s:""}`,onTouchStart:d,onTouchEnd:m,onTouchCancel:m,onMouseDown:f,onMouseUp:p,onMouseLeave:p,disabled:l,children:n})},e.TransportContext=f,e.useExternalGames=function(e){const{serverUrl:t,enabled:n=!0}=e,[o,a]=r.useState([]),[s,i]=r.useState(!1),[l,c]=r.useState(null),[u,d]=r.useState(0);return r.useEffect(()=>{if(!n)return;let e=!1;return i(!0),fetch(`${t}/api/games`).then(e=>e.json()).then(t=>{if(e)return;const r=(t.games||[]).map(e=>({id:e.id,title:e.title,description:e.description||"",minPlayers:e.minPlayers||2,maxPlayers:e.maxPlayers||8,thumbnail:e.thumbnail||"/thumbnails/g8.jpeg",categories:e.categories||["party"],type:"external",hostUrl:e.hostUrl,playerUrl:e.playerUrl,available:!(!e.hostUrl||!e.playerUrl),rating:4,heroRequired:!1}));a(r),c(null)}).catch(t=>{e||c(t.message)}).finally(()=>{e||i(!1)}),()=>{e=!0}},[t,n,u]),{games:o,loading:s,error:l,refresh:()=>d(e=>e+1)}},e.useGameHost=function(e){const{gameId:t,onInput:n,onStateRequest:o,onPlayerLeave:a,onPlayerDisconnect:s,onPlayerReconnect:i,listeners:l}=e,c=g(),u=p(),d=r.useRef(n),m=r.useRef(o),f=r.useRef(a),h=r.useRef(s),_=r.useRef(i);r.useEffect(()=>{d.current=n},[n]),r.useEffect(()=>{m.current=o},[o]),r.useEffect(()=>{f.current=a},[a]),r.useEffect(()=>{h.current=s},[s]),r.useEffect(()=>{_.current=i},[i]),r.useEffect(()=>{if(!u||!d.current)return;const e=[],r=d.current;for(const n of Object.keys(r)){const r=`${t}:${n}`,o=e=>{const t=d.current?.[n];t&&t(e?.sessionId??e?.playerId,e)};u.on(r,o),e.push({event:r,handler:o})}return()=>{for(const{event:t,handler:r}of e)u.off(t,r)}},[t,u]),r.useEffect(()=>{if(!u)return;const e=e=>{const r=m.current;if(!r)return;const n=r(e.requesterId);u.emit("game:state-response",{targetSessionId:e.requesterId,gameState:{gameId:t,...n}})};return u.on("game:state-request",e),()=>{u.off("game:state-request",e)}},[u,t]),r.useEffect(()=>{if(!u)return;const e=e=>{f.current?.(e?.sessionId??e?.playerId)},t=e=>{h.current?.(e?.sessionId??e?.playerId)},r=e=>{_.current?.(e?.sessionId??e?.playerId)};return u.on("room:player-left",e),u.on("room:player-disconnected",t),u.on("room:player-reconnected",r),()=>{u.off("room:player-left",e),u.off("room:player-disconnected",t),u.off("room:player-reconnected",r)}},[u]);const b=r.useRef(l);return b.current=l,r.useEffect(()=>{if(!u||!b.current)return;const e=Object.entries(b.current).map(([e,t])=>(u.on(e,t),()=>{u.off(e,t)}));return()=>e.forEach(e=>e())},[u,l]),{room:c,broadcast:r.useCallback((e,t)=>{u?.emit(e,t)},[u]),sendToPlayer:r.useCallback((e,r,n)=>{u?.emit("game:state-to-player",{targetSessionId:e,gameId:t,event:r,state:n})},[u,t]),emitGameOver:r.useCallback(e=>{u?.emit("room:game-over",{gameId:t,results:e})},[u,t])}},e.useGamePlayer=function(e){const t=b(),n=p(),{isConnected:o}=t,{gameId:a,listeners:s}=e,[i,l]=r.useState(null),c=r.useRef(s);return c.current=s,r.useEffect(()=>{if(!n||!c.current)return;const e=[];return Object.entries(c.current).forEach(([t,r])=>{n.on(t,r),e.push(()=>n.off(t,r))}),()=>e.forEach(e=>e())},[n,s]),r.useEffect(()=>{if(!n)return;const e=e=>{e.gameId===a&&l(e)};return n.on("game:state-response",e),()=>{n.off("game:state-response",e)}},[n,a]),r.useEffect(()=>{if(!n)return;const e=e=>{e.gameId===a&&l(e.state)};return n.on("game:state-to-player",e),()=>{n.off("game:state-to-player",e)}},[n,a]),r.useEffect(()=>{if(!n)return;const e=()=>{document.hidden||n.emit("game:request-state",{gameId:a})};return document.addEventListener("visibilitychange",e),()=>document.removeEventListener("visibilitychange",e)},[n,a]),{room:t,emit:r.useCallback((e,t,r)=>{n&&(r?n.emit(e,t,r):n.emit(e,t))},[n]),sendTapInput:r.useCallback(e=>{n&&n.emit(`${a}:${e}`)},[n,a]),sendHoldInput:r.useCallback((e,t)=>{n&&n.emit(`${a}:${e}:${t}`)},[n,a]),isConnected:o,gameState:i}},e.useHostRoom=g,e.usePlayerRoom=b,e.useRoom=_,e.useTransport=p});
2
+ //# sourceMappingURL=smore-sdk.umd.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smore-sdk.umd.min.js","sources":["../../../../node_modules/.pnpm/style-inject@0.3.0/node_modules/style-inject/dist/style-inject.es.js","../../src/transport/DirectTransport.ts","../../src/context/RoomProvider.tsx","../../src/components/DirectionPad.tsx","../../src/components/HoldButton.tsx","../../src/transport/PostMessageTransport.ts","../../src/transport/protocol.ts","../../src/components/SwipeArea.tsx","../../src/components/TapButton.tsx","../../src/hooks/useExternalGames.ts","../../src/hooks/useGameHost.ts","../../src/hooks/useGamePlayer.ts"],"sourcesContent":["function styleInject(css, ref) {\n if ( ref === void 0 ) ref = {};\n var insertAt = ref.insertAt;\n\n if (!css || typeof document === 'undefined') { return; }\n\n var head = document.head || document.getElementsByTagName('head')[0];\n var style = document.createElement('style');\n style.type = 'text/css';\n\n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild);\n } else {\n head.appendChild(style);\n }\n } else {\n head.appendChild(style);\n }\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n}\n\nexport default styleInject;\n","/**\n * DirectTransport - Wraps a Socket.IO socket as a Transport.\n * Used by bundled (internal) games. Behaviour is identical to using socket directly.\n */\n\nimport type { Socket } from 'socket.io-client';\nimport type { Transport, TransportEventHandler } from './types';\n\nexport class DirectTransport implements Transport {\n constructor(private socket: Socket) {}\n\n emit(event: string, ...args: any[]): void {\n this.socket.emit(event, ...args);\n }\n\n on(event: string, handler: TransportEventHandler): void {\n this.socket.on(event, handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (handler) {\n this.socket.off(event, handler);\n } else {\n this.socket.off(event);\n }\n }\n}\n","/**\n * RoomProvider - SDK Room Context\n *\n * Foundation context that all other SDK hooks depend on.\n * Provides room state (players, roomCode, leaderId) for both host and player sides.\n *\n * Also provides a Transport abstraction via TransportContext.\n * - HostRoomProvider / PlayerRoomProvider create a DirectTransport from the socket.\n * - IframeRoomProvider (external) provides a PostMessageTransport.\n *\n * Usage:\n * - Host: <HostRoomProvider roomCode={...} players={...} leaderId={...} socket={...}>\n * - Player: <PlayerRoomProvider roomCode={...} players={...} leaderId={...} mySessionId={...} isLeader={...} socket={...} isConnected={...}>\n */\n\nimport React, { createContext, useContext, useMemo } from 'react';\nimport type { Player } from '@smore/shared';\nimport type { Socket } from 'socket.io-client';\nimport type { Transport } from '../transport/types';\nimport { DirectTransport } from '../transport/DirectTransport';\n\n// ===== Transport Context =====\n\nconst TransportContext = createContext<Transport | null>(null);\n\nexport function useTransport(): Transport {\n const transport = useContext(TransportContext);\n if (!transport) {\n throw new Error('useTransport must be used within a RoomProvider that supplies a Transport');\n }\n return transport;\n}\n\nexport { TransportContext };\n\n// ===== State Types =====\n\nexport interface RoomState {\n roomCode: string;\n players: Player[];\n connectedPlayers: Player[];\n leaderId: string | null;\n}\n\nexport interface HostRoomState extends RoomState {\n socket: Socket;\n}\n\nexport interface PlayerRoomState extends RoomState {\n mySessionId: string;\n isLeader: boolean;\n socket: Socket;\n isConnected: boolean;\n}\n\nexport interface RoomContextValue {\n roomCode: string;\n players: Player[];\n connectedPlayers: Player[];\n leaderId: string | null;\n side: 'host' | 'player';\n host: HostRoomState | null;\n player: PlayerRoomState | null;\n}\n\n// ===== Context =====\n\nexport const RoomContext = createContext<RoomContextValue | null>(null);\n\n// ===== Host Provider =====\n\ninterface HostRoomProviderProps {\n roomCode: string;\n players: Player[];\n leaderId: string | null;\n socket: Socket;\n children: React.ReactNode;\n}\n\nexport const HostRoomProvider: React.FC<HostRoomProviderProps> = ({\n roomCode,\n players,\n leaderId,\n socket,\n children,\n}) => {\n const connectedPlayers = useMemo(\n () => players.filter((p) => p.connected !== false),\n [players]\n );\n\n const hostState: HostRoomState = useMemo(\n () => ({ roomCode, players, connectedPlayers, leaderId, socket }),\n [roomCode, players, connectedPlayers, leaderId, socket]\n );\n\n const value: RoomContextValue = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n side: 'host' as const,\n host: hostState,\n player: null,\n }),\n [roomCode, players, connectedPlayers, leaderId, hostState]\n );\n\n const transport = useMemo(() => new DirectTransport(socket), [socket]);\n\n return (\n <TransportContext.Provider value={transport}>\n <RoomContext.Provider value={value}>{children}</RoomContext.Provider>\n </TransportContext.Provider>\n );\n};\n\n// ===== Player Provider =====\n\ninterface PlayerRoomProviderProps {\n roomCode: string;\n players: Player[];\n leaderId: string | null;\n mySessionId: string;\n isLeader: boolean;\n socket: Socket;\n isConnected: boolean;\n children: React.ReactNode;\n}\n\nexport const PlayerRoomProvider: React.FC<PlayerRoomProviderProps> = ({\n roomCode,\n players,\n leaderId,\n mySessionId,\n isLeader,\n socket,\n isConnected,\n children,\n}) => {\n const connectedPlayers = useMemo(\n () => players.filter((p) => p.connected !== false),\n [players]\n );\n\n const playerState: PlayerRoomState = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n mySessionId,\n isLeader,\n socket,\n isConnected,\n }),\n [roomCode, players, connectedPlayers, leaderId, mySessionId, isLeader, socket, isConnected]\n );\n\n const value: RoomContextValue = useMemo(\n () => ({\n roomCode,\n players,\n connectedPlayers,\n leaderId,\n side: 'player' as const,\n host: null,\n player: playerState,\n }),\n [roomCode, players, connectedPlayers, leaderId, playerState]\n );\n\n const transport = useMemo(() => new DirectTransport(socket), [socket]);\n\n return (\n <TransportContext.Provider value={transport}>\n <RoomContext.Provider value={value}>{children}</RoomContext.Provider>\n </TransportContext.Provider>\n );\n};\n\n// ===== Hooks =====\n\nexport function useRoom(): RoomContextValue {\n const context = useContext(RoomContext);\n if (!context) {\n throw new Error('useRoom must be used within HostRoomProvider or PlayerRoomProvider');\n }\n return context;\n}\n\nexport function useHostRoom(): HostRoomState {\n const context = useRoom();\n if (context.side !== 'host' || !context.host) {\n throw new Error('useHostRoom must be used within HostRoomProvider');\n }\n return context.host;\n}\n\nexport function usePlayerRoom(): PlayerRoomState {\n const context = useRoom();\n if (context.side !== 'player' || !context.player) {\n throw new Error('usePlayerRoom must be used within PlayerRoomProvider');\n }\n return context.player;\n}\n","/**\n * S'MORE Game SDK - DirectionPad Component\n *\n * 4-direction or 2-direction control pad\n */\n\nimport { useCallback, useRef } from 'react';\nimport type { DirectionPadProps } from '../types';\nimport styles from './DirectionPad.module.css';\n\n/**\n * DirectionPad - For directional input\n *\n * @example\n * ```tsx\n * // 4 directions\n * <DirectionPad onDirection={(dir) => send('move', { direction: dir })} />\n *\n * // Left/Right only\n * <DirectionPad leftRightOnly onDirection={(dir) => send('move', { direction: dir })} />\n * ```\n */\nexport function DirectionPad({\n onDirection,\n leftRightOnly = false,\n upDownOnly = false,\n className,\n}: DirectionPadProps) {\n const pressedRef = useRef<Set<string>>(new Set());\n\n const handlePress = useCallback((direction: 'up' | 'down' | 'left' | 'right') => {\n if (pressedRef.current.has(direction)) return;\n pressedRef.current.add(direction);\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onDirection(direction);\n }, [onDirection]);\n\n const handleRelease = useCallback((direction: string) => {\n pressedRef.current.delete(direction);\n }, []);\n\n const createButton = (direction: 'up' | 'down' | 'left' | 'right', label: string) => (\n <button\n key={direction}\n className={`${styles.dirButton} ${styles[direction]}`}\n onTouchStart={(e) => {\n e.preventDefault();\n handlePress(direction);\n }}\n onTouchEnd={(e) => {\n e.preventDefault();\n handleRelease(direction);\n }}\n onTouchCancel={() => handleRelease(direction)}\n onMouseDown={() => handlePress(direction)}\n onMouseUp={() => handleRelease(direction)}\n onMouseLeave={() => handleRelease(direction)}\n >\n {label}\n </button>\n );\n\n if (leftRightOnly) {\n return (\n <div className={`${styles.padContainer} ${styles.horizontal} ${className || ''}`}>\n {createButton('left', '◀')}\n {createButton('right', '▶')}\n </div>\n );\n }\n\n if (upDownOnly) {\n return (\n <div className={`${styles.padContainer} ${styles.vertical} ${className || ''}`}>\n {createButton('up', '▲')}\n {createButton('down', '▼')}\n </div>\n );\n }\n\n return (\n <div className={`${styles.padContainer} ${styles.full} ${className || ''}`}>\n <div className={styles.row}>\n {createButton('up', '▲')}\n </div>\n <div className={styles.row}>\n {createButton('left', '◀')}\n {createButton('right', '▶')}\n </div>\n <div className={styles.row}>\n {createButton('down', '▼')}\n </div>\n </div>\n );\n}\n\nexport default DirectionPad;\n","/**\n * S'MORE Game SDK - HoldButton Component\n *\n * Button that detects hold start/end events\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { HoldButtonProps } from '../types';\nimport styles from './HoldButton.module.css';\n\n/**\n * HoldButton - For hold/release input patterns\n *\n * @example\n * ```tsx\n * <HoldButton\n * onHoldStart={() => send('charge', { type: 'start' })}\n * onHoldEnd={() => send('charge', { type: 'end' })}\n * >\n * HOLD\n * </HoldButton>\n * ```\n */\nexport function HoldButton({\n onHoldStart,\n onHoldEnd,\n children,\n className,\n disabled = false,\n}: HoldButtonProps) {\n const isHolding = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const startHold = useCallback(() => {\n if (disabled || isHolding.current) return;\n isHolding.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onHoldStart();\n }, [onHoldStart, disabled]);\n\n const endHold = useCallback(() => {\n if (!isHolding.current) return;\n isHolding.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n onHoldEnd();\n }, [onHoldEnd]);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n startHold();\n }, [startHold]);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n endHold();\n }, [endHold]);\n\n return (\n <button\n ref={buttonRef}\n className={`${styles.holdButton} ${className || ''} ${disabled ? styles.disabled : ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={handleTouchEnd}\n onMouseDown={startHold}\n onMouseUp={endHold}\n onMouseLeave={endHold}\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\nexport default HoldButton;\n","/**\n * PostMessageTransport - Transport over window.postMessage for iframe-hosted games.\n *\n * Used inside an iframe. Sends `smore:emit` to parent and listens for `smore:event` from parent.\n */\n\nimport type { Transport, TransportEventHandler } from './types';\nimport type { SmoreEventMessage, SmoreAckMessage } from './protocol';\nimport { isSmoreMessage } from './protocol';\n\nexport class PostMessageTransport implements Transport {\n private handlers = new Map<string, Set<TransportEventHandler>>();\n private ackCallbacks = new Map<string, (...args: any[]) => void>();\n private ackCounter = 0;\n private parentOrigin: string;\n private boundMessageHandler: (e: MessageEvent) => void;\n\n constructor(parentOrigin: string = '*') {\n this.parentOrigin = parentOrigin;\n this.boundMessageHandler = this.handleMessage.bind(this);\n window.addEventListener('message', this.boundMessageHandler);\n }\n\n emit(event: string, ...args: any[]): void {\n // Detect if last arg is a callback (ack pattern)\n let data: any = args[0];\n let ackId: string | undefined;\n\n if (args.length >= 2 && typeof args[args.length - 1] === 'function') {\n data = args.length === 2 ? args[0] : args[0];\n const callback = args[args.length - 1];\n ackId = `ack_${++this.ackCounter}`;\n this.ackCallbacks.set(ackId, callback);\n }\n\n window.parent.postMessage(\n { type: 'smore:emit', payload: { event, data, ackId } },\n this.parentOrigin,\n );\n }\n\n on(event: string, handler: TransportEventHandler): void {\n let set = this.handlers.get(event);\n if (!set) {\n set = new Set();\n this.handlers.set(event, set);\n }\n set.add(handler);\n }\n\n off(event: string, handler?: TransportEventHandler): void {\n if (!handler) {\n this.handlers.delete(event);\n return;\n }\n this.handlers.get(event)?.delete(handler);\n }\n\n destroy(): void {\n window.removeEventListener('message', this.boundMessageHandler);\n this.handlers.clear();\n this.ackCallbacks.clear();\n }\n\n private handleMessage(e: MessageEvent): void {\n // Origin validation: only accept messages from the expected parent\n if (this.parentOrigin !== '*' && e.origin !== this.parentOrigin) return;\n\n const msg = e.data;\n if (!isSmoreMessage(msg)) return;\n\n if (msg.type === 'smore:event') {\n const { event, data } = (msg as SmoreEventMessage).payload;\n const set = this.handlers.get(event);\n if (set) {\n set.forEach((handler) => handler(data));\n }\n } else if (msg.type === 'smore:ack') {\n const { ackId, data } = (msg as SmoreAckMessage).payload;\n const cb = this.ackCallbacks.get(ackId);\n if (cb) {\n this.ackCallbacks.delete(ackId);\n cb(data);\n }\n }\n }\n}\n","/**\n * postMessage protocol types for iframe ↔ parent communication.\n */\n\nexport const SMORE_MSG_PREFIX = 'smore:' as const;\n\nexport interface SmoreReadyMessage {\n type: 'smore:ready';\n}\n\nexport interface SmoreInitMessage {\n type: 'smore:init';\n payload: {\n side: 'host' | 'player';\n roomCode: string;\n players: any[];\n leaderId: string | null;\n mySessionId?: string;\n isLeader?: boolean;\n };\n}\n\nexport interface SmoreEmitMessage {\n type: 'smore:emit';\n payload: {\n event: string;\n data?: any;\n ackId?: string;\n };\n}\n\nexport interface SmoreEventMessage {\n type: 'smore:event';\n payload: {\n event: string;\n data?: any;\n };\n}\n\nexport interface SmoreAckMessage {\n type: 'smore:ack';\n payload: {\n ackId: string;\n data?: any;\n };\n}\n\nexport interface SmoreUpdateMessage {\n type: 'smore:update';\n payload: {\n players?: any[];\n leaderId?: string | null;\n };\n}\n\nexport type SmoreMessage =\n | SmoreReadyMessage\n | SmoreInitMessage\n | SmoreEmitMessage\n | SmoreEventMessage\n | SmoreAckMessage\n | SmoreUpdateMessage;\n\nexport function isSmoreMessage(data: any): data is SmoreMessage {\n return data && typeof data === 'object' && typeof data.type === 'string' && data.type.startsWith(SMORE_MSG_PREFIX);\n}\n","/**\n * S'MORE Game SDK - SwipeArea Component\n *\n * Detects swipe gestures\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { SwipeAreaProps } from '../types';\nimport styles from './SwipeArea.module.css';\n\n/**\n * SwipeArea - For swipe gesture input\n *\n * @example\n * ```tsx\n * <SwipeArea onSwipe={(dir) => send('swipe', { direction: dir })}>\n * <div>Swipe here!</div>\n * </SwipeArea>\n * ```\n */\nexport function SwipeArea({\n onSwipe,\n threshold = 50,\n children,\n className,\n}: SwipeAreaProps) {\n const touchStart = useRef<{ x: number; y: number } | null>(null);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n const touch = e.touches[0];\n if (!touch) return;\n touchStart.current = { x: touch.clientX, y: touch.clientY };\n }, []);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n if (!touchStart.current) return;\n\n const touch = e.changedTouches[0];\n if (!touch) return;\n const deltaX = touch.clientX - touchStart.current.x;\n const deltaY = touch.clientY - touchStart.current.y;\n\n const absX = Math.abs(deltaX);\n const absY = Math.abs(deltaY);\n\n // Check if swipe exceeds threshold\n if (absX < threshold && absY < threshold) {\n touchStart.current = null;\n return;\n }\n\n // Determine direction\n let direction: 'up' | 'down' | 'left' | 'right';\n if (absX > absY) {\n direction = deltaX > 0 ? 'right' : 'left';\n } else {\n direction = deltaY > 0 ? 'down' : 'up';\n }\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(15);\n }\n\n onSwipe(direction);\n touchStart.current = null;\n }, [onSwipe, threshold]);\n\n return (\n <div\n className={`${styles.swipeArea} ${className || ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={() => { touchStart.current = null; }}\n >\n {children}\n </div>\n );\n}\n\nexport default SwipeArea;\n","/**\n * S'MORE Game SDK - TapButton Component\n *\n * Optimized touch button with haptic feedback\n */\n\nimport { useRef, useCallback } from 'react';\nimport type React from 'react';\nimport type { TapButtonProps } from '../types';\nimport styles from './TapButton.module.css';\n\n/**\n * TapButton - Optimized for mobile touch input\n *\n * @example\n * ```tsx\n * <TapButton onTap={() => send('tap')}>\n * TAP!\n * </TapButton>\n * ```\n */\nexport function TapButton({\n onTap,\n children,\n className,\n disabled = false,\n}: TapButtonProps) {\n const isPressed = useRef(false);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n const handleTouchStart = useCallback((e: React.TouchEvent) => {\n if (disabled) return;\n e.preventDefault();\n isPressed.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n\n // Haptic feedback\n if (navigator.vibrate) {\n navigator.vibrate(10);\n }\n\n onTap();\n }, [onTap, disabled]);\n\n const handleTouchEnd = useCallback((e: React.TouchEvent) => {\n e.preventDefault();\n isPressed.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n }, []);\n\n const handleMouseDown = useCallback(() => {\n if (disabled) return;\n isPressed.current = true;\n buttonRef.current?.classList.add(styles.pressed || '');\n onTap();\n }, [onTap, disabled]);\n\n const handleMouseUp = useCallback(() => {\n isPressed.current = false;\n buttonRef.current?.classList.remove(styles.pressed || '');\n }, []);\n\n return (\n <button\n ref={buttonRef}\n className={`${styles.tapButton} ${className || ''} ${disabled ? styles.disabled : ''}`}\n onTouchStart={handleTouchStart}\n onTouchEnd={handleTouchEnd}\n onTouchCancel={handleTouchEnd}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n disabled={disabled}\n >\n {children}\n </button>\n );\n}\n\nexport default TapButton;\n","/**\n * useExternalGames - Fetches external games from the server API.\n *\n * Returns a list of GameMetadata-compatible objects for external (iframe) games.\n * Consumers merge this with their local GAMES array.\n */\n\nimport { useState, useEffect } from 'react';\n\nexport interface ExternalGameMetadata {\n id: string;\n title: string;\n description: string;\n minPlayers: number;\n maxPlayers: number;\n thumbnail: string;\n categories: string[];\n type: 'external';\n hostUrl: string | null;\n playerUrl: string | null;\n available: boolean;\n rating: number;\n heroRequired: boolean;\n}\n\nexport interface UseExternalGamesConfig {\n serverUrl: string;\n enabled?: boolean;\n}\n\nexport function useExternalGames(config: UseExternalGamesConfig): {\n games: ExternalGameMetadata[];\n loading: boolean;\n error: string | null;\n refresh: () => void;\n} {\n const { serverUrl, enabled = true } = config;\n const [games, setGames] = useState<ExternalGameMetadata[]>([]);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [refreshKey, setRefreshKey] = useState(0);\n\n useEffect(() => {\n if (!enabled) return;\n\n let cancelled = false;\n setLoading(true);\n\n fetch(`${serverUrl}/api/games`)\n .then((res) => res.json())\n .then((data) => {\n if (cancelled) return;\n const external: ExternalGameMetadata[] = (data.games || []).map((g: any) => ({\n id: g.id,\n title: g.title,\n description: g.description || '',\n minPlayers: g.minPlayers || 2,\n maxPlayers: g.maxPlayers || 8,\n thumbnail: g.thumbnail || '/thumbnails/g8.jpeg',\n categories: g.categories || ['party'],\n type: 'external' as const,\n hostUrl: g.hostUrl,\n playerUrl: g.playerUrl,\n available: !!(g.hostUrl && g.playerUrl),\n rating: 4.0,\n heroRequired: false,\n }));\n setGames(external);\n setError(null);\n })\n .catch((err) => {\n if (cancelled) return;\n setError(err.message);\n })\n .finally(() => {\n if (!cancelled) setLoading(false);\n });\n\n return () => { cancelled = true; };\n }, [serverUrl, enabled, refreshKey]);\n\n const refresh = () => setRefreshKey((k) => k + 1);\n\n return { games, loading, error, refresh };\n}\n","/**\n * useGameHost - Host-side game hook for the S'MORE SDK\n *\n * Provides host game developers with:\n * - Automatic room state access (via useHostRoom context)\n * - Input listening (dedicated socket events)\n * - Broadcasting to all/specific players\n * - Game over emission\n * - Player lifecycle callbacks\n *\n * Internally uses Transport abstraction so the same API works over\n * Socket.IO (bundled games) or postMessage (iframe games).\n */\nimport { useEffect, useCallback, useRef } from 'react';\nimport { useHostRoom } from '../context/RoomProvider';\nimport { useTransport } from '../context/RoomProvider';\nimport type { HostRoomState } from '../context/RoomProvider';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype InputHandler = (playerId: string, data?: any) => void;\n\nexport interface UseGameHostConfig {\n /** Unique game identifier (e.g. 'fibbage', 'wasd') */\n gameId: string;\n\n /**\n * Map of action names to handler functions.\n * Listens directly on socket for `{gameId}:{key}` events.\n */\n onInput?: Record<string, InputHandler>;\n\n /**\n * Called when a player requests game state (e.g. after returning from background).\n * Return the current game state object to send back to that player.\n */\n onStateRequest?: (playerId: string) => Record<string, any>;\n\n /** Called when a player leaves the room. */\n onPlayerLeave?: (playerId: string) => void;\n\n /** Called when a player disconnects (may reconnect). */\n onPlayerDisconnect?: (playerId: string) => void;\n\n /** Called when a previously disconnected player reconnects. */\n onPlayerReconnect?: (playerId: string) => void;\n\n /**\n * Generic socket event listeners (for server broadcasts the host needs to receive).\n * Keys are full event names, values are handler functions.\n */\n listeners?: Record<string, (data: any) => void>;\n}\n\nexport interface UseGameHostReturn {\n /** Current room state from HostRoomProvider context. */\n room: HostRoomState;\n\n /** Broadcast an event to all players via the host socket. */\n broadcast: (event: string, data: any) => void;\n\n /** Send state/event to a specific player by sessionId. */\n sendToPlayer: (sessionId: string, event: string, data: any) => void;\n\n /** Emit game-over with optional results payload. */\n emitGameOver: (results?: any) => void;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nexport function useGameHost(config: UseGameHostConfig): UseGameHostReturn {\n const { gameId, onInput, onStateRequest, onPlayerLeave, onPlayerDisconnect, onPlayerReconnect, listeners } = config;\n\n const hostRoom = useHostRoom();\n const transport = useTransport();\n\n // Stable refs to avoid stale closures in listeners\n const onInputRef = useRef(onInput);\n const onStateRequestRef = useRef(onStateRequest);\n const onPlayerLeaveRef = useRef(onPlayerLeave);\n const onPlayerDisconnectRef = useRef(onPlayerDisconnect);\n const onPlayerReconnectRef = useRef(onPlayerReconnect);\n\n useEffect(() => { onInputRef.current = onInput; }, [onInput]);\n useEffect(() => { onStateRequestRef.current = onStateRequest; }, [onStateRequest]);\n useEffect(() => { onPlayerLeaveRef.current = onPlayerLeave; }, [onPlayerLeave]);\n useEffect(() => { onPlayerDisconnectRef.current = onPlayerDisconnect; }, [onPlayerDisconnect]);\n useEffect(() => { onPlayerReconnectRef.current = onPlayerReconnect; }, [onPlayerReconnect]);\n\n // -------------------------------------------------------------------------\n // Dedicated input listeners (transport events)\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport || !onInputRef.current) return;\n\n const registeredEvents: Array<{ event: string; handler: (...args: any[]) => void }> = [];\n\n // For each handler key, listen on transport for \"{gameId}:{key}\"\n const inputMap = onInputRef.current;\n for (const key of Object.keys(inputMap)) {\n const eventName = `${gameId}:${key}`;\n const handler = (data: any) => {\n const currentHandler = onInputRef.current?.[key];\n if (currentHandler) {\n currentHandler(data?.sessionId ?? data?.playerId, data);\n }\n };\n transport.on(eventName, handler);\n registeredEvents.push({ event: eventName, handler });\n }\n\n return () => {\n for (const { event, handler } of registeredEvents) {\n transport.off(event, handler);\n }\n };\n }, [gameId, transport]);\n\n // -------------------------------------------------------------------------\n // State request handler\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport) return;\n\n const handler = (data: { requesterId: string }) => {\n const stateFn = onStateRequestRef.current;\n if (!stateFn) return;\n\n const gameState = stateFn(data.requesterId);\n transport.emit('game:state-response', {\n targetSessionId: data.requesterId,\n gameState: {\n gameId,\n ...gameState,\n },\n });\n };\n\n transport.on('game:state-request', handler);\n return () => {\n transport.off('game:state-request', handler);\n };\n }, [transport, gameId]);\n\n // -------------------------------------------------------------------------\n // Player lifecycle listeners\n // -------------------------------------------------------------------------\n useEffect(() => {\n if (!transport) return;\n\n const onLeft = (data: any) => {\n onPlayerLeaveRef.current?.(data?.sessionId ?? data?.playerId);\n };\n const onDisconnected = (data: any) => {\n onPlayerDisconnectRef.current?.(data?.sessionId ?? data?.playerId);\n };\n const onReconnected = (data: any) => {\n onPlayerReconnectRef.current?.(data?.sessionId ?? data?.playerId);\n };\n\n transport.on('room:player-left', onLeft);\n transport.on('room:player-disconnected', onDisconnected);\n transport.on('room:player-reconnected', onReconnected);\n\n return () => {\n transport.off('room:player-left', onLeft);\n transport.off('room:player-disconnected', onDisconnected);\n transport.off('room:player-reconnected', onReconnected);\n };\n }, [transport]);\n\n // -------------------------------------------------------------------------\n // Generic listeners\n // -------------------------------------------------------------------------\n const listenersRef = useRef(listeners);\n listenersRef.current = listeners;\n\n useEffect(() => {\n if (!transport || !listenersRef.current) return;\n const entries = Object.entries(listenersRef.current);\n const handlers = entries.map(([event, handler]) => {\n transport.on(event, handler);\n return () => { transport.off(event, handler); };\n });\n return () => handlers.forEach(fn => fn());\n }, [transport, listeners]);\n\n // -------------------------------------------------------------------------\n // Actions\n // -------------------------------------------------------------------------\n\n const broadcast = useCallback(\n (event: string, data: any) => {\n transport?.emit(event, data);\n },\n [transport],\n );\n\n const sendToPlayer = useCallback(\n (sessionId: string, event: string, data: any) => {\n transport?.emit('game:state-to-player', {\n targetSessionId: sessionId,\n gameId,\n event,\n state: data,\n });\n },\n [transport, gameId],\n );\n\n const emitGameOver = useCallback(\n (results?: any) => {\n transport?.emit('room:game-over', { gameId, results });\n },\n [transport, gameId],\n );\n\n return {\n room: hostRoom,\n broadcast,\n sendToPlayer,\n emitGameOver,\n };\n}\n","import { useEffect, useCallback, useState, useRef } from 'react';\nimport { usePlayerRoom } from '../context/RoomProvider';\nimport { useTransport } from '../context/RoomProvider';\nimport type { PlayerRoomState } from '../context/RoomProvider';\n\nexport interface UseGamePlayerConfig {\n gameId: string;\n listeners?: Record<string, (data: any) => void>;\n}\n\nexport interface UseGamePlayerReturn {\n room: PlayerRoomState;\n emit: (event: string, data?: any, callback?: (response: any) => void) => void;\n /** Emit a tap input: sends `{gameId}:{action}` event */\n sendTapInput: (action: string) => void;\n /** Emit a hold input: sends `{gameId}:{action}:{type}` event */\n sendHoldInput: (action: string, type: 'START' | 'END') => void;\n isConnected: boolean;\n gameState: Record<string, any> | null;\n}\n\nexport function useGamePlayer(config: UseGamePlayerConfig): UseGamePlayerReturn {\n const room = usePlayerRoom();\n const transport = useTransport();\n const { isConnected } = room;\n const { gameId, listeners } = config;\n const [gameState, setGameState] = useState<Record<string, any> | null>(null);\n const listenersRef = useRef(listeners);\n listenersRef.current = listeners;\n\n // Transport listeners\n useEffect(() => {\n if (!transport || !listenersRef.current) return;\n const cleanups: (() => void)[] = [];\n Object.entries(listenersRef.current).forEach(([event, handler]) => {\n transport.on(event, handler);\n cleanups.push(() => transport.off(event, handler));\n });\n return () => cleanups.forEach(fn => fn());\n }, [transport, listeners]);\n\n // Reconnection: game:state-response\n useEffect(() => {\n if (!transport) return;\n const handler = (state: any) => {\n if (state.gameId !== gameId) return;\n setGameState(state);\n };\n transport.on('game:state-response', handler);\n return () => { transport.off('game:state-response', handler); };\n }, [transport, gameId]);\n\n // game:state-to-player (Host push)\n useEffect(() => {\n if (!transport) return;\n const handler = (data: { gameId: string; state: any }) => {\n if (data.gameId !== gameId) return;\n setGameState(data.state);\n };\n transport.on('game:state-to-player', handler);\n return () => { transport.off('game:state-to-player', handler); };\n }, [transport, gameId]);\n\n // Visibility change\n useEffect(() => {\n if (!transport) return;\n const handler = () => {\n if (!document.hidden) {\n transport.emit('game:request-state', { gameId });\n }\n };\n document.addEventListener('visibilitychange', handler);\n return () => document.removeEventListener('visibilitychange', handler);\n }, [transport, gameId]);\n\n // API\n const emit = useCallback((event: string, data?: any, callback?: (response: any) => void) => {\n if (!transport) return;\n if (callback) {\n transport.emit(event, data, callback);\n } else {\n transport.emit(event, data);\n }\n }, [transport]);\n\n const sendTapInput = useCallback((action: string) => {\n if (!transport) return;\n transport.emit(`${gameId}:${action}`);\n }, [transport, gameId]);\n\n const sendHoldInput = useCallback((action: string, type: 'START' | 'END') => {\n if (!transport) return;\n transport.emit(`${gameId}:${action}:${type}`);\n }, [transport, gameId]);\n\n return { room, emit, sendTapInput, sendHoldInput, isConnected, gameState };\n}\n"],"names":["styleInject","css","ref","insertAt","document","head","getElementsByTagName","style","createElement","type","firstChild","insertBefore","appendChild","styleSheet","cssText","createTextNode","DirectTransport","constructor","socket","this","emit","event","args","on","handler","off","TransportContext","createContext","useTransport","transport","useContext","Error","RoomContext","useRoom","context","useHostRoom","side","host","usePlayerRoom","player","onDirection","leftRightOnly","upDownOnly","className","pressedRef","useRef","Set","handlePress","useCallback","direction","current","has","add","navigator","vibrate","handleRelease","delete","createButton","label","jsx","styles","dirButton","onTouchStart","e","preventDefault","onTouchEnd","onTouchCancel","onMouseDown","onMouseUp","onMouseLeave","children","jsxs","padContainer","horizontal","vertical","full","row","onHoldStart","onHoldEnd","disabled","isHolding","buttonRef","startHold","classList","endHold","remove","handleTouchStart","handleTouchEnd","roomCode","players","leaderId","connectedPlayers","useMemo","filter","p","connected","hostState","value","Provider","mySessionId","isLeader","isConnected","playerState","handlers","Map","ackCallbacks","ackCounter","parentOrigin","boundMessageHandler","handleMessage","bind","window","addEventListener","ackId","data","length","callback","set","parent","postMessage","payload","get","destroy","removeEventListener","clear","origin","msg","startsWith","forEach","cb","onSwipe","threshold","touchStart","touch","touches","x","clientX","y","clientY","changedTouches","deltaX","deltaY","absX","Math","abs","absY","onTap","isPressed","handleMouseDown","handleMouseUp","config","serverUrl","enabled","games","setGames","useState","loading","setLoading","error","setError","refreshKey","setRefreshKey","useEffect","cancelled","fetch","then","res","json","external","map","g","id","title","description","minPlayers","maxPlayers","thumbnail","categories","hostUrl","playerUrl","available","rating","heroRequired","catch","err","message","finally","refresh","k","gameId","onInput","onStateRequest","onPlayerLeave","onPlayerDisconnect","onPlayerReconnect","listeners","hostRoom","onInputRef","onStateRequestRef","onPlayerLeaveRef","onPlayerDisconnectRef","onPlayerReconnectRef","registeredEvents","inputMap","key","Object","keys","eventName","currentHandler","sessionId","playerId","push","stateFn","gameState","requesterId","targetSessionId","onLeft","onDisconnected","onReconnected","listenersRef","entries","fn","room","broadcast","sendToPlayer","state","emitGameOver","results","setGameState","cleanups","hidden","sendTapInput","action","sendHoldInput"],"mappings":"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","x_google_ignoreList":[0]}
package/package.json ADDED
@@ -0,0 +1,87 @@
1
+ {
2
+ "name": "@smoregg/sdk",
3
+ "version": "0.1.0",
4
+ "description": "S'MORE Game SDK - Simplified interface for building party games",
5
+ "type": "module",
6
+ "main": "./dist/esm/index.js",
7
+ "types": "./dist/types/index.d.ts",
8
+ "unpkg": "dist/umd/smore-sdk.umd.min.js",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/types/index.d.ts",
12
+ "import": "./dist/esm/index.js",
13
+ "require": "./dist/cjs/index.cjs"
14
+ },
15
+ "./iframe": {
16
+ "types": "./dist/types/iframe/index.d.ts",
17
+ "import": "./dist/esm/iframe/index.js",
18
+ "require": "./dist/cjs/iframe/index.cjs"
19
+ },
20
+ "./server": {
21
+ "types": "./dist/types/server/index.d.ts",
22
+ "import": "./dist/esm/server/index.js",
23
+ "require": "./dist/cjs/server/index.cjs"
24
+ },
25
+ "./dev": {
26
+ "types": "./dist/types/dev/index.d.ts",
27
+ "import": "./dist/esm/dev/index.js",
28
+ "require": "./dist/cjs/dev/index.cjs"
29
+ },
30
+ "./components/*": {
31
+ "types": "./dist/types/components/*.d.ts",
32
+ "import": "./dist/esm/components/*.js",
33
+ "require": "./dist/cjs/components/*.cjs"
34
+ },
35
+ "./transport": {
36
+ "types": "./dist/types/transport/index.d.ts",
37
+ "import": "./dist/esm/transport/index.js",
38
+ "require": "./dist/cjs/transport/index.cjs"
39
+ }
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "rollup -c && tsc --project tsconfig.build.json",
47
+ "typecheck": "tsc --noEmit",
48
+ "check-game": "node scripts/check-game.js",
49
+ "clean": "rm -rf dist",
50
+ "prepublishOnly": "pnpm build",
51
+ "publish:npm": "node -e \"const p=require('./package.json');p.name='@smoregg/sdk';delete p.dependencies;require('fs').writeFileSync('./package.json',JSON.stringify(p,null,2))\" && npm publish --access public && git checkout package.json"
52
+ },
53
+ "peerDependencies": {
54
+ "react": "^18.0.0 || ^19.0.0",
55
+ "socket.io": "^4",
56
+ "socket.io-client": "^4"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "socket.io": {
60
+ "optional": true
61
+ }
62
+ },
63
+ "devDependencies": {
64
+ "@rollup/plugin-commonjs": "^28.0.0",
65
+ "@rollup/plugin-node-resolve": "^16.0.0",
66
+ "@rollup/plugin-terser": "^0.4.0",
67
+ "@types/react": "^19.1.16",
68
+ "react": "^19.1.1",
69
+ "rollup": "^4.0.0",
70
+ "rollup-plugin-esbuild": "^6.2.1",
71
+ "rollup-plugin-postcss": "^4.0.0",
72
+ "tslib": "^2.8.0",
73
+ "typescript": "^5.7.3"
74
+ },
75
+ "publishConfig": {
76
+ "access": "public"
77
+ },
78
+ "keywords": [
79
+ "game",
80
+ "party-game",
81
+ "multiplayer",
82
+ "sdk",
83
+ "react"
84
+ ],
85
+ "author": "S'MORE Team",
86
+ "license": "MIT"
87
+ }