@ankhorage/zora 21.0.23 → 21.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 (554) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +6 -2
  3. package/dist/features/authoring/allowedChildren.d.ts +5 -2
  4. package/dist/features/authoring/allowedChildren.d.ts.map +1 -1
  5. package/dist/features/authoring/allowedChildren.js +13 -2
  6. package/dist/features/authoring/allowedChildren.js.map +1 -1
  7. package/dist/features/authoring/componentMeta.d.ts.map +1 -1
  8. package/dist/features/authoring/componentMeta.js +21 -0
  9. package/dist/features/authoring/componentMeta.js.map +1 -1
  10. package/dist/features/authoring/constants.d.ts +3 -0
  11. package/dist/features/authoring/constants.d.ts.map +1 -1
  12. package/dist/features/authoring/constants.js +3 -0
  13. package/dist/features/authoring/constants.js.map +1 -1
  14. package/dist/features/card/cardMeta.d.ts +1 -1
  15. package/dist/features/card/cardMeta.d.ts.map +1 -1
  16. package/dist/features/card/cardMeta.js +7 -2
  17. package/dist/features/card/cardMeta.js.map +1 -1
  18. package/dist/features/chess/adapters/inbound/ChessBoard.d.ts +5 -0
  19. package/dist/features/chess/adapters/inbound/ChessBoard.d.ts.map +1 -0
  20. package/dist/features/chess/adapters/inbound/ChessBoard.js +119 -0
  21. package/dist/features/chess/adapters/inbound/ChessBoard.js.map +1 -0
  22. package/dist/features/chess/adapters/inbound/OpeningBook.d.ts +5 -0
  23. package/dist/features/chess/adapters/inbound/OpeningBook.d.ts.map +1 -0
  24. package/dist/features/chess/adapters/inbound/OpeningBook.js +94 -0
  25. package/dist/features/chess/adapters/inbound/OpeningBook.js.map +1 -0
  26. package/dist/features/chess/meta.d.ts +219 -0
  27. package/dist/features/chess/meta.d.ts.map +1 -0
  28. package/dist/features/chess/meta.js +165 -0
  29. package/dist/features/chess/meta.js.map +1 -0
  30. package/dist/features/chess/public.d.ts +12 -0
  31. package/dist/features/chess/public.d.ts.map +1 -0
  32. package/dist/features/chess/public.js +10 -0
  33. package/dist/features/chess/public.js.map +1 -0
  34. package/dist/features/chess/utils/chessSquares.d.ts +4 -0
  35. package/dist/features/chess/utils/chessSquares.d.ts.map +1 -0
  36. package/dist/features/chess/utils/chessSquares.js +3 -0
  37. package/dist/features/chess/utils/chessSquares.js.map +1 -0
  38. package/dist/features/chess/utils/createBoardSquares.d.ts +4 -0
  39. package/dist/features/chess/utils/createBoardSquares.d.ts.map +1 -0
  40. package/dist/features/chess/utils/createBoardSquares.js +9 -0
  41. package/dist/features/chess/utils/createBoardSquares.js.map +1 -0
  42. package/dist/features/chess/utils/createChessBoardColorScheme.d.ts +35 -0
  43. package/dist/features/chess/utils/createChessBoardColorScheme.d.ts.map +1 -0
  44. package/dist/features/chess/utils/createChessBoardColorScheme.js +26 -0
  45. package/dist/features/chess/utils/createChessBoardColorScheme.js.map +1 -0
  46. package/dist/features/chess/utils/createOpeningBookColorScheme.d.ts +11 -0
  47. package/dist/features/chess/utils/createOpeningBookColorScheme.d.ts.map +1 -0
  48. package/dist/features/chess/utils/createOpeningBookColorScheme.js +21 -0
  49. package/dist/features/chess/utils/createOpeningBookColorScheme.js.map +1 -0
  50. package/dist/features/chess/utils/getSquareFile.d.ts +4 -0
  51. package/dist/features/chess/utils/getSquareFile.d.ts.map +1 -0
  52. package/dist/features/chess/utils/getSquareFile.js +5 -0
  53. package/dist/features/chess/utils/getSquareFile.js.map +1 -0
  54. package/dist/features/chess/utils/getSquareRank.d.ts +4 -0
  55. package/dist/features/chess/utils/getSquareRank.d.ts.map +1 -0
  56. package/dist/features/chess/utils/getSquareRank.js +5 -0
  57. package/dist/features/chess/utils/getSquareRank.js.map +1 -0
  58. package/dist/features/chess/utils/isLightSquare.d.ts +4 -0
  59. package/dist/features/chess/utils/isLightSquare.d.ts.map +1 -0
  60. package/dist/features/chess/utils/isLightSquare.js +6 -0
  61. package/dist/features/chess/utils/isLightSquare.js.map +1 -0
  62. package/dist/features/game/adapters/inbound/Game.d.ts +5 -0
  63. package/dist/features/game/adapters/inbound/Game.d.ts.map +1 -0
  64. package/dist/features/game/adapters/inbound/Game.js +24 -0
  65. package/dist/features/game/adapters/inbound/Game.js.map +1 -0
  66. package/dist/features/game/adapters/inbound/GameEntity.d.ts +5 -0
  67. package/dist/features/game/adapters/inbound/GameEntity.d.ts.map +1 -0
  68. package/dist/features/game/adapters/inbound/GameEntity.js +29 -0
  69. package/dist/features/game/adapters/inbound/GameEntity.js.map +1 -0
  70. package/dist/features/game/adapters/inbound/GameField.d.ts +4 -0
  71. package/dist/features/game/adapters/inbound/GameField.d.ts.map +1 -0
  72. package/dist/features/game/adapters/inbound/GameField.js +32 -0
  73. package/dist/features/game/adapters/inbound/GameField.js.map +1 -0
  74. package/dist/features/game/adapters/inbound/GameInputZone.d.ts +4 -0
  75. package/dist/features/game/adapters/inbound/GameInputZone.d.ts.map +1 -0
  76. package/dist/features/game/adapters/inbound/GameInputZone.js +50 -0
  77. package/dist/features/game/adapters/inbound/GameInputZone.js.map +1 -0
  78. package/dist/features/game/adapters/inbound/GameMeasurementProbe.d.ts +4 -0
  79. package/dist/features/game/adapters/inbound/GameMeasurementProbe.d.ts.map +1 -0
  80. package/dist/features/game/adapters/inbound/GameMeasurementProbe.js +54 -0
  81. package/dist/features/game/adapters/inbound/GameMeasurementProbe.js.map +1 -0
  82. package/dist/features/game/adapters/inbound/GameOverlay.d.ts +4 -0
  83. package/dist/features/game/adapters/inbound/GameOverlay.d.ts.map +1 -0
  84. package/dist/features/game/adapters/inbound/GameOverlay.js +39 -0
  85. package/dist/features/game/adapters/inbound/GameOverlay.js.map +1 -0
  86. package/dist/features/game/adapters/inbound/createGameKeyboardEvent.d.ts +16 -0
  87. package/dist/features/game/adapters/inbound/createGameKeyboardEvent.d.ts.map +1 -0
  88. package/dist/features/game/adapters/inbound/createGameKeyboardEvent.js +16 -0
  89. package/dist/features/game/adapters/inbound/createGameKeyboardEvent.js.map +1 -0
  90. package/dist/features/game/adapters/inbound/createGameMeasurementEvent.d.ts +14 -0
  91. package/dist/features/game/adapters/inbound/createGameMeasurementEvent.d.ts.map +1 -0
  92. package/dist/features/game/adapters/inbound/createGameMeasurementEvent.js +25 -0
  93. package/dist/features/game/adapters/inbound/createGameMeasurementEvent.js.map +1 -0
  94. package/dist/features/game/adapters/inbound/createGamePointerEvent.d.ts +17 -0
  95. package/dist/features/game/adapters/inbound/createGamePointerEvent.d.ts.map +1 -0
  96. package/dist/features/game/adapters/inbound/createGamePointerEvent.js +20 -0
  97. package/dist/features/game/adapters/inbound/createGamePointerEvent.js.map +1 -0
  98. package/dist/features/game/adapters/inbound/measureGameEntity.d.ts +5 -0
  99. package/dist/features/game/adapters/inbound/measureGameEntity.d.ts.map +1 -0
  100. package/dist/features/game/adapters/inbound/measureGameEntity.js +22 -0
  101. package/dist/features/game/adapters/inbound/measureGameEntity.js.map +1 -0
  102. package/dist/features/game/adapters/inbound/useGameInputZoneResponder.d.ts +15 -0
  103. package/dist/features/game/adapters/inbound/useGameInputZoneResponder.d.ts.map +1 -0
  104. package/dist/features/game/adapters/inbound/useGameInputZoneResponder.js +67 -0
  105. package/dist/features/game/adapters/inbound/useGameInputZoneResponder.js.map +1 -0
  106. package/dist/features/game/composition/GameRuntimeContext.d.ts +5 -0
  107. package/dist/features/game/composition/GameRuntimeContext.d.ts.map +1 -0
  108. package/dist/features/game/composition/GameRuntimeContext.js +4 -0
  109. package/dist/features/game/composition/GameRuntimeContext.js.map +1 -0
  110. package/dist/features/game/composition/createGameBindingContext.d.ts +4 -0
  111. package/dist/features/game/composition/createGameBindingContext.d.ts.map +1 -0
  112. package/dist/features/game/composition/createGameBindingContext.js +10 -0
  113. package/dist/features/game/composition/createGameBindingContext.js.map +1 -0
  114. package/dist/features/game/composition/createGameMeasurementRegistry.d.ts +4 -0
  115. package/dist/features/game/composition/createGameMeasurementRegistry.d.ts.map +1 -0
  116. package/dist/features/game/composition/createGameMeasurementRegistry.js +15 -0
  117. package/dist/features/game/composition/createGameMeasurementRegistry.js.map +1 -0
  118. package/dist/features/game/composition/useGameRuntime.d.ts +5 -0
  119. package/dist/features/game/composition/useGameRuntime.d.ts.map +1 -0
  120. package/dist/features/game/composition/useGameRuntime.js +117 -0
  121. package/dist/features/game/composition/useGameRuntime.js.map +1 -0
  122. package/dist/features/game/composition/useGameScheduledEffects.d.ts +17 -0
  123. package/dist/features/game/composition/useGameScheduledEffects.d.ts.map +1 -0
  124. package/dist/features/game/composition/useGameScheduledEffects.js +40 -0
  125. package/dist/features/game/composition/useGameScheduledEffects.js.map +1 -0
  126. package/dist/features/game/meta/gameEntityMeta.d.ts +403 -0
  127. package/dist/features/game/meta/gameEntityMeta.d.ts.map +1 -0
  128. package/dist/features/game/meta/gameEntityMeta.js +224 -0
  129. package/dist/features/game/meta/gameEntityMeta.js.map +1 -0
  130. package/dist/features/game/meta/gameFieldMeta.d.ts +61 -0
  131. package/dist/features/game/meta/gameFieldMeta.d.ts.map +1 -0
  132. package/dist/features/game/meta/gameFieldMeta.js +48 -0
  133. package/dist/features/game/meta/gameFieldMeta.js.map +1 -0
  134. package/dist/features/game/meta/gameInputZoneMeta.d.ts +163 -0
  135. package/dist/features/game/meta/gameInputZoneMeta.d.ts.map +1 -0
  136. package/dist/features/game/meta/gameInputZoneMeta.js +138 -0
  137. package/dist/features/game/meta/gameInputZoneMeta.js.map +1 -0
  138. package/dist/features/game/meta/gameMeasurementProbeMeta.d.ts +112 -0
  139. package/dist/features/game/meta/gameMeasurementProbeMeta.d.ts.map +1 -0
  140. package/dist/features/game/meta/gameMeasurementProbeMeta.js +70 -0
  141. package/dist/features/game/meta/gameMeasurementProbeMeta.js.map +1 -0
  142. package/dist/features/game/meta/gameMeta.d.ts +130 -0
  143. package/dist/features/game/meta/gameMeta.d.ts.map +1 -0
  144. package/dist/features/game/meta/gameMeta.js +113 -0
  145. package/dist/features/game/meta/gameMeta.js.map +1 -0
  146. package/dist/features/game/meta/gameOverlayMeta.d.ts +55 -0
  147. package/dist/features/game/meta/gameOverlayMeta.d.ts.map +1 -0
  148. package/dist/features/game/meta/gameOverlayMeta.js +65 -0
  149. package/dist/features/game/meta/gameOverlayMeta.js.map +1 -0
  150. package/dist/features/game/public.d.ts +8 -0
  151. package/dist/features/game/public.d.ts.map +1 -0
  152. package/dist/features/game/public.js +7 -0
  153. package/dist/features/game/public.js.map +1 -0
  154. package/dist/features/game/utils/clampGamePercentage.d.ts +3 -0
  155. package/dist/features/game/utils/clampGamePercentage.d.ts.map +1 -0
  156. package/dist/features/game/utils/clampGamePercentage.js +5 -0
  157. package/dist/features/game/utils/clampGamePercentage.js.map +1 -0
  158. package/dist/features/game/utils/resolveGameEntityMotionPlan.d.ts +15 -0
  159. package/dist/features/game/utils/resolveGameEntityMotionPlan.d.ts.map +1 -0
  160. package/dist/features/game/utils/resolveGameEntityMotionPlan.js +31 -0
  161. package/dist/features/game/utils/resolveGameEntityMotionPlan.js.map +1 -0
  162. package/dist/features/game/utils/toGamePercentage.d.ts +3 -0
  163. package/dist/features/game/utils/toGamePercentage.d.ts.map +1 -0
  164. package/dist/features/game/utils/toGamePercentage.js +6 -0
  165. package/dist/features/game/utils/toGamePercentage.js.map +1 -0
  166. package/dist/features/game/utils/useAnimatedGameEntityValue.d.ts +5 -0
  167. package/dist/features/game/utils/useAnimatedGameEntityValue.d.ts.map +1 -0
  168. package/dist/features/game/utils/useAnimatedGameEntityValue.js +33 -0
  169. package/dist/features/game/utils/useAnimatedGameEntityValue.js.map +1 -0
  170. package/dist/features/game/utils/useGameEntityAnimatedStyle.d.ts +16 -0
  171. package/dist/features/game/utils/useGameEntityAnimatedStyle.d.ts.map +1 -0
  172. package/dist/features/game/utils/useGameEntityAnimatedStyle.js +52 -0
  173. package/dist/features/game/utils/useGameEntityAnimatedStyle.js.map +1 -0
  174. package/dist/features/game/utils/useGameEntityMeasurement.d.ts +5 -0
  175. package/dist/features/game/utils/useGameEntityMeasurement.d.ts.map +1 -0
  176. package/dist/features/game/utils/useGameEntityMeasurement.js +14 -0
  177. package/dist/features/game/utils/useGameEntityMeasurement.js.map +1 -0
  178. package/dist/features/game/utils/useGameEntityMotionProgress.d.ts +5 -0
  179. package/dist/features/game/utils/useGameEntityMotionProgress.d.ts.map +1 -0
  180. package/dist/features/game/utils/useGameEntityMotionProgress.js +87 -0
  181. package/dist/features/game/utils/useGameEntityMotionProgress.js.map +1 -0
  182. package/dist/features/game/utils/useGameReducedMotion.d.ts +3 -0
  183. package/dist/features/game/utils/useGameReducedMotion.d.ts.map +1 -0
  184. package/dist/features/game/utils/useGameReducedMotion.js +13 -0
  185. package/dist/features/game/utils/useGameReducedMotion.js.map +1 -0
  186. package/dist/features/layout/gridMeta.d.ts +1 -1
  187. package/dist/features/layout/gridMeta.d.ts.map +1 -1
  188. package/dist/features/layout/gridMeta.js +7 -2
  189. package/dist/features/layout/gridMeta.js.map +1 -1
  190. package/dist/features/layout/screenMeta.d.ts +1 -1
  191. package/dist/features/layout/viewMeta.d.ts +1 -1
  192. package/dist/features/layout/viewMeta.d.ts.map +1 -1
  193. package/dist/features/layout/viewMeta.js +6 -2
  194. package/dist/features/layout/viewMeta.js.map +1 -1
  195. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.d.ts.map +1 -1
  196. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js +16 -0
  197. package/dist/features/registry/ZORA_COMPONENT_REGISTRY.js.map +1 -1
  198. package/dist/features/section/screenSectionMeta.d.ts +1 -1
  199. package/dist/features/tabletop/adapters/inbound/CardBack.d.ts +5 -0
  200. package/dist/features/tabletop/adapters/inbound/CardBack.d.ts.map +1 -0
  201. package/dist/features/tabletop/adapters/inbound/CardBack.js +47 -0
  202. package/dist/features/tabletop/adapters/inbound/CardBack.js.map +1 -0
  203. package/dist/features/tabletop/adapters/inbound/CardHand.d.ts +5 -0
  204. package/dist/features/tabletop/adapters/inbound/CardHand.d.ts.map +1 -0
  205. package/dist/features/tabletop/adapters/inbound/CardHand.js +28 -0
  206. package/dist/features/tabletop/adapters/inbound/CardHand.js.map +1 -0
  207. package/dist/features/tabletop/adapters/inbound/PlayingCard.d.ts +5 -0
  208. package/dist/features/tabletop/adapters/inbound/PlayingCard.d.ts.map +1 -0
  209. package/dist/features/tabletop/adapters/inbound/PlayingCard.js +64 -0
  210. package/dist/features/tabletop/adapters/inbound/PlayingCard.js.map +1 -0
  211. package/dist/features/tabletop/adapters/inbound/PokerTrainingTable.d.ts +5 -0
  212. package/dist/features/tabletop/adapters/inbound/PokerTrainingTable.d.ts.map +1 -0
  213. package/dist/features/tabletop/adapters/inbound/PokerTrainingTable.js +12 -0
  214. package/dist/features/tabletop/adapters/inbound/PokerTrainingTable.js.map +1 -0
  215. package/dist/features/tabletop/adapters/inbound/TabletopTable.d.ts +5 -0
  216. package/dist/features/tabletop/adapters/inbound/TabletopTable.d.ts.map +1 -0
  217. package/dist/features/tabletop/adapters/inbound/TabletopTable.js +206 -0
  218. package/dist/features/tabletop/adapters/inbound/TabletopTable.js.map +1 -0
  219. package/dist/features/tabletop/meta.d.ts +353 -0
  220. package/dist/features/tabletop/meta.d.ts.map +1 -0
  221. package/dist/features/tabletop/meta.js +252 -0
  222. package/dist/features/tabletop/meta.js.map +1 -0
  223. package/dist/features/tabletop/public.d.ts +10 -0
  224. package/dist/features/tabletop/public.d.ts.map +1 -0
  225. package/dist/features/tabletop/public.js +9 -0
  226. package/dist/features/tabletop/public.js.map +1 -0
  227. package/dist/features/tabletop/utils/createPokerTrainingTableState.d.ts +13 -0
  228. package/dist/features/tabletop/utils/createPokerTrainingTableState.d.ts.map +1 -0
  229. package/dist/features/tabletop/utils/createPokerTrainingTableState.js +112 -0
  230. package/dist/features/tabletop/utils/createPokerTrainingTableState.js.map +1 -0
  231. package/dist/features/tabletop/utils/createTabletopColorScheme.d.ts +36 -0
  232. package/dist/features/tabletop/utils/createTabletopColorScheme.d.ts.map +1 -0
  233. package/dist/features/tabletop/utils/createTabletopColorScheme.js +144 -0
  234. package/dist/features/tabletop/utils/createTabletopColorScheme.js.map +1 -0
  235. package/dist/features/tabletop/utils/createTabletopGameSeats.d.ts +13 -0
  236. package/dist/features/tabletop/utils/createTabletopGameSeats.d.ts.map +1 -0
  237. package/dist/features/tabletop/utils/createTabletopGameSeats.js +22 -0
  238. package/dist/features/tabletop/utils/createTabletopGameSeats.js.map +1 -0
  239. package/dist/features/tabletop/utils/getPlayingCardLabel.d.ts +4 -0
  240. package/dist/features/tabletop/utils/getPlayingCardLabel.d.ts.map +1 -0
  241. package/dist/features/tabletop/utils/getPlayingCardLabel.js +6 -0
  242. package/dist/features/tabletop/utils/getPlayingCardLabel.js.map +1 -0
  243. package/dist/features/tabletop/utils/getTabletopCardDimensions.d.ts +12 -0
  244. package/dist/features/tabletop/utils/getTabletopCardDimensions.d.ts.map +1 -0
  245. package/dist/features/tabletop/utils/getTabletopCardDimensions.js +35 -0
  246. package/dist/features/tabletop/utils/getTabletopCardDimensions.js.map +1 -0
  247. package/dist/features/tabletop/utils/getTabletopSeatPosition.d.ts +9 -0
  248. package/dist/features/tabletop/utils/getTabletopSeatPosition.d.ts.map +1 -0
  249. package/dist/features/tabletop/utils/getTabletopSeatPosition.js +88 -0
  250. package/dist/features/tabletop/utils/getTabletopSeatPosition.js.map +1 -0
  251. package/dist/index.d.ts +8 -0
  252. package/dist/index.d.ts.map +1 -1
  253. package/dist/index.js +4 -0
  254. package/dist/index.js.map +1 -1
  255. package/dist/types/chess.d.ts +83 -0
  256. package/dist/types/chess.d.ts.map +1 -0
  257. package/dist/types/chess.js +2 -0
  258. package/dist/types/chess.js.map +1 -0
  259. package/dist/types/gamePresentation.d.ts +94 -0
  260. package/dist/types/gamePresentation.d.ts.map +1 -0
  261. package/dist/types/gamePresentation.js +2 -0
  262. package/dist/types/gamePresentation.js.map +1 -0
  263. package/dist/types/gameRuntime.d.ts +29 -0
  264. package/dist/types/gameRuntime.d.ts.map +1 -0
  265. package/dist/types/gameRuntime.js +2 -0
  266. package/dist/types/gameRuntime.js.map +1 -0
  267. package/dist/types/tabletop.d.ts +129 -0
  268. package/dist/types/tabletop.d.ts.map +1 -0
  269. package/dist/types/tabletop.js +2 -0
  270. package/dist/types/tabletop.js.map +1 -0
  271. package/package.json +3 -1
  272. package/src/features/authoring/allowedChildren.ts +15 -2
  273. package/src/features/authoring/componentMeta.test.ts +93 -0
  274. package/src/features/authoring/componentMeta.ts +27 -0
  275. package/src/features/authoring/constants.ts +3 -0
  276. package/src/features/card/cardMeta.ts +12 -2
  277. package/src/features/chess/adapters/inbound/ChessBoard.tsx +169 -0
  278. package/src/features/chess/adapters/inbound/OpeningBook.tsx +131 -0
  279. package/src/features/chess/meta.ts +168 -0
  280. package/src/features/chess/public.test.tsx +165 -0
  281. package/src/features/chess/public.ts +27 -0
  282. package/src/features/chess/utils/chessSquares.ts +6 -0
  283. package/src/features/chess/utils/createBoardSquares.ts +13 -0
  284. package/src/features/chess/utils/createChessBoardColorScheme.ts +55 -0
  285. package/src/features/chess/utils/createOpeningBookColorScheme.ts +26 -0
  286. package/src/features/chess/utils/getSquareFile.ts +6 -0
  287. package/src/features/chess/utils/getSquareRank.ts +6 -0
  288. package/src/features/chess/utils/isLightSquare.ts +8 -0
  289. package/src/features/chessTabletopOwnership.test.ts +71 -0
  290. package/src/features/game/adapters/inbound/Game.tsx +43 -0
  291. package/src/features/game/adapters/inbound/GameEntity.tsx +44 -0
  292. package/src/features/game/adapters/inbound/GameField.tsx +52 -0
  293. package/src/features/game/adapters/inbound/GameInputZone.tsx +99 -0
  294. package/src/features/game/adapters/inbound/GameMeasurementProbe.tsx +83 -0
  295. package/src/features/game/adapters/inbound/GameOverlay.tsx +58 -0
  296. package/src/features/game/adapters/inbound/createGameKeyboardEvent.test.ts +51 -0
  297. package/src/features/game/adapters/inbound/createGameKeyboardEvent.ts +33 -0
  298. package/src/features/game/adapters/inbound/createGameMeasurementEvent.test.ts +56 -0
  299. package/src/features/game/adapters/inbound/createGameMeasurementEvent.ts +38 -0
  300. package/src/features/game/adapters/inbound/createGamePointerEvent.test.ts +56 -0
  301. package/src/features/game/adapters/inbound/createGamePointerEvent.ts +39 -0
  302. package/src/features/game/adapters/inbound/measureGameEntity.ts +28 -0
  303. package/src/features/game/adapters/inbound/useGameInputZoneResponder.ts +85 -0
  304. package/src/features/game/composition/GameRuntimeContext.ts +6 -0
  305. package/src/features/game/composition/createGameBindingContext.test.ts +66 -0
  306. package/src/features/game/composition/createGameBindingContext.ts +11 -0
  307. package/src/features/game/composition/createGameMeasurementRegistry.test.ts +35 -0
  308. package/src/features/game/composition/createGameMeasurementRegistry.ts +16 -0
  309. package/src/features/game/composition/useGameRuntime.test.tsx +173 -0
  310. package/src/features/game/composition/useGameRuntime.ts +200 -0
  311. package/src/features/game/composition/useGameScheduledEffects.ts +85 -0
  312. package/src/features/game/meta/gameEntityMeta.ts +226 -0
  313. package/src/features/game/meta/gameFieldMeta.ts +49 -0
  314. package/src/features/game/meta/gameInputZoneMeta.ts +140 -0
  315. package/src/features/game/meta/gameMeasurementProbeMeta.ts +72 -0
  316. package/src/features/game/meta/gameMeta.ts +115 -0
  317. package/src/features/game/meta/gameOverlayMeta.ts +66 -0
  318. package/src/features/game/public.test.tsx +64 -0
  319. package/src/features/game/public.ts +19 -0
  320. package/src/features/game/utils/clampGamePercentage.ts +4 -0
  321. package/src/features/game/utils/resolveGameEntityMotionPlan.test.ts +63 -0
  322. package/src/features/game/utils/resolveGameEntityMotionPlan.ts +53 -0
  323. package/src/features/game/utils/toGamePercentage.ts +6 -0
  324. package/src/features/game/utils/useAnimatedGameEntityValue.ts +41 -0
  325. package/src/features/game/utils/useGameEntityAnimatedStyle.ts +87 -0
  326. package/src/features/game/utils/useGameEntityMeasurement.ts +19 -0
  327. package/src/features/game/utils/useGameEntityMotionProgress.ts +114 -0
  328. package/src/features/game/utils/useGameReducedMotion.ts +15 -0
  329. package/src/features/layout/gridMeta.ts +12 -2
  330. package/src/features/layout/viewMeta.ts +10 -2
  331. package/src/features/registry/ZORA_COMPONENT_REGISTRY.ts +29 -0
  332. package/src/features/tabletop/adapters/inbound/CardBack.tsx +70 -0
  333. package/src/features/tabletop/adapters/inbound/CardHand.tsx +61 -0
  334. package/src/features/tabletop/adapters/inbound/PlayingCard.tsx +95 -0
  335. package/src/features/tabletop/adapters/inbound/PokerTrainingTable.tsx +34 -0
  336. package/src/features/tabletop/adapters/inbound/TabletopTable.tsx +264 -0
  337. package/src/features/tabletop/meta.ts +254 -0
  338. package/src/features/tabletop/public.test.tsx +127 -0
  339. package/src/features/tabletop/public.ts +32 -0
  340. package/src/features/tabletop/utils/createPokerTrainingTableState.ts +152 -0
  341. package/src/features/tabletop/utils/createTabletopColorScheme.ts +232 -0
  342. package/src/features/tabletop/utils/createTabletopGameSeats.ts +31 -0
  343. package/src/features/tabletop/utils/getPlayingCardLabel.ts +8 -0
  344. package/src/features/tabletop/utils/getTabletopCardDimensions.ts +45 -0
  345. package/src/features/tabletop/utils/getTabletopSeatPosition.ts +100 -0
  346. package/src/index.ts +83 -0
  347. package/src/types/chess.ts +95 -0
  348. package/src/types/gamePresentation.ts +103 -0
  349. package/src/types/gameRuntime.ts +34 -0
  350. package/src/types/tabletop.ts +131 -0
  351. package/web-dist/chunks/{Accordion-cscmtcn8.js → Accordion-0txegc16.js} +1 -1
  352. package/web-dist/chunks/{Accordion-06588rzn.js → Accordion-10xw59gm.js} +1 -1
  353. package/web-dist/chunks/{Accordion-8kgtg62g.js → Accordion-2zh15wt9.js} +6 -6
  354. package/web-dist/chunks/{Accordion-pkqj4g3r.js → Accordion-481bknsd.js} +5 -5
  355. package/web-dist/chunks/{Accordion-grfbz6f2.js → Accordion-4fkjn6r5.js} +1 -1
  356. package/web-dist/chunks/{Accordion-ftjkdjqs.js → Accordion-4gx45mn0.js} +3 -3
  357. package/web-dist/chunks/{Accordion-fjnck2tg.js → Accordion-4s69xvqy.js} +6 -6
  358. package/web-dist/chunks/{Accordion-jh7nxehr.js → Accordion-50jz5nhg.js} +1 -1
  359. package/web-dist/chunks/{Accordion-t6sdgmbz.js → Accordion-52xke54s.js} +1 -1
  360. package/web-dist/chunks/{Accordion-far6szrp.js → Accordion-6npzmbgk.js} +5 -5
  361. package/web-dist/chunks/{Accordion-q7c1ryf2.js → Accordion-6z4npcgf.js} +4 -4
  362. package/web-dist/chunks/{Accordion-gbba10rg.js → Accordion-8gw5tkfw.js} +6 -6
  363. package/web-dist/chunks/{Accordion-fmxygyb6.js → Accordion-8qteyww0.js} +4 -4
  364. package/web-dist/chunks/{Accordion-1pp37dtg.js → Accordion-9h5dx3ck.js} +4 -4
  365. package/web-dist/chunks/{Accordion-paha5aje.js → Accordion-9mmqf3wr.js} +2 -2
  366. package/web-dist/chunks/{Accordion-f5swy5bs.js → Accordion-b21zrnzj.js} +1 -1
  367. package/web-dist/chunks/{Accordion-ars389m1.js → Accordion-b8qd23hr.js} +3 -3
  368. package/web-dist/chunks/{Accordion-hxfa71g9.js → Accordion-c79y8g44.js} +7 -7
  369. package/web-dist/chunks/Accordion-ca2csh5r.js +321 -0
  370. package/web-dist/chunks/{Accordion-49gf1zb8.js → Accordion-cjht9dyv.js} +1 -1
  371. package/web-dist/chunks/{Accordion-sz21xsf4.js → Accordion-cq6hn45r.js} +1 -1
  372. package/web-dist/chunks/{Accordion-33rd76r7.js → Accordion-d90g9wcb.js} +8 -8
  373. package/web-dist/chunks/{Accordion-crx58d5n.js → Accordion-f5jb299b.js} +2 -2
  374. package/web-dist/chunks/{Accordion-h95wvyn5.js → Accordion-fe6vmbpf.js} +2 -2
  375. package/web-dist/chunks/{Accordion-jzbq36ec.js → Accordion-fqm027n3.js} +8 -8
  376. package/web-dist/chunks/{Accordion-0jkm3y3w.js → Accordion-gpccarct.js} +1 -1
  377. package/web-dist/chunks/{Accordion-v6ykq9hv.js → Accordion-h95h3xdb.js} +10 -10
  378. package/web-dist/chunks/{Accordion-t3p4ykg7.js → Accordion-j8ab9k8k.js} +8 -8
  379. package/web-dist/chunks/{Accordion-qpwhmqzd.js → Accordion-k5z591wx.js} +13 -13
  380. package/web-dist/chunks/{Accordion-rrpej6sv.js → Accordion-kdncjvc7.js} +7 -7
  381. package/web-dist/chunks/{Accordion-f05a7r28.js → Accordion-ks4a1c6w.js} +5 -5
  382. package/web-dist/chunks/{Accordion-x0j8b2by.js → Accordion-ma1sfe5z.js} +5 -5
  383. package/web-dist/chunks/{Accordion-2dws3778.js → Accordion-mhtyce1k.js} +4 -4
  384. package/web-dist/chunks/{Accordion-1vewf8aa.js → Accordion-n7gtb5ec.js} +2 -2
  385. package/web-dist/chunks/{Accordion-0psdn97s.js → Accordion-p42mm8rr.js} +1 -1
  386. package/web-dist/chunks/{Accordion-3404tth9.js → Accordion-panw5f0q.js} +7 -7
  387. package/web-dist/chunks/{Accordion-4a6wj3ez.js → Accordion-pxq8gfgg.js} +9 -9
  388. package/web-dist/chunks/{Accordion-xshn7k8f.js → Accordion-qwbshc4s.js} +4 -4
  389. package/web-dist/chunks/{Accordion-395r3wra.js → Accordion-r51wsmvy.js} +2 -2
  390. package/web-dist/chunks/Accordion-rt13cqr7.js +830 -0
  391. package/web-dist/chunks/{Accordion-hz4xaqjf.js → Accordion-s1f9hb5a.js} +9 -9
  392. package/web-dist/chunks/{Accordion-7ja4mtbz.js → Accordion-sv87mbqa.js} +1 -1
  393. package/web-dist/chunks/{Accordion-r4c9k9y7.js → Accordion-t4k9egq6.js} +2 -2
  394. package/web-dist/chunks/{Accordion-96cqeekv.js → Accordion-t64m1kca.js} +5 -5
  395. package/web-dist/chunks/Accordion-wg31jkvp.js +1559 -0
  396. package/web-dist/chunks/{Accordion-ch67q4t0.js → Accordion-y9zr4x2x.js} +4 -4
  397. package/web-dist/chunks/{Accordion-31aeqxak.js → Accordion-ye3k55r7.js} +3 -3
  398. package/web-dist/chunks/{Accordion-s42wwh6m.js → Accordion-z29agann.js} +6 -6
  399. package/web-dist/chunks/{Accordion-f1h2f05v.js → Accordion-ze26effy.js} +5 -5
  400. package/web-dist/chunks/{Accordion-tx78txec.js → Accordion-zqzcagxz.js} +5 -5
  401. package/web-dist/components/accordion/Accordion.js +12 -12
  402. package/web-dist/components/accordion-item/AccordionItem.js +12 -12
  403. package/web-dist/components/activity-indicator/ActivityIndicator.js +3 -3
  404. package/web-dist/components/app-bar/AppBar.js +19 -19
  405. package/web-dist/components/app-shell/AppShell.js +6 -6
  406. package/web-dist/components/avatar/Avatar.js +12 -12
  407. package/web-dist/components/avatar-group/AvatarGroup.js +12 -12
  408. package/web-dist/components/badge/Badge.js +7 -7
  409. package/web-dist/components/barcode-scanner-view/BarcodeScannerView.js +20 -20
  410. package/web-dist/components/bottom-sheet/BottomSheet.js +8 -8
  411. package/web-dist/components/bottom-sheet-flat-list/BottomSheetFlatList.js +8 -8
  412. package/web-dist/components/bottom-sheet-scroll-view/BottomSheetScrollView.js +8 -8
  413. package/web-dist/components/bottom-sheet-section-list/BottomSheetSectionList.js +8 -8
  414. package/web-dist/components/bottom-sheet-view/BottomSheetView.js +8 -8
  415. package/web-dist/components/bottom-sheet-virtualized-list/BottomSheetVirtualizedList.js +8 -8
  416. package/web-dist/components/breadcrumbs/Breadcrumbs.js +15 -15
  417. package/web-dist/components/button/Button.js +12 -12
  418. package/web-dist/components/button-group/ButtonGroup.js +12 -12
  419. package/web-dist/components/camera-permission-view/CameraPermissionView.js +20 -20
  420. package/web-dist/components/card/Card.js +19 -19
  421. package/web-dist/components/card-back/CardBack.d.ts +7 -0
  422. package/web-dist/components/card-back/CardBack.js +19 -0
  423. package/web-dist/components/card-back/index.d.ts +1 -0
  424. package/web-dist/components/card-back/index.js +2 -0
  425. package/web-dist/components/card-hand/CardHand.d.ts +7 -0
  426. package/web-dist/components/card-hand/CardHand.js +19 -0
  427. package/web-dist/components/card-hand/index.d.ts +1 -0
  428. package/web-dist/components/card-hand/index.js +2 -0
  429. package/web-dist/components/chat-list-item/ChatListItem.js +16 -16
  430. package/web-dist/components/checkbox/Checkbox.js +12 -12
  431. package/web-dist/components/checkbox-group/CheckboxGroup.js +12 -12
  432. package/web-dist/components/chess-board/ChessBoard.d.ts +4 -0
  433. package/web-dist/components/chess-board/ChessBoard.js +13 -0
  434. package/web-dist/components/chess-board/index.d.ts +1 -0
  435. package/web-dist/components/chess-board/index.js +2 -0
  436. package/web-dist/components/chip/Chip.js +13 -13
  437. package/web-dist/components/chip-group/ChipGroup.js +13 -13
  438. package/web-dist/components/collection-editor/CollectionEditor.js +19 -19
  439. package/web-dist/components/content-rail/ContentRail.js +13 -13
  440. package/web-dist/components/data-table/DataTable.js +26 -26
  441. package/web-dist/components/date-picker/DatePicker.js +17 -17
  442. package/web-dist/components/dialog/Dialog.js +12 -12
  443. package/web-dist/components/divider/Divider.js +6 -6
  444. package/web-dist/components/empty-state/EmptyState.js +20 -20
  445. package/web-dist/components/field/Field.js +12 -12
  446. package/web-dist/components/flat-list/FlatList.js +13 -13
  447. package/web-dist/components/forgot-password-form/ForgotPasswordForm.js +18 -18
  448. package/web-dist/components/form/Form.js +16 -16
  449. package/web-dist/components/form-actions/FormActions.js +16 -16
  450. package/web-dist/components/form-error/FormError.js +16 -16
  451. package/web-dist/components/game/Game.d.ts +8 -0
  452. package/web-dist/components/game/Game.js +25 -0
  453. package/web-dist/components/game/index.d.ts +1 -0
  454. package/web-dist/components/game/index.js +2 -0
  455. package/web-dist/components/game-entity/GameEntity.d.ts +8 -0
  456. package/web-dist/components/game-entity/GameEntity.js +25 -0
  457. package/web-dist/components/game-entity/index.d.ts +1 -0
  458. package/web-dist/components/game-entity/index.js +2 -0
  459. package/web-dist/components/game-field/GameField.d.ts +8 -0
  460. package/web-dist/components/game-field/GameField.js +25 -0
  461. package/web-dist/components/game-field/index.d.ts +1 -0
  462. package/web-dist/components/game-field/index.js +2 -0
  463. package/web-dist/components/game-input-zone/GameInputZone.d.ts +8 -0
  464. package/web-dist/components/game-input-zone/GameInputZone.js +25 -0
  465. package/web-dist/components/game-input-zone/index.d.ts +1 -0
  466. package/web-dist/components/game-input-zone/index.js +2 -0
  467. package/web-dist/components/game-measurement-probe/GameMeasurementProbe.d.ts +8 -0
  468. package/web-dist/components/game-measurement-probe/GameMeasurementProbe.js +25 -0
  469. package/web-dist/components/game-measurement-probe/index.d.ts +1 -0
  470. package/web-dist/components/game-measurement-probe/index.js +2 -0
  471. package/web-dist/components/game-overlay/GameOverlay.d.ts +8 -0
  472. package/web-dist/components/game-overlay/GameOverlay.js +25 -0
  473. package/web-dist/components/game-overlay/index.d.ts +1 -0
  474. package/web-dist/components/game-overlay/index.js +2 -0
  475. package/web-dist/components/gradient/Gradient.js +7 -7
  476. package/web-dist/components/gradient-renderer-provider/GradientRendererProvider.js +7 -7
  477. package/web-dist/components/grid/Grid.js +6 -6
  478. package/web-dist/components/heading/Heading.js +6 -6
  479. package/web-dist/components/hero/Hero.js +19 -19
  480. package/web-dist/components/icon/Icon.js +4 -4
  481. package/web-dist/components/icon-button/IconButton.js +12 -12
  482. package/web-dist/components/image/Image.js +10 -10
  483. package/web-dist/components/keyboard-avoiding-view/KeyboardAvoidingView.js +2 -2
  484. package/web-dist/components/list/List.js +13 -13
  485. package/web-dist/components/list-item/ListItem.js +13 -13
  486. package/web-dist/components/list-section/ListSection.js +13 -13
  487. package/web-dist/components/media-card/MediaCard.js +19 -19
  488. package/web-dist/components/message-bubble/MessageBubble.js +16 -16
  489. package/web-dist/components/metric-card/MetricCard.js +19 -19
  490. package/web-dist/components/missing-element/MissingElement.js +11 -11
  491. package/web-dist/components/o-auth-provider-button/OAuthProviderButton.js +18 -18
  492. package/web-dist/components/o-auth-provider-list/OAuthProviderList.js +18 -18
  493. package/web-dist/components/opening-book/OpeningBook.d.ts +4 -0
  494. package/web-dist/components/opening-book/OpeningBook.js +13 -0
  495. package/web-dist/components/opening-book/index.d.ts +1 -0
  496. package/web-dist/components/opening-book/index.js +2 -0
  497. package/web-dist/components/otp-form/OtpForm.js +18 -18
  498. package/web-dist/components/pagination/Pagination.js +13 -13
  499. package/web-dist/components/palette-item/PaletteItem.js +19 -19
  500. package/web-dist/components/playing-card/PlayingCard.d.ts +7 -0
  501. package/web-dist/components/playing-card/PlayingCard.js +19 -0
  502. package/web-dist/components/playing-card/index.d.ts +1 -0
  503. package/web-dist/components/playing-card/index.js +2 -0
  504. package/web-dist/components/poker-training-table/PokerTrainingTable.d.ts +7 -0
  505. package/web-dist/components/poker-training-table/PokerTrainingTable.js +19 -0
  506. package/web-dist/components/poker-training-table/index.d.ts +1 -0
  507. package/web-dist/components/poker-training-table/index.js +2 -0
  508. package/web-dist/components/popover-menu/PopoverMenu.js +14 -14
  509. package/web-dist/components/post-card/PostCard.js +19 -19
  510. package/web-dist/components/product-card/ProductCard.js +19 -19
  511. package/web-dist/components/progress/Progress.js +10 -10
  512. package/web-dist/components/progress-ring/ProgressRing.js +10 -10
  513. package/web-dist/components/radio/Radio.js +14 -14
  514. package/web-dist/components/radio-group/RadioGroup.js +14 -14
  515. package/web-dist/components/rating/Rating.js +9 -9
  516. package/web-dist/components/reader-surface/ReaderSurface.js +21 -21
  517. package/web-dist/components/scan-overlay/ScanOverlay.js +20 -20
  518. package/web-dist/components/screen/Screen.js +6 -6
  519. package/web-dist/components/screen-section/ScreenSection.js +10 -10
  520. package/web-dist/components/scroll-view/ScrollView.js +6 -6
  521. package/web-dist/components/search-input/SearchInput.js +13 -13
  522. package/web-dist/components/section-header/SectionHeader.js +10 -10
  523. package/web-dist/components/section-list/SectionList.js +13 -13
  524. package/web-dist/components/select/Select.js +16 -16
  525. package/web-dist/components/selectable-item/SelectableItem.js +5 -5
  526. package/web-dist/components/selection-provider/SelectionProvider.js +5 -5
  527. package/web-dist/components/sign-in-form/SignInForm.js +18 -18
  528. package/web-dist/components/sign-up-form/SignUpForm.js +18 -18
  529. package/web-dist/components/skeleton/Skeleton.js +22 -22
  530. package/web-dist/components/skeleton-card/SkeletonCard.js +22 -22
  531. package/web-dist/components/skeleton-list/SkeletonList.js +22 -22
  532. package/web-dist/components/skeleton-text/SkeletonText.js +22 -22
  533. package/web-dist/components/surface/Surface.js +7 -7
  534. package/web-dist/components/switch/Switch.js +7 -7
  535. package/web-dist/components/tab/Tab.js +7 -7
  536. package/web-dist/components/tab-list/TabList.js +7 -7
  537. package/web-dist/components/tab-panel/TabPanel.js +7 -7
  538. package/web-dist/components/tabletop-table/TabletopTable.d.ts +7 -0
  539. package/web-dist/components/tabletop-table/TabletopTable.js +19 -0
  540. package/web-dist/components/tabletop-table/index.d.ts +1 -0
  541. package/web-dist/components/tabletop-table/index.js +2 -0
  542. package/web-dist/components/tabs/Tabs.js +7 -7
  543. package/web-dist/components/text/Text.js +6 -6
  544. package/web-dist/components/text-input/TextInput.js +13 -13
  545. package/web-dist/components/time-picker/TimePicker.js +17 -17
  546. package/web-dist/components/timeline/Timeline.js +11 -11
  547. package/web-dist/components/toast/Toast.js +9 -9
  548. package/web-dist/components/toast-provider/ToastProvider.js +9 -9
  549. package/web-dist/components/toolbar/Toolbar.js +19 -19
  550. package/web-dist/components/tree-item/TreeItem.js +16 -16
  551. package/web-dist/components/uploader/Uploader.js +22 -22
  552. package/web-dist/components/view/View.js +6 -6
  553. package/web-dist/manifest.json +1650 -1379
  554. package/web-dist/runtime/ZoraProvider.js +8 -8
@@ -0,0 +1,1559 @@
1
+ 'use client';
2
+ import {
3
+ require_cjs
4
+ } from "./Accordion-cjht9dyv.js";
5
+ import {
6
+ View2
7
+ } from "./Accordion-t64m1kca.js";
8
+ import {
9
+ __toESM
10
+ } from "./Accordion-9qvmwkxe.js";
11
+
12
+ // src/features/game/adapters/inbound/GameField.tsx
13
+ var import_react_native = __toESM(require_cjs(), 1);
14
+ import { jsx } from "react/jsx-runtime";
15
+ function GameField2({
16
+ children,
17
+ aspectRatio,
18
+ minHeight = 320,
19
+ fill = false,
20
+ clip = true,
21
+ accessibilityLabel,
22
+ interactionPolicy,
23
+ testID
24
+ }) {
25
+ return /* @__PURE__ */ jsx(View2, {
26
+ ...accessibilityLabel === undefined ? {} : { accessibilityLabel },
27
+ ...testID === undefined ? {} : { testID },
28
+ interactionPolicy,
29
+ pointerEvents: interactionPolicy === "passive" ? "none" : "auto",
30
+ style: [
31
+ styles.root,
32
+ clip ? styles.clipped : styles.overflowVisible,
33
+ fill ? styles.fill : undefined,
34
+ {
35
+ ...aspectRatio === undefined ? {} : { aspectRatio },
36
+ minHeight
37
+ }
38
+ ],
39
+ children
40
+ });
41
+ }
42
+ var styles = import_react_native.StyleSheet.create({
43
+ clipped: {
44
+ overflow: "hidden"
45
+ },
46
+ fill: {
47
+ flex: 1
48
+ },
49
+ overflowVisible: {
50
+ overflow: "visible"
51
+ },
52
+ root: {
53
+ position: "relative",
54
+ width: "100%"
55
+ }
56
+ });
57
+ // node_modules/@ankhorage/runtime/dist/RuntimeRendererConfig.js
58
+ import React, { createContext, use } from "react";
59
+ import { jsx as jsx2 } from "react/jsx-runtime";
60
+ var EMPTY_RUNTIME_RENDERER_CONFIG = {};
61
+ var RuntimeRendererConfigContext = createContext(EMPTY_RUNTIME_RENDERER_CONFIG);
62
+ function composeRuntimeRendererWrapNode(innerWrapNode, outerWrapNode) {
63
+ if (!innerWrapNode) {
64
+ return outerWrapNode;
65
+ }
66
+ if (!outerWrapNode) {
67
+ return innerWrapNode;
68
+ }
69
+ return (args) => outerWrapNode({ ...args, rendered: innerWrapNode(args) });
70
+ }
71
+ function composeRuntimeNodePropsResolver(localResolver, inheritedResolver) {
72
+ if (!localResolver) {
73
+ return inheritedResolver;
74
+ }
75
+ if (!inheritedResolver) {
76
+ return localResolver;
77
+ }
78
+ return (args) => {
79
+ const inheritedProps = inheritedResolver(args);
80
+ return localResolver({ ...args, props: inheritedProps });
81
+ };
82
+ }
83
+ function mergeRuntimeRendererConfig(localConfig, inheritedConfig) {
84
+ if (!localConfig && !inheritedConfig) {
85
+ return EMPTY_RUNTIME_RENDERER_CONFIG;
86
+ }
87
+ const actionHandlers = mergeRecordConfig(inheritedConfig?.actionHandlers, localConfig?.actionHandlers);
88
+ const bindingContext = mergeRecordConfig(inheritedConfig?.bindingContext, localConfig?.bindingContext);
89
+ const operationResults = mergeRecordConfig(inheritedConfig?.operationResults, localConfig?.operationResults);
90
+ return {
91
+ disableActions: localConfig?.disableActions === true || inheritedConfig?.disableActions === true,
92
+ registry: localConfig?.registry ?? inheritedConfig?.registry,
93
+ wrapNode: composeRuntimeRendererWrapNode(localConfig?.wrapNode, inheritedConfig?.wrapNode),
94
+ resolveNodeProps: composeRuntimeNodePropsResolver(localConfig?.resolveNodeProps, inheritedConfig?.resolveNodeProps),
95
+ resolveMediaAsset: localConfig?.resolveMediaAsset ?? inheritedConfig?.resolveMediaAsset,
96
+ mediaAssets: localConfig?.mediaAssets ?? inheritedConfig?.mediaAssets,
97
+ actionHandlers,
98
+ dbAdapter: localConfig?.dbAdapter ?? inheritedConfig?.dbAdapter,
99
+ dbRealtimeAdapter: localConfig?.dbRealtimeAdapter ?? inheritedConfig?.dbRealtimeAdapter,
100
+ stateAdapter: localConfig?.stateAdapter ?? inheritedConfig?.stateAdapter,
101
+ bindingContext,
102
+ apis: localConfig?.apis ?? inheritedConfig?.apis,
103
+ dataBindings: localConfig?.dataBindings ?? inheritedConfig?.dataBindings,
104
+ operationResults,
105
+ writeOperationResult: localConfig?.writeOperationResult ?? inheritedConfig?.writeOperationResult,
106
+ executeAction: localConfig?.executeAction ?? inheritedConfig?.executeAction,
107
+ executeOperation: localConfig?.executeOperation ?? inheritedConfig?.executeOperation,
108
+ onDiagnostics: localConfig?.onDiagnostics ?? inheritedConfig?.onDiagnostics,
109
+ eventOperationLifecycle: localConfig?.eventOperationLifecycle ?? inheritedConfig?.eventOperationLifecycle,
110
+ eventOperationState: localConfig?.eventOperationState ?? inheritedConfig?.eventOperationState
111
+ };
112
+ }
113
+ function RuntimeRendererConfigProvider(props) {
114
+ const { value, children } = props;
115
+ const inheritedConfig = use(RuntimeRendererConfigContext);
116
+ const mergedConfig = mergeRuntimeRendererConfig(value, inheritedConfig);
117
+ return /* @__PURE__ */ jsx2(RuntimeRendererConfigContext, {
118
+ value: mergedConfig,
119
+ children
120
+ });
121
+ }
122
+ function mergeRecordConfig(inherited, local) {
123
+ if (!inherited && !local)
124
+ return;
125
+ return {
126
+ ...inherited ?? {},
127
+ ...local ?? {}
128
+ };
129
+ }
130
+ // src/features/game/adapters/inbound/Game.tsx
131
+ import React5 from "react";
132
+
133
+ // src/features/game/composition/createGameBindingContext.ts
134
+ function createGameBindingContext(session) {
135
+ return {
136
+ game: {
137
+ entities: Object.values(session.entities),
138
+ session
139
+ }
140
+ };
141
+ }
142
+
143
+ // src/features/game/composition/createGameMeasurementRegistry.ts
144
+ function createGameMeasurementRegistry() {
145
+ const readers = new Map;
146
+ return {
147
+ registerMeasurement: (id, reader) => {
148
+ readers.set(id, reader);
149
+ return () => {
150
+ if (readers.get(id) === reader)
151
+ readers.delete(id);
152
+ };
153
+ },
154
+ measure: (id) => readers.get(id)?.() ?? Promise.resolve(undefined)
155
+ };
156
+ }
157
+
158
+ // src/features/game/composition/GameRuntimeContext.ts
159
+ import React2 from "react";
160
+ var GameRuntimeContext = React2.createContext(null);
161
+
162
+ // node_modules/@ankhorage/game/dist/features/session/utils/gamePath.js
163
+ function readGamePath(value, path) {
164
+ if (path === undefined || path.length === 0)
165
+ return value;
166
+ return path.split(".").reduce((current, segment) => {
167
+ if (current === undefined || current === null)
168
+ return;
169
+ if (isGameArray(current)) {
170
+ const index = Number(segment);
171
+ return Number.isInteger(index) ? current.at(index) : undefined;
172
+ }
173
+ if (typeof current !== "object")
174
+ return;
175
+ return readRecordEntry(current, segment);
176
+ }, value);
177
+ }
178
+ function writeGamePath(root, path, value) {
179
+ const segments = path.split(".").filter((segment) => segment.length > 0);
180
+ if (segments.length === 0)
181
+ throw new Error("Game state path must not be empty.");
182
+ return writeObjectPath(root, segments, value);
183
+ }
184
+ function readRecordEntry(record, key) {
185
+ return Object.entries(record).find(([entryKey]) => entryKey === key)?.[1];
186
+ }
187
+ function writeObjectPath(root, segments, value) {
188
+ const [segment, ...rest] = segments;
189
+ if (segment === undefined)
190
+ return root;
191
+ const nextValue = rest.length === 0 ? value : writeObjectPath(toRecord(readRecordEntry(root, segment)), rest, value);
192
+ return replaceRecordEntry(root, segment, nextValue);
193
+ }
194
+ function toRecord(value) {
195
+ if (value === null || value === undefined || typeof value !== "object" || isGameArray(value)) {
196
+ return {};
197
+ }
198
+ return value;
199
+ }
200
+ function isGameArray(value) {
201
+ return Array.isArray(value);
202
+ }
203
+ function replaceRecordEntry(root, key, value) {
204
+ return Object.fromEntries([
205
+ ...Object.entries(root).filter(([entryKey]) => entryKey !== key),
206
+ [key, value]
207
+ ]);
208
+ }
209
+
210
+ // node_modules/@ankhorage/game/dist/features/session/domain/evaluateGameExpression.js
211
+ function evaluateGameExpression(expression, context) {
212
+ switch (expression.kind) {
213
+ case "literal":
214
+ return expression.value;
215
+ case "reference":
216
+ return resolveReference(expression.source, expression.path, context);
217
+ case "math":
218
+ return evaluateMath(expression.operator, expression.values, context);
219
+ case "clamp":
220
+ return Math.min(numberValue(evaluateGameExpression(expression.max, context)), Math.max(numberValue(evaluateGameExpression(expression.min, context)), numberValue(evaluateGameExpression(expression.value, context))));
221
+ case "split":
222
+ return splitValue(expression.value, expression.separator, context);
223
+ case "join":
224
+ return expression.values.map((value) => stringValue(evaluateGameExpression(value, context))).join(expression.separator ?? "");
225
+ case "entities":
226
+ return entityValues(context.session, expression.poolId);
227
+ }
228
+ }
229
+ function resolveReference(source, path, context) {
230
+ const sourceValue = referenceRoot(source, context);
231
+ const value = readGamePath(sourceValue, path);
232
+ if (value === undefined) {
233
+ throw new Error(`Game reference ${source}:${path ?? "<root>"} is undefined.`);
234
+ }
235
+ return value;
236
+ }
237
+ function referenceRoot(source, context) {
238
+ if (source === "state")
239
+ return context.session.state;
240
+ if (source === "input")
241
+ return context.input;
242
+ if (source === "local")
243
+ return context.local;
244
+ if (source === "entity") {
245
+ return context.entity === undefined ? undefined : entityValue(context.entity);
246
+ }
247
+ if (source === "event") {
248
+ return context.event === undefined ? undefined : eventValue(context.event);
249
+ }
250
+ return {
251
+ elapsedMs: context.session.elapsedMs,
252
+ phase: context.session.phase,
253
+ sequence: context.session.sequence,
254
+ stageId: context.session.stageId
255
+ };
256
+ }
257
+ function entityValue(entity) {
258
+ return {
259
+ ...entity.state,
260
+ id: entity.id,
261
+ templateId: entity.templateId,
262
+ ...entity.poolId === undefined ? {} : { poolId: entity.poolId }
263
+ };
264
+ }
265
+ function eventValue(event) {
266
+ return {
267
+ ...event.payload ?? {},
268
+ type: event.type,
269
+ ...event.entityId === undefined ? {} : { entityId: event.entityId },
270
+ ...event.seed === undefined ? {} : { seed: event.seed }
271
+ };
272
+ }
273
+ function entityValues(session, poolId) {
274
+ return Object.values(session.entities).filter((entity) => poolId === undefined || entity.poolId === poolId).map(entityValue);
275
+ }
276
+ function splitValue(expression, separator, context) {
277
+ const value = evaluateGameExpression(expression, context);
278
+ if (typeof value !== "string")
279
+ throw new Error("split expression requires a string value.");
280
+ return value.split(separator);
281
+ }
282
+ function stringValue(value) {
283
+ if (typeof value === "object" && value !== null) {
284
+ throw new Error("join expression accepts only scalar values.");
285
+ }
286
+ return String(value);
287
+ }
288
+ function evaluateMath(operator, expressions, context) {
289
+ const values = expressions.map((expression) => numberValue(evaluateGameExpression(expression, context)));
290
+ if (values.length === 0) {
291
+ throw new Error(`Math operator ${operator} requires at least one value.`);
292
+ }
293
+ if (operator === "add")
294
+ return values.reduce((total, value) => total + value, 0);
295
+ if (operator === "multiply")
296
+ return values.reduce((total, value) => total * value, 1);
297
+ if (operator === "min")
298
+ return Math.min(...values);
299
+ if (operator === "max")
300
+ return Math.max(...values);
301
+ const [first, ...rest] = values;
302
+ if (first === undefined)
303
+ throw new Error(`Math operator ${operator} requires a first value.`);
304
+ if (operator === "subtract")
305
+ return rest.reduce((result, value) => result - value, first);
306
+ return rest.reduce((result, value) => result / value, first);
307
+ }
308
+ function numberValue(value) {
309
+ if (typeof value !== "number" || !Number.isFinite(value)) {
310
+ throw new Error("Game numeric expression resolved to a non-finite number.");
311
+ }
312
+ return value;
313
+ }
314
+
315
+ // node_modules/@ankhorage/game/dist/features/session/domain/applyEntityEffect.js
316
+ function applyEntityEffect(definition, result, effect, contextSnapshot, context, applyNestedEffects) {
317
+ if (effect.kind === "spawnEntity")
318
+ return spawnEntity(definition, result, effect, context);
319
+ if (effect.kind === "removeEntity")
320
+ return removeEntity(result, effect.entityId, context);
321
+ if (effect.kind === "forEach") {
322
+ return forEachValue(result, effect, contextSnapshot, context, applyNestedEffects);
323
+ }
324
+ throw new Error(`Unsupported entity effect: ${effect.kind}`);
325
+ }
326
+ function spawnEntity(definition, result, effect, context) {
327
+ const template = definition.entityTemplates?.find((candidate) => candidate.id === effect.templateId);
328
+ if (template === undefined)
329
+ throw new Error(`Unknown entity template: ${effect.templateId}`);
330
+ const id = scalarId(evaluateGameExpression(effect.id, context), "spawnEntity id");
331
+ const mappedState = Object.entries(effect.state ?? {}).reduce((state, [key, expression]) => ({
332
+ ...state,
333
+ [key]: evaluateGameExpression(expression, context)
334
+ }), {});
335
+ const entity = {
336
+ id,
337
+ templateId: template.id,
338
+ state: { ...template.initialState ?? {}, ...mappedState }
339
+ };
340
+ const entities = Object.fromEntries([
341
+ ...Object.entries(result.session.entities).filter(([entityId]) => entityId !== id),
342
+ [id, entity]
343
+ ]);
344
+ return withSession(result, {
345
+ ...result.session,
346
+ entities,
347
+ sequence: result.session.sequence + 1
348
+ });
349
+ }
350
+ function removeEntity(result, idExpression, context) {
351
+ const id = scalarId(evaluateGameExpression(idExpression, context), "removeEntity id");
352
+ const entities = Object.fromEntries(Object.entries(result.session.entities).filter(([entityId]) => entityId !== id));
353
+ return withSession(result, { ...result.session, entities });
354
+ }
355
+ function forEachValue(result, effect, contextSnapshot, context, applyNestedEffects) {
356
+ const source = evaluateGameExpression(effect.source, context);
357
+ if (typeof source !== "string" && !isGameValueArray(source)) {
358
+ throw new Error("forEach source must be array or string.");
359
+ }
360
+ const values = typeof source === "string" ? [...source] : source;
361
+ return values.reduce((current, item, index) => {
362
+ const nested = applyNestedEffects(current.session, effect.effects, {
363
+ ...contextSnapshot,
364
+ local: { ...contextSnapshot.local ?? {}, item, index }
365
+ });
366
+ return {
367
+ session: nested.session,
368
+ outputs: [...current.outputs, ...nested.outputs]
369
+ };
370
+ }, result);
371
+ }
372
+ function isGameValueArray(value) {
373
+ return Array.isArray(value);
374
+ }
375
+ function scalarId(value, label) {
376
+ if (typeof value !== "string" && typeof value !== "number") {
377
+ throw new Error(`${label} must resolve to string or number.`);
378
+ }
379
+ return String(value);
380
+ }
381
+ function withSession(result, session) {
382
+ return { ...result, session };
383
+ }
384
+
385
+ // node_modules/@ankhorage/game/dist/features/session/domain/applyLifecycleEffect.js
386
+ function applyLifecycleEffect(definition, result, effect, context) {
387
+ if (effect.kind === "transitionStage") {
388
+ return transitionStage(definition, result, effect.stageId, effect.clearEntities ?? true, context);
389
+ }
390
+ if (effect.kind === "restartStage") {
391
+ return restartStage(definition, result, effect.clearEntities ?? true);
392
+ }
393
+ throw new Error(`Unsupported lifecycle effect: ${effect.kind}`);
394
+ }
395
+ function transitionStage(definition, result, stageExpression, clearEntities, context) {
396
+ const currentStage = stageById(definition, result.session.stageId);
397
+ const stageIdValue = stageExpression === undefined ? currentStage.nextStageId : evaluateGameExpression(stageExpression, context);
398
+ if (typeof stageIdValue !== "string") {
399
+ throw new Error("transitionStage requires a target stage id.");
400
+ }
401
+ return withSession2(result, resetForStage(result.session, stageById(definition, stageIdValue), clearEntities));
402
+ }
403
+ function restartStage(definition, result, clearEntities) {
404
+ return withSession2(result, resetForStage(result.session, stageById(definition, result.session.stageId), clearEntities));
405
+ }
406
+ function resetForStage(session, stage, clearEntities) {
407
+ return {
408
+ ...session,
409
+ stageId: stage.id,
410
+ phase: "playing",
411
+ state: { ...session.state, ...stage.initialState ?? {} },
412
+ entities: clearEntities ? {} : session.entities,
413
+ scheduled: [],
414
+ sequence: session.sequence + 1
415
+ };
416
+ }
417
+ function stageById(definition, stageId) {
418
+ const stage = definition.stages.find((candidate) => candidate.id === stageId);
419
+ if (stage === undefined)
420
+ throw new Error(`Unknown game stage: ${stageId}`);
421
+ return stage;
422
+ }
423
+ function withSession2(result, session) {
424
+ return { ...result, session };
425
+ }
426
+
427
+ // node_modules/@ankhorage/game/dist/features/session/domain/evaluateGameCondition.js
428
+ function evaluateGameCondition(condition, context) {
429
+ switch (condition.kind) {
430
+ case "all":
431
+ return condition.conditions.every((candidate) => evaluateGameCondition(candidate, context));
432
+ case "any":
433
+ return condition.conditions.some((candidate) => evaluateGameCondition(candidate, context));
434
+ case "not":
435
+ return !evaluateGameCondition(condition.condition, context);
436
+ case "truthy":
437
+ return Boolean(evaluateGameExpression(condition.value, context));
438
+ default: {
439
+ const left = evaluateGameExpression(condition.left, context);
440
+ const right = evaluateGameExpression(condition.right, context);
441
+ if (condition.kind === "equals")
442
+ return deepEquals(left, right);
443
+ if (condition.kind === "notEquals")
444
+ return !deepEquals(left, right);
445
+ if (condition.kind === "includes")
446
+ return includesValue(left, right);
447
+ const [leftNumber, rightNumber] = numericPair(left, right);
448
+ if (condition.kind === "greaterThan")
449
+ return leftNumber > rightNumber;
450
+ if (condition.kind === "greaterThanOrEqual")
451
+ return leftNumber >= rightNumber;
452
+ if (condition.kind === "lessThan")
453
+ return leftNumber < rightNumber;
454
+ return leftNumber <= rightNumber;
455
+ }
456
+ }
457
+ }
458
+ function deepEquals(left, right) {
459
+ return JSON.stringify(left) === JSON.stringify(right);
460
+ }
461
+ function includesValue(container, value) {
462
+ if (typeof container === "string" && typeof value === "string")
463
+ return container.includes(value);
464
+ if (!Array.isArray(container))
465
+ return false;
466
+ return container.some((candidate) => deepEquals(candidate, value));
467
+ }
468
+ function numericPair(left, right) {
469
+ if (typeof left !== "number" || typeof right !== "number" || !Number.isFinite(left) || !Number.isFinite(right)) {
470
+ throw new Error("Numeric game condition requires two finite numbers.");
471
+ }
472
+ return [left, right];
473
+ }
474
+
475
+ // node_modules/@ankhorage/game/dist/features/session/domain/refreshGamePool.js
476
+ function refreshGamePool(definition, session, input, poolId, seed) {
477
+ const pool = definition.pools?.find((candidate) => candidate.id === poolId);
478
+ if (pool === undefined)
479
+ throw new Error(`Unknown game pool: ${poolId}`);
480
+ const template = definition.entityTemplates?.find((candidate) => candidate.id === pool.entityTemplateId);
481
+ if (template === undefined)
482
+ throw new Error(`Unknown entity template: ${pool.entityTemplateId}`);
483
+ const source = evaluateGameExpression(pool.source, { session, input });
484
+ if (!Array.isArray(source)) {
485
+ throw new Error(`Game pool ${poolId} source must resolve to an array.`);
486
+ }
487
+ const excludedIds = collectExcludedIds(pool, session);
488
+ const rotated = rotate(source, seed).filter((item) => !excludedIds.has(readItemId(item, pool.idPath)));
489
+ const selected = selectItems(rotated, pool, session, input, seed);
490
+ const retained = Object.fromEntries(Object.entries(session.entities).filter(([, entity]) => entity.poolId !== poolId));
491
+ const generated = selected.reduce((entries, item, index) => {
492
+ const itemId = readItemId(item, pool.idPath);
493
+ const local = localContext(item, index, seed);
494
+ const state = buildEntityState(template.initialState ?? {}, pool, session, input, local);
495
+ const priorStates = entries.map(([, entity]) => entity.state);
496
+ const placedState = placeEntity(state, pool, priorStates, index, seed);
497
+ const id = `${pool.id}:${itemId}:${session.sequence + index + 1}`;
498
+ const entity = {
499
+ id,
500
+ templateId: template.id,
501
+ poolId: pool.id,
502
+ state: placedState
503
+ };
504
+ return [...entries, [id, entity]];
505
+ }, []);
506
+ return { ...retained, ...Object.fromEntries(generated) };
507
+ }
508
+ function collectExcludedIds(pool, session) {
509
+ const values = (pool.excludeIdsFromStatePaths ?? []).flatMap((path) => {
510
+ const value = readGamePath(session.state, path);
511
+ return Array.isArray(value) ? value.filter(isScalarId) : [];
512
+ });
513
+ return new Set(values);
514
+ }
515
+ function selectItems(source, pool, session, input, seed) {
516
+ const selected = pool.selectors.reduce((current, selector) => {
517
+ const candidates = source.filter((item) => {
518
+ if (current.some((existing) => readItemId(existing, pool.idPath) === readItemId(item, pool.idPath))) {
519
+ return false;
520
+ }
521
+ if (selector.where === undefined)
522
+ return true;
523
+ return evaluateGameCondition(selector.where, { session, input, local: { item, seed } });
524
+ });
525
+ return [...current, ...candidates.slice(0, selector.count)];
526
+ }, []);
527
+ if (selected.length !== pool.size) {
528
+ throw new Error(`Game pool ${pool.id} selected ${selected.length} items; expected ${pool.size}.`);
529
+ }
530
+ return selected;
531
+ }
532
+ function buildEntityState(initialState, pool, session, input, local) {
533
+ const mapped = Object.entries(pool.entityState ?? {}).reduce((state, [key, expression]) => ({
534
+ ...state,
535
+ [key]: evaluateGameExpression(expression, { session, input, local })
536
+ }), {});
537
+ return { ...initialState, data: local.item ?? null, ...mapped };
538
+ }
539
+ function placeEntity(state, pool, priorStates, index, seed) {
540
+ const { placement } = pool;
541
+ if (placement === undefined)
542
+ return state;
543
+ const priorPositions = priorStates.flatMap((priorState) => {
544
+ const x = readGamePath(priorState, placement.xStatePath);
545
+ const y = readGamePath(priorState, placement.yStatePath);
546
+ return typeof x === "number" && typeof y === "number" ? [{ x, y }] : [];
547
+ });
548
+ const point = Array.from({ length: 32 }, (_, attempt) => deterministicPoint(placement, index + attempt * 17, seed)).find((candidate) => priorPositions.every((prior) => Math.hypot(candidate.x - prior.x, candidate.y - prior.y) >= (placement.minimumDistance ?? 0))) ?? deterministicPoint(placement, index, seed);
549
+ return writeGamePath(writeGamePath(state, placement.xStatePath, point.x), placement.yStatePath, point.y);
550
+ }
551
+ function deterministicPoint(placement, sequence, seed) {
552
+ const xRatio = fractional(seed + (sequence + 1) * 0.61803398875);
553
+ const yRatio = fractional(seed + (sequence + 1) * 0.41421356237);
554
+ return {
555
+ x: placement.xMin + xRatio * (placement.xMax - placement.xMin),
556
+ y: placement.yMin + yRatio * (placement.yMax - placement.yMin)
557
+ };
558
+ }
559
+ function rotate(values, seed) {
560
+ if (values.length === 0)
561
+ return values;
562
+ const offset = Math.floor(fractional(seed) * values.length);
563
+ return [...values.slice(offset), ...values.slice(0, offset)];
564
+ }
565
+ function localContext(item, index, seed) {
566
+ return { item, index, seed, random: fractional(seed + (index + 1) * 0.754877666) };
567
+ }
568
+ function readItemId(item, idPath = "id") {
569
+ const id = readGamePath(item, idPath);
570
+ if (!isScalarId(id)) {
571
+ throw new Error(`Game pool item id at ${idPath} must be a string or number.`);
572
+ }
573
+ return id;
574
+ }
575
+ function isScalarId(value) {
576
+ return typeof value === "string" || typeof value === "number";
577
+ }
578
+ function fractional(value) {
579
+ const finite = Number.isFinite(value) ? value : 0;
580
+ return (finite % 1 + 1) % 1;
581
+ }
582
+
583
+ // node_modules/@ankhorage/game/dist/features/session/domain/applyStateEffect.js
584
+ function applyStateEffect(definition, result, effect, input, contextSnapshot, context) {
585
+ switch (effect.kind) {
586
+ case "set":
587
+ return withSession3(result, {
588
+ ...result.session,
589
+ state: writeGamePath(result.session.state, effect.path, evaluateGameExpression(effect.value, context))
590
+ });
591
+ case "append":
592
+ return appendState(result, effect, context);
593
+ case "increment":
594
+ return incrementState(result, effect, context);
595
+ case "setPhase":
596
+ return setPhase(result, effect.phase, context);
597
+ case "emit":
598
+ return emitOutput(result, effect.type, effect.payload, context);
599
+ case "schedule":
600
+ return scheduleEffects(result, effect, context, contextSnapshot);
601
+ case "refreshPool":
602
+ return refreshPool(definition, result, effect, input, contextSnapshot, context);
603
+ default:
604
+ throw new Error(`Unsupported state effect: ${effect.kind}`);
605
+ }
606
+ }
607
+ function appendState(result, effect, context) {
608
+ const current = readGamePath(result.session.state, effect.path);
609
+ if (current !== undefined && !isGameValueArray2(current)) {
610
+ throw new Error(`append requires array state at ${effect.path}.`);
611
+ }
612
+ if (effect.maxLength !== undefined && (!Number.isInteger(effect.maxLength) || effect.maxLength < 0)) {
613
+ throw new Error("append maxLength must be a non-negative integer.");
614
+ }
615
+ const appended = [...current ?? [], evaluateGameExpression(effect.value, context)];
616
+ const next = effect.maxLength === undefined ? appended : appended.slice(-effect.maxLength);
617
+ return withSession3(result, {
618
+ ...result.session,
619
+ state: writeGamePath(result.session.state, effect.path, next)
620
+ });
621
+ }
622
+ function isGameValueArray2(value) {
623
+ return Array.isArray(value);
624
+ }
625
+ function incrementState(result, effect, context) {
626
+ const current = readGamePath(result.session.state, effect.path);
627
+ const amount = evaluateGameExpression(effect.value, context);
628
+ if (typeof current !== "number" || typeof amount !== "number") {
629
+ throw new Error(`increment requires numeric state at ${effect.path}.`);
630
+ }
631
+ const min = effect.min === undefined ? Number.NEGATIVE_INFINITY : numeric(effect.min, context);
632
+ const max = effect.max === undefined ? Number.POSITIVE_INFINITY : numeric(effect.max, context);
633
+ return withSession3(result, {
634
+ ...result.session,
635
+ state: writeGamePath(result.session.state, effect.path, Math.min(max, Math.max(min, current + amount)))
636
+ });
637
+ }
638
+ function numeric(expression, context) {
639
+ const value = evaluateGameExpression(expression, context);
640
+ if (typeof value !== "number" || !Number.isFinite(value)) {
641
+ throw new Error("Expected numeric game expression.");
642
+ }
643
+ return value;
644
+ }
645
+ function setPhase(result, phaseExpression, context) {
646
+ const phase = evaluateGameExpression(phaseExpression, context);
647
+ if (typeof phase !== "string")
648
+ throw new Error("setPhase requires a string expression.");
649
+ return withSession3(result, { ...result.session, phase });
650
+ }
651
+ function emitOutput(result, type, payloadDefinition, context) {
652
+ const payload = Object.entries(payloadDefinition ?? {}).reduce((record, [key, expression]) => ({
653
+ ...record,
654
+ [key]: evaluateGameExpression(expression, context)
655
+ }), {});
656
+ const output = { type, payload };
657
+ return { ...result, outputs: [...result.outputs, output] };
658
+ }
659
+ function scheduleEffects(result, effect, context, contextSnapshot) {
660
+ const delayMs = evaluateGameExpression(effect.delayMs, context);
661
+ if (typeof delayMs !== "number" || delayMs < 0) {
662
+ throw new Error("schedule delay must be non-negative.");
663
+ }
664
+ const scheduled = {
665
+ id: result.session.sequence + result.session.scheduled.length + 1,
666
+ remainingMs: delayMs,
667
+ effects: effect.effects,
668
+ context: contextSnapshot
669
+ };
670
+ return withSession3(result, {
671
+ ...result.session,
672
+ scheduled: [...result.session.scheduled, scheduled]
673
+ });
674
+ }
675
+ function refreshPool(definition, result, effect, input, contextSnapshot, context) {
676
+ const seedValue = effect.seed === undefined ? contextSnapshot.event?.seed ?? result.session.sequence : evaluateGameExpression(effect.seed, context);
677
+ if (typeof seedValue !== "number")
678
+ throw new Error("refreshPool seed must be numeric.");
679
+ return withSession3(result, {
680
+ ...result.session,
681
+ entities: refreshGamePool(definition, result.session, input, effect.poolId, seedValue),
682
+ sequence: result.session.sequence + 1
683
+ });
684
+ }
685
+ function withSession3(result, session) {
686
+ return { ...result, session };
687
+ }
688
+
689
+ // node_modules/@ankhorage/game/dist/features/session/domain/applyGameEffects.js
690
+ function applyGameEffects(definition, session, effects, input, contextSnapshot = {}) {
691
+ return effects.reduce((result, effect) => applyEffect(definition, result, effect, input, contextSnapshot), { session, outputs: [] });
692
+ }
693
+ function applyEffect(definition, result, effect, input, contextSnapshot) {
694
+ const context = createExpressionContext(result.session, input, contextSnapshot);
695
+ if (isEntityEffect(effect)) {
696
+ return applyEntityEffect(definition, result, effect, contextSnapshot, context, (nestedSession, nestedEffects, nestedContext) => applyGameEffects(definition, nestedSession, nestedEffects, input, nestedContext));
697
+ }
698
+ if (isLifecycleEffect(effect)) {
699
+ return applyLifecycleEffect(definition, result, effect, context);
700
+ }
701
+ return applyStateEffect(definition, result, effect, input, contextSnapshot, context);
702
+ }
703
+ function createExpressionContext(session, input, contextSnapshot) {
704
+ const entity = contextSnapshot.entityId === undefined ? undefined : Object.values(session.entities).find((candidate) => candidate.id === contextSnapshot.entityId);
705
+ return {
706
+ session,
707
+ input,
708
+ ...contextSnapshot.event === undefined ? {} : { event: contextSnapshot.event },
709
+ ...entity === undefined ? {} : { entity },
710
+ ...contextSnapshot.local === undefined ? {} : { local: contextSnapshot.local }
711
+ };
712
+ }
713
+ function isEntityEffect(effect) {
714
+ return effect.kind === "spawnEntity" || effect.kind === "removeEntity" || effect.kind === "forEach";
715
+ }
716
+ function isLifecycleEffect(effect) {
717
+ return effect.kind === "transitionStage" || effect.kind === "restartStage";
718
+ }
719
+
720
+ // node_modules/@ankhorage/game/dist/features/session/application/use-cases/advanceGameTime.js
721
+ function advanceGameTime(definition, session, elapsedMs, input = {}) {
722
+ if (!Number.isFinite(elapsedMs) || elapsedMs < 0) {
723
+ throw new Error("Game elapsed time must be a non-negative finite number.");
724
+ }
725
+ const scheduled = session.scheduled.map((candidate) => ({
726
+ ...candidate,
727
+ remainingMs: candidate.remainingMs - elapsedMs
728
+ }));
729
+ const advanced = {
730
+ ...session,
731
+ elapsedMs: session.elapsedMs + elapsedMs,
732
+ scheduled: scheduled.filter((candidate) => candidate.remainingMs > 0)
733
+ };
734
+ const due = scheduled.filter((candidate) => candidate.remainingMs <= 0).sort((left, right) => left.id - right.id);
735
+ return due.reduce((result, candidate) => executeScheduled(definition, result, candidate, input), { session: advanced, outputs: [] });
736
+ }
737
+ function executeScheduled(definition, result, scheduled, input) {
738
+ const applied = applyGameEffects(definition, result.session, scheduled.effects, input, scheduled.context);
739
+ return { session: applied.session, outputs: [...result.outputs, ...applied.outputs] };
740
+ }
741
+ // node_modules/@ankhorage/game/dist/features/session/application/use-cases/applyGameEvent.js
742
+ function applyGameEvent(definition, session, event, input = {}) {
743
+ if (session.definitionId !== definition.id) {
744
+ throw new Error(`Session belongs to ${session.definitionId}, not ${definition.id}.`);
745
+ }
746
+ const entity = event.entityId === undefined ? undefined : session.entities[event.entityId];
747
+ return definition.rules.filter((rule) => rule.event === event.type).reduce((result, rule) => {
748
+ const currentEntity = event.entityId === undefined ? undefined : result.session.entities[event.entityId];
749
+ const ruleEntity = currentEntity ?? entity;
750
+ const conditionContext = {
751
+ session: result.session,
752
+ input,
753
+ event,
754
+ ...ruleEntity === undefined ? {} : { entity: ruleEntity }
755
+ };
756
+ const matches = rule.when === undefined || evaluateGameCondition(rule.when, conditionContext);
757
+ if (!matches)
758
+ return result;
759
+ const applied = applyGameEffects(definition, result.session, rule.effects, input, {
760
+ event,
761
+ ...event.entityId === undefined ? {} : { entityId: event.entityId }
762
+ });
763
+ return { session: applied.session, outputs: [...result.outputs, ...applied.outputs] };
764
+ }, { session, outputs: [] });
765
+ }
766
+ // node_modules/@ankhorage/game/dist/features/session/application/use-cases/createGameSession.js
767
+ function createGameSession(definition, initialization = {}) {
768
+ const firstStage = definition.stages.at(0);
769
+ if (firstStage === undefined)
770
+ throw new Error("Game definition requires at least one stage.");
771
+ const { input = {}, seed = 0 } = initialization;
772
+ if (!Number.isFinite(seed))
773
+ throw new Error("Game session seed must be finite.");
774
+ const session = {
775
+ definitionId: definition.id,
776
+ stageId: firstStage.id,
777
+ phase: definition.initialPhase ?? "playing",
778
+ state: { ...definition.initialState ?? {}, ...firstStage.initialState ?? {} },
779
+ entities: {},
780
+ scheduled: [],
781
+ elapsedMs: 0,
782
+ sequence: 0
783
+ };
784
+ return applyGameEvent(definition, session, { type: "game.start", seed }, input);
785
+ }
786
+ // src/features/game/composition/useGameRuntime.ts
787
+ import React4 from "react";
788
+
789
+ // src/features/game/composition/useGameScheduledEffects.ts
790
+ import React3 from "react";
791
+ function useGameScheduledEffects({
792
+ clockRef,
793
+ definitionRef,
794
+ enabled,
795
+ inputRef,
796
+ runtimeKey,
797
+ scheduled,
798
+ setRuntime
799
+ }) {
800
+ React3.useEffect(() => {
801
+ if (!enabled || scheduled.length === 0)
802
+ return;
803
+ const delayMs = resolveNextScheduledDelay(scheduled);
804
+ const timer = setTimeout(() => {
805
+ const now = Date.now();
806
+ const elapsedMs = Math.max(0, now - clockRef.current);
807
+ clockRef.current = now;
808
+ setRuntime((current) => advanceScheduledRuntime({
809
+ current,
810
+ definition: definitionRef.current,
811
+ elapsedMs,
812
+ input: inputRef.current,
813
+ runtimeKey
814
+ }));
815
+ }, delayMs);
816
+ return () => clearTimeout(timer);
817
+ }, [clockRef, definitionRef, enabled, inputRef, runtimeKey, scheduled, setRuntime]);
818
+ }
819
+ function advanceScheduledRuntime({
820
+ current,
821
+ definition,
822
+ elapsedMs,
823
+ input,
824
+ runtimeKey
825
+ }) {
826
+ if (current.key !== runtimeKey)
827
+ return current;
828
+ const result = advanceGameTime(definition, current.session, elapsedMs, input);
829
+ return {
830
+ key: runtimeKey,
831
+ session: result.session,
832
+ outputs: [...current.outputs, ...result.outputs],
833
+ revision: current.revision + 1
834
+ };
835
+ }
836
+ function resolveNextScheduledDelay(scheduledEffects) {
837
+ return scheduledEffects.reduce((nearest, scheduled) => Math.min(nearest, scheduled.remainingMs), Number.POSITIVE_INFINITY);
838
+ }
839
+
840
+ // src/features/game/composition/useGameRuntime.ts
841
+ var EMPTY_GAME_INPUT = {};
842
+ function useGameRuntime(props) {
843
+ const { definition, input = EMPTY_GAME_INPUT, seed = 0, resetKey = "" } = props;
844
+ const definitionRef = useLatestValue(definition);
845
+ const inputRef = useLatestValue(input);
846
+ const outputRef = useLatestValue(props.onOutput);
847
+ const autoAdvanceTime = props.autoAdvanceTime ?? true;
848
+ const clockRef = React4.useRef(0);
849
+ const runtimeKey = createRuntimeKey(definition.id, resetKey, seed);
850
+ const [runtime, setRuntime] = React4.useState(() => createRuntimeState(definition, input, seed, runtimeKey, 0));
851
+ useGameRuntimeReset({
852
+ clockRef,
853
+ definitionRef,
854
+ inputRef,
855
+ runtimeKey,
856
+ seed,
857
+ setRuntime
858
+ });
859
+ useGameAutoAdvanceClock(autoAdvanceTime, clockRef);
860
+ useGameOutputEmitter(runtime, outputRef, setRuntime);
861
+ const dispatch = React4.useCallback((event) => {
862
+ const now = Date.now();
863
+ setRuntime((current) => applyRuntimeEvent({
864
+ autoAdvanceTime,
865
+ current,
866
+ definition: definitionRef.current,
867
+ elapsedMs: Math.max(0, now - clockRef.current),
868
+ event,
869
+ input: inputRef.current,
870
+ runtimeKey,
871
+ seed
872
+ }));
873
+ clockRef.current = now;
874
+ }, [autoAdvanceTime, definitionRef, inputRef, runtimeKey, seed]);
875
+ useGameScheduledEffects({
876
+ clockRef,
877
+ definitionRef,
878
+ enabled: autoAdvanceTime,
879
+ inputRef,
880
+ runtimeKey,
881
+ scheduled: runtime.session.scheduled,
882
+ setRuntime
883
+ });
884
+ return React4.useMemo(() => ({ session: runtime.session, dispatch }), [dispatch, runtime.session]);
885
+ }
886
+ function useGameRuntimeReset({
887
+ clockRef,
888
+ definitionRef,
889
+ inputRef,
890
+ runtimeKey,
891
+ seed,
892
+ setRuntime
893
+ }) {
894
+ React4.useEffect(() => {
895
+ clockRef.current = Date.now();
896
+ setRuntime((current) => current.key === runtimeKey ? current : createRuntimeState(definitionRef.current, inputRef.current, seed, runtimeKey, current.revision + 1));
897
+ }, [clockRef, definitionRef, inputRef, runtimeKey, seed, setRuntime]);
898
+ }
899
+ function useGameAutoAdvanceClock(enabled, clockRef) {
900
+ const previousEnabledRef = React4.useRef(enabled);
901
+ React4.useEffect(() => {
902
+ if (enabled && !previousEnabledRef.current) {
903
+ clockRef.current = Date.now();
904
+ }
905
+ previousEnabledRef.current = enabled;
906
+ }, [clockRef, enabled]);
907
+ }
908
+ function useGameOutputEmitter(runtime, outputRef, setRuntime) {
909
+ React4.useEffect(() => {
910
+ if (runtime.outputs.length === 0)
911
+ return;
912
+ setRuntime((current) => current.revision === runtime.revision ? { ...current, outputs: [] } : current);
913
+ emitGameOutputs(runtime.outputs, outputRef.current);
914
+ }, [outputRef, runtime.outputs, runtime.revision, setRuntime]);
915
+ }
916
+ function applyRuntimeEvent(args) {
917
+ const base = args.current.key === args.runtimeKey ? args.current : createRuntimeState(args.definition, args.input, args.seed, args.runtimeKey, args.current.revision);
918
+ const timed = args.autoAdvanceTime ? advanceGameTime(args.definition, base.session, args.elapsedMs, args.input) : { session: base.session, outputs: [] };
919
+ const result = applyGameEvent(args.definition, timed.session, args.event, args.input);
920
+ return {
921
+ key: args.runtimeKey,
922
+ session: result.session,
923
+ outputs: [...base.outputs, ...timed.outputs, ...result.outputs],
924
+ revision: args.current.revision + 1
925
+ };
926
+ }
927
+ function createRuntimeState(definition, input, seed, key, revision) {
928
+ const result = createGameSession(definition, { input, seed });
929
+ return { key, session: result.session, outputs: result.outputs, revision };
930
+ }
931
+ function createRuntimeKey(definitionId, resetKey, seed) {
932
+ return `${definitionId}:${resetKey}:${seed}`;
933
+ }
934
+ function emitGameOutputs(outputs, onOutput) {
935
+ if (onOutput === undefined)
936
+ return;
937
+ outputs.forEach((output) => onOutput(output));
938
+ }
939
+ function useLatestValue(value) {
940
+ const ref = React4.useRef(value);
941
+ React4.useEffect(() => {
942
+ ref.current = value;
943
+ }, [value]);
944
+ return ref;
945
+ }
946
+
947
+ // src/features/game/adapters/inbound/Game.tsx
948
+ import { jsx as jsx3 } from "react/jsx-runtime";
949
+ function Game2(props) {
950
+ const runtime = useGameRuntime(props);
951
+ const [measurementRegistry] = React5.useState(createGameMeasurementRegistry);
952
+ const runtimeContext = React5.useMemo(() => ({ ...runtime, ...measurementRegistry, interactionPolicy: props.interactionPolicy }), [measurementRegistry, props.interactionPolicy, runtime]);
953
+ const runtimeBindingConfig = React5.useMemo(() => ({ bindingContext: createGameBindingContext(runtime.session) }), [runtime.session]);
954
+ return /* @__PURE__ */ jsx3(GameRuntimeContext.Provider, {
955
+ value: runtimeContext,
956
+ children: /* @__PURE__ */ jsx3(RuntimeRendererConfigProvider, {
957
+ value: runtimeBindingConfig,
958
+ children: /* @__PURE__ */ jsx3(GameField2, {
959
+ ...props.aspectRatio === undefined ? {} : { aspectRatio: props.aspectRatio },
960
+ ...props.minHeight === undefined ? {} : { minHeight: props.minHeight },
961
+ ...props.fill === undefined ? {} : { fill: props.fill },
962
+ ...props.clip === undefined ? {} : { clip: props.clip },
963
+ ...props.accessibilityLabel === undefined ? {} : { accessibilityLabel: props.accessibilityLabel },
964
+ ...props.testID === undefined ? {} : { testID: props.testID },
965
+ interactionPolicy: props.interactionPolicy,
966
+ children: props.children
967
+ })
968
+ })
969
+ });
970
+ }
971
+
972
+ // src/features/game/adapters/inbound/GameEntity.tsx
973
+ var import_react_native6 = __toESM(require_cjs(), 1);
974
+ import React10 from "react";
975
+
976
+ // src/features/game/utils/useGameEntityAnimatedStyle.ts
977
+ var import_react_native5 = __toESM(require_cjs(), 1);
978
+
979
+ // src/features/game/utils/resolveGameEntityMotionPlan.ts
980
+ function resolveGameEntityMotionPlan(props, reduceMotion) {
981
+ const essential = props.motionEssential === true;
982
+ const motionEnabled = hasMotionOffset(props) && normalizeDuration(props.motionDurationMs) > 0 && (!reduceMotion || essential);
983
+ return {
984
+ transitionDurationMs: reduceMotion ? 0 : normalizeDuration(props.transitionDurationMs),
985
+ transitionEasing: props.transitionEasing ?? "linear",
986
+ motionDurationMs: normalizeDuration(props.motionDurationMs),
987
+ motionDelayMs: normalizeDuration(props.motionDelayMs),
988
+ motionEasing: props.motionEasing ?? "linear",
989
+ motionEnabled,
990
+ motionRepeat: props.motionRepeat === true,
991
+ motionAlternate: props.motionRepeat === true && props.motionAlternate === true,
992
+ motionPaused: props.motionPaused === true
993
+ };
994
+ }
995
+ function hasMotionOffset(props) {
996
+ return (props.motionOffsetX ?? 0) !== 0 || (props.motionOffsetY ?? 0) !== 0 || (props.motionOpacityDelta ?? 0) !== 0 || (props.motionScaleDelta ?? 0) !== 0 || (props.motionRotationDelta ?? 0) !== 0;
997
+ }
998
+ function normalizeDuration(value) {
999
+ return value === undefined || !Number.isFinite(value) ? 0 : Math.max(0, value);
1000
+ }
1001
+
1002
+ // src/features/game/utils/useAnimatedGameEntityValue.ts
1003
+ var import_react_native2 = __toESM(require_cjs(), 1);
1004
+ import React6 from "react";
1005
+ function useAnimatedGameEntityValue(target, durationMs, easing) {
1006
+ const [value] = React6.useState(() => new import_react_native2.Animated.Value(target));
1007
+ React6.useEffect(() => {
1008
+ value.stopAnimation();
1009
+ if (durationMs === 0) {
1010
+ value.setValue(target);
1011
+ return;
1012
+ }
1013
+ const animation = import_react_native2.Animated.timing(value, {
1014
+ toValue: target,
1015
+ duration: durationMs,
1016
+ easing: resolveGameEntityEasing(easing),
1017
+ useNativeDriver: false
1018
+ });
1019
+ animation.start();
1020
+ return () => animation.stop();
1021
+ }, [durationMs, easing, target, value]);
1022
+ return value;
1023
+ }
1024
+ function resolveGameEntityEasing(easing) {
1025
+ if (easing === "ease-in")
1026
+ return import_react_native2.Easing.in(import_react_native2.Easing.ease);
1027
+ if (easing === "ease-out")
1028
+ return import_react_native2.Easing.out(import_react_native2.Easing.ease);
1029
+ if (easing === "ease-in-out")
1030
+ return import_react_native2.Easing.inOut(import_react_native2.Easing.ease);
1031
+ return import_react_native2.Easing.linear;
1032
+ }
1033
+
1034
+ // src/features/game/utils/useGameEntityMotionProgress.ts
1035
+ var import_react_native3 = __toESM(require_cjs(), 1);
1036
+ import React7 from "react";
1037
+ function useGameEntityMotionProgress(plan) {
1038
+ const [progress] = React7.useState(() => new import_react_native3.Animated.Value(0));
1039
+ const signature = createMotionSignature(plan);
1040
+ const previousSignature = React7.useRef(signature);
1041
+ const {
1042
+ motionEnabled,
1043
+ motionPaused,
1044
+ motionDurationMs,
1045
+ motionDelayMs,
1046
+ motionEasing,
1047
+ motionRepeat,
1048
+ motionAlternate
1049
+ } = plan;
1050
+ React7.useEffect(() => {
1051
+ progress.stopAnimation();
1052
+ if (!motionEnabled) {
1053
+ progress.setValue(0);
1054
+ return;
1055
+ }
1056
+ if (previousSignature.current !== signature) {
1057
+ progress.setValue(0);
1058
+ previousSignature.current = signature;
1059
+ }
1060
+ if (motionPaused)
1061
+ return;
1062
+ const animation = createMotionAnimation(progress, {
1063
+ durationMs: motionDurationMs,
1064
+ delayMs: motionDelayMs,
1065
+ easing: motionEasing,
1066
+ repeat: motionRepeat,
1067
+ alternate: motionAlternate
1068
+ });
1069
+ animation.start();
1070
+ return () => animation.stop();
1071
+ }, [
1072
+ motionAlternate,
1073
+ motionDelayMs,
1074
+ motionDurationMs,
1075
+ motionEasing,
1076
+ motionEnabled,
1077
+ motionPaused,
1078
+ motionRepeat,
1079
+ progress,
1080
+ signature
1081
+ ]);
1082
+ return progress;
1083
+ }
1084
+ function createMotionAnimation(progress, input) {
1085
+ const forward = () => import_react_native3.Animated.timing(progress, {
1086
+ toValue: 1,
1087
+ duration: input.durationMs,
1088
+ easing: resolveMotionEasing(input.easing),
1089
+ useNativeDriver: false
1090
+ });
1091
+ const reverse = () => import_react_native3.Animated.timing(progress, {
1092
+ toValue: 0,
1093
+ duration: input.durationMs,
1094
+ easing: resolveMotionEasing(input.easing),
1095
+ useNativeDriver: false
1096
+ });
1097
+ const movement = input.alternate ? import_react_native3.Animated.loop(import_react_native3.Animated.sequence([forward(), reverse()])) : input.repeat ? import_react_native3.Animated.loop(forward()) : forward();
1098
+ return input.delayMs === 0 ? movement : import_react_native3.Animated.sequence([import_react_native3.Animated.delay(input.delayMs), movement]);
1099
+ }
1100
+ function createMotionSignature(plan) {
1101
+ return [
1102
+ plan.motionDurationMs,
1103
+ plan.motionDelayMs,
1104
+ plan.motionEasing,
1105
+ plan.motionEnabled,
1106
+ plan.motionRepeat,
1107
+ plan.motionAlternate
1108
+ ].join(":");
1109
+ }
1110
+ function resolveMotionEasing(easing) {
1111
+ if (easing === "ease-in")
1112
+ return import_react_native3.Easing.in(import_react_native3.Easing.ease);
1113
+ if (easing === "ease-out")
1114
+ return import_react_native3.Easing.out(import_react_native3.Easing.ease);
1115
+ if (easing === "ease-in-out")
1116
+ return import_react_native3.Easing.inOut(import_react_native3.Easing.ease);
1117
+ return import_react_native3.Easing.linear;
1118
+ }
1119
+
1120
+ // src/features/game/utils/useGameReducedMotion.ts
1121
+ var import_react_native4 = __toESM(require_cjs(), 1);
1122
+ import React8 from "react";
1123
+ function useGameReducedMotion() {
1124
+ const [reduceMotion, setReduceMotion] = React8.useState(false);
1125
+ React8.useEffect(() => {
1126
+ import_react_native4.AccessibilityInfo.isReduceMotionEnabled().then(setReduceMotion);
1127
+ const subscription = import_react_native4.AccessibilityInfo.addEventListener("reduceMotionChanged", setReduceMotion);
1128
+ return () => subscription.remove();
1129
+ }, []);
1130
+ return reduceMotion;
1131
+ }
1132
+
1133
+ // src/features/game/utils/useGameEntityAnimatedStyle.ts
1134
+ function useGameEntityAnimatedStyle(input) {
1135
+ const reduceMotion = useGameReducedMotion();
1136
+ const plan = resolveGameEntityMotionPlan(input, reduceMotion);
1137
+ const values = {
1138
+ x: useAnimatedGameEntityValue(input.x ?? 0, plan.transitionDurationMs, plan.transitionEasing),
1139
+ y: useAnimatedGameEntityValue(input.y ?? 0, plan.transitionDurationMs, plan.transitionEasing),
1140
+ opacity: useAnimatedGameEntityValue(input.opacity ?? 1, plan.transitionDurationMs, plan.transitionEasing),
1141
+ scale: useAnimatedGameEntityValue(input.scale ?? 1, plan.transitionDurationMs, plan.transitionEasing),
1142
+ rotation: useAnimatedGameEntityValue(input.rotation ?? 0, plan.transitionDurationMs, plan.transitionEasing),
1143
+ progress: useGameEntityMotionProgress(plan)
1144
+ };
1145
+ return createGameEntityAnimatedStyle(values, input);
1146
+ }
1147
+ function createGameEntityAnimatedStyle(values, input) {
1148
+ const left = import_react_native5.Animated.add(values.x, import_react_native5.Animated.multiply(values.progress, input.motionOffsetX ?? 0));
1149
+ const top = import_react_native5.Animated.add(values.y, import_react_native5.Animated.multiply(values.progress, input.motionOffsetY ?? 0));
1150
+ const opacity = import_react_native5.Animated.add(values.opacity, import_react_native5.Animated.multiply(values.progress, input.motionOpacityDelta ?? 0));
1151
+ const scale = import_react_native5.Animated.add(values.scale, import_react_native5.Animated.multiply(values.progress, input.motionScaleDelta ?? 0));
1152
+ const rotation = import_react_native5.Animated.add(values.rotation, import_react_native5.Animated.multiply(values.progress, input.motionRotationDelta ?? 0));
1153
+ return {
1154
+ left: left.interpolate({
1155
+ inputRange: [-1e4, 1e4],
1156
+ outputRange: ["-10000%", "10000%"]
1157
+ }),
1158
+ top: top.interpolate({
1159
+ inputRange: [-1e4, 1e4],
1160
+ outputRange: ["-10000%", "10000%"]
1161
+ }),
1162
+ opacity: opacity.interpolate({
1163
+ inputRange: [0, 1],
1164
+ outputRange: [0, 1],
1165
+ extrapolate: "clamp"
1166
+ }),
1167
+ transform: [
1168
+ { scale },
1169
+ {
1170
+ rotate: rotation.interpolate({
1171
+ inputRange: [-36000, 36000],
1172
+ outputRange: ["-36000deg", "36000deg"]
1173
+ })
1174
+ }
1175
+ ]
1176
+ };
1177
+ }
1178
+
1179
+ // src/features/game/utils/useGameEntityMeasurement.ts
1180
+ import React9 from "react";
1181
+
1182
+ // src/features/game/adapters/inbound/measureGameEntity.ts
1183
+ function measureGameEntity(element) {
1184
+ if (element === null)
1185
+ return Promise.resolve(undefined);
1186
+ return new Promise((resolve) => {
1187
+ element.measureInWindow((left, top, width, height) => {
1188
+ if (![left, top, width, height].every(Number.isFinite) || width < 0 || height < 0) {
1189
+ resolve(undefined);
1190
+ return;
1191
+ }
1192
+ resolve({
1193
+ left,
1194
+ right: left + width,
1195
+ top,
1196
+ bottom: top + height,
1197
+ width,
1198
+ height
1199
+ });
1200
+ });
1201
+ });
1202
+ }
1203
+
1204
+ // src/features/game/utils/useGameEntityMeasurement.ts
1205
+ function useGameEntityMeasurement(elementRef, measurementId) {
1206
+ const runtime = React9.useContext(GameRuntimeContext);
1207
+ const registerMeasurement = runtime?.registerMeasurement;
1208
+ React9.useEffect(() => {
1209
+ if (measurementId === undefined || registerMeasurement === undefined)
1210
+ return;
1211
+ return registerMeasurement(measurementId, () => measureGameEntity(elementRef.current));
1212
+ }, [elementRef, measurementId, registerMeasurement]);
1213
+ }
1214
+
1215
+ // src/features/game/adapters/inbound/GameEntity.tsx
1216
+ import { jsx as jsx4 } from "react/jsx-runtime";
1217
+ function GameEntity2(props) {
1218
+ const elementRef = React10.useRef(null);
1219
+ const animatedStyle = useGameEntityAnimatedStyle(props);
1220
+ useGameEntityMeasurement(elementRef, props.measurementId);
1221
+ return /* @__PURE__ */ jsx4(import_react_native6.Animated.View, {
1222
+ ref: elementRef,
1223
+ accessibilityLabel: props.accessibilityLabel,
1224
+ testID: props.testID,
1225
+ pointerEvents: props.interactionPolicy === "passive" ? "none" : props.pointerEvents ?? "auto",
1226
+ style: [styles2.root, createEntityStaticStyle(props), animatedStyle],
1227
+ children: props.children
1228
+ });
1229
+ }
1230
+ function createEntityStaticStyle(props) {
1231
+ return {
1232
+ display: props.hidden === true ? "none" : "flex",
1233
+ position: "absolute",
1234
+ zIndex: props.zIndex ?? 0,
1235
+ ...props.height === undefined ? {} : { height: props.height },
1236
+ ...props.width === undefined ? {} : { width: props.width }
1237
+ };
1238
+ }
1239
+ var styles2 = import_react_native6.StyleSheet.create({
1240
+ root: {
1241
+ position: "absolute"
1242
+ }
1243
+ });
1244
+
1245
+ // src/features/game/adapters/inbound/GameInputZone.tsx
1246
+ var import_react_native7 = __toESM(require_cjs(), 1);
1247
+
1248
+ // src/features/game/utils/clampGamePercentage.ts
1249
+ function clampGamePercentage(value) {
1250
+ return Math.min(100, Math.max(0, value));
1251
+ }
1252
+
1253
+ // src/features/game/utils/toGamePercentage.ts
1254
+ function toGamePercentage(value) {
1255
+ return `${clampGamePercentage(value)}%`;
1256
+ }
1257
+
1258
+ // src/features/game/adapters/inbound/useGameInputZoneResponder.ts
1259
+ import React11 from "react";
1260
+
1261
+ // src/features/game/adapters/inbound/createGameKeyboardEvent.ts
1262
+ function createGameKeyboardEvent(input) {
1263
+ const binding = input.bindings.find((candidate) => candidate.key === input.key);
1264
+ if (binding === undefined)
1265
+ return;
1266
+ const entityId = binding.entityId ?? input.fallbackEntityId;
1267
+ return {
1268
+ event: {
1269
+ type: binding.eventType ?? input.fallbackEventType,
1270
+ ...entityId === undefined ? {} : { entityId },
1271
+ payload: { key: input.key }
1272
+ },
1273
+ preventDefault: binding.preventDefault ?? false
1274
+ };
1275
+ }
1276
+
1277
+ // src/features/game/adapters/inbound/createGamePointerEvent.ts
1278
+ function createGamePointerEvent(input) {
1279
+ if (!Number.isFinite(input.measuredWidth) || !Number.isFinite(input.measuredHeight) || input.measuredWidth <= 0 || input.measuredHeight <= 0) {
1280
+ return;
1281
+ }
1282
+ const localX = clampGamePercentage(input.localX / input.measuredWidth * 100);
1283
+ const localY = clampGamePercentage(input.localY / input.measuredHeight * 100);
1284
+ const x = clampGamePercentage(input.zoneX + localX * input.zoneWidth / 100);
1285
+ const y = clampGamePercentage(input.zoneY + localY * input.zoneHeight / 100);
1286
+ return {
1287
+ type: input.eventType,
1288
+ ...input.entityId === undefined ? {} : { entityId: input.entityId },
1289
+ payload: { x, y }
1290
+ };
1291
+ }
1292
+
1293
+ // src/features/game/adapters/inbound/useGameInputZoneResponder.ts
1294
+ function useGameInputZoneResponder(props) {
1295
+ const runtime = React11.useContext(GameRuntimeContext);
1296
+ if (runtime === null)
1297
+ throw new Error("GameInputZone must be rendered inside Game.");
1298
+ const measuredSizeRef = React11.useRef({ width: 0, height: 0 });
1299
+ const handleLayout = React11.useCallback((event) => {
1300
+ const { width, height } = event.nativeEvent.layout;
1301
+ measuredSizeRef.current = { width, height };
1302
+ }, []);
1303
+ const dispatchPointer = React11.useCallback((event) => {
1304
+ if (runtime.interactionPolicy === "passive" || props.interactionPolicy === "passive")
1305
+ return;
1306
+ const measured = measuredSizeRef.current;
1307
+ const gameEvent = createGamePointerEvent({
1308
+ eventType: props.eventType,
1309
+ ...props.entityId === undefined ? {} : { entityId: props.entityId },
1310
+ localX: event.nativeEvent.locationX,
1311
+ localY: event.nativeEvent.locationY,
1312
+ measuredWidth: measured.width,
1313
+ measuredHeight: measured.height,
1314
+ zoneX: props.x ?? 0,
1315
+ zoneY: props.y ?? 0,
1316
+ zoneWidth: props.width ?? 100,
1317
+ zoneHeight: props.height ?? 100
1318
+ });
1319
+ if (gameEvent !== undefined)
1320
+ runtime.dispatch(gameEvent);
1321
+ }, [
1322
+ props.entityId,
1323
+ props.eventType,
1324
+ props.height,
1325
+ props.interactionPolicy,
1326
+ props.width,
1327
+ props.x,
1328
+ props.y,
1329
+ runtime
1330
+ ]);
1331
+ const dispatchKeyboard = React11.useCallback((event) => {
1332
+ if (runtime.interactionPolicy === "passive" || props.interactionPolicy === "passive")
1333
+ return;
1334
+ const result = createGameKeyboardEvent({
1335
+ bindings: props.keyboardBindings ?? [],
1336
+ fallbackEventType: props.eventType,
1337
+ ...props.entityId === undefined ? {} : { fallbackEntityId: props.entityId },
1338
+ key: event.key
1339
+ });
1340
+ if (result === undefined)
1341
+ return;
1342
+ if (result.preventDefault)
1343
+ event.preventDefault();
1344
+ runtime.dispatch(result.event);
1345
+ }, [props.entityId, props.eventType, props.interactionPolicy, props.keyboardBindings, runtime]);
1346
+ return {
1347
+ dispatchKeyboard,
1348
+ dispatchPointer,
1349
+ handleLayout,
1350
+ shouldSetResponder: () => (props.enabled ?? true) && props.interactionPolicy !== "passive" && runtime.interactionPolicy !== "passive"
1351
+ };
1352
+ }
1353
+
1354
+ // src/features/game/adapters/inbound/GameInputZone.tsx
1355
+ import { jsx as jsx5 } from "react/jsx-runtime";
1356
+ function GameInputZone2({
1357
+ x = 0,
1358
+ y = 0,
1359
+ width = 100,
1360
+ height = 100,
1361
+ zIndex = 0,
1362
+ enabled = true,
1363
+ continuous = true,
1364
+ keyboardBindings,
1365
+ accessibilityLabel,
1366
+ interactionPolicy,
1367
+ testID,
1368
+ ...inputProps
1369
+ }) {
1370
+ const { dispatchKeyboard, dispatchPointer, handleLayout, shouldSetResponder } = useGameInputZoneResponder({
1371
+ ...inputProps,
1372
+ x,
1373
+ y,
1374
+ width,
1375
+ height,
1376
+ enabled: enabled && interactionPolicy !== "passive",
1377
+ interactionPolicy,
1378
+ continuous,
1379
+ ...keyboardBindings === undefined ? {} : { keyboardBindings }
1380
+ });
1381
+ const keyboardProps = createGameInputZoneKeyboardProps({
1382
+ dispatchKeyboard,
1383
+ enabled: enabled && interactionPolicy !== "passive",
1384
+ keyboardBindings
1385
+ });
1386
+ return /* @__PURE__ */ jsx5(import_react_native7.View, {
1387
+ ...keyboardProps,
1388
+ ...accessibilityLabel === undefined ? {} : { accessibilityLabel },
1389
+ ...testID === undefined ? {} : { testID },
1390
+ ...continuous ? { onResponderGrant: dispatchPointer, onResponderMove: dispatchPointer } : { onResponderRelease: dispatchPointer },
1391
+ collapsable: false,
1392
+ onLayout: handleLayout,
1393
+ onStartShouldSetResponder: shouldSetResponder,
1394
+ pointerEvents: enabled && interactionPolicy !== "passive" ? "auto" : "none",
1395
+ style: createInputZoneStyle({ x, y, width, height, zIndex })
1396
+ });
1397
+ }
1398
+ function createGameInputZoneKeyboardProps({
1399
+ dispatchKeyboard,
1400
+ enabled,
1401
+ keyboardBindings
1402
+ }) {
1403
+ if (import_react_native7.Platform.OS !== "web" || !enabled || keyboardBindings === undefined)
1404
+ return {};
1405
+ if (keyboardBindings.length === 0)
1406
+ return {};
1407
+ return { onKeyDown: dispatchKeyboard, tabIndex: 0 };
1408
+ }
1409
+ function createInputZoneStyle({ x, y, width, height, zIndex }) {
1410
+ return {
1411
+ left: toGamePercentage(x),
1412
+ top: toGamePercentage(y),
1413
+ width: toGamePercentage(width),
1414
+ height: toGamePercentage(height),
1415
+ zIndex,
1416
+ ...styles3.root
1417
+ };
1418
+ }
1419
+ var styles3 = import_react_native7.StyleSheet.create({
1420
+ root: {
1421
+ position: "absolute"
1422
+ }
1423
+ });
1424
+
1425
+ // src/features/game/adapters/inbound/GameMeasurementProbe.tsx
1426
+ import React12 from "react";
1427
+
1428
+ // src/features/game/adapters/inbound/createGameMeasurementEvent.ts
1429
+ function createGameMeasurementEvent(input) {
1430
+ return {
1431
+ type: input.eventType,
1432
+ entityId: input.entityId ?? input.sourceId,
1433
+ payload: {
1434
+ sourceId: input.sourceId,
1435
+ targetId: input.targetId,
1436
+ source: toGameMeasurementRecord(input.source),
1437
+ target: toGameMeasurementRecord(input.target)
1438
+ }
1439
+ };
1440
+ }
1441
+ function toGameMeasurementRecord(bounds) {
1442
+ return {
1443
+ left: bounds.left,
1444
+ right: bounds.right,
1445
+ top: bounds.top,
1446
+ bottom: bounds.bottom,
1447
+ width: bounds.width,
1448
+ height: bounds.height
1449
+ };
1450
+ }
1451
+
1452
+ // src/features/game/adapters/inbound/GameMeasurementProbe.tsx
1453
+ function GameMeasurementProbe2({
1454
+ sourceId,
1455
+ targetId,
1456
+ eventType = "game.measurement",
1457
+ entityId,
1458
+ delayMs = 0,
1459
+ enabled = true,
1460
+ interactionPolicy
1461
+ }) {
1462
+ const runtime = React12.useContext(GameRuntimeContext);
1463
+ if (runtime === null)
1464
+ throw new Error("GameMeasurementProbe must be rendered inside Game.");
1465
+ React12.useEffect(() => {
1466
+ if (!enabled || interactionPolicy === "passive" || runtime.interactionPolicy === "passive")
1467
+ return;
1468
+ const timer = setTimeout(() => {
1469
+ dispatchGameMeasurement({
1470
+ dispatch: runtime.dispatch,
1471
+ measure: runtime.measure,
1472
+ sourceId,
1473
+ targetId,
1474
+ eventType,
1475
+ ...entityId === undefined ? {} : { entityId }
1476
+ });
1477
+ }, Math.max(0, delayMs));
1478
+ return () => clearTimeout(timer);
1479
+ }, [
1480
+ delayMs,
1481
+ enabled,
1482
+ interactionPolicy,
1483
+ entityId,
1484
+ eventType,
1485
+ runtime.dispatch,
1486
+ runtime.interactionPolicy,
1487
+ runtime.measure,
1488
+ sourceId,
1489
+ targetId
1490
+ ]);
1491
+ return null;
1492
+ }
1493
+ async function dispatchGameMeasurement(input) {
1494
+ const [source, target] = await Promise.all([
1495
+ input.measure(input.sourceId),
1496
+ input.measure(input.targetId)
1497
+ ]);
1498
+ if (source === undefined || target === undefined)
1499
+ return;
1500
+ input.dispatch(createGameMeasurementEvent({
1501
+ eventType: input.eventType,
1502
+ ...input.entityId === undefined ? {} : { entityId: input.entityId },
1503
+ sourceId: input.sourceId,
1504
+ targetId: input.targetId,
1505
+ source,
1506
+ target
1507
+ }));
1508
+ }
1509
+
1510
+ // src/features/game/adapters/inbound/GameOverlay.tsx
1511
+ var import_react_native8 = __toESM(require_cjs(), 1);
1512
+ import { jsx as jsx6 } from "react/jsx-runtime";
1513
+ function GameOverlay2({
1514
+ children,
1515
+ placement = "fill",
1516
+ blocking = false,
1517
+ padding = 0,
1518
+ accessibilityLabel,
1519
+ interactionPolicy,
1520
+ testID
1521
+ }) {
1522
+ return /* @__PURE__ */ jsx6(View2, {
1523
+ ...accessibilityLabel === undefined ? {} : { accessibilityLabel },
1524
+ ...testID === undefined ? {} : { testID },
1525
+ pointerEvents: interactionPolicy === "passive" ? "none" : blocking ? "auto" : "box-none",
1526
+ style: [styles4.root, resolvePlacementStyle(placement), { padding }],
1527
+ children
1528
+ });
1529
+ }
1530
+ function resolvePlacementStyle(placement) {
1531
+ switch (placement) {
1532
+ case "center":
1533
+ return { alignItems: "center", justifyContent: "center" };
1534
+ case "top":
1535
+ return { alignItems: "center", justifyContent: "flex-start" };
1536
+ case "bottom":
1537
+ return { alignItems: "center", justifyContent: "flex-end" };
1538
+ case "top-left":
1539
+ return { alignItems: "flex-start", justifyContent: "flex-start" };
1540
+ case "top-right":
1541
+ return { alignItems: "flex-end", justifyContent: "flex-start" };
1542
+ case "bottom-left":
1543
+ return { alignItems: "flex-start", justifyContent: "flex-end" };
1544
+ case "bottom-right":
1545
+ return { alignItems: "flex-end", justifyContent: "flex-end" };
1546
+ case "fill":
1547
+ return {};
1548
+ }
1549
+ }
1550
+ var styles4 = import_react_native8.StyleSheet.create({
1551
+ root: {
1552
+ bottom: 0,
1553
+ left: 0,
1554
+ position: "absolute",
1555
+ right: 0,
1556
+ top: 0
1557
+ }
1558
+ });
1559
+ export { GameField2, Game2, GameEntity2, GameInputZone2, GameMeasurementProbe2, GameOverlay2 };