blacktrigram 0.7.44 → 0.7.45

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 (746) hide show
  1. package/lib/audio/AudioManager.d.ts +26 -0
  2. package/lib/audio/AudioManager.d.ts.map +1 -1
  3. package/lib/audio/AudioManager.js +26 -0
  4. package/lib/audio/AudioManager.js.map +1 -1
  5. package/lib/audio/index.d.ts.map +1 -1
  6. package/lib/audio/index.js.map +1 -1
  7. package/lib/audio/types.d.ts +18 -2
  8. package/lib/audio/types.d.ts.map +1 -1
  9. package/lib/audio/types.js +1 -0
  10. package/lib/audio/types.js.map +1 -1
  11. package/lib/components/effects/WindParticles3D.d.ts.map +1 -1
  12. package/lib/components/index.d.ts.map +1 -1
  13. package/lib/components/index.js.map +1 -1
  14. package/lib/components/screens/combat/CombatScreen3D.d.ts.map +1 -1
  15. package/lib/components/screens/combat/CombatScreen3D.js.map +1 -1
  16. package/lib/components/screens/combat/components/controls/KeyboardHints.d.ts +0 -1
  17. package/lib/components/screens/combat/components/controls/KeyboardHints.d.ts.map +1 -1
  18. package/lib/components/screens/combat/components/controls/KeyboardHints.js +0 -1
  19. package/lib/components/screens/combat/components/controls/KeyboardHints.js.map +1 -1
  20. package/lib/components/screens/combat/components/controls/PauseMenu.d.ts.map +1 -1
  21. package/lib/components/screens/combat/components/controls/PauseMenu.js.map +1 -1
  22. package/lib/components/screens/combat/components/effects/ArterialSpray3D.d.ts.map +1 -1
  23. package/lib/components/screens/combat/components/effects/BloodDecals3D.d.ts.map +1 -1
  24. package/lib/components/screens/combat/components/effects/BloodDecals3D.js.map +1 -1
  25. package/lib/components/screens/combat/components/effects/BloodLossOverlayHtml.d.ts.map +1 -1
  26. package/lib/components/screens/combat/components/effects/BloodLossOverlayHtml.js.map +1 -1
  27. package/lib/components/screens/combat/components/effects/BloodParticles3D.d.ts.map +1 -1
  28. package/lib/components/screens/combat/components/effects/BloodParticles3D.js.map +1 -1
  29. package/lib/components/screens/combat/components/effects/BloodViscosity3D.d.ts.map +1 -1
  30. package/lib/components/screens/combat/components/effects/BloodViscosity3D.js.map +1 -1
  31. package/lib/components/screens/combat/components/effects/BoneCrackParticles3D.d.ts.map +1 -1
  32. package/lib/components/screens/combat/components/effects/CombatParticleEffects3D.d.ts.map +1 -1
  33. package/lib/components/screens/combat/components/effects/CombatParticleEffects3D.js.map +1 -1
  34. package/lib/components/screens/combat/components/effects/ConsciousnessBlur.d.ts.map +1 -1
  35. package/lib/components/screens/combat/components/effects/ConsciousnessBlur.js.map +1 -1
  36. package/lib/components/screens/combat/components/effects/DustClouds3D.d.ts.map +1 -1
  37. package/lib/components/screens/combat/components/effects/EarthCrackEffect3D.d.ts.map +1 -1
  38. package/lib/components/screens/combat/components/effects/EarthHealingEffect3D.d.ts.map +1 -1
  39. package/lib/components/screens/combat/components/effects/ImpactSparks3D.d.ts.map +1 -1
  40. package/lib/components/screens/combat/components/effects/InternalDamage3D.d.ts.map +1 -1
  41. package/lib/components/screens/combat/components/effects/InternalDamage3D.js.map +1 -1
  42. package/lib/components/screens/combat/components/effects/LiPrecisionTargetingOverlay.d.ts.map +1 -1
  43. package/lib/components/screens/combat/components/effects/NerveStrikeParticles3D.d.ts.map +1 -1
  44. package/lib/components/screens/combat/components/effects/PainVignette.d.ts.map +1 -1
  45. package/lib/components/screens/combat/components/effects/PainVignette.js.map +1 -1
  46. package/lib/components/screens/combat/components/effects/ParticleAudio3D.d.ts.map +1 -1
  47. package/lib/components/screens/combat/components/effects/ParticleAudio3D.js.map +1 -1
  48. package/lib/components/screens/combat/components/effects/TraumaOverlay3D.d.ts.map +1 -1
  49. package/lib/components/screens/combat/components/effects/TraumaOverlay3D.js.map +1 -1
  50. package/lib/components/screens/combat/components/effects/WaterRipple3D.d.ts.map +1 -1
  51. package/lib/components/screens/combat/components/effects/WaterWave3D.d.ts.map +1 -1
  52. package/lib/components/screens/combat/components/effects/index.d.ts.map +1 -1
  53. package/lib/components/screens/combat/components/feedback/MatchCountdown.d.ts.map +1 -1
  54. package/lib/components/screens/combat/components/feedback/MatchCountdown.js.map +1 -1
  55. package/lib/components/screens/combat/components/feedback/RoundAnnouncementOverlayHtml.d.ts.map +1 -1
  56. package/lib/components/screens/combat/components/feedback/RoundAnnouncementOverlayHtml.js.map +1 -1
  57. package/lib/components/screens/combat/components/feedback/RoundStartAnnouncementOverlayHtml.d.ts.map +1 -1
  58. package/lib/components/screens/combat/components/feedback/RoundStartAnnouncementOverlayHtml.js.map +1 -1
  59. package/lib/components/screens/combat/components/hud/CombatBottomHUD.d.ts.map +1 -1
  60. package/lib/components/screens/combat/components/hud/CombatBottomHUD.js.map +1 -1
  61. package/lib/components/screens/combat/components/hud/CombatLeftHUD.d.ts.map +1 -1
  62. package/lib/components/screens/combat/components/hud/CombatLeftHUD.js.map +1 -1
  63. package/lib/components/screens/combat/components/hud/CombatPortraitStatusStrip.d.ts.map +1 -1
  64. package/lib/components/screens/combat/components/hud/CombatPortraitStatusStrip.js.map +1 -1
  65. package/lib/components/screens/combat/components/hud/CombatRightHUD.d.ts.map +1 -1
  66. package/lib/components/screens/combat/components/hud/CombatRightHUD.js.map +1 -1
  67. package/lib/components/screens/combat/components/hud/CombatTopHUD.d.ts.map +1 -1
  68. package/lib/components/screens/combat/components/hud/CombatTopHUD.js.map +1 -1
  69. package/lib/components/screens/combat/components/hud/DifficultyIndicator.d.ts.map +1 -1
  70. package/lib/components/screens/combat/components/hud/DifficultyIndicator.js.map +1 -1
  71. package/lib/components/screens/combat/components/hud/FPSMonitor.d.ts.map +1 -1
  72. package/lib/components/screens/combat/components/hud/FPSMonitor.js.map +1 -1
  73. package/lib/components/screens/combat/components/hud/PlayerStateOverlayHtml.d.ts.map +1 -1
  74. package/lib/components/screens/combat/components/hud/PlayerStateOverlayHtml.js.map +1 -1
  75. package/lib/components/screens/combat/components/indicators/BalanceIndicator.d.ts.map +1 -1
  76. package/lib/components/screens/combat/components/indicators/BalanceIndicator.js.map +1 -1
  77. package/lib/components/screens/combat/components/indicators/InputBufferDisplay.d.ts +0 -1
  78. package/lib/components/screens/combat/components/indicators/InputBufferDisplay.d.ts.map +1 -1
  79. package/lib/components/screens/combat/components/indicators/InputBufferDisplay.js +0 -1
  80. package/lib/components/screens/combat/components/indicators/InputBufferDisplay.js.map +1 -1
  81. package/lib/components/screens/combat/components/indicators/StaminaWarning.d.ts.map +1 -1
  82. package/lib/components/screens/combat/components/indicators/StaminaWarning.js.map +1 -1
  83. package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.d.ts +0 -2
  84. package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.d.ts.map +1 -1
  85. package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.js +0 -1
  86. package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.js.map +1 -1
  87. package/lib/components/screens/combat/helpers/AnimationUpdater.d.ts.map +1 -1
  88. package/lib/components/screens/combat/helpers/AnimationUpdater.js.map +1 -1
  89. package/lib/components/screens/combat/helpers/combatHelpers.d.ts.map +1 -1
  90. package/lib/components/screens/combat/helpers/combatHelpers.js.map +1 -1
  91. package/lib/components/screens/combat/hooks/useAICombat.d.ts.map +1 -1
  92. package/lib/components/screens/combat/hooks/useAICombat.js.map +1 -1
  93. package/lib/components/screens/combat/hooks/useCombatActions.d.ts.map +1 -1
  94. package/lib/components/screens/combat/hooks/useCombatActions.js.map +1 -1
  95. package/lib/components/screens/combat/hooks/useCombatAttackMovement.d.ts.map +1 -1
  96. package/lib/components/screens/combat/hooks/useCombatAttackMovement.js.map +1 -1
  97. package/lib/components/screens/combat/hooks/useCombatAudio.d.ts.map +1 -1
  98. package/lib/components/screens/combat/hooks/useCombatAudio.js.map +1 -1
  99. package/lib/components/screens/combat/hooks/useCombatLayout.d.ts.map +1 -1
  100. package/lib/components/screens/combat/hooks/useCombatLayout.js.map +1 -1
  101. package/lib/components/screens/combat/hooks/useCombatState.d.ts.map +1 -1
  102. package/lib/components/screens/combat/hooks/useCombatState.js.map +1 -1
  103. package/lib/components/screens/combat/hooks/useGrapplingAudio.d.ts.map +1 -1
  104. package/lib/components/screens/combat/hooks/usePreloadCombatAudio.d.ts.map +1 -1
  105. package/lib/components/screens/controls/ControlsScreen3D.d.ts.map +1 -1
  106. package/lib/components/screens/controls/ControlsScreen3D.js.map +1 -1
  107. package/lib/components/screens/controls/components/ControlBindingsOverlayHtml.d.ts.map +1 -1
  108. package/lib/components/screens/controls/components/ControlBindingsOverlayHtml.js.map +1 -1
  109. package/lib/components/screens/controls/components/GamepadVisualization3D.d.ts.map +1 -1
  110. package/lib/components/screens/controls/components/GamepadVisualization3D.js.map +1 -1
  111. package/lib/components/screens/controls/components/InteractiveControlDemoOverlayHtml.d.ts.map +1 -1
  112. package/lib/components/screens/controls/components/InteractiveControlDemoOverlayHtml.js.map +1 -1
  113. package/lib/components/screens/controls/components/Key3D.d.ts.map +1 -1
  114. package/lib/components/screens/controls/components/Key3D.js.map +1 -1
  115. package/lib/components/screens/controls/components/VisualKeyboard3D.d.ts.map +1 -1
  116. package/lib/components/screens/controls/components/VisualKeyboard3D.js.map +1 -1
  117. package/lib/components/screens/controls/constants/ControlsConstants.d.ts.map +1 -1
  118. package/lib/components/screens/controls/constants/ControlsConstants.js.map +1 -1
  119. package/lib/components/screens/controls/hooks/useControlsState.d.ts.map +1 -1
  120. package/lib/components/screens/controls/hooks/useControlsState.js.map +1 -1
  121. package/lib/components/screens/endscreen/EndScreen3D.d.ts.map +1 -1
  122. package/lib/components/screens/endscreen/EndScreen3D.js.map +1 -1
  123. package/lib/components/screens/endscreen/components/DefeatAnimation3D.d.ts.map +1 -1
  124. package/lib/components/screens/endscreen/components/DefeatAnimation3D.js.map +1 -1
  125. package/lib/components/screens/endscreen/components/NavigationButtonsOverlayHtml.d.ts.map +1 -1
  126. package/lib/components/screens/endscreen/components/NavigationButtonsOverlayHtml.js.map +1 -1
  127. package/lib/components/screens/endscreen/components/PerformanceBreakdownOverlayHtml.d.ts.map +1 -1
  128. package/lib/components/screens/endscreen/components/PerformanceBreakdownOverlayHtml.js.map +1 -1
  129. package/lib/components/screens/endscreen/components/PerformanceRatingOverlayHtml.d.ts.map +1 -1
  130. package/lib/components/screens/endscreen/components/PerformanceRatingOverlayHtml.js.map +1 -1
  131. package/lib/components/screens/endscreen/components/VictoryAnimation3D.d.ts.map +1 -1
  132. package/lib/components/screens/endscreen/components/VictoryAnimation3D.js.map +1 -1
  133. package/lib/components/screens/endscreen/components/WinnerDisplayOverlayHtml.d.ts.map +1 -1
  134. package/lib/components/screens/endscreen/components/WinnerDisplayOverlayHtml.js.map +1 -1
  135. package/lib/components/screens/endscreen/components/index.d.ts.map +1 -1
  136. package/lib/components/screens/endscreen/index.d.ts.map +1 -1
  137. package/lib/components/screens/intro/IntroScreen3D.d.ts.map +1 -1
  138. package/lib/components/screens/intro/IntroScreen3D.js +1 -1
  139. package/lib/components/screens/intro/IntroScreen3D.js.map +1 -1
  140. package/lib/components/screens/intro/components/AbilityListOverlayHtml.d.ts.map +1 -1
  141. package/lib/components/screens/intro/components/AbilityListOverlayHtml.js.map +1 -1
  142. package/lib/components/screens/intro/components/ArchetypeCardGridOverlayHtml.d.ts.map +1 -1
  143. package/lib/components/screens/intro/components/ArchetypeCardGridOverlayHtml.js.map +1 -1
  144. package/lib/components/screens/intro/components/ArchetypeCardOverlayHtml.d.ts.map +1 -1
  145. package/lib/components/screens/intro/components/ArchetypeCardOverlayHtml.js.map +1 -1
  146. package/lib/components/screens/intro/components/ArchetypeDisplayOverlayHtml.d.ts.map +1 -1
  147. package/lib/components/screens/intro/components/ArchetypeDisplayOverlayHtml.js.map +1 -1
  148. package/lib/components/screens/intro/components/EnhancedArchetypeDisplayOverlayHtml.d.ts.map +1 -1
  149. package/lib/components/screens/intro/components/EnhancedArchetypeDisplayOverlayHtml.js.map +1 -1
  150. package/lib/components/screens/intro/components/MenuButtonsOverlayHtml.d.ts.map +1 -1
  151. package/lib/components/screens/intro/components/MenuButtonsOverlayHtml.js.map +1 -1
  152. package/lib/components/screens/intro/components/MenuSectionOverlayHtml.d.ts.map +1 -1
  153. package/lib/components/screens/intro/components/MenuSectionOverlayHtml.js.map +1 -1
  154. package/lib/components/screens/intro/components/StatBarOverlayHtml.d.ts.map +1 -1
  155. package/lib/components/screens/intro/components/StatBarOverlayHtml.js.map +1 -1
  156. package/lib/components/screens/philosophy/PhilosophyScreen3D.d.ts.map +1 -1
  157. package/lib/components/screens/philosophy/PhilosophyScreen3D.js.map +1 -1
  158. package/lib/components/screens/philosophy/components/InteractiveTrigramGridOverlayHtml.d.ts +0 -1
  159. package/lib/components/screens/philosophy/components/InteractiveTrigramGridOverlayHtml.d.ts.map +1 -1
  160. package/lib/components/screens/philosophy/components/PhilosophyNavigationOverlayHtml.d.ts +0 -1
  161. package/lib/components/screens/philosophy/components/PhilosophyNavigationOverlayHtml.d.ts.map +1 -1
  162. package/lib/components/screens/philosophy/components/PhilosophySectionOverlayHtml.d.ts +0 -1
  163. package/lib/components/screens/philosophy/components/PhilosophySectionOverlayHtml.d.ts.map +1 -1
  164. package/lib/components/screens/philosophy/components/PhilosophyTextOverlayHtml.d.ts +0 -1
  165. package/lib/components/screens/philosophy/components/PhilosophyTextOverlayHtml.d.ts.map +1 -1
  166. package/lib/components/screens/philosophy/components/TrigramSymbol3D.d.ts +0 -1
  167. package/lib/components/screens/philosophy/components/TrigramSymbol3D.d.ts.map +1 -1
  168. package/lib/components/screens/philosophy/components/TrigramVisualization3D.d.ts +0 -1
  169. package/lib/components/screens/philosophy/components/TrigramVisualization3D.d.ts.map +1 -1
  170. package/lib/components/screens/philosophy/hooks/usePhilosophyState.d.ts +0 -1
  171. package/lib/components/screens/philosophy/hooks/usePhilosophyState.d.ts.map +1 -1
  172. package/lib/components/screens/training/TrainingScreen3D.d.ts.map +1 -1
  173. package/lib/components/screens/training/TrainingScreen3D.js.map +1 -1
  174. package/lib/components/screens/training/components/AnatomyControlsOverlayHtml.d.ts.map +1 -1
  175. package/lib/components/screens/training/components/AnatomyControlsOverlayHtml.js.map +1 -1
  176. package/lib/components/screens/training/components/AnatomyOverlay3D.d.ts.map +1 -1
  177. package/lib/components/screens/training/components/AnatomyOverlay3D.js.map +1 -1
  178. package/lib/components/screens/training/components/DamageNumber3D.d.ts.map +1 -1
  179. package/lib/components/screens/training/components/FootPlacementMarkers3D.d.ts.map +1 -1
  180. package/lib/components/screens/training/components/FootPlacementMarkers3D.js.map +1 -1
  181. package/lib/components/screens/training/components/FootworkDrillsOverlayHtml.d.ts.map +1 -1
  182. package/lib/components/screens/training/components/FootworkDrillsOverlayHtml.js.map +1 -1
  183. package/lib/components/screens/training/components/HitFeedbackEffect3D.d.ts.map +1 -1
  184. package/lib/components/screens/training/components/HitFeedbackEffect3D.js.map +1 -1
  185. package/lib/components/screens/training/components/TrainingAICharacter3D.d.ts.map +1 -1
  186. package/lib/components/screens/training/components/TrainingArena3D.d.ts.map +1 -1
  187. package/lib/components/screens/training/components/TrainingControlsOverlayHtml.d.ts.map +1 -1
  188. package/lib/components/screens/training/components/TrainingControlsOverlayHtml.js.map +1 -1
  189. package/lib/components/screens/training/components/TrainingDummy3D.d.ts.map +1 -1
  190. package/lib/components/screens/training/components/TrainingDummy3D.js.map +1 -1
  191. package/lib/components/screens/training/components/TrainingFeedbackOverlayHtml.d.ts.map +1 -1
  192. package/lib/components/screens/training/components/TrainingFeedbackOverlayHtml.js.map +1 -1
  193. package/lib/components/screens/training/components/TrainingHitEffects3D.d.ts.map +1 -1
  194. package/lib/components/screens/training/components/TrainingModeSelectorOverlayHtml.d.ts.map +1 -1
  195. package/lib/components/screens/training/components/TrainingModeSelectorOverlayHtml.js.map +1 -1
  196. package/lib/components/screens/training/components/TrainingStatsOverlayHtml.d.ts.map +1 -1
  197. package/lib/components/screens/training/components/TrainingStatsOverlayHtml.js.map +1 -1
  198. package/lib/components/screens/training/components/VitalPointMarker3D.d.ts.map +1 -1
  199. package/lib/components/screens/training/components/VitalPointMarker3D.js.map +1 -1
  200. package/lib/components/screens/training/components/VitalPointTrainingOverlayHtml.d.ts.map +1 -1
  201. package/lib/components/screens/training/components/VitalPointTrainingOverlayHtml.js.map +1 -1
  202. package/lib/components/screens/training/components/hud/TrainingBottomHUD.d.ts.map +1 -1
  203. package/lib/components/screens/training/components/hud/TrainingBottomHUD.js.map +1 -1
  204. package/lib/components/screens/training/components/hud/TrainingLeftHUD.d.ts.map +1 -1
  205. package/lib/components/screens/training/components/hud/TrainingLeftHUD.js.map +1 -1
  206. package/lib/components/screens/training/components/hud/TrainingRightHUD.d.ts.map +1 -1
  207. package/lib/components/screens/training/components/hud/TrainingRightHUD.js.map +1 -1
  208. package/lib/components/screens/training/components/hud/TrainingTopHUD.d.ts.map +1 -1
  209. package/lib/components/screens/training/components/hud/TrainingTopHUD.js.map +1 -1
  210. package/lib/components/screens/training/components/index.d.ts.map +1 -1
  211. package/lib/components/screens/training/hooks/useAttackMovement.d.ts.map +1 -1
  212. package/lib/components/screens/training/hooks/useAttackMovement.js.map +1 -1
  213. package/lib/components/screens/training/hooks/useTrainingActions.d.ts.map +1 -1
  214. package/lib/components/screens/training/hooks/useTrainingActions.js.map +1 -1
  215. package/lib/components/screens/training/hooks/useTrainingLayout.d.ts.map +1 -1
  216. package/lib/components/screens/training/hooks/useTrainingLayout.js.map +1 -1
  217. package/lib/components/screens/training/hooks/useTrainingState.d.ts.map +1 -1
  218. package/lib/components/screens/training/hooks/useTrainingState.js.map +1 -1
  219. package/lib/components/shared/base/AccessibilityProvider.d.ts.map +1 -1
  220. package/lib/components/shared/base/BaseButton.d.ts.map +1 -1
  221. package/lib/components/shared/base/BaseButton.js.map +1 -1
  222. package/lib/components/shared/base/BaseButtonOverlayHtml.d.ts.map +1 -1
  223. package/lib/components/shared/base/BaseButtonOverlayHtml.js.map +1 -1
  224. package/lib/components/shared/base/BasePanel.d.ts.map +1 -1
  225. package/lib/components/shared/base/BasePanel.js.map +1 -1
  226. package/lib/components/shared/base/BaseText.d.ts.map +1 -1
  227. package/lib/components/shared/base/BaseText.js.map +1 -1
  228. package/lib/components/shared/base/ResponsiveContainer.d.ts.map +1 -1
  229. package/lib/components/shared/base/index.d.ts.map +1 -1
  230. package/lib/components/shared/base/useKoreanTheme.d.ts.map +1 -1
  231. package/lib/components/shared/base/useKoreanTheme.js.map +1 -1
  232. package/lib/components/shared/debug/PerformanceDebugOverlayHtml.d.ts.map +1 -1
  233. package/lib/components/shared/debug/PerformanceDebugOverlayHtml.js.map +1 -1
  234. package/lib/components/shared/effects/ScreenFlash.d.ts.map +1 -1
  235. package/lib/components/shared/mobile/ActionButtons.d.ts.map +1 -1
  236. package/lib/components/shared/mobile/ActionButtons.js +0 -1
  237. package/lib/components/shared/mobile/ActionButtons.js.map +1 -1
  238. package/lib/components/shared/mobile/GestureRecognizerPure.d.ts +0 -1
  239. package/lib/components/shared/mobile/GestureRecognizerPure.d.ts.map +1 -1
  240. package/lib/components/shared/mobile/GestureRecognizerPure.js +0 -1
  241. package/lib/components/shared/mobile/GestureRecognizerPure.js.map +1 -1
  242. package/lib/components/shared/mobile/HapticController.d.ts +0 -13
  243. package/lib/components/shared/mobile/HapticController.d.ts.map +1 -1
  244. package/lib/components/shared/mobile/HapticController.js +0 -10
  245. package/lib/components/shared/mobile/HapticController.js.map +1 -1
  246. package/lib/components/shared/mobile/MobileControlsPure.d.ts.map +1 -1
  247. package/lib/components/shared/mobile/MobileControlsPure.js.map +1 -1
  248. package/lib/components/shared/mobile/PerformanceMonitor.d.ts +0 -15
  249. package/lib/components/shared/mobile/PerformanceMonitor.d.ts.map +1 -1
  250. package/lib/components/shared/mobile/StanceWheelPure.d.ts +0 -1
  251. package/lib/components/shared/mobile/StanceWheelPure.d.ts.map +1 -1
  252. package/lib/components/shared/mobile/StanceWheelPure.js +0 -1
  253. package/lib/components/shared/mobile/StanceWheelPure.js.map +1 -1
  254. package/lib/components/shared/mobile/TouchOptimizer.d.ts +0 -4
  255. package/lib/components/shared/mobile/TouchOptimizer.d.ts.map +1 -1
  256. package/lib/components/shared/mobile/TouchOptimizer.js +0 -3
  257. package/lib/components/shared/mobile/TouchOptimizer.js.map +1 -1
  258. package/lib/components/shared/mobile/VirtualDPad.d.ts.map +1 -1
  259. package/lib/components/shared/mobile/VirtualDPad.js +0 -1
  260. package/lib/components/shared/mobile/VirtualDPad.js.map +1 -1
  261. package/lib/components/shared/mobile/index.d.ts.map +1 -1
  262. package/lib/components/shared/three/anatomy/BodySurface.d.ts.map +1 -1
  263. package/lib/components/shared/three/anatomy/BodySurface.js.map +1 -1
  264. package/lib/components/shared/three/anatomy/BoneAttachedMuscles.d.ts.map +1 -1
  265. package/lib/components/shared/three/anatomy/BoneAttachedMuscles.js.map +1 -1
  266. package/lib/components/shared/three/anatomy/BoneClothing.d.ts.map +1 -1
  267. package/lib/components/shared/three/anatomy/BoneClothing.js.map +1 -1
  268. package/lib/components/shared/three/anatomy/BoneRenderer.d.ts +0 -1
  269. package/lib/components/shared/three/anatomy/BoneRenderer.d.ts.map +1 -1
  270. package/lib/components/shared/three/anatomy/BoneRenderer.js.map +1 -1
  271. package/lib/components/shared/three/anatomy/Face3D.d.ts.map +1 -1
  272. package/lib/components/shared/three/anatomy/Face3D.js.map +1 -1
  273. package/lib/components/shared/three/anatomy/Foot3D.d.ts +0 -1
  274. package/lib/components/shared/three/anatomy/Foot3D.d.ts.map +1 -1
  275. package/lib/components/shared/three/anatomy/Foot3D.js.map +1 -1
  276. package/lib/components/shared/three/anatomy/Hand3D.d.ts +0 -1
  277. package/lib/components/shared/three/anatomy/Hand3D.d.ts.map +1 -1
  278. package/lib/components/shared/three/anatomy/Hand3D.js.map +1 -1
  279. package/lib/components/shared/three/effects/ActionFeedback.d.ts.map +1 -1
  280. package/lib/components/shared/three/effects/ActionFeedback.js.map +1 -1
  281. package/lib/components/shared/three/effects/DamageNumbers.d.ts.map +1 -1
  282. package/lib/components/shared/three/effects/DamageNumbers.js.map +1 -1
  283. package/lib/components/shared/three/effects/ExplosiveBurstEffect3D.d.ts.map +1 -1
  284. package/lib/components/shared/three/effects/GrapplingIndicator3D.d.ts.map +1 -1
  285. package/lib/components/shared/three/effects/HitEffects3D.d.ts.map +1 -1
  286. package/lib/components/shared/three/effects/HitEffects3D.js.map +1 -1
  287. package/lib/components/shared/three/effects/LimbExposureIndicator3D.d.ts.map +1 -1
  288. package/lib/components/shared/three/effects/NerveDisruptionEffect3D.d.ts.map +1 -1
  289. package/lib/components/shared/three/effects/PlayerStateIndicators.d.ts.map +1 -1
  290. package/lib/components/shared/three/effects/PlayerStateIndicators.js.map +1 -1
  291. package/lib/components/shared/three/effects/StanceSymbol3D.d.ts.map +1 -1
  292. package/lib/components/shared/three/effects/StanceSymbol3D.js.map +1 -1
  293. package/lib/components/shared/three/effects/StanceTransitionEffect.d.ts.map +1 -1
  294. package/lib/components/shared/three/effects/StanceTransitionEffect.js.map +1 -1
  295. package/lib/components/shared/three/effects/ThunderEffect3D.d.ts.map +1 -1
  296. package/lib/components/shared/three/effects/VitalPointMarkers3D.d.ts.map +1 -1
  297. package/lib/components/shared/three/effects/VitalPointMarkers3D.js.map +1 -1
  298. package/lib/components/shared/three/index.d.ts.map +1 -1
  299. package/lib/components/shared/three/indicators/ElementalColorSystem.d.ts +0 -6
  300. package/lib/components/shared/three/indicators/ElementalColorSystem.d.ts.map +1 -1
  301. package/lib/components/shared/three/indicators/ElementalColorSystem.js +0 -4
  302. package/lib/components/shared/three/indicators/ElementalColorSystem.js.map +1 -1
  303. package/lib/components/shared/three/indicators/GuardIndicator.d.ts +0 -1
  304. package/lib/components/shared/three/indicators/GuardIndicator.d.ts.map +1 -1
  305. package/lib/components/shared/three/indicators/GuardIndicator.js +0 -1
  306. package/lib/components/shared/three/indicators/GuardIndicator.js.map +1 -1
  307. package/lib/components/shared/three/indicators/HapticFeedback.d.ts +0 -7
  308. package/lib/components/shared/three/indicators/HapticFeedback.d.ts.map +1 -1
  309. package/lib/components/shared/three/indicators/HapticFeedback.js +0 -2
  310. package/lib/components/shared/three/indicators/HapticFeedback.js.map +1 -1
  311. package/lib/components/shared/three/indicators/StanceChangeIndicator.d.ts +0 -1
  312. package/lib/components/shared/three/indicators/StanceChangeIndicator.d.ts.map +1 -1
  313. package/lib/components/shared/three/indicators/StanceChangeIndicator.js +0 -1
  314. package/lib/components/shared/three/indicators/StanceChangeIndicator.js.map +1 -1
  315. package/lib/components/shared/three/indicators/TrigramSymbol3D.d.ts +0 -1
  316. package/lib/components/shared/three/indicators/TrigramSymbol3D.d.ts.map +1 -1
  317. package/lib/components/shared/three/models/Player3DWithTransitions.d.ts.map +1 -1
  318. package/lib/components/shared/three/models/Player3DWithTransitions.js.map +1 -1
  319. package/lib/components/shared/three/models/SkeletalPlayer3D.d.ts.map +1 -1
  320. package/lib/components/shared/three/models/SkeletalPlayer3D.js.map +1 -1
  321. package/lib/components/shared/three/optimization/AdaptiveQuality.d.ts.map +1 -1
  322. package/lib/components/shared/three/optimization/AdaptiveQuality.js.map +1 -1
  323. package/lib/components/shared/three/optimization/InstancedGeometry.d.ts.map +1 -1
  324. package/lib/components/shared/three/optimization/LODSystem.d.ts.map +1 -1
  325. package/lib/components/shared/three/scene/AtmosphericParticles3D.d.ts.map +1 -1
  326. package/lib/components/shared/three/scene/AtmosphericParticles3D.js.map +1 -1
  327. package/lib/components/shared/three/scene/BackgroundScene3D.d.ts.map +1 -1
  328. package/lib/components/shared/three/scene/BackgroundScene3D.js.map +1 -1
  329. package/lib/components/shared/three/scene/CombatArena3D.d.ts.map +1 -1
  330. package/lib/components/shared/three/scene/CombatArena3D.js.map +1 -1
  331. package/lib/components/shared/three/scene/DebugCollision.d.ts +0 -2
  332. package/lib/components/shared/three/scene/DebugCollision.d.ts.map +1 -1
  333. package/lib/components/shared/three/scene/KoreanSignage3D.d.ts.map +1 -1
  334. package/lib/components/shared/three/scene/KoreanSignage3D.js.map +1 -1
  335. package/lib/components/shared/three/ui/ArchetypeCard.d.ts.map +1 -1
  336. package/lib/components/shared/three/ui/ArchetypeCard.js.map +1 -1
  337. package/lib/components/shared/three/ui/BodyPartHealthDisplay.d.ts.map +1 -1
  338. package/lib/components/shared/three/ui/BodyPartHealthDisplay.js.map +1 -1
  339. package/lib/components/shared/three/ui/BreathingIndicator.d.ts.map +1 -1
  340. package/lib/components/shared/three/ui/BreathingIndicator2.js.map +1 -1
  341. package/lib/components/shared/three/ui/CombatReadinessBar.d.ts.map +1 -1
  342. package/lib/components/shared/three/ui/CombatReadinessBar.js.map +1 -1
  343. package/lib/components/shared/three/ui/ComboCounter.d.ts.map +1 -1
  344. package/lib/components/shared/three/ui/ComboCounter.js.map +1 -1
  345. package/lib/components/shared/three/ui/HealthBar.d.ts.map +1 -1
  346. package/lib/components/shared/three/ui/HealthBar.js.map +1 -1
  347. package/lib/components/shared/three/ui/KoreanButton.d.ts.map +1 -1
  348. package/lib/components/shared/three/ui/KoreanButton.js.map +1 -1
  349. package/lib/components/shared/three/ui/KoreanPanel.d.ts.map +1 -1
  350. package/lib/components/shared/three/ui/KoreanPanel.js.map +1 -1
  351. package/lib/components/shared/three/ui/KoreanText.d.ts.map +1 -1
  352. package/lib/components/shared/three/ui/KoreanText.js.map +1 -1
  353. package/lib/components/shared/three/ui/MenuList.d.ts.map +1 -1
  354. package/lib/components/shared/three/ui/MenuList.js.map +1 -1
  355. package/lib/components/shared/three/ui/PlayerHUD.d.ts.map +1 -1
  356. package/lib/components/shared/three/ui/PlayerHUD.js.map +1 -1
  357. package/lib/components/shared/three/ui/ProgressBar.d.ts.map +1 -1
  358. package/lib/components/shared/three/ui/ProgressBar.js.map +1 -1
  359. package/lib/components/shared/three/ui/SpeedIndicatorHUD.d.ts +0 -1
  360. package/lib/components/shared/three/ui/SpeedIndicatorHUD.d.ts.map +1 -1
  361. package/lib/components/shared/three/ui/SpeedIndicatorHUD.js +0 -1
  362. package/lib/components/shared/three/ui/SpeedIndicatorHUD.js.map +1 -1
  363. package/lib/components/shared/three/ui/StaminaBar.d.ts.map +1 -1
  364. package/lib/components/shared/three/ui/StaminaBar.js.map +1 -1
  365. package/lib/components/shared/three/ui/TechniqueBar.d.ts.map +1 -1
  366. package/lib/components/shared/three/ui/TechniqueBar.js.map +1 -1
  367. package/lib/components/shared/three/ui/TechniqueBarContainer.d.ts.map +1 -1
  368. package/lib/components/shared/three/ui/TechniqueCard.d.ts.map +1 -1
  369. package/lib/components/shared/three/ui/TechniqueCard.js.map +1 -1
  370. package/lib/components/shared/three/ui/VitalPointOverlayControlsHtml.d.ts.map +1 -1
  371. package/lib/components/shared/three/ui/VitalPointOverlayControlsHtml.js.map +1 -1
  372. package/lib/components/shared/three/ui/VulnerabilityWindowHUD.d.ts.map +1 -1
  373. package/lib/components/shared/ui/BaseHUDContainer.d.ts.map +1 -1
  374. package/lib/components/shared/ui/BaseHUDContainer.js.map +1 -1
  375. package/lib/components/shared/ui/CombatTimer.d.ts.map +1 -1
  376. package/lib/components/shared/ui/CombatTimer.js.map +1 -1
  377. package/lib/components/shared/ui/ErrorBoundary.d.ts.map +1 -1
  378. package/lib/components/shared/ui/ErrorModal.d.ts.map +1 -1
  379. package/lib/components/shared/ui/ErrorModal.js.map +1 -1
  380. package/lib/components/shared/ui/HUDSection.d.ts.map +1 -1
  381. package/lib/components/shared/ui/LoadingState.d.ts.map +1 -1
  382. package/lib/components/shared/ui/LoadingState.js.map +1 -1
  383. package/lib/components/shared/ui/MobileHUDLayout.d.ts +0 -1
  384. package/lib/components/shared/ui/MobileHUDLayout.d.ts.map +1 -1
  385. package/lib/components/shared/ui/ResponsiveContainer.d.ts +0 -1
  386. package/lib/components/shared/ui/ResponsiveContainer.d.ts.map +1 -1
  387. package/lib/components/shared/ui/SplashScreen.d.ts.map +1 -1
  388. package/lib/components/shared/ui/SplashScreen.js +2 -2
  389. package/lib/components/shared/ui/SplashScreen.js.map +1 -1
  390. package/lib/components/shared/ui/StyledHUDPanel.d.ts.map +1 -1
  391. package/lib/components/shared/ui/VitalPointOverlayControlsPure.d.ts.map +1 -1
  392. package/lib/components/shared/ui/VitalPointOverlayControlsPure.js.map +1 -1
  393. package/lib/components/shared/ui/VolumeControl.d.ts.map +1 -1
  394. package/lib/components/shared/ui/VolumeControl.js.map +1 -1
  395. package/lib/components/shared/ui/shared/ConfirmDialog.d.ts.map +1 -1
  396. package/lib/components/shared/ui/shared/ConfirmDialog.js.map +1 -1
  397. package/lib/components/test/Hello3D.d.ts.map +1 -1
  398. package/lib/components/ui/combat/BalanceIndicatorOverlayHtml.d.ts.map +1 -1
  399. package/lib/components/ui/combat/BalanceIndicatorOverlayHtml.js.map +1 -1
  400. package/lib/components/ui/combat/ComboCounter.d.ts.map +1 -1
  401. package/lib/components/ui/combat/PressureMeter.d.ts.map +1 -1
  402. package/lib/systems/CombatSystem.d.ts +0 -6
  403. package/lib/systems/CombatSystem.d.ts.map +1 -1
  404. package/lib/systems/CombatSystem.js +0 -6
  405. package/lib/systems/CombatSystem.js.map +1 -1
  406. package/lib/systems/EffectCalculator.d.ts +0 -7
  407. package/lib/systems/EffectCalculator.d.ts.map +1 -1
  408. package/lib/systems/EffectCalculator.js +0 -4
  409. package/lib/systems/EffectCalculator.js.map +1 -1
  410. package/lib/systems/LayoutSystem.d.ts +0 -1
  411. package/lib/systems/LayoutSystem.d.ts.map +1 -1
  412. package/lib/systems/LayoutSystem.js +0 -1
  413. package/lib/systems/LayoutSystem.js.map +1 -1
  414. package/lib/systems/PlayerEffectManager.d.ts +0 -10
  415. package/lib/systems/PlayerEffectManager.d.ts.map +1 -1
  416. package/lib/systems/PlayerEffectManager.js +0 -3
  417. package/lib/systems/PlayerEffectManager.js.map +1 -1
  418. package/lib/systems/ResponsiveScaling.d.ts +0 -12
  419. package/lib/systems/ResponsiveScaling.d.ts.map +1 -1
  420. package/lib/systems/ResponsiveScaling.js +0 -12
  421. package/lib/systems/ResponsiveScaling.js.map +1 -1
  422. package/lib/systems/TrigramSystem.d.ts +0 -13
  423. package/lib/systems/TrigramSystem.d.ts.map +1 -1
  424. package/lib/systems/TrigramSystem.js +0 -13
  425. package/lib/systems/TrigramSystem.js.map +1 -1
  426. package/lib/systems/VitalPointSystem.d.ts +0 -10
  427. package/lib/systems/VitalPointSystem.d.ts.map +1 -1
  428. package/lib/systems/VitalPointSystem.js +0 -10
  429. package/lib/systems/VitalPointSystem.js.map +1 -1
  430. package/lib/systems/animation/builders/KeyframeInterpolation.d.ts +0 -4
  431. package/lib/systems/animation/builders/KeyframeInterpolation.d.ts.map +1 -1
  432. package/lib/systems/animation/builders/KeyframeInterpolation.js +0 -1
  433. package/lib/systems/animation/builders/KeyframeInterpolation.js.map +1 -1
  434. package/lib/systems/animation/builders/SkeletonRig.d.ts +0 -4
  435. package/lib/systems/animation/builders/SkeletonRig.d.ts.map +1 -1
  436. package/lib/systems/animation/builders/SkeletonRig.js +0 -3
  437. package/lib/systems/animation/builders/SkeletonRig.js.map +1 -1
  438. package/lib/systems/animation/catalogs/RecoveryAnimations.d.ts +0 -5
  439. package/lib/systems/animation/catalogs/RecoveryAnimations.d.ts.map +1 -1
  440. package/lib/systems/animation/catalogs/RecoveryAnimations.js +0 -5
  441. package/lib/systems/animation/catalogs/RecoveryAnimations.js.map +1 -1
  442. package/lib/systems/animation/core/AnimationHitTiming.d.ts +0 -6
  443. package/lib/systems/animation/core/AnimationHitTiming.d.ts.map +1 -1
  444. package/lib/systems/animation/core/AnimationHitTiming.js +0 -4
  445. package/lib/systems/animation/core/AnimationHitTiming.js.map +1 -1
  446. package/lib/systems/animation/core/AnimationTransitions.d.ts +0 -3
  447. package/lib/systems/animation/core/AnimationTransitions.d.ts.map +1 -1
  448. package/lib/systems/animation/core/AnimationTransitions.js.map +1 -1
  449. package/lib/systems/animation/core/LateralityTransform.d.ts +0 -3
  450. package/lib/systems/animation/core/LateralityTransform.d.ts.map +1 -1
  451. package/lib/systems/animation/core/LateralityTransform.js +0 -1
  452. package/lib/systems/animation/core/LateralityTransform.js.map +1 -1
  453. package/lib/systems/animation/core/RecoveryPhaseEnhancer.d.ts +0 -1
  454. package/lib/systems/animation/core/RecoveryPhaseEnhancer.d.ts.map +1 -1
  455. package/lib/systems/animation/core/RecoveryPhaseEnhancer.js.map +1 -1
  456. package/lib/systems/animation/core/TechniqueAnimationMapper.d.ts +0 -10
  457. package/lib/systems/animation/core/TechniqueAnimationMapper.d.ts.map +1 -1
  458. package/lib/systems/animation/core/TechniqueAnimationMapper.js +0 -8
  459. package/lib/systems/animation/core/TechniqueAnimationMapper.js.map +1 -1
  460. package/lib/systems/animation/core/TrigramAnimationMapping.d.ts +0 -10
  461. package/lib/systems/animation/core/TrigramAnimationMapping.d.ts.map +1 -1
  462. package/lib/systems/animation/core/TrigramStanceTransitions.d.ts +0 -2
  463. package/lib/systems/animation/core/TrigramStanceTransitions.d.ts.map +1 -1
  464. package/lib/systems/animation/core/types.d.ts +0 -39
  465. package/lib/systems/animation/core/types.d.ts.map +1 -1
  466. package/lib/systems/animation/core/types.js +0 -9
  467. package/lib/systems/animation/core/types.js.map +1 -1
  468. package/lib/systems/animation/systems/AdvancedJointMovements.d.ts +0 -27
  469. package/lib/systems/animation/systems/AdvancedJointMovements.d.ts.map +1 -1
  470. package/lib/systems/animation/systems/AdvancedJointMovements.js +0 -1
  471. package/lib/systems/animation/systems/AdvancedJointMovements.js.map +1 -1
  472. package/lib/systems/animation/systems/BodyFacingSystem.d.ts +0 -19
  473. package/lib/systems/animation/systems/BodyFacingSystem.d.ts.map +1 -1
  474. package/lib/systems/animation/systems/BodyFacingSystem.js +0 -14
  475. package/lib/systems/animation/systems/BodyFacingSystem.js.map +1 -1
  476. package/lib/systems/animation/systems/FacialExpressions.d.ts +0 -10
  477. package/lib/systems/animation/systems/FacialExpressions.d.ts.map +1 -1
  478. package/lib/systems/animation/systems/FacialExpressions.js +0 -2
  479. package/lib/systems/animation/systems/FacialExpressions.js.map +1 -1
  480. package/lib/systems/animation/systems/FallAnimations.d.ts +0 -4
  481. package/lib/systems/animation/systems/FallAnimations.d.ts.map +1 -1
  482. package/lib/systems/animation/systems/FallAnimations.js +0 -2
  483. package/lib/systems/animation/systems/FallAnimations.js.map +1 -1
  484. package/lib/systems/animation/systems/HeadMovements.d.ts +0 -10
  485. package/lib/systems/animation/systems/HeadMovements.d.ts.map +1 -1
  486. package/lib/systems/bodypart/BodyPartDamageIntegration.d.ts +0 -7
  487. package/lib/systems/bodypart/BodyPartDamageIntegration.d.ts.map +1 -1
  488. package/lib/systems/bodypart/BodyPartDamageIntegration.js +0 -7
  489. package/lib/systems/bodypart/BodyPartDamageIntegration.js.map +1 -1
  490. package/lib/systems/bodypart/BodyPartHealthSystem.d.ts +0 -13
  491. package/lib/systems/bodypart/BodyPartHealthSystem.d.ts.map +1 -1
  492. package/lib/systems/bodypart/BodyPartHealthSystem.js +0 -13
  493. package/lib/systems/bodypart/BodyPartHealthSystem.js.map +1 -1
  494. package/lib/systems/bodypart/BodyPartPositionMapping.d.ts +0 -6
  495. package/lib/systems/bodypart/BodyPartPositionMapping.d.ts.map +1 -1
  496. package/lib/systems/bodypart/BodyPartPositionMapping.js +0 -6
  497. package/lib/systems/bodypart/BodyPartPositionMapping.js.map +1 -1
  498. package/lib/systems/bodypart/CombatInjuryIntegration.d.ts +0 -10
  499. package/lib/systems/bodypart/CombatInjuryIntegration.d.ts.map +1 -1
  500. package/lib/systems/bodypart/CombatInjuryIntegration.js +0 -8
  501. package/lib/systems/bodypart/CombatInjuryIntegration.js.map +1 -1
  502. package/lib/systems/bodypart/InjuryIntegration.d.ts +0 -2
  503. package/lib/systems/bodypart/InjuryIntegration.d.ts.map +1 -1
  504. package/lib/systems/bodypart/InjuryIntegration.js +0 -2
  505. package/lib/systems/bodypart/InjuryIntegration.js.map +1 -1
  506. package/lib/systems/bodypart/InjuryTracker.d.ts +0 -14
  507. package/lib/systems/bodypart/InjuryTracker.d.ts.map +1 -1
  508. package/lib/systems/bodypart/InjuryTracker.js +0 -12
  509. package/lib/systems/bodypart/InjuryTracker.js.map +1 -1
  510. package/lib/systems/bodypart/MovementPenaltySystem.d.ts +0 -8
  511. package/lib/systems/bodypart/MovementPenaltySystem.d.ts.map +1 -1
  512. package/lib/systems/bodypart/MovementPenaltySystem.js +0 -8
  513. package/lib/systems/bodypart/MovementPenaltySystem.js.map +1 -1
  514. package/lib/systems/bodypart/PlayerInjuryTrackingManager.d.ts +0 -8
  515. package/lib/systems/bodypart/PlayerInjuryTrackingManager.d.ts.map +1 -1
  516. package/lib/systems/bodypart/PlayerInjuryTrackingManager.js +0 -8
  517. package/lib/systems/bodypart/PlayerInjuryTrackingManager.js.map +1 -1
  518. package/lib/systems/bodypart/types.d.ts +0 -13
  519. package/lib/systems/bodypart/types.d.ts.map +1 -1
  520. package/lib/systems/bodypart/types.js +0 -5
  521. package/lib/systems/bodypart/types.js.map +1 -1
  522. package/lib/systems/breathing/BreathingDisruptionSystem.d.ts +0 -3
  523. package/lib/systems/breathing/BreathingDisruptionSystem.d.ts.map +1 -1
  524. package/lib/systems/breathing/BreathingDisruptionSystem.js +0 -2
  525. package/lib/systems/breathing/BreathingDisruptionSystem.js.map +1 -1
  526. package/lib/systems/combat/BalanceSystem.d.ts +0 -25
  527. package/lib/systems/combat/BalanceSystem.d.ts.map +1 -1
  528. package/lib/systems/combat/BalanceSystem.js +0 -25
  529. package/lib/systems/combat/BalanceSystem.js.map +1 -1
  530. package/lib/systems/combat/BreakingStatusEffects.d.ts +0 -4
  531. package/lib/systems/combat/BreakingStatusEffects.d.ts.map +1 -1
  532. package/lib/systems/combat/BreakingStatusEffects.js +0 -3
  533. package/lib/systems/combat/BreakingStatusEffects.js.map +1 -1
  534. package/lib/systems/combat/CombatStateSystem.d.ts +0 -9
  535. package/lib/systems/combat/CombatStateSystem.d.ts.map +1 -1
  536. package/lib/systems/combat/CombatStateSystem.js +0 -9
  537. package/lib/systems/combat/CombatStateSystem.js.map +1 -1
  538. package/lib/systems/combat/ConsciousnessSystem.d.ts +0 -16
  539. package/lib/systems/combat/ConsciousnessSystem.d.ts.map +1 -1
  540. package/lib/systems/combat/ConsciousnessSystem.js +0 -16
  541. package/lib/systems/combat/ConsciousnessSystem.js.map +1 -1
  542. package/lib/systems/combat/FallIntegration.d.ts +0 -3
  543. package/lib/systems/combat/FallIntegration.d.ts.map +1 -1
  544. package/lib/systems/combat/FallIntegration.js +0 -3
  545. package/lib/systems/combat/FallIntegration.js.map +1 -1
  546. package/lib/systems/combat/GrappleSystem.d.ts +0 -2
  547. package/lib/systems/combat/GrappleSystem.d.ts.map +1 -1
  548. package/lib/systems/combat/GrappleSystem.js +0 -2
  549. package/lib/systems/combat/GrappleSystem.js.map +1 -1
  550. package/lib/systems/combat/LimbExposureSystem.d.ts +0 -7
  551. package/lib/systems/combat/LimbExposureSystem.d.ts.map +1 -1
  552. package/lib/systems/combat/LimbExposureSystem.js +0 -7
  553. package/lib/systems/combat/LimbExposureSystem.js.map +1 -1
  554. package/lib/systems/combat/PainResponseSystem.d.ts +0 -11
  555. package/lib/systems/combat/PainResponseSystem.d.ts.map +1 -1
  556. package/lib/systems/combat/PainResponseSystem.js +0 -11
  557. package/lib/systems/combat/PainResponseSystem.js.map +1 -1
  558. package/lib/systems/combat/painConsciousnessUtils.d.ts +0 -7
  559. package/lib/systems/combat/painConsciousnessUtils.d.ts.map +1 -1
  560. package/lib/systems/combat/painConsciousnessUtils.js +0 -7
  561. package/lib/systems/combat/painConsciousnessUtils.js.map +1 -1
  562. package/lib/systems/effects.d.ts +11 -0
  563. package/lib/systems/effects.d.ts.map +1 -1
  564. package/lib/systems/effects.js +10 -0
  565. package/lib/systems/effects.js.map +1 -1
  566. package/lib/systems/game.d.ts +16 -0
  567. package/lib/systems/game.d.ts.map +1 -1
  568. package/lib/systems/game.js +1 -0
  569. package/lib/systems/game.js.map +1 -1
  570. package/lib/systems/index.d.ts +5 -1
  571. package/lib/systems/index.d.ts.map +1 -1
  572. package/lib/systems/index.js.map +1 -1
  573. package/lib/systems/movement/InjuryMovementModifier.d.ts +0 -10
  574. package/lib/systems/movement/InjuryMovementModifier.d.ts.map +1 -1
  575. package/lib/systems/movement/InjuryMovementModifier.js +0 -7
  576. package/lib/systems/movement/InjuryMovementModifier.js.map +1 -1
  577. package/lib/systems/movement/integration.d.ts +0 -3
  578. package/lib/systems/movement/integration.d.ts.map +1 -1
  579. package/lib/systems/movement/integration.js +0 -3
  580. package/lib/systems/movement/integration.js.map +1 -1
  581. package/lib/systems/physics/AttackMovementPhysics.d.ts +0 -9
  582. package/lib/systems/physics/AttackMovementPhysics.d.ts.map +1 -1
  583. package/lib/systems/physics/AttackMovementPhysics.js +0 -7
  584. package/lib/systems/physics/AttackMovementPhysics.js.map +1 -1
  585. package/lib/systems/physics/CollisionDetection.d.ts +0 -6
  586. package/lib/systems/physics/CollisionDetection.d.ts.map +1 -1
  587. package/lib/systems/physics/CollisionDetection.js +0 -6
  588. package/lib/systems/physics/CollisionDetection.js.map +1 -1
  589. package/lib/systems/physics/CoordinateMapper.d.ts +0 -1
  590. package/lib/systems/physics/CoordinateMapper.d.ts.map +1 -1
  591. package/lib/systems/physics/CoordinateMapper.js +0 -1
  592. package/lib/systems/physics/CoordinateMapper.js.map +1 -1
  593. package/lib/systems/physics/KnockbackPhysics.d.ts +0 -11
  594. package/lib/systems/physics/KnockbackPhysics.d.ts.map +1 -1
  595. package/lib/systems/physics/KnockbackPhysics.js +0 -8
  596. package/lib/systems/physics/KnockbackPhysics.js.map +1 -1
  597. package/lib/systems/physics/MovementPhysics.d.ts +0 -10
  598. package/lib/systems/physics/MovementPhysics.d.ts.map +1 -1
  599. package/lib/systems/physics/MovementPhysics.js +0 -8
  600. package/lib/systems/physics/MovementPhysics.js.map +1 -1
  601. package/lib/systems/physics/PhysicalReachCalculator.d.ts +0 -6
  602. package/lib/systems/physics/PhysicalReachCalculator.d.ts.map +1 -1
  603. package/lib/systems/physics/PhysicalReachCalculator.js +0 -5
  604. package/lib/systems/physics/PhysicalReachCalculator.js.map +1 -1
  605. package/lib/systems/physics/SpeedModifierSystem.d.ts +0 -5
  606. package/lib/systems/physics/SpeedModifierSystem.d.ts.map +1 -1
  607. package/lib/systems/physics/SpeedModifierSystem.js +0 -4
  608. package/lib/systems/physics/SpeedModifierSystem.js.map +1 -1
  609. package/lib/systems/player.d.ts +0 -5
  610. package/lib/systems/player.d.ts.map +1 -1
  611. package/lib/systems/trigram/TrigramCalculator.d.ts +0 -1
  612. package/lib/systems/trigram/TrigramCalculator.d.ts.map +1 -1
  613. package/lib/systems/trigram/TrigramCalculator.js +0 -1
  614. package/lib/systems/trigram/TrigramCalculator.js.map +1 -1
  615. package/lib/systems/trigram/types.d.ts +0 -4
  616. package/lib/systems/trigram/types.d.ts.map +1 -1
  617. package/lib/systems/trigram/types.js +0 -2
  618. package/lib/systems/trigram/types.js.map +1 -1
  619. package/lib/systems/types.d.ts +7 -2
  620. package/lib/systems/types.d.ts.map +1 -1
  621. package/lib/systems/types.js.map +1 -1
  622. package/lib/systems/vitalpoint/DamageCalculator.d.ts +0 -3
  623. package/lib/systems/vitalpoint/DamageCalculator.d.ts.map +1 -1
  624. package/lib/systems/vitalpoint/DamageCalculator.js +0 -3
  625. package/lib/systems/vitalpoint/DamageCalculator.js.map +1 -1
  626. package/lib/systems/vitalpoint/KoreanVitalPoints.d.ts +0 -8
  627. package/lib/systems/vitalpoint/KoreanVitalPoints.d.ts.map +1 -1
  628. package/lib/systems/vitalpoint/KoreanVitalPoints.js +0 -8
  629. package/lib/systems/vitalpoint/KoreanVitalPoints.js.map +1 -1
  630. package/lib/systems/vitalpoint/VitalPointsData.d.ts +0 -3
  631. package/lib/systems/vitalpoint/VitalPointsData.d.ts.map +1 -1
  632. package/lib/systems/vitalpoint/VitalPointsData.js +0 -1
  633. package/lib/systems/vitalpoint/VitalPointsData.js.map +1 -1
  634. package/lib/types/PhysicsTypes.d.ts +21 -78
  635. package/lib/types/PhysicsTypes.d.ts.map +1 -1
  636. package/lib/types/PhysicsTypes.js +17 -63
  637. package/lib/types/PhysicsTypes.js.map +1 -1
  638. package/lib/types/clothing.d.ts +0 -9
  639. package/lib/types/clothing.d.ts.map +1 -1
  640. package/lib/types/constants/animations.d.ts +35 -1
  641. package/lib/types/constants/animations.d.ts.map +1 -1
  642. package/lib/types/constants/animations.js +12 -1
  643. package/lib/types/constants/animations.js.map +1 -1
  644. package/lib/types/constants/colors.d.ts +28 -2
  645. package/lib/types/constants/colors.d.ts.map +1 -1
  646. package/lib/types/constants/colors.js +30 -4
  647. package/lib/types/constants/colors.js.map +1 -1
  648. package/lib/types/constants/index.d.ts +5 -1
  649. package/lib/types/constants/index.d.ts.map +1 -1
  650. package/lib/types/constants/index.js.map +1 -1
  651. package/lib/types/constants/performance.d.ts +0 -2
  652. package/lib/types/constants/performance.d.ts.map +1 -1
  653. package/lib/types/constants/performance.js +0 -2
  654. package/lib/types/constants/performance.js.map +1 -1
  655. package/lib/types/constants/typography.d.ts +40 -2
  656. package/lib/types/constants/typography.d.ts.map +1 -1
  657. package/lib/types/constants/typography.js +40 -2
  658. package/lib/types/constants/typography.js.map +1 -1
  659. package/lib/types/constants/ui.d.ts +89 -1
  660. package/lib/types/constants/ui.d.ts.map +1 -1
  661. package/lib/types/constants/ui.js +33 -1
  662. package/lib/types/constants/ui.js.map +1 -1
  663. package/lib/types/facial.d.ts +0 -15
  664. package/lib/types/facial.d.ts.map +1 -1
  665. package/lib/types/facial.js +0 -8
  666. package/lib/types/facial.js.map +1 -1
  667. package/lib/types/hand-animation.d.ts +34 -147
  668. package/lib/types/hand-animation.d.ts.map +1 -1
  669. package/lib/types/hand-animation.js +0 -2
  670. package/lib/types/hand-animation.js.map +1 -1
  671. package/lib/types/injury.d.ts +0 -2
  672. package/lib/types/injury.d.ts.map +1 -1
  673. package/lib/types/injury.js +0 -1
  674. package/lib/types/injury.js.map +1 -1
  675. package/lib/types/physics.d.ts +0 -21
  676. package/lib/types/physics.d.ts.map +1 -1
  677. package/lib/types/physics.js +0 -6
  678. package/lib/types/physics.js.map +1 -1
  679. package/lib/types/physicsConstants.d.ts +0 -12
  680. package/lib/types/physicsConstants.d.ts.map +1 -1
  681. package/lib/types/physicsConstants.js +0 -12
  682. package/lib/types/physicsConstants.js.map +1 -1
  683. package/lib/types/player-visual.d.ts +45 -189
  684. package/lib/types/player-visual.d.ts.map +1 -1
  685. package/lib/types/technique.d.ts +1 -5
  686. package/lib/types/technique.d.ts.map +1 -1
  687. package/lib/types/techniqueId.d.ts +0 -1
  688. package/lib/types/techniqueId.d.ts.map +1 -1
  689. package/lib/types/techniqueId.js +0 -1
  690. package/lib/types/techniqueId.js.map +1 -1
  691. package/lib/utils/arenaWorldDimensions.d.ts +0 -11
  692. package/lib/utils/arenaWorldDimensions.d.ts.map +1 -1
  693. package/lib/utils/arenaWorldDimensions.js +0 -6
  694. package/lib/utils/arenaWorldDimensions.js.map +1 -1
  695. package/lib/utils/controlMapping.d.ts +3 -4
  696. package/lib/utils/controlMapping.d.ts.map +1 -1
  697. package/lib/utils/controlMapping.js +1 -2
  698. package/lib/utils/controlMapping.js.map +1 -1
  699. package/lib/utils/deviceDetection.d.ts +0 -5
  700. package/lib/utils/deviceDetection.d.ts.map +1 -1
  701. package/lib/utils/deviceDetection.js +0 -5
  702. package/lib/utils/deviceDetection.js.map +1 -1
  703. package/lib/utils/hapticFeedback.d.ts +23 -95
  704. package/lib/utils/hapticFeedback.d.ts.map +1 -1
  705. package/lib/utils/hapticFeedback.js +9 -39
  706. package/lib/utils/hapticFeedback.js.map +1 -1
  707. package/lib/utils/haptics.d.ts +0 -3
  708. package/lib/utils/haptics.d.ts.map +1 -1
  709. package/lib/utils/haptics.js +0 -1
  710. package/lib/utils/haptics.js.map +1 -1
  711. package/lib/utils/math.d.ts +0 -3
  712. package/lib/utils/math.d.ts.map +1 -1
  713. package/lib/utils/math.js +0 -2
  714. package/lib/utils/math.js.map +1 -1
  715. package/lib/utils/mobileLayoutHelpers.d.ts +0 -3
  716. package/lib/utils/mobileLayoutHelpers.d.ts.map +1 -1
  717. package/lib/utils/mobileLayoutHelpers.js +0 -1
  718. package/lib/utils/mobileLayoutHelpers.js.map +1 -1
  719. package/lib/utils/mobileUIUtils.d.ts +5 -100
  720. package/lib/utils/mobileUIUtils.d.ts.map +1 -1
  721. package/lib/utils/mobileUIUtils.js +0 -9
  722. package/lib/utils/mobileUIUtils.js.map +1 -1
  723. package/lib/utils/physicalAttributeValidation.d.ts.map +1 -1
  724. package/lib/utils/player3DHelpers.d.ts.map +1 -1
  725. package/lib/utils/player3DHelpers.js.map +1 -1
  726. package/lib/utils/responsiveLayoutHelpers.d.ts +0 -65
  727. package/lib/utils/responsiveLayoutHelpers.d.ts.map +1 -1
  728. package/lib/utils/responsiveLayoutHelpers.js +0 -65
  729. package/lib/utils/responsiveLayoutHelpers.js.map +1 -1
  730. package/lib/utils/responsiveOrientationConstants.d.ts +0 -7
  731. package/lib/utils/responsiveOrientationConstants.d.ts.map +1 -1
  732. package/lib/utils/responsiveOrientationConstants.js +0 -7
  733. package/lib/utils/responsiveOrientationConstants.js.map +1 -1
  734. package/lib/utils/safeAreaUtils.d.ts +0 -6
  735. package/lib/utils/safeAreaUtils.d.ts.map +1 -1
  736. package/lib/utils/safeAreaUtils.js +0 -2
  737. package/lib/utils/safeAreaUtils.js.map +1 -1
  738. package/lib/utils/sharedPhysicsConfig.d.ts +0 -4
  739. package/lib/utils/sharedPhysicsConfig.d.ts.map +1 -1
  740. package/lib/utils/sharedPhysicsConfig.js +0 -2
  741. package/lib/utils/sharedPhysicsConfig.js.map +1 -1
  742. package/lib/utils/skeletonScaling.d.ts +0 -9
  743. package/lib/utils/skeletonScaling.d.ts.map +1 -1
  744. package/lib/utils/skeletonScaling.js +0 -1
  745. package/lib/utils/skeletonScaling.js.map +1 -1
  746. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"PerformanceRatingOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/PerformanceRatingOverlayHtml.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { MatchStatistics } from \"../../../../systems/combat\";\nimport {\n FONT_FAMILY,\n KOREAN_COLORS,\n PERFORMANCE_RATING_THRESHOLDS,\n} from \"../../../../types/constants\";\nimport { hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { pulseAnimation } from \"./animations\";\n\nexport interface PerformanceRatingProps {\n readonly matchStats: MatchStatistics;\n readonly isMobile: boolean;\n readonly isTablet: boolean;\n}\n\n/**\n * Helper to convert hex color to CSS string\n */\nconst toCssColor = (hex: number): string => hexToRgbaString(hex, 1);\n\n/**\n * Calculate performance score based on match statistics\n * Score ranges from 0-100 based on combat effectiveness\n */\nfunction calculatePerformanceScore(stats: MatchStatistics): number {\n const winnerStats = stats.winner === 0 ? stats.player1 : stats.player2;\n\n // Calculate accuracy based on offensive performance only\n // Use a normalized scale: higher hits landed = better accuracy\n const accuracy = Math.min((winnerStats.hitsLanded / 10) * 100, 100);\n\n // Calculate damage efficiency (damage dealt / damage taken ratio)\n // Perfect defense (no damage taken) gets bonus ratio\n const damageRatio =\n winnerStats.totalDamageReceived > 0\n ? winnerStats.totalDamageDealt / winnerStats.totalDamageReceived\n : winnerStats.totalDamageDealt > 0\n ? 2\n : 0;\n const damageScore = Math.min(damageRatio * 30, 30); // Max 30 points\n\n // Perfect strikes and vital point hits bonus\n const precisionBonus =\n winnerStats.perfectStrikes * 5 + winnerStats.vitalPointHits * 3;\n const precisionScore = Math.min(precisionBonus, 25); // Max 25 points\n\n // Speed bonus (shorter match duration is better)\n const speedScore =\n stats.matchDuration < 60 ? 15 : stats.matchDuration < 120 ? 10 : 5;\n\n // Combine scores\n const totalScore = accuracy * 0.3 + damageScore + precisionScore + speedScore;\n\n return Math.min(Math.round(totalScore), 100);\n}\n\n/**\n * Get performance rating based on score\n */\nfunction getPerformanceRating(\n score: number\n): keyof typeof PERFORMANCE_RATING_THRESHOLDS {\n if (score >= PERFORMANCE_RATING_THRESHOLDS.S.minScore) return \"S\";\n if (score >= PERFORMANCE_RATING_THRESHOLDS.A.minScore) return \"A\";\n if (score >= PERFORMANCE_RATING_THRESHOLDS.B.minScore) return \"B\";\n return \"C\";\n}\n\n/**\n * Performance Rating Component\n * Displays S/A/B/C ranking based on combat performance\n */\nexport const PerformanceRating: React.FC<PerformanceRatingProps> = ({\n matchStats,\n isMobile,\n isTablet,\n}) => {\n const ratingFontSize = isMobile ? 36 : isTablet ? 48 : 56;\n const labelFontSize = isMobile ? 12 : isTablet ? 14 : 15;\n const scoreFontSize = isMobile ? 18 : isTablet ? 20 : 24;\n const padding = isMobile ? 10 : isTablet ? 12 : 15;\n\n const performanceScore = useMemo(\n () => calculatePerformanceScore(matchStats),\n [matchStats]\n );\n\n const rating = useMemo(\n () => getPerformanceRating(performanceScore),\n [performanceScore]\n );\n\n const ratingInfo = PERFORMANCE_RATING_THRESHOLDS[rating];\n\n // Extract winner stats for clarity\n const winnerStats = useMemo(\n () => (matchStats.winner === 0 ? matchStats.player1 : matchStats.player2),\n [matchStats]\n );\n\n return (\n <div\n data-testid=\"performance-rating\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_DARK, 0.9),\n border: `3px solid ${hexToRgbaString(ratingInfo.color, 0.8)}`,\n borderRadius: \"16px\",\n padding: padding,\n marginBottom: padding / 2,\n minWidth: isMobile ? \"260px\" : \"300px\",\n boxShadow: `0 0 30px ${hexToRgbaString(ratingInfo.color, 0.3)}`,\n animation: \"ratingPulse 2s ease-in-out infinite\",\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: labelFontSize,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding / 2,\n textTransform: \"uppercase\",\n letterSpacing: \"0.1em\",\n }}\n data-testid=\"rating-label\"\n >\n 전투 등급 | Performance Rating\n </div>\n\n {/* Rating Letter */}\n <div\n style={{\n fontSize: ratingFontSize,\n fontWeight: \"bold\",\n color: toCssColor(ratingInfo.color),\n fontFamily: FONT_FAMILY.KOREAN,\n textShadow: `0 0 20px ${hexToRgbaString(ratingInfo.color, 0.6)}`,\n marginBottom: padding / 2,\n animation: \"ratingGlow 1.5s ease-in-out infinite\",\n }}\n data-testid=\"rating-letter\"\n >\n {rating}\n </div>\n\n {/* Rating Description */}\n <div\n style={{\n fontSize: labelFontSize,\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding,\n textAlign: \"center\",\n }}\n data-testid=\"rating-description\"\n >\n {ratingInfo.description.korean} | {ratingInfo.description.english}\n </div>\n\n {/* Performance Score */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n width: \"100%\",\n padding: padding,\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_MEDIUM, 0.4),\n borderRadius: \"8px\",\n }}\n >\n <div\n style={{\n fontSize: scoreFontSize,\n fontWeight: \"bold\",\n color: toCssColor(ratingInfo.color),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding / 4,\n }}\n data-testid=\"performance-score\"\n >\n {performanceScore}\n </div>\n <div\n style={{\n fontSize: labelFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_TERTIARY),\n fontFamily: FONT_FAMILY.KOREAN,\n }}\n >\n 전투 점수 | Combat Score\n </div>\n\n {/* Score Breakdown */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: padding / 2,\n marginTop: padding,\n width: \"100%\",\n fontSize: labelFontSize - 4,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n }}\n data-testid=\"score-breakdown\"\n >\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.ACCENT_GOLD),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.perfectStrikes ?? 0}\n </div>\n <div>완벽 | Perfect</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.VITAL_POINT_HIT),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.vitalPointHits ?? 0}\n </div>\n <div>급소 | Vital Hits</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.techniques?.length ?? 0}\n </div>\n <div>기술 | Techniques</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.CRITICAL_HIT),\n fontWeight: \"bold\",\n }}\n >\n {matchStats.criticalHits}\n </div>\n <div>치명타 | Criticals</div>\n </div>\n </div>\n </div>\n\n {/* CSS Animations */}\n <style>{`\n ${pulseAnimation}\n\n @keyframes ratingGlow {\n 0%, 100% {\n text-shadow: 0 0 20px ${hexToRgbaString(ratingInfo.color, 0.6)};\n }\n 50% {\n text-shadow: 0 0 30px ${hexToRgbaString(\n ratingInfo.color,\n 0.9\n )}, 0 0 50px ${hexToRgbaString(ratingInfo.color, 0.5)};\n }\n }\n `}</style>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"PerformanceRatingOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/PerformanceRatingOverlayHtml.tsx"],"sourcesContent":["import React, { useMemo } from \"react\";\nimport { MatchStatistics } from \"../../../../systems/combat\";\nimport {\n FONT_FAMILY,\n KOREAN_COLORS,\n PERFORMANCE_RATING_THRESHOLDS,\n} from \"../../../../types/constants\";\nimport { hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { pulseAnimation } from \"./animations\";\n\nexport interface PerformanceRatingProps {\n readonly matchStats: MatchStatistics;\n readonly isMobile: boolean;\n readonly isTablet: boolean;\n}\n\n/**\n * Helper to convert hex color to CSS string\n */\nconst toCssColor = (hex: number): string => hexToRgbaString(hex, 1);\n\n/**\n * Calculate performance score based on match statistics\n * Score ranges from 0-100 based on combat effectiveness\n */\nfunction calculatePerformanceScore(stats: MatchStatistics): number {\n const winnerStats = stats.winner === 0 ? stats.player1 : stats.player2;\n\n const accuracy = Math.min((winnerStats.hitsLanded / 10) * 100, 100);\n\n const damageRatio =\n winnerStats.totalDamageReceived > 0\n ? winnerStats.totalDamageDealt / winnerStats.totalDamageReceived\n : winnerStats.totalDamageDealt > 0\n ? 2\n : 0;\n const damageScore = Math.min(damageRatio * 30, 30); // Max 30 points\n\n const precisionBonus =\n winnerStats.perfectStrikes * 5 + winnerStats.vitalPointHits * 3;\n const precisionScore = Math.min(precisionBonus, 25); // Max 25 points\n\n const speedScore =\n stats.matchDuration < 60 ? 15 : stats.matchDuration < 120 ? 10 : 5;\n\n const totalScore = accuracy * 0.3 + damageScore + precisionScore + speedScore;\n\n return Math.min(Math.round(totalScore), 100);\n}\n\n/**\n * Get performance rating based on score\n */\nfunction getPerformanceRating(\n score: number\n): keyof typeof PERFORMANCE_RATING_THRESHOLDS {\n if (score >= PERFORMANCE_RATING_THRESHOLDS.S.minScore) return \"S\";\n if (score >= PERFORMANCE_RATING_THRESHOLDS.A.minScore) return \"A\";\n if (score >= PERFORMANCE_RATING_THRESHOLDS.B.minScore) return \"B\";\n return \"C\";\n}\n\n/**\n * Performance Rating Component\n * Displays S/A/B/C ranking based on combat performance\n */\nexport const PerformanceRating: React.FC<PerformanceRatingProps> = ({\n matchStats,\n isMobile,\n isTablet,\n}) => {\n const ratingFontSize = isMobile ? 36 : isTablet ? 48 : 56;\n const labelFontSize = isMobile ? 12 : isTablet ? 14 : 15;\n const scoreFontSize = isMobile ? 18 : isTablet ? 20 : 24;\n const padding = isMobile ? 10 : isTablet ? 12 : 15;\n\n const performanceScore = useMemo(\n () => calculatePerformanceScore(matchStats),\n [matchStats]\n );\n\n const rating = useMemo(\n () => getPerformanceRating(performanceScore),\n [performanceScore]\n );\n\n const ratingInfo = PERFORMANCE_RATING_THRESHOLDS[rating];\n\n const winnerStats = useMemo(\n () => (matchStats.winner === 0 ? matchStats.player1 : matchStats.player2),\n [matchStats]\n );\n\n return (\n <div\n data-testid=\"performance-rating\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_DARK, 0.9),\n border: `3px solid ${hexToRgbaString(ratingInfo.color, 0.8)}`,\n borderRadius: \"16px\",\n padding: padding,\n marginBottom: padding / 2,\n minWidth: isMobile ? \"260px\" : \"300px\",\n boxShadow: `0 0 30px ${hexToRgbaString(ratingInfo.color, 0.3)}`,\n animation: \"ratingPulse 2s ease-in-out infinite\",\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: labelFontSize,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding / 2,\n textTransform: \"uppercase\",\n letterSpacing: \"0.1em\",\n }}\n data-testid=\"rating-label\"\n >\n 전투 등급 | Performance Rating\n </div>\n\n {/* Rating Letter */}\n <div\n style={{\n fontSize: ratingFontSize,\n fontWeight: \"bold\",\n color: toCssColor(ratingInfo.color),\n fontFamily: FONT_FAMILY.KOREAN,\n textShadow: `0 0 20px ${hexToRgbaString(ratingInfo.color, 0.6)}`,\n marginBottom: padding / 2,\n animation: \"ratingGlow 1.5s ease-in-out infinite\",\n }}\n data-testid=\"rating-letter\"\n >\n {rating}\n </div>\n\n {/* Rating Description */}\n <div\n style={{\n fontSize: labelFontSize,\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding,\n textAlign: \"center\",\n }}\n data-testid=\"rating-description\"\n >\n {ratingInfo.description.korean} | {ratingInfo.description.english}\n </div>\n\n {/* Performance Score */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n width: \"100%\",\n padding: padding,\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_MEDIUM, 0.4),\n borderRadius: \"8px\",\n }}\n >\n <div\n style={{\n fontSize: scoreFontSize,\n fontWeight: \"bold\",\n color: toCssColor(ratingInfo.color),\n fontFamily: FONT_FAMILY.KOREAN,\n marginBottom: padding / 4,\n }}\n data-testid=\"performance-score\"\n >\n {performanceScore}\n </div>\n <div\n style={{\n fontSize: labelFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_TERTIARY),\n fontFamily: FONT_FAMILY.KOREAN,\n }}\n >\n 전투 점수 | Combat Score\n </div>\n\n {/* Score Breakdown */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: \"1fr 1fr\",\n gap: padding / 2,\n marginTop: padding,\n width: \"100%\",\n fontSize: labelFontSize - 4,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n }}\n data-testid=\"score-breakdown\"\n >\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.ACCENT_GOLD),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.perfectStrikes ?? 0}\n </div>\n <div>완벽 | Perfect</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.VITAL_POINT_HIT),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.vitalPointHits ?? 0}\n </div>\n <div>급소 | Vital Hits</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n fontWeight: \"bold\",\n }}\n >\n {winnerStats.techniques?.length ?? 0}\n </div>\n <div>기술 | Techniques</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.CRITICAL_HIT),\n fontWeight: \"bold\",\n }}\n >\n {matchStats.criticalHits}\n </div>\n <div>치명타 | Criticals</div>\n </div>\n </div>\n </div>\n\n {/* CSS Animations */}\n <style>{`\n ${pulseAnimation}\n\n @keyframes ratingGlow {\n 0%, 100% {\n text-shadow: 0 0 20px ${hexToRgbaString(ratingInfo.color, 0.6)};\n }\n 50% {\n text-shadow: 0 0 30px ${hexToRgbaString(\n ratingInfo.color,\n 0.9\n )}, 0 0 50px ${hexToRgbaString(ratingInfo.color, 0.5)};\n }\n }\n `}</style>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"VictoryAnimation3D.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/VictoryAnimation3D.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAoTtC,CAAC"}
1
+ {"version":3,"file":"VictoryAnimation3D.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/VictoryAnimation3D.tsx"],"names":[],"mappings":"AACA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAI3D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAmStC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"VictoryAnimation3D.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/VictoryAnimation3D.tsx"],"sourcesContent":["import { useFrame } from \"@react-three/fiber\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport * as THREE from \"three\";\nimport { KOREAN_COLORS } from \"../../../../types/constants\";\n\n/**\n * Victory Animation 3D Component\n * Displays celebratory 3D particle effects for victory screen\n * Enhanced with additional Korean symbolism and dynamic effects\n * Optimized for 60fps performance with object reuse\n */\nexport const VictoryAnimation3D: React.FC = () => {\n const groupRef = useRef<THREE.Group>(null);\n const particlesRef = useRef<THREE.Points>(null);\n const ringsRef = useRef<THREE.Group>(null);\n const symbolsRef = useRef<THREE.Group>(null);\n\n // Reusable objects for animation calculations to avoid per-frame allocations\n // These are reused across all animation frames for scale and position updates\n const [reusableScale] = useState(() => new THREE.Vector3());\n const [reusablePosition] = useState(() => new THREE.Vector3());\n\n // Create victory particles - use useState with lazy initializer\n const [particlePositions] = useState(() => {\n const count = 200; // Increased from 150 for more dramatic effect\n const positions = new Float32Array(count * 3);\n\n for (let i = 0; i < count; i++) {\n const i3 = i * 3;\n const radius = 3 + Math.random() * 2;\n const theta = Math.random() * Math.PI * 2;\n const phi = Math.random() * Math.PI;\n\n positions[i3] = radius * Math.sin(phi) * Math.cos(theta);\n positions[i3 + 1] = radius * Math.cos(phi);\n positions[i3 + 2] = radius * Math.sin(phi) * Math.sin(theta);\n }\n\n return positions;\n });\n\n // Create secondary particle layer for depth\n const [secondaryParticles] = useState(() => {\n const count = 50;\n const positions = new Float32Array(count * 3);\n\n for (let i = 0; i < count; i++) {\n const i3 = i * 3;\n const radius = 5 + Math.random() * 3;\n const theta = Math.random() * Math.PI * 2;\n\n positions[i3] = radius * Math.cos(theta);\n positions[i3 + 1] = Math.random() * 4 - 2;\n positions[i3 + 2] = radius * Math.sin(theta);\n }\n\n return positions;\n });\n\n // Animate victory effects - optimized for 60fps\n useFrame((state) => {\n const time = state.clock.elapsedTime;\n\n // Rotate entire group\n if (groupRef.current) {\n groupRef.current.rotation.y = time * 0.3;\n }\n\n // Pulse particles with wave effect - use reusable objects\n if (particlesRef.current) {\n const scale = 1 + Math.sin(time * 2) * 0.2;\n reusableScale.setScalar(scale);\n particlesRef.current.scale.copy(reusableScale);\n \n // Rising motion\n reusablePosition.set(0, Math.sin(time * 0.8) * 0.5, 0);\n particlesRef.current.position.copy(reusablePosition);\n }\n\n // Rotate rings at different speeds\n if (ringsRef.current) {\n ringsRef.current.rotation.x = time * 0.5;\n ringsRef.current.rotation.z = time * 0.3;\n }\n\n // Rotate Korean symbols\n if (symbolsRef.current) {\n symbolsRef.current.rotation.y = -time * 0.4;\n symbolsRef.current.rotation.x = Math.sin(time * 0.5) * 0.1;\n }\n });\n\n // Cleanup Three.js resources on unmount\n useEffect(() => {\n // Capture ref values at effect setup time to avoid stale references in cleanup\n const group = groupRef.current;\n const particles = particlesRef.current;\n const rings = ringsRef.current;\n const symbols = symbolsRef.current;\n\n return () => {\n // Dispose geometries and materials to prevent memory leaks\n // Clean up specific refs (these are children of groupRef but we handle them explicitly)\n if (particles) {\n particles.geometry?.dispose();\n if (particles.material) {\n (particles.material as THREE.Material).dispose();\n }\n }\n if (rings?.children && Array.isArray(rings.children)) {\n rings.children.forEach((child) => {\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n if (symbols?.children && Array.isArray(symbols.children)) {\n symbols.children.forEach((child) => {\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n // Additionally iterate groupRef.current.children to dispose any meshes/points without explicit refs\n // (e.g., secondary particles, central glow sphere, outer glow sphere, inner glow layer)\n if (group?.children && Array.isArray(group.children)) {\n group.children.forEach((child) => {\n // Skip objects that are already handled via specific refs\n if (\n child === particles ||\n child === rings ||\n child === symbols\n ) {\n return;\n }\n\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n } else if (child instanceof THREE.Points) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n };\n }, []);\n\n return (\n <group\n ref={groupRef}\n position={[0, 2, 0]}\n data-testid=\"victory-animation-3d\"\n >\n {/* Primary victory particles */}\n <points ref={particlesRef}>\n <bufferGeometry>\n <bufferAttribute\n attach=\"attributes-position\"\n count={200}\n itemSize={3}\n args={[particlePositions, 3]}\n />\n </bufferGeometry>\n <pointsMaterial\n size={0.2}\n color={new THREE.Color(KOREAN_COLORS.ACCENT_GOLD)}\n transparent\n opacity={0.8}\n sizeAttenuation\n depthWrite={false}\n />\n </points>\n\n {/* Secondary particle layer */}\n <points position={[0, 1, 0]}>\n <bufferGeometry>\n <bufferAttribute\n attach=\"attributes-position\"\n count={50}\n itemSize={3}\n args={[secondaryParticles, 3]}\n />\n </bufferGeometry>\n <pointsMaterial\n size={0.15}\n color={new THREE.Color(KOREAN_COLORS.PRIMARY_CYAN)}\n transparent\n opacity={0.6}\n sizeAttenuation\n depthWrite={false}\n />\n </points>\n\n {/* Rotating rings */}\n <group ref={ringsRef}>\n <mesh rotation={[Math.PI / 2, 0, 0]}>\n <torusGeometry args={[2, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.6}\n />\n </mesh>\n\n <mesh rotation={[Math.PI / 2, Math.PI / 4, 0]}>\n <torusGeometry args={[2.5, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n transparent\n opacity={0.4}\n />\n </mesh>\n\n <mesh rotation={[Math.PI / 2, Math.PI / 2, 0]}>\n <torusGeometry args={[3, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.3}\n />\n </mesh>\n </group>\n\n {/* Korean symbol elements - octagonal shape representing 팔괘 (eight trigrams) */}\n <group ref={symbolsRef}>\n {Array.from({ length: 8 }).map((_, i) => {\n const angle = (i / 8) * Math.PI * 2;\n const radius = 4;\n return (\n <mesh\n key={i}\n position={[\n Math.cos(angle) * radius,\n 0,\n Math.sin(angle) * radius,\n ]}\n rotation={[0, angle + Math.PI / 2, 0]}\n >\n <boxGeometry args={[0.8, 0.1, 0.1]} />\n <meshStandardMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n emissive={KOREAN_COLORS.ACCENT_GOLD}\n emissiveIntensity={0.5}\n transparent\n opacity={0.7}\n />\n </mesh>\n );\n })}\n </group>\n\n {/* Central glow sphere */}\n <mesh>\n <sphereGeometry args={[0.5, 32, 32]} />\n <meshStandardMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n emissive={KOREAN_COLORS.ACCENT_GOLD}\n emissiveIntensity={1.5}\n transparent\n opacity={0.8}\n />\n </mesh>\n\n {/* Outer glow */}\n <mesh>\n <sphereGeometry args={[0.8, 32, 32]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.2}\n side={THREE.BackSide}\n />\n </mesh>\n\n {/* Additional inner glow layer */}\n <mesh>\n <sphereGeometry args={[0.6, 32, 32]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n transparent\n opacity={0.3}\n side={THREE.BackSide}\n />\n </mesh>\n\n {/* Point light for glow effect */}\n <pointLight\n position={[0, 0, 0]}\n intensity={3}\n distance={10}\n color={KOREAN_COLORS.ACCENT_GOLD}\n />\n\n {/* Secondary accent lights */}\n <pointLight\n position={[2, 2, 0]}\n intensity={1.5}\n distance={6}\n color={KOREAN_COLORS.PRIMARY_CYAN}\n />\n <pointLight\n position={[-2, 2, 0]}\n intensity={1.5}\n distance={6}\n color={KOREAN_COLORS.PRIMARY_CYAN}\n />\n </group>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"VictoryAnimation3D.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/VictoryAnimation3D.tsx"],"sourcesContent":["import { useFrame } from \"@react-three/fiber\";\nimport React, { useEffect, useRef, useState } from \"react\";\nimport * as THREE from \"three\";\nimport { KOREAN_COLORS } from \"../../../../types/constants\";\n\n/**\n * Victory Animation 3D Component\n * Displays celebratory 3D particle effects for victory screen\n * Enhanced with additional Korean symbolism and dynamic effects\n * Optimized for 60fps performance with object reuse\n */\nexport const VictoryAnimation3D: React.FC = () => {\n const groupRef = useRef<THREE.Group>(null);\n const particlesRef = useRef<THREE.Points>(null);\n const ringsRef = useRef<THREE.Group>(null);\n const symbolsRef = useRef<THREE.Group>(null);\n\n const [reusableScale] = useState(() => new THREE.Vector3());\n const [reusablePosition] = useState(() => new THREE.Vector3());\n\n const [particlePositions] = useState(() => {\n const count = 200; // Increased from 150 for more dramatic effect\n const positions = new Float32Array(count * 3);\n\n for (let i = 0; i < count; i++) {\n const i3 = i * 3;\n const radius = 3 + Math.random() * 2;\n const theta = Math.random() * Math.PI * 2;\n const phi = Math.random() * Math.PI;\n\n positions[i3] = radius * Math.sin(phi) * Math.cos(theta);\n positions[i3 + 1] = radius * Math.cos(phi);\n positions[i3 + 2] = radius * Math.sin(phi) * Math.sin(theta);\n }\n\n return positions;\n });\n\n const [secondaryParticles] = useState(() => {\n const count = 50;\n const positions = new Float32Array(count * 3);\n\n for (let i = 0; i < count; i++) {\n const i3 = i * 3;\n const radius = 5 + Math.random() * 3;\n const theta = Math.random() * Math.PI * 2;\n\n positions[i3] = radius * Math.cos(theta);\n positions[i3 + 1] = Math.random() * 4 - 2;\n positions[i3 + 2] = radius * Math.sin(theta);\n }\n\n return positions;\n });\n\n useFrame((state) => {\n const time = state.clock.elapsedTime;\n\n if (groupRef.current) {\n groupRef.current.rotation.y = time * 0.3;\n }\n\n if (particlesRef.current) {\n const scale = 1 + Math.sin(time * 2) * 0.2;\n reusableScale.setScalar(scale);\n particlesRef.current.scale.copy(reusableScale);\n \n reusablePosition.set(0, Math.sin(time * 0.8) * 0.5, 0);\n particlesRef.current.position.copy(reusablePosition);\n }\n\n if (ringsRef.current) {\n ringsRef.current.rotation.x = time * 0.5;\n ringsRef.current.rotation.z = time * 0.3;\n }\n\n if (symbolsRef.current) {\n symbolsRef.current.rotation.y = -time * 0.4;\n symbolsRef.current.rotation.x = Math.sin(time * 0.5) * 0.1;\n }\n });\n\n useEffect(() => {\n const group = groupRef.current;\n const particles = particlesRef.current;\n const rings = ringsRef.current;\n const symbols = symbolsRef.current;\n\n return () => {\n if (particles) {\n particles.geometry?.dispose();\n if (particles.material) {\n (particles.material as THREE.Material).dispose();\n }\n }\n if (rings?.children && Array.isArray(rings.children)) {\n rings.children.forEach((child) => {\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n if (symbols?.children && Array.isArray(symbols.children)) {\n symbols.children.forEach((child) => {\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n if (group?.children && Array.isArray(group.children)) {\n group.children.forEach((child) => {\n if (\n child === particles ||\n child === rings ||\n child === symbols\n ) {\n return;\n }\n\n if (child instanceof THREE.Mesh) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n } else if (child instanceof THREE.Points) {\n child.geometry?.dispose();\n if (child.material) {\n (child.material as THREE.Material).dispose();\n }\n }\n });\n }\n };\n }, []);\n\n return (\n <group\n ref={groupRef}\n position={[0, 2, 0]}\n data-testid=\"victory-animation-3d\"\n >\n {/* Primary victory particles */}\n <points ref={particlesRef}>\n <bufferGeometry>\n <bufferAttribute\n attach=\"attributes-position\"\n count={200}\n itemSize={3}\n args={[particlePositions, 3]}\n />\n </bufferGeometry>\n <pointsMaterial\n size={0.2}\n color={new THREE.Color(KOREAN_COLORS.ACCENT_GOLD)}\n transparent\n opacity={0.8}\n sizeAttenuation\n depthWrite={false}\n />\n </points>\n\n {/* Secondary particle layer */}\n <points position={[0, 1, 0]}>\n <bufferGeometry>\n <bufferAttribute\n attach=\"attributes-position\"\n count={50}\n itemSize={3}\n args={[secondaryParticles, 3]}\n />\n </bufferGeometry>\n <pointsMaterial\n size={0.15}\n color={new THREE.Color(KOREAN_COLORS.PRIMARY_CYAN)}\n transparent\n opacity={0.6}\n sizeAttenuation\n depthWrite={false}\n />\n </points>\n\n {/* Rotating rings */}\n <group ref={ringsRef}>\n <mesh rotation={[Math.PI / 2, 0, 0]}>\n <torusGeometry args={[2, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.6}\n />\n </mesh>\n\n <mesh rotation={[Math.PI / 2, Math.PI / 4, 0]}>\n <torusGeometry args={[2.5, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n transparent\n opacity={0.4}\n />\n </mesh>\n\n <mesh rotation={[Math.PI / 2, Math.PI / 2, 0]}>\n <torusGeometry args={[3, 0.05, 16, 100]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.3}\n />\n </mesh>\n </group>\n\n {/* Korean symbol elements - octagonal shape representing 팔괘 (eight trigrams) */}\n <group ref={symbolsRef}>\n {Array.from({ length: 8 }).map((_, i) => {\n const angle = (i / 8) * Math.PI * 2;\n const radius = 4;\n return (\n <mesh\n key={i}\n position={[\n Math.cos(angle) * radius,\n 0,\n Math.sin(angle) * radius,\n ]}\n rotation={[0, angle + Math.PI / 2, 0]}\n >\n <boxGeometry args={[0.8, 0.1, 0.1]} />\n <meshStandardMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n emissive={KOREAN_COLORS.ACCENT_GOLD}\n emissiveIntensity={0.5}\n transparent\n opacity={0.7}\n />\n </mesh>\n );\n })}\n </group>\n\n {/* Central glow sphere */}\n <mesh>\n <sphereGeometry args={[0.5, 32, 32]} />\n <meshStandardMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n emissive={KOREAN_COLORS.ACCENT_GOLD}\n emissiveIntensity={1.5}\n transparent\n opacity={0.8}\n />\n </mesh>\n\n {/* Outer glow */}\n <mesh>\n <sphereGeometry args={[0.8, 32, 32]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.PRIMARY_CYAN}\n transparent\n opacity={0.2}\n side={THREE.BackSide}\n />\n </mesh>\n\n {/* Additional inner glow layer */}\n <mesh>\n <sphereGeometry args={[0.6, 32, 32]} />\n <meshBasicMaterial\n color={KOREAN_COLORS.ACCENT_GOLD}\n transparent\n opacity={0.3}\n side={THREE.BackSide}\n />\n </mesh>\n\n {/* Point light for glow effect */}\n <pointLight\n position={[0, 0, 0]}\n intensity={3}\n distance={10}\n color={KOREAN_COLORS.ACCENT_GOLD}\n />\n\n {/* Secondary accent lights */}\n <pointLight\n position={[2, 2, 0]}\n intensity={1.5}\n distance={6}\n color={KOREAN_COLORS.PRIMARY_CYAN}\n />\n <pointLight\n position={[-2, 2, 0]}\n intensity={1.5}\n distance={6}\n color={KOREAN_COLORS.PRIMARY_CYAN}\n />\n </group>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"WinnerDisplayOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/WinnerDisplayOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASlD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAOD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyKtD,CAAC"}
1
+ {"version":3,"file":"WinnerDisplayOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/WinnerDisplayOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AASlD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAOD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwKtD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WinnerDisplayOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/WinnerDisplayOverlayHtml.tsx"],"sourcesContent":["import React from \"react\";\nimport { PlayerState } from \"../../../../systems\";\nimport {\n ARCHETYPE_ASSETS,\n FONT_FAMILY,\n KOREAN_COLORS,\n} from \"../../../../types/constants\";\nimport { hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { fadeInAnimation, scaleInAnimation } from \"./animations\";\n\nexport interface WinnerDisplayProps {\n readonly winner: PlayerState;\n readonly isVictory: boolean;\n readonly isMobile: boolean;\n readonly isTablet: boolean;\n}\n\n/**\n * Helper to convert hex color to CSS string\n */\nconst toCssColor = (hex: number): string => hexToRgbaString(hex, 1);\n\n/**\n * Winner Display Component\n * Shows winner announcement with archetype details\n */\nexport const WinnerDisplay: React.FC<WinnerDisplayProps> = ({\n winner,\n isVictory,\n isMobile,\n isTablet,\n}) => {\n const titleFontSize = isMobile ? 28 : isTablet ? 36 : 44;\n const subtitleFontSize = isMobile ? 16 : isTablet ? 18 : 22;\n const detailFontSize = isMobile ? 12 : 14;\n const spacing = isMobile ? 10 : isTablet ? 12 : 15;\n\n const primaryColor = isVictory\n ? KOREAN_COLORS.ACCENT_GOLD\n : KOREAN_COLORS.ACCENT_RED;\n\n const resultText = isVictory\n ? { korean: \"승리!\", english: \"Victory!\" }\n : { korean: \"패배\", english: \"Defeat\" };\n\n // Get archetype asset info\n const archetypeKey =\n winner.archetype.toLowerCase() as keyof typeof ARCHETYPE_ASSETS;\n const archetypeAsset =\n ARCHETYPE_ASSETS[archetypeKey] || ARCHETYPE_ASSETS.musa;\n\n return (\n <div\n data-testid=\"winner-display\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n marginBottom: spacing,\n animation: \"fadeIn 0.8s ease-in\",\n }}\n >\n {/* Result Title with glow effect */}\n <div\n style={{\n fontSize: titleFontSize,\n fontWeight: \"bold\",\n color: toCssColor(primaryColor),\n textShadow: `0 0 20px ${hexToRgbaString(\n primaryColor,\n 0.8\n )}, 0 0 40px ${hexToRgbaString(primaryColor, 0.4)}`,\n marginBottom: spacing,\n textAlign: \"center\",\n fontFamily: FONT_FAMILY.KOREAN,\n animation: \"scaleIn 0.5s ease-out\",\n }}\n data-testid=\"result-title\"\n >\n {resultText.korean} | {resultText.english}\n </div>\n\n {/* Winner Name */}\n <div\n style={{\n fontSize: subtitleFontSize,\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n marginBottom: spacing / 2,\n textAlign: \"center\",\n fontFamily: FONT_FAMILY.KOREAN,\n fontWeight: \"bold\",\n }}\n data-testid=\"winner-name\"\n >\n {winner.name.korean} | {winner.name.english}\n </div>\n\n {/* Archetype Display */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_MEDIUM, 0.6),\n border: `2px solid ${hexToRgbaString(primaryColor, 0.8)}`,\n borderRadius: \"12px\",\n padding: spacing,\n marginTop: spacing / 2,\n minWidth: isMobile ? \"280px\" : \"320px\",\n }}\n data-testid=\"winner-archetype-display\"\n >\n {/* Archetype Name */}\n <div\n style={{\n fontSize: detailFontSize + 2,\n color: toCssColor(KOREAN_COLORS.ACCENT_GOLD),\n fontFamily: FONT_FAMILY.KOREAN,\n fontWeight: \"bold\",\n marginBottom: spacing / 2,\n }}\n data-testid=\"winner-archetype\"\n >\n {archetypeAsset.name_korean} | {archetypeAsset.name_english}\n </div>\n\n {/* Archetype Code */}\n <div\n style={{\n fontSize: detailFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n fontFamily: FONT_FAMILY.KOREAN,\n textTransform: \"uppercase\",\n letterSpacing: \"0.1em\",\n }}\n data-testid=\"archetype-code\"\n >\n {winner.archetype.toUpperCase()}\n </div>\n\n {/* Combat Stats Summary */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n gap: spacing,\n marginTop: spacing,\n fontSize: detailFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_TERTIARY),\n }}\n data-testid=\"combat-stats-summary\"\n >\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.HEALTH_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.health)}\n </div>\n <div>체력 | HP</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.KI_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.ki)}\n </div>\n <div>기력 | Ki</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.STAMINA_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.stamina)}\n </div>\n <div>스태미나 | Stamina</div>\n </div>\n </div>\n </div>\n\n {/* CSS Animations */}\n <style>{`\n ${fadeInAnimation}\n ${scaleInAnimation}\n `}</style>\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"WinnerDisplayOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/endscreen/components/WinnerDisplayOverlayHtml.tsx"],"sourcesContent":["import React from \"react\";\nimport { PlayerState } from \"../../../../systems\";\nimport {\n ARCHETYPE_ASSETS,\n FONT_FAMILY,\n KOREAN_COLORS,\n} from \"../../../../types/constants\";\nimport { hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { fadeInAnimation, scaleInAnimation } from \"./animations\";\n\nexport interface WinnerDisplayProps {\n readonly winner: PlayerState;\n readonly isVictory: boolean;\n readonly isMobile: boolean;\n readonly isTablet: boolean;\n}\n\n/**\n * Helper to convert hex color to CSS string\n */\nconst toCssColor = (hex: number): string => hexToRgbaString(hex, 1);\n\n/**\n * Winner Display Component\n * Shows winner announcement with archetype details\n */\nexport const WinnerDisplay: React.FC<WinnerDisplayProps> = ({\n winner,\n isVictory,\n isMobile,\n isTablet,\n}) => {\n const titleFontSize = isMobile ? 28 : isTablet ? 36 : 44;\n const subtitleFontSize = isMobile ? 16 : isTablet ? 18 : 22;\n const detailFontSize = isMobile ? 12 : 14;\n const spacing = isMobile ? 10 : isTablet ? 12 : 15;\n\n const primaryColor = isVictory\n ? KOREAN_COLORS.ACCENT_GOLD\n : KOREAN_COLORS.ACCENT_RED;\n\n const resultText = isVictory\n ? { korean: \"승리!\", english: \"Victory!\" }\n : { korean: \"패배\", english: \"Defeat\" };\n\n const archetypeKey =\n winner.archetype.toLowerCase() as keyof typeof ARCHETYPE_ASSETS;\n const archetypeAsset =\n ARCHETYPE_ASSETS[archetypeKey] || ARCHETYPE_ASSETS.musa;\n\n return (\n <div\n data-testid=\"winner-display\"\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n marginBottom: spacing,\n animation: \"fadeIn 0.8s ease-in\",\n }}\n >\n {/* Result Title with glow effect */}\n <div\n style={{\n fontSize: titleFontSize,\n fontWeight: \"bold\",\n color: toCssColor(primaryColor),\n textShadow: `0 0 20px ${hexToRgbaString(\n primaryColor,\n 0.8\n )}, 0 0 40px ${hexToRgbaString(primaryColor, 0.4)}`,\n marginBottom: spacing,\n textAlign: \"center\",\n fontFamily: FONT_FAMILY.KOREAN,\n animation: \"scaleIn 0.5s ease-out\",\n }}\n data-testid=\"result-title\"\n >\n {resultText.korean} | {resultText.english}\n </div>\n\n {/* Winner Name */}\n <div\n style={{\n fontSize: subtitleFontSize,\n color: toCssColor(KOREAN_COLORS.PRIMARY_CYAN),\n marginBottom: spacing / 2,\n textAlign: \"center\",\n fontFamily: FONT_FAMILY.KOREAN,\n fontWeight: \"bold\",\n }}\n data-testid=\"winner-name\"\n >\n {winner.name.korean} | {winner.name.english}\n </div>\n\n {/* Archetype Display */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_MEDIUM, 0.6),\n border: `2px solid ${hexToRgbaString(primaryColor, 0.8)}`,\n borderRadius: \"12px\",\n padding: spacing,\n marginTop: spacing / 2,\n minWidth: isMobile ? \"280px\" : \"320px\",\n }}\n data-testid=\"winner-archetype-display\"\n >\n {/* Archetype Name */}\n <div\n style={{\n fontSize: detailFontSize + 2,\n color: toCssColor(KOREAN_COLORS.ACCENT_GOLD),\n fontFamily: FONT_FAMILY.KOREAN,\n fontWeight: \"bold\",\n marginBottom: spacing / 2,\n }}\n data-testid=\"winner-archetype\"\n >\n {archetypeAsset.name_korean} | {archetypeAsset.name_english}\n </div>\n\n {/* Archetype Code */}\n <div\n style={{\n fontSize: detailFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_SECONDARY),\n fontFamily: FONT_FAMILY.KOREAN,\n textTransform: \"uppercase\",\n letterSpacing: \"0.1em\",\n }}\n data-testid=\"archetype-code\"\n >\n {winner.archetype.toUpperCase()}\n </div>\n\n {/* Combat Stats Summary */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"row\",\n gap: spacing,\n marginTop: spacing,\n fontSize: detailFontSize - 2,\n color: toCssColor(KOREAN_COLORS.TEXT_TERTIARY),\n }}\n data-testid=\"combat-stats-summary\"\n >\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.HEALTH_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.health)}\n </div>\n <div>체력 | HP</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.KI_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.ki)}\n </div>\n <div>기력 | Ki</div>\n </div>\n <div style={{ textAlign: \"center\" }}>\n <div\n style={{\n color: toCssColor(KOREAN_COLORS.STAMINA_FULL),\n fontWeight: \"bold\",\n }}\n >\n {Math.round(winner.stamina)}\n </div>\n <div>스태미나 | Stamina</div>\n </div>\n </div>\n </div>\n\n {/* CSS Animations */}\n <style>{`\n ${fadeInAnimation}\n ${scaleInAnimation}\n `}</style>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,YAAY,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAEnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAG7E,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/endscreen/components/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,YAAY,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAC7E,YAAY,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAEvF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAEnF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,YAAY,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAE7E,cAAc,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/screens/endscreen/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,cAAc,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/screens/endscreen/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEtD,cAAc,cAAc,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"IntroScreen3D.d.ts","sourceRoot":"","sources":["../../../../src/components/screens/intro/IntroScreen3D.tsx"],"names":[],"mappings":"AAEA,OAAO,KAMN,MAAM,OAAO,CAAC;AAMf,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAmBlE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CAChD;AAkCD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAmkBtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"IntroScreen3D.d.ts","sourceRoot":"","sources":["../../../../src/components/screens/intro/IntroScreen3D.tsx"],"names":[],"mappings":"AACA,OAAO,KAMN,MAAM,OAAO,CAAC;AAMf,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAmBlE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IAC7E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IAClE,QAAQ,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAC;IAC7C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,CAAC;CAChD;AA+BD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwhBtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
@@ -21,7 +21,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
21
21
  import { jsx, jsxs } from "react/jsx-runtime";
22
22
  import { Canvas } from "@react-three/fiber";
23
23
  //#region src/components/screens/intro/IntroScreen3D.tsx
24
- var APP_VERSION = "0.7.44";
24
+ var APP_VERSION = "0.7.45";
25
25
  var MENU_ITEMS = [
26
26
  {
27
27
  mode: GameMode.VERSUS,
@@ -1 +1 @@
1
- {"version":3,"file":"IntroScreen3D.js","names":[],"sources":["../../../../src/components/screens/intro/IntroScreen3D.tsx"],"sourcesContent":["// UI renders outside Canvas in absolute-positioned div - no Html needed\nimport { Canvas } from \"@react-three/fiber\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useAudio } from \"../../../audio/AudioProvider\";\nimport { useWebGLContextLossHandler } from \"../../../hooks/useWebGLContextLossHandler\";\nimport { useWindowSize } from \"../../../hooks/useWindowSize\";\nimport { getScreenSize } from \"../../../systems/ResponsiveScaling\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../../../systems/types\";\nimport { GameMode, PlayerArchetype } from \"../../../types/common\";\nimport {\n ARCHETYPE_BACKGROUNDS,\n getKoreanFontSize,\n getPerformanceSettings,\n} from \"../../../types/constants\";\nimport { Z_INDEX } from \"../../../types/LayoutTypes\";\nimport { hexToRgbaString } from \"../../../utils/colorUtils\";\nimport { shouldUseMobileControls } from \"../../../utils/deviceDetection\";\nimport { getArchetypeAssets } from \"../../../utils/playerUtils\";\nimport { useKoreanTheme } from \"../../shared/base/useKoreanTheme\";\nimport { BackgroundScene3D } from \"../../shared/three\";\nimport { VolumeControl } from \"../../shared/ui/VolumeControl\";\nimport { ArchetypeDisplayOverlayHtml } from \"./components/ArchetypeDisplayOverlayHtml\";\nimport { EnhancedArchetypeDisplay } from \"./components/EnhancedArchetypeDisplayOverlayHtml\";\nimport { MenuSectionOverlayHtml } from \"./components/MenuSectionOverlayHtml\";\n\nconst APP_VERSION = import.meta.env.APP_VERSION;\n\nexport interface IntroScreen3DProps {\n readonly onMenuSelect: (mode: GameMode, archetype?: PlayerArchetype) => void;\n readonly onArchetypeSelect?: (archetype: PlayerArchetype) => void;\n readonly selectedArchetype?: PlayerArchetype;\n readonly width?: number;\n readonly height?: number;\n readonly useEnhancedArchetypeDisplay?: boolean; // Use enhanced card display\n}\n\nconst MENU_ITEMS: { mode: GameMode; korean: string; english: string }[] = [\n { mode: GameMode.VERSUS, korean: \"대전\", english: \"Combat\" },\n { mode: GameMode.TRAINING, korean: \"훈련\", english: \"Training\" },\n { mode: GameMode.CONTROLS, korean: \"조작\", english: \"Controls\" },\n { mode: GameMode.PHILOSOPHY, korean: \"철학\", english: \"Philosophy\" },\n];\n\n// Texture key mapping for archetypes\nconst ARCHETYPE_TEXTURE_MAPPING: Record<PlayerArchetype, string> = {\n [PlayerArchetype.MUSA]: \"musa\",\n [PlayerArchetype.AMSALJA]: \"amsalja\",\n [PlayerArchetype.HACKER]: \"hacker\",\n [PlayerArchetype.JEONGBO_YOWON]: \"jeongbo_yowon\",\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: \"jojik_pokryeokbae\",\n};\n\n// Helper function to convert PlayerArchetype enum to array index\nconst getArchetypeIndex = (archetype: PlayerArchetype): number => {\n const archetypeKeys = Object.keys(\n PLAYER_ARCHETYPES_DATA,\n ) as PlayerArchetype[];\n return archetypeKeys.indexOf(archetype);\n};\n\n// Helper function to convert array index to PlayerArchetype enum\nconst getArchetypeFromIndex = (index: number): PlayerArchetype => {\n const archetypeKeys = Object.keys(\n PLAYER_ARCHETYPES_DATA,\n ) as PlayerArchetype[];\n return archetypeKeys[index] ?? PlayerArchetype.MUSA;\n};\n\n/**\n * Three.js-based IntroScreen Component\n */\nexport const IntroScreen3D: React.FC<IntroScreen3DProps> = ({\n onMenuSelect,\n onArchetypeSelect,\n selectedArchetype = PlayerArchetype.MUSA,\n width: propWidth,\n height: propHeight,\n useEnhancedArchetypeDisplay = true, // Default to enhanced display\n}) => {\n const audio = useAudio();\n const introMusicStarted = useRef(false);\n const [selectedMenuIndex, setSelectedMenuIndex] = useState(0);\n // UI now renders outside Canvas - no canvas ready state needed\n\n // Handle WebGL context loss and restoration (for 3D background only)\n useWebGLContextLossHandler({\n onContextLost: () => {\n console.warn(\"⚠️ WebGL context lost in IntroScreen\");\n },\n onContextRestored: () => {\n console.log(\"✓ WebGL context restored in IntroScreen\");\n },\n autoRestore: true,\n });\n\n // Add local state for archetype management\n const [currentArchetype, setCurrentArchetype] =\n useState<PlayerArchetype>(selectedArchetype);\n const [selectedArchetypeIndex, setSelectedArchetypeIndex] = useState<number>(\n getArchetypeIndex(selectedArchetype),\n );\n\n const { width, height } = useWindowSize();\n\n // Use prop dimensions if provided, otherwise use window size with defensive fallbacks\n // Ensure minimum valid dimensions to prevent rendering issues\n const screenWidth = propWidth ?? (width || 1200);\n const screenHeight = propHeight ?? (height || 800);\n\n // Create archetype data with texture keys from PLAYER_ARCHETYPES_DATA\n const archetypeData = useMemo(() => {\n return Object.entries(PLAYER_ARCHETYPES_DATA).map(([key, data]) => {\n const archetypeEnum = key as PlayerArchetype;\n return {\n id: key.toLowerCase(),\n korean: data.name.korean,\n english: data.name.english,\n description: data.description.korean,\n color: data.colors.primary,\n textureKey: ARCHETYPE_TEXTURE_MAPPING[archetypeEnum],\n stats: data.stats,\n philosophy: data.philosophy,\n specialAbilities: data.specialAbilities, // Include special abilities\n };\n });\n }, []);\n\n // Sync with prop changes\n useEffect(() => {\n setCurrentArchetype(selectedArchetype);\n setSelectedArchetypeIndex(getArchetypeIndex(selectedArchetype));\n }, [selectedArchetype]);\n\n // Direct menu selection - MOVED BEFORE useEffect that uses it\n const handleMenuItemSelect = useCallback(\n (mode: GameMode) => {\n onMenuSelect(mode, currentArchetype);\n },\n [onMenuSelect, currentArchetype],\n );\n\n // Handle archetype change by index - MOVED BEFORE useEffect that uses it\n const handleArchetypeIndexChange = useCallback(\n (index: number) => {\n const newArchetype = getArchetypeFromIndex(index);\n setSelectedArchetypeIndex(index);\n setCurrentArchetype(newArchetype);\n onArchetypeSelect?.(newArchetype);\n\n // Check if audio system is ready, not individual methods\n if (audio.isAudioReady) {\n audio.playSFX(\"menu_hover\");\n\n // Play archetype theme music preview when archetype changes\n // Use getArchetypeAssets utility for proper error handling and fallback\n const archetypeAssets = getArchetypeAssets(newArchetype);\n // Stop intro music and play archetype theme\n audio.stopMusic();\n audio.playMusic(archetypeAssets.themeId);\n }\n },\n [onArchetypeSelect, audio],\n );\n\n // Play intro music after first user interaction\n useEffect(() => {\n const startMusic = () => {\n if (audio.isAudioReady && !introMusicStarted.current) {\n introMusicStarted.current = true;\n audio.playMusic(\"intro_theme\");\n }\n };\n // Event listeners with { once: true } are automatically removed after triggering\n window.addEventListener(\"keydown\", startMusic, { once: true });\n window.addEventListener(\"mousedown\", startMusic, { once: true });\n window.addEventListener(\"touchstart\", startMusic, { once: true, passive: true });\n\n return () => {\n // Safe cleanup - check if audio is initialized before stopping music\n if (audio.isInitialized) {\n audio.stopMusic();\n }\n };\n }, [audio]);\n\n // Keyboard navigation\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n // Archetype navigation (handleArchetypeIndexChange already plays menu_hover SFX)\n if (event.key === \"ArrowLeft\") {\n const newIndex =\n selectedArchetypeIndex === 0\n ? archetypeData.length - 1\n : selectedArchetypeIndex - 1;\n handleArchetypeIndexChange(newIndex);\n } else if (event.key === \"ArrowRight\") {\n const newIndex = (selectedArchetypeIndex + 1) % archetypeData.length;\n handleArchetypeIndexChange(newIndex);\n } else {\n // Direct game mode shortcuts\n switch (event.key.toLowerCase()) {\n case \"c\":\n handleMenuItemSelect(GameMode.CONTROLS);\n break;\n case \"p\":\n handleMenuItemSelect(GameMode.PHILOSOPHY);\n break;\n case \"t\":\n handleMenuItemSelect(GameMode.TRAINING);\n break;\n case \"v\":\n handleMenuItemSelect(GameMode.VERSUS);\n break;\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [\n audio,\n archetypeData.length,\n selectedArchetypeIndex,\n handleArchetypeIndexChange,\n handleMenuItemSelect,\n ]);\n\n // Responsive layout calculations with large desktop support\n // Use device detection instead of width-only breakpoint to correctly identify high-res mobile devices\n // shouldUseMobileControls() uses user-agent detection which doesn't change during session\n // Use isMobile only for mobile CONTROLS (touch controls, etc.)\n // Layout sizing should use screenWidth-based calculations\n const isMobile = useMemo(() => shouldUseMobileControls(), []);\n\n // Use Korean theme hook for consistent theming\n const theme = useKoreanTheme({\n variant: \"primary\",\n size: \"md\",\n isMobile,\n });\n\n // Memoize colors from theme for performance\n const colors = useMemo(\n () => ({\n trigramTextShadow: `0 0 10px ${hexToRgbaString(\n theme.colors.PRIMARY_CYAN,\n 0.8,\n )}`,\n footerBackground: hexToRgbaString(theme.colors.UI_BACKGROUND_DARK, 0.9),\n footerBorder: hexToRgbaString(theme.colors.ACCENT_GOLD, 0.3),\n }),\n [theme],\n );\n\n // Performance settings based on device tier\n const performanceSettings = useMemo(() => {\n return getPerformanceSettings(screenWidth, isMobile);\n }, [screenWidth, isMobile]);\n\n // Get screen size category for layout calculations (mobile, tablet, desktop, large, xlarge)\n const screenSize = useMemo(() => getScreenSize(screenWidth), [screenWidth]);\n\n // Use percentage-based layout based on screen dimensions\n // Logo takes priority - larger and more prominent\n const logoSize = useMemo(() => {\n // Logo should be prominent - use percentage of smaller dimension\n const minDim = Math.min(screenWidth, screenHeight);\n // Scale based on screen size category\n const logoScale = {\n mobile: 0.28,\n tablet: 0.22,\n desktop: 0.18,\n large: 0.15,\n xlarge: 0.12,\n }[screenSize];\n // Cap at reasonable max size for very large screens\n return Math.min(minDim * logoScale, screenSize === \"xlarge\" ? 250 : 300);\n }, [screenWidth, screenHeight, screenSize]);\n\n // Dynamic heights based on available screen space (percentage-based)\n // All calculations use screen dimensions, not device type\n const layoutHeights = useMemo(() => {\n const availableHeight = screenHeight;\n\n // Title area - small header with title and description\n const titleHeight = screenWidth < 768 ? 32 : 38;\n\n // Logo area - based on logo size plus trigram symbols (compact)\n const trigramHeight = screenWidth < 768 ? 16 : 22;\n const logoAreaHeight = logoSize + trigramHeight;\n\n // Footer - compact with all info\n const footerHeight = Math.max(availableHeight * 0.05, 48);\n\n // Remaining space for menu + archetype\n const contentHeight =\n availableHeight - titleHeight - logoAreaHeight - footerHeight;\n\n // Menu needs enough height for 2x2 grid (2 rows of ~40px buttons + title + padding)\n // Mobile needs column layout (4 buttons stacked)\n const menuMinHeight = screenWidth < 768 ? 180 : 120;\n const menuPercent = screenWidth < 768 ? 0.38 : 0.25;\n const menuHeight = Math.max(contentHeight * menuPercent, menuMinHeight);\n const archetypeHeight = contentHeight - menuHeight - 8; // 8px gap\n\n // Gap scales with screen (minimal)\n const gap = Math.max(screenHeight * 0.002, 2);\n\n return {\n titleHeight,\n logoAreaHeight,\n menuHeight,\n archetypeHeight,\n footerHeight,\n gap,\n };\n }, [screenHeight, screenWidth, logoSize]);\n return (\n <div\n style={{\n width: screenWidth,\n height: screenHeight,\n position: \"relative\",\n overflow: \"hidden\",\n }}\n data-testid=\"intro-screen\"\n >\n {/* Archetype background image (very subtle, behind 3D scene) */}\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundImage: `url(${ARCHETYPE_BACKGROUNDS.overview})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n opacity: 0.08,\n filter: \"blur(4px)\",\n zIndex: Z_INDEX.BACKGROUND,\n }}\n data-testid=\"archetype-background\"\n />\n\n {/* Volume Control - outside Canvas to maintain AudioProvider context */}\n <VolumeControl position=\"top-right\" compact={isMobile} />\n\n {/* Three.js Canvas for 3D background */}\n <Canvas\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n zIndex: Z_INDEX.ARENA,\n }}\n gl={{\n antialias: performanceSettings.antialias,\n alpha: true,\n powerPreference: \"high-performance\",\n }}\n dpr={performanceSettings.dpr}\n camera={{ position: [0, 5, 10], fov: 75 }}\n onCreated={({ gl }) => {\n gl.setClearColor(theme.colors.UI_BACKGROUND_DARK, 0.95);\n }}\n >\n {/* 3D Background Scene */}\n <BackgroundScene3D theme=\"intro\" />\n </Canvas>\n\n {/* UI Overlay (positioned absolutely over Canvas) - matches CombatScreen pattern */}\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: Z_INDEX.HUD,\n }}\n data-testid=\"intro-hud-overlay\"\n >\n <div\n style={{\n width: \"100vw\",\n height: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: 0,\n pointerEvents: \"none\",\n zIndex: Z_INDEX.HUD,\n overflow: \"hidden\",\n }}\n >\n {/* Title - Small, above logo */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2px\",\n pointerEvents: \"none\",\n marginTop: \"4px\",\n flexShrink: 0,\n }}\n data-testid=\"main-title-container\"\n >\n <div\n style={{\n fontSize: screenWidth < 768 ? \"14px\" : \"16px\",\n fontWeight: \"bold\",\n fontFamily: theme.koreanTypography.fontFamily,\n lineHeight: theme.koreanTypography.lineHeight,\n letterSpacing: theme.koreanTypography.letterSpacing,\n wordBreak: theme.koreanTypography.wordBreak,\n color: `#${theme.colors.ACCENT_GOLD.toString(16).padStart(6, \"0\")}`,\n textShadow: \"0 0 10px rgba(255, 170, 0, 0.5)\",\n }}\n >\n 흑괘 | Black Trigram\n </div>\n <div\n style={{\n fontSize: screenWidth < 768 ? \"10px\" : \"11px\",\n fontFamily: theme.koreanTypography.fontFamily,\n color: `#${theme.colors.TEXT_SECONDARY.toString(16).padStart(6, \"0\")}`,\n }}\n >\n 한국 무술 시뮬레이터 | Korean Martial Arts Simulator\n </div>\n </div>\n\n {/* Logo Section - Primary branding */}\n <div\n style={{\n flexShrink: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: `${layoutHeights.logoAreaHeight}px`,\n pointerEvents: \"none\",\n }}\n data-testid=\"logo-section\"\n >\n {/* Logo Image - Prominent */}\n <img\n src=\"/assets/visual/logo/black-trigram.png\"\n alt=\"Black Trigram Logo\"\n style={{\n width: `${logoSize}px`,\n height: `${logoSize}px`,\n objectFit: \"contain\",\n filter: \"drop-shadow(0 0 30px rgba(0, 255, 255, 0.6))\",\n }}\n data-testid=\"main-logo\"\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n\n {/* Trigram Symbols */}\n <div\n style={{\n fontSize: screenWidth < 768 ? \"16px\" : \"18px\",\n color: `#${theme.colors.PRIMARY_CYAN.toString(16).padStart(\n 6,\n \"0\",\n )}`,\n letterSpacing: screenWidth < 768 ? \"6px\" : \"8px\",\n textAlign: \"center\",\n marginTop: screenWidth < 768 ? \"8px\" : \"10px\",\n textShadow: colors.trigramTextShadow,\n }}\n data-testid=\"trigram-symbols\"\n >\n ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷\n </div>\n </div>\n\n {/* Main Content Area */}\n <div\n style={{\n width: \"100%\",\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"flex-start\",\n gap: \"4px\",\n paddingLeft: screenWidth < 768 ? \"8px\" : \"16px\",\n paddingRight: screenWidth < 768 ? \"8px\" : \"16px\",\n overflow: \"hidden\",\n pointerEvents: \"auto\",\n minHeight: 0,\n }}\n data-testid=\"main-content\"\n >\n {/* Menu Section - Compact */}\n <div\n style={{\n width: screenWidth < 768 ? \"95%\" : \"70%\",\n maxWidth: screenWidth < 768 ? \"100%\" : \"600px\",\n }}\n data-testid=\"menu-section-container\"\n >\n <MenuSectionOverlayHtml\n menuItems={MENU_ITEMS}\n selectedIndex={selectedMenuIndex}\n onModeSelect={handleMenuItemSelect}\n onSelectedIndexChange={setSelectedMenuIndex}\n onPlaySFX={audio.playSFX}\n width={\n // Compact menu width - narrower for better proportions\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(500, screenWidth * 0.6)\n : Math.min(550, screenWidth * 0.4)\n }\n height={layoutHeights.menuHeight}\n isMobile={isMobile}\n />\n </div>\n\n {/* Archetype Selection - Scrollable container */}\n <div\n style={{\n width: screenWidth < 768 ? \"100%\" : \"85%\",\n maxWidth: screenWidth < 768 ? \"100%\" : \"900px\",\n flex: 1,\n minHeight: 0,\n overflowY: \"auto\",\n overflowX: \"hidden\",\n }}\n data-testid=\"archetype-section-container\"\n >\n {useEnhancedArchetypeDisplay ? (\n <EnhancedArchetypeDisplay\n archetypes={archetypeData}\n selectedIndex={selectedArchetypeIndex}\n onArchetypeChange={handleArchetypeIndexChange}\n onPlaySFX={audio.playSFX}\n width={\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(700, screenWidth * 0.7)\n : Math.min(850, screenWidth * 0.55)\n }\n height={Math.max(layoutHeights.archetypeHeight - 40, 200)}\n isMobile={isMobile}\n allowDetailedView={screenWidth >= 768}\n />\n ) : (\n <ArchetypeDisplayOverlayHtml\n archetypes={archetypeData}\n selectedIndex={selectedArchetypeIndex}\n onArchetypeChange={handleArchetypeIndexChange}\n onPlaySFX={audio.playSFX}\n width={\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(700, screenWidth * 0.7)\n : Math.min(850, screenWidth * 0.55)\n }\n height={Math.max(layoutHeights.archetypeHeight - 40, 200)}\n isMobile={isMobile}\n />\n )}\n </div>\n </div>\n\n {/* Footer - Compact with all info */}\n <div\n style={{\n width: \"100%\",\n minHeight: `${layoutHeights.footerHeight}px`,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"1px\",\n background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${colors.footerBackground})`,\n borderTop: `1px solid ${colors.footerBorder}`,\n pointerEvents: \"auto\",\n paddingBottom: \"2px\",\n flexShrink: 0,\n }}\n data-testid=\"intro-footer\"\n >\n {/* Motto */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 3, 10)}px`,\n color: `#${theme.colors.ACCENT_CYAN.toString(16).padStart(6, \"0\")}`,\n fontFamily: theme.koreanTypography.fontFamily,\n fontStyle: \"italic\",\n textAlign: \"center\",\n }}\n data-testid=\"footer-motto\"\n >\n 흑괘의 길을 걸어라 - Walk the Path of the Black Trigram\n </div>\n {/* Open Source Link */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 4, 9)}px`,\n color: `#${theme.colors.ACCENT_BLUE.toString(16).padStart(6, \"0\")}`,\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={() =>\n window.open(\"https://github.com/Hack23/blacktrigram\", \"_blank\")\n }\n data-testid=\"footer-link\"\n >\n Open Source Korean Martial Arts Game by Hack23\n </div>\n {/* Version */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 5, 8)}px`,\n color: `#${theme.colors.ACCENT_BLUE.toString(16).padStart(6, \"0\")}`,\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={() =>\n window.open(\n `https://github.com/Hack23/blacktrigram/releases/tag/v${APP_VERSION}`,\n \"_blank\",\n )\n }\n data-testid=\"footer-version\"\n >\n v{APP_VERSION}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default IntroScreen3D;\n"],"mappings":"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"}
1
+ {"version":3,"file":"IntroScreen3D.js","names":[],"sources":["../../../../src/components/screens/intro/IntroScreen3D.tsx"],"sourcesContent":["import { Canvas } from \"@react-three/fiber\";\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport { useAudio } from \"../../../audio/AudioProvider\";\nimport { useWebGLContextLossHandler } from \"../../../hooks/useWebGLContextLossHandler\";\nimport { useWindowSize } from \"../../../hooks/useWindowSize\";\nimport { getScreenSize } from \"../../../systems/ResponsiveScaling\";\nimport { PLAYER_ARCHETYPES_DATA } from \"../../../systems/types\";\nimport { GameMode, PlayerArchetype } from \"../../../types/common\";\nimport {\n ARCHETYPE_BACKGROUNDS,\n getKoreanFontSize,\n getPerformanceSettings,\n} from \"../../../types/constants\";\nimport { Z_INDEX } from \"../../../types/LayoutTypes\";\nimport { hexToRgbaString } from \"../../../utils/colorUtils\";\nimport { shouldUseMobileControls } from \"../../../utils/deviceDetection\";\nimport { getArchetypeAssets } from \"../../../utils/playerUtils\";\nimport { useKoreanTheme } from \"../../shared/base/useKoreanTheme\";\nimport { BackgroundScene3D } from \"../../shared/three\";\nimport { VolumeControl } from \"../../shared/ui/VolumeControl\";\nimport { ArchetypeDisplayOverlayHtml } from \"./components/ArchetypeDisplayOverlayHtml\";\nimport { EnhancedArchetypeDisplay } from \"./components/EnhancedArchetypeDisplayOverlayHtml\";\nimport { MenuSectionOverlayHtml } from \"./components/MenuSectionOverlayHtml\";\n\nconst APP_VERSION = import.meta.env.APP_VERSION;\n\nexport interface IntroScreen3DProps {\n readonly onMenuSelect: (mode: GameMode, archetype?: PlayerArchetype) => void;\n readonly onArchetypeSelect?: (archetype: PlayerArchetype) => void;\n readonly selectedArchetype?: PlayerArchetype;\n readonly width?: number;\n readonly height?: number;\n readonly useEnhancedArchetypeDisplay?: boolean; // Use enhanced card display\n}\n\nconst MENU_ITEMS: { mode: GameMode; korean: string; english: string }[] = [\n { mode: GameMode.VERSUS, korean: \"대전\", english: \"Combat\" },\n { mode: GameMode.TRAINING, korean: \"훈련\", english: \"Training\" },\n { mode: GameMode.CONTROLS, korean: \"조작\", english: \"Controls\" },\n { mode: GameMode.PHILOSOPHY, korean: \"철학\", english: \"Philosophy\" },\n];\n\nconst ARCHETYPE_TEXTURE_MAPPING: Record<PlayerArchetype, string> = {\n [PlayerArchetype.MUSA]: \"musa\",\n [PlayerArchetype.AMSALJA]: \"amsalja\",\n [PlayerArchetype.HACKER]: \"hacker\",\n [PlayerArchetype.JEONGBO_YOWON]: \"jeongbo_yowon\",\n [PlayerArchetype.JOJIK_POKRYEOKBAE]: \"jojik_pokryeokbae\",\n};\n\nconst getArchetypeIndex = (archetype: PlayerArchetype): number => {\n const archetypeKeys = Object.keys(\n PLAYER_ARCHETYPES_DATA,\n ) as PlayerArchetype[];\n return archetypeKeys.indexOf(archetype);\n};\n\nconst getArchetypeFromIndex = (index: number): PlayerArchetype => {\n const archetypeKeys = Object.keys(\n PLAYER_ARCHETYPES_DATA,\n ) as PlayerArchetype[];\n return archetypeKeys[index] ?? PlayerArchetype.MUSA;\n};\n\n/**\n * Three.js-based IntroScreen Component\n */\nexport const IntroScreen3D: React.FC<IntroScreen3DProps> = ({\n onMenuSelect,\n onArchetypeSelect,\n selectedArchetype = PlayerArchetype.MUSA,\n width: propWidth,\n height: propHeight,\n useEnhancedArchetypeDisplay = true, // Default to enhanced display\n}) => {\n const audio = useAudio();\n const introMusicStarted = useRef(false);\n const [selectedMenuIndex, setSelectedMenuIndex] = useState(0);\n\n useWebGLContextLossHandler({\n onContextLost: () => {\n console.warn(\"⚠️ WebGL context lost in IntroScreen\");\n },\n onContextRestored: () => {\n console.log(\"✓ WebGL context restored in IntroScreen\");\n },\n autoRestore: true,\n });\n\n const [currentArchetype, setCurrentArchetype] =\n useState<PlayerArchetype>(selectedArchetype);\n const [selectedArchetypeIndex, setSelectedArchetypeIndex] = useState<number>(\n getArchetypeIndex(selectedArchetype),\n );\n\n const { width, height } = useWindowSize();\n\n const screenWidth = propWidth ?? (width || 1200);\n const screenHeight = propHeight ?? (height || 800);\n\n const archetypeData = useMemo(() => {\n return Object.entries(PLAYER_ARCHETYPES_DATA).map(([key, data]) => {\n const archetypeEnum = key as PlayerArchetype;\n return {\n id: key.toLowerCase(),\n korean: data.name.korean,\n english: data.name.english,\n description: data.description.korean,\n color: data.colors.primary,\n textureKey: ARCHETYPE_TEXTURE_MAPPING[archetypeEnum],\n stats: data.stats,\n philosophy: data.philosophy,\n specialAbilities: data.specialAbilities, // Include special abilities\n };\n });\n }, []);\n\n useEffect(() => {\n setCurrentArchetype(selectedArchetype);\n setSelectedArchetypeIndex(getArchetypeIndex(selectedArchetype));\n }, [selectedArchetype]);\n\n const handleMenuItemSelect = useCallback(\n (mode: GameMode) => {\n onMenuSelect(mode, currentArchetype);\n },\n [onMenuSelect, currentArchetype],\n );\n\n const handleArchetypeIndexChange = useCallback(\n (index: number) => {\n const newArchetype = getArchetypeFromIndex(index);\n setSelectedArchetypeIndex(index);\n setCurrentArchetype(newArchetype);\n onArchetypeSelect?.(newArchetype);\n\n if (audio.isAudioReady) {\n audio.playSFX(\"menu_hover\");\n\n const archetypeAssets = getArchetypeAssets(newArchetype);\n audio.stopMusic();\n audio.playMusic(archetypeAssets.themeId);\n }\n },\n [onArchetypeSelect, audio],\n );\n\n useEffect(() => {\n const startMusic = () => {\n if (audio.isAudioReady && !introMusicStarted.current) {\n introMusicStarted.current = true;\n audio.playMusic(\"intro_theme\");\n }\n };\n window.addEventListener(\"keydown\", startMusic, { once: true });\n window.addEventListener(\"mousedown\", startMusic, { once: true });\n window.addEventListener(\"touchstart\", startMusic, { once: true, passive: true });\n\n return () => {\n if (audio.isInitialized) {\n audio.stopMusic();\n }\n };\n }, [audio]);\n\n useEffect(() => {\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"ArrowLeft\") {\n const newIndex =\n selectedArchetypeIndex === 0\n ? archetypeData.length - 1\n : selectedArchetypeIndex - 1;\n handleArchetypeIndexChange(newIndex);\n } else if (event.key === \"ArrowRight\") {\n const newIndex = (selectedArchetypeIndex + 1) % archetypeData.length;\n handleArchetypeIndexChange(newIndex);\n } else {\n switch (event.key.toLowerCase()) {\n case \"c\":\n handleMenuItemSelect(GameMode.CONTROLS);\n break;\n case \"p\":\n handleMenuItemSelect(GameMode.PHILOSOPHY);\n break;\n case \"t\":\n handleMenuItemSelect(GameMode.TRAINING);\n break;\n case \"v\":\n handleMenuItemSelect(GameMode.VERSUS);\n break;\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeyDown);\n return () => window.removeEventListener(\"keydown\", handleKeyDown);\n }, [\n audio,\n archetypeData.length,\n selectedArchetypeIndex,\n handleArchetypeIndexChange,\n handleMenuItemSelect,\n ]);\n\n const isMobile = useMemo(() => shouldUseMobileControls(), []);\n\n const theme = useKoreanTheme({\n variant: \"primary\",\n size: \"md\",\n isMobile,\n });\n\n const colors = useMemo(\n () => ({\n trigramTextShadow: `0 0 10px ${hexToRgbaString(\n theme.colors.PRIMARY_CYAN,\n 0.8,\n )}`,\n footerBackground: hexToRgbaString(theme.colors.UI_BACKGROUND_DARK, 0.9),\n footerBorder: hexToRgbaString(theme.colors.ACCENT_GOLD, 0.3),\n }),\n [theme],\n );\n\n const performanceSettings = useMemo(() => {\n return getPerformanceSettings(screenWidth, isMobile);\n }, [screenWidth, isMobile]);\n\n const screenSize = useMemo(() => getScreenSize(screenWidth), [screenWidth]);\n\n const logoSize = useMemo(() => {\n const minDim = Math.min(screenWidth, screenHeight);\n const logoScale = {\n mobile: 0.28,\n tablet: 0.22,\n desktop: 0.18,\n large: 0.15,\n xlarge: 0.12,\n }[screenSize];\n return Math.min(minDim * logoScale, screenSize === \"xlarge\" ? 250 : 300);\n }, [screenWidth, screenHeight, screenSize]);\n\n const layoutHeights = useMemo(() => {\n const availableHeight = screenHeight;\n\n const titleHeight = screenWidth < 768 ? 32 : 38;\n\n const trigramHeight = screenWidth < 768 ? 16 : 22;\n const logoAreaHeight = logoSize + trigramHeight;\n\n const footerHeight = Math.max(availableHeight * 0.05, 48);\n\n const contentHeight =\n availableHeight - titleHeight - logoAreaHeight - footerHeight;\n\n const menuMinHeight = screenWidth < 768 ? 180 : 120;\n const menuPercent = screenWidth < 768 ? 0.38 : 0.25;\n const menuHeight = Math.max(contentHeight * menuPercent, menuMinHeight);\n const archetypeHeight = contentHeight - menuHeight - 8; // 8px gap\n\n const gap = Math.max(screenHeight * 0.002, 2);\n\n return {\n titleHeight,\n logoAreaHeight,\n menuHeight,\n archetypeHeight,\n footerHeight,\n gap,\n };\n }, [screenHeight, screenWidth, logoSize]);\n return (\n <div\n style={{\n width: screenWidth,\n height: screenHeight,\n position: \"relative\",\n overflow: \"hidden\",\n }}\n data-testid=\"intro-screen\"\n >\n {/* Archetype background image (very subtle, behind 3D scene) */}\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n backgroundImage: `url(${ARCHETYPE_BACKGROUNDS.overview})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n backgroundRepeat: \"no-repeat\",\n opacity: 0.08,\n filter: \"blur(4px)\",\n zIndex: Z_INDEX.BACKGROUND,\n }}\n data-testid=\"archetype-background\"\n />\n\n {/* Volume Control - outside Canvas to maintain AudioProvider context */}\n <VolumeControl position=\"top-right\" compact={isMobile} />\n\n {/* Three.js Canvas for 3D background */}\n <Canvas\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n zIndex: Z_INDEX.ARENA,\n }}\n gl={{\n antialias: performanceSettings.antialias,\n alpha: true,\n powerPreference: \"high-performance\",\n }}\n dpr={performanceSettings.dpr}\n camera={{ position: [0, 5, 10], fov: 75 }}\n onCreated={({ gl }) => {\n gl.setClearColor(theme.colors.UI_BACKGROUND_DARK, 0.95);\n }}\n >\n {/* 3D Background Scene */}\n <BackgroundScene3D theme=\"intro\" />\n </Canvas>\n\n {/* UI Overlay (positioned absolutely over Canvas) - matches CombatScreen pattern */}\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n pointerEvents: \"none\",\n zIndex: Z_INDEX.HUD,\n }}\n data-testid=\"intro-hud-overlay\"\n >\n <div\n style={{\n width: \"100vw\",\n height: \"100vh\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: 0,\n pointerEvents: \"none\",\n zIndex: Z_INDEX.HUD,\n overflow: \"hidden\",\n }}\n >\n {/* Title - Small, above logo */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"2px\",\n pointerEvents: \"none\",\n marginTop: \"4px\",\n flexShrink: 0,\n }}\n data-testid=\"main-title-container\"\n >\n <div\n style={{\n fontSize: screenWidth < 768 ? \"14px\" : \"16px\",\n fontWeight: \"bold\",\n fontFamily: theme.koreanTypography.fontFamily,\n lineHeight: theme.koreanTypography.lineHeight,\n letterSpacing: theme.koreanTypography.letterSpacing,\n wordBreak: theme.koreanTypography.wordBreak,\n color: `#${theme.colors.ACCENT_GOLD.toString(16).padStart(6, \"0\")}`,\n textShadow: \"0 0 10px rgba(255, 170, 0, 0.5)\",\n }}\n >\n 흑괘 | Black Trigram\n </div>\n <div\n style={{\n fontSize: screenWidth < 768 ? \"10px\" : \"11px\",\n fontFamily: theme.koreanTypography.fontFamily,\n color: `#${theme.colors.TEXT_SECONDARY.toString(16).padStart(6, \"0\")}`,\n }}\n >\n 한국 무술 시뮬레이터 | Korean Martial Arts Simulator\n </div>\n </div>\n\n {/* Logo Section - Primary branding */}\n <div\n style={{\n flexShrink: 0,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n height: `${layoutHeights.logoAreaHeight}px`,\n pointerEvents: \"none\",\n }}\n data-testid=\"logo-section\"\n >\n {/* Logo Image - Prominent */}\n <img\n src=\"/assets/visual/logo/black-trigram.png\"\n alt=\"Black Trigram Logo\"\n style={{\n width: `${logoSize}px`,\n height: `${logoSize}px`,\n objectFit: \"contain\",\n filter: \"drop-shadow(0 0 30px rgba(0, 255, 255, 0.6))\",\n }}\n data-testid=\"main-logo\"\n onError={(e) => {\n e.currentTarget.style.display = \"none\";\n }}\n />\n\n {/* Trigram Symbols */}\n <div\n style={{\n fontSize: screenWidth < 768 ? \"16px\" : \"18px\",\n color: `#${theme.colors.PRIMARY_CYAN.toString(16).padStart(\n 6,\n \"0\",\n )}`,\n letterSpacing: screenWidth < 768 ? \"6px\" : \"8px\",\n textAlign: \"center\",\n marginTop: screenWidth < 768 ? \"8px\" : \"10px\",\n textShadow: colors.trigramTextShadow,\n }}\n data-testid=\"trigram-symbols\"\n >\n ☰ ☱ ☲ ☳ ☴ ☵ ☶ ☷\n </div>\n </div>\n\n {/* Main Content Area */}\n <div\n style={{\n width: \"100%\",\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"flex-start\",\n gap: \"4px\",\n paddingLeft: screenWidth < 768 ? \"8px\" : \"16px\",\n paddingRight: screenWidth < 768 ? \"8px\" : \"16px\",\n overflow: \"hidden\",\n pointerEvents: \"auto\",\n minHeight: 0,\n }}\n data-testid=\"main-content\"\n >\n {/* Menu Section - Compact */}\n <div\n style={{\n width: screenWidth < 768 ? \"95%\" : \"70%\",\n maxWidth: screenWidth < 768 ? \"100%\" : \"600px\",\n }}\n data-testid=\"menu-section-container\"\n >\n <MenuSectionOverlayHtml\n menuItems={MENU_ITEMS}\n selectedIndex={selectedMenuIndex}\n onModeSelect={handleMenuItemSelect}\n onSelectedIndexChange={setSelectedMenuIndex}\n onPlaySFX={audio.playSFX}\n width={\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(500, screenWidth * 0.6)\n : Math.min(550, screenWidth * 0.4)\n }\n height={layoutHeights.menuHeight}\n isMobile={isMobile}\n />\n </div>\n\n {/* Archetype Selection - Scrollable container */}\n <div\n style={{\n width: screenWidth < 768 ? \"100%\" : \"85%\",\n maxWidth: screenWidth < 768 ? \"100%\" : \"900px\",\n flex: 1,\n minHeight: 0,\n overflowY: \"auto\",\n overflowX: \"hidden\",\n }}\n data-testid=\"archetype-section-container\"\n >\n {useEnhancedArchetypeDisplay ? (\n <EnhancedArchetypeDisplay\n archetypes={archetypeData}\n selectedIndex={selectedArchetypeIndex}\n onArchetypeChange={handleArchetypeIndexChange}\n onPlaySFX={audio.playSFX}\n width={\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(700, screenWidth * 0.7)\n : Math.min(850, screenWidth * 0.55)\n }\n height={Math.max(layoutHeights.archetypeHeight - 40, 200)}\n isMobile={isMobile}\n allowDetailedView={screenWidth >= 768}\n />\n ) : (\n <ArchetypeDisplayOverlayHtml\n archetypes={archetypeData}\n selectedIndex={selectedArchetypeIndex}\n onArchetypeChange={handleArchetypeIndexChange}\n onPlaySFX={audio.playSFX}\n width={\n screenWidth < 768\n ? screenWidth * 0.9\n : screenWidth < 1024\n ? Math.min(700, screenWidth * 0.7)\n : Math.min(850, screenWidth * 0.55)\n }\n height={Math.max(layoutHeights.archetypeHeight - 40, 200)}\n isMobile={isMobile}\n />\n )}\n </div>\n </div>\n\n {/* Footer - Compact with all info */}\n <div\n style={{\n width: \"100%\",\n minHeight: `${layoutHeights.footerHeight}px`,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n gap: \"1px\",\n background: `linear-gradient(to bottom, rgba(0, 0, 0, 0), ${colors.footerBackground})`,\n borderTop: `1px solid ${colors.footerBorder}`,\n pointerEvents: \"auto\",\n paddingBottom: \"2px\",\n flexShrink: 0,\n }}\n data-testid=\"intro-footer\"\n >\n {/* Motto */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 3, 10)}px`,\n color: `#${theme.colors.ACCENT_CYAN.toString(16).padStart(6, \"0\")}`,\n fontFamily: theme.koreanTypography.fontFamily,\n fontStyle: \"italic\",\n textAlign: \"center\",\n }}\n data-testid=\"footer-motto\"\n >\n 흑괘의 길을 걸어라 - Walk the Path of the Black Trigram\n </div>\n {/* Open Source Link */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 4, 9)}px`,\n color: `#${theme.colors.ACCENT_BLUE.toString(16).padStart(6, \"0\")}`,\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={() =>\n window.open(\"https://github.com/Hack23/blacktrigram\", \"_blank\")\n }\n data-testid=\"footer-link\"\n >\n Open Source Korean Martial Arts Game by Hack23\n </div>\n {/* Version */}\n <div\n style={{\n fontSize: `${Math.max(getKoreanFontSize(\"SMALL\", screenWidth) - 5, 8)}px`,\n color: `#${theme.colors.ACCENT_BLUE.toString(16).padStart(6, \"0\")}`,\n textAlign: \"center\",\n cursor: \"pointer\",\n }}\n onClick={() =>\n window.open(\n `https://github.com/Hack23/blacktrigram/releases/tag/v${APP_VERSION}`,\n \"_blank\",\n )\n }\n data-testid=\"footer-version\"\n >\n v{APP_VERSION}\n </div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default IntroScreen3D;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AbilityListOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/AbilityListOverlayHtml.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,EAAE,CAAC;IAC3D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuJlD,CAAC;AAIF,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"AbilityListOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/AbilityListOverlayHtml.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAKvC,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,OAAO,EAAE,CAAC;IAC3D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA2IlD,CAAC;AAIF,eAAe,WAAW,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"AbilityListOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/intro/components/AbilityListOverlayHtml.tsx"],"sourcesContent":["/**\n * AbilityList - Enhanced ability list component with Korean theming\n * \n * Refactored to use useKoreanTheme hook for consistent styling\n * Displays a list of special abilities with bilingual support\n * \n * Performance optimized with React.memo and useMemo\n * \n * @module components/screens/intro\n * @category Intro UI\n * @korean 능력리스트\n */\n\nimport React, { useMemo } from \"react\";\nimport { useKoreanTheme } from \"../../../shared/base/useKoreanTheme\";\nimport { KOREAN_COLORS } from \"../../../../types/constants\";\nimport { hexToRgbaString, hexColorToCSS } from \"../../../../utils/colorUtils\";\n\nexport interface Ability {\n readonly korean: string;\n readonly english: string;\n readonly description?: {\n readonly korean: string;\n readonly english: string;\n };\n}\n\nexport interface AbilityListProps {\n readonly abilities: readonly string[] | readonly Ability[];\n readonly maxAbilities?: number; // Maximum abilities to show\n readonly color?: number; // Accent color for abilities\n readonly isMobile?: boolean;\n}\n\n/**\n * AbilityList component - Displays a list of special abilities\n * \n * Refactored to use useKoreanTheme for consistent Korean theming:\n * - Uses Korean typography configuration\n * - Applies Korean color palette\n * - Responsive sizing based on device type\n * - Memoized for optimal performance\n * \n * Used in archetype cards to show key techniques and skills\n * \n * @example\n * ```tsx\n * <AbilityList\n * abilities={[\n * { korean: \"급소격\", english: \"Vital Strike\" },\n * { korean: \"연격\", english: \"Chain Attack\" }\n * ]}\n * color={KOREAN_COLORS.PRIMARY_CYAN}\n * isMobile={false}\n * />\n * ```\n */\nexport const AbilityList: React.FC<AbilityListProps> = React.memo(\n ({ abilities, maxAbilities = 3, color = KOREAN_COLORS.ACCENT_GOLD, isMobile = false }) => {\n // Use Korean theme hook for consistent styling\n const { koreanTypography, calculateResponsiveSize, fontFamily } = useKoreanTheme({\n size: \"small\",\n isMobile,\n });\n\n // Normalize abilities to consistent format\n const normalizedAbilities = useMemo(() => {\n return abilities.slice(0, maxAbilities).map((ability, index) => {\n if (typeof ability === \"string\") {\n // TEMPORARY: This fallback violates PRIO 2 bilingual support guidelines.\n // All abilities should use the object format with Korean/English fields.\n // See: src/systems/types.ts PLAYER_ARCHETYPES_DATA for correct format.\n // Replace with proper bilingual objects as soon as translations are available.\n return {\n id: `ability-${index}`,\n english: ability,\n korean: ability, // TEMPORARY: English used as Korean fallback\n };\n } else {\n // Object format with Korean/English\n return {\n id: `ability-${index}`,\n english: ability.english,\n korean: ability.korean,\n description: ability.description,\n };\n }\n });\n }, [abilities, maxAbilities]);\n\n // Memoize color calculations with Korean theme\n const colors = useMemo(\n () => ({\n abilityBorder: hexToRgbaString(color, 0.5),\n abilityBackground: hexToRgbaString(\n KOREAN_COLORS.UI_BACKGROUND_MEDIUM,\n 0.7\n ),\n abilityText: hexColorToCSS(color),\n descriptionText: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n }),\n [color]\n );\n\n // Responsive sizing using Korean theme utilities\n const fontSize = calculateResponsiveSize(isMobile ? 10 : 12);\n const descFontSize = calculateResponsiveSize(isMobile ? 8 : 10);\n const padding = isMobile ? `${calculateResponsiveSize(6)}px ${calculateResponsiveSize(10)}px` : `${calculateResponsiveSize(8)}px ${calculateResponsiveSize(12)}px`;\n\n if (normalizedAbilities.length === 0) {\n return null;\n }\n\n return (\n <div\n style={{\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(8)}px`,\n }}\n data-testid=\"ability-list\"\n >\n {/* Header with Korean typography */}\n <div\n style={{\n fontSize: `${calculateResponsiveSize(isMobile ? 12 : 14)}px`,\n fontWeight: \"bold\",\n fontFamily: fontFamily.KOREAN,\n color: colors.abilityText,\n // Apply Korean typography optimization\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n }}\n data-testid=\"ability-list-header\"\n >\n 특수 능력 | Special Abilities\n </div>\n\n {/* Ability items */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(6)}px`,\n }}\n >\n {normalizedAbilities.map((ability) => (\n <div\n key={ability.id}\n style={{\n padding,\n background: colors.abilityBackground,\n border: `1px solid ${colors.abilityBorder}`,\n borderRadius: \"4px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(4)}px`,\n }}\n data-testid={ability.id}\n >\n {/* Ability name with Korean typography */}\n <div\n style={{\n fontSize: `${fontSize}px`,\n fontWeight: \"bold\",\n fontFamily: fontFamily.KOREAN,\n color: colors.abilityText,\n // Apply Korean typography optimization\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n wordBreak: koreanTypography.wordBreak,\n }}\n data-testid={`${ability.id}-name`}\n >\n {ability.korean} | {ability.english}\n </div>\n\n {/* Ability description (if available) */}\n {ability.description && (\n <div\n style={{\n fontSize: `${descFontSize}px`,\n fontStyle: \"italic\",\n fontFamily: fontFamily.KOREAN,\n color: colors.descriptionText,\n // Apply Korean typography optimization\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n wordBreak: koreanTypography.wordBreak,\n }}\n data-testid={`${ability.id}-description`}\n >\n {ability.description.korean}\n {ability.description.english && (\n <>\n <br />\n {ability.description.english}\n </>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nAbilityList.displayName = \"AbilityList\";\n\nexport default AbilityList;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,IAAa,cAA0C,MAAM,MAC1D,EAAE,WAAW,eAAe,GAAG,QAAQ,cAAc,aAAa,WAAW,YAAY;CAExF,MAAM,EAAE,kBAAkB,yBAAyB,eAAe,eAAe;EAC/E,MAAM;EACN;EACD,CAAC;CAGF,MAAM,sBAAsB,cAAc;EACxC,OAAO,UAAU,MAAM,GAAG,aAAa,CAAC,KAAK,SAAS,UAAU;GAC9D,IAAI,OAAO,YAAY,UAKrB,OAAO;IACL,IAAI,WAAW;IACf,SAAS;IACT,QAAQ;IACT;QAGD,OAAO;IACL,IAAI,WAAW;IACf,SAAS,QAAQ;IACjB,QAAQ,QAAQ;IAChB,aAAa,QAAQ;IACtB;IAEH;IACD,CAAC,WAAW,aAAa,CAAC;CAG7B,MAAM,SAAS,eACN;EACL,eAAe,gBAAgB,OAAO,GAAI;EAC1C,mBAAmB,gBACjB,cAAc,sBACd,GACD;EACD,aAAa,cAAc,MAAM;EACjC,iBAAiB,cAAc,cAAc,eAAe;EAC7D,GACD,CAAC,MAAM,CACR;CAGD,MAAM,WAAW,wBAAwB,WAAW,KAAK,GAAG;CAC5D,MAAM,eAAe,wBAAwB,WAAW,IAAI,GAAG;CAC/D,MAAM,UAAU,WAAW,GAAG,wBAAwB,EAAE,CAAC,KAAK,wBAAwB,GAAG,CAAC,MAAM,GAAG,wBAAwB,EAAE,CAAC,KAAK,wBAAwB,GAAG,CAAC;CAE/J,IAAI,oBAAoB,WAAW,GACjC,OAAO;CAGT,OACE,qBAAC,OAAD;EACE,OAAO;GACL,OAAO;GACP,SAAS;GACT,eAAe;GACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;GACpC;EACD,eAAY;YAPd,CAUE,oBAAC,OAAD;GACE,OAAO;IACL,UAAU,GAAG,wBAAwB,WAAW,KAAK,GAAG,CAAC;IACzD,YAAY;IACZ,YAAY,WAAW;IACvB,OAAO,OAAO;IAEd,YAAY,iBAAiB;IAC7B,eAAe,iBAAiB;IACjC;GACD,eAAY;aACb;GAEK,CAAA,EAGN,oBAAC,OAAD;GACE,OAAO;IACL,SAAS;IACT,eAAe;IACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;IACpC;aAEA,oBAAoB,KAAK,YACxB,qBAAC,OAAD;IAEE,OAAO;KACL;KACA,YAAY,OAAO;KACnB,QAAQ,aAAa,OAAO;KAC5B,cAAc;KACd,SAAS;KACT,eAAe;KACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;KACpC;IACD,eAAa,QAAQ;cAXvB,CAcE,qBAAC,OAAD;KACE,OAAO;MACL,UAAU,GAAG,SAAS;MACtB,YAAY;MACZ,YAAY,WAAW;MACvB,OAAO,OAAO;MAEd,YAAY,iBAAiB;MAC7B,eAAe,iBAAiB;MAChC,WAAW,iBAAiB;MAC7B;KACD,eAAa,GAAG,QAAQ,GAAG;eAX7B;MAaG,QAAQ;MAAO;MAAI,QAAQ;MACxB;QAGL,QAAQ,eACP,qBAAC,OAAD;KACE,OAAO;MACL,UAAU,GAAG,aAAa;MAC1B,WAAW;MACX,YAAY,WAAW;MACvB,OAAO,OAAO;MAEd,YAAY,iBAAiB;MAC7B,eAAe,iBAAiB;MAChC,WAAW,iBAAiB;MAC7B;KACD,eAAa,GAAG,QAAQ,GAAG;eAX7B,CAaG,QAAQ,YAAY,QACpB,QAAQ,YAAY,WACnB,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,MAAD,EAAM,CAAA,EACL,QAAQ,YAAY,QACpB,EAAA,CAAA,CAED;OAEJ;MArDC,QAAQ,GAqDT,CACN;GACE,CAAA,CACF;;EAGX;AAED,YAAY,cAAc"}
1
+ {"version":3,"file":"AbilityListOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/intro/components/AbilityListOverlayHtml.tsx"],"sourcesContent":["/**\n * AbilityList - Enhanced ability list component with Korean theming\n * \n * Refactored to use useKoreanTheme hook for consistent styling\n * Displays a list of special abilities with bilingual support\n * \n * Performance optimized with React.memo and useMemo\n * \n * @module components/screens/intro\n * @category Intro UI\n * @korean 능력리스트\n */\n\nimport React, { useMemo } from \"react\";\nimport { useKoreanTheme } from \"../../../shared/base/useKoreanTheme\";\nimport { KOREAN_COLORS } from \"../../../../types/constants\";\nimport { hexToRgbaString, hexColorToCSS } from \"../../../../utils/colorUtils\";\n\nexport interface Ability {\n readonly korean: string;\n readonly english: string;\n readonly description?: {\n readonly korean: string;\n readonly english: string;\n };\n}\n\nexport interface AbilityListProps {\n readonly abilities: readonly string[] | readonly Ability[];\n readonly maxAbilities?: number; // Maximum abilities to show\n readonly color?: number; // Accent color for abilities\n readonly isMobile?: boolean;\n}\n\n/**\n * AbilityList component - Displays a list of special abilities\n * \n * Refactored to use useKoreanTheme for consistent Korean theming:\n * - Uses Korean typography configuration\n * - Applies Korean color palette\n * - Responsive sizing based on device type\n * - Memoized for optimal performance\n * \n * Used in archetype cards to show key techniques and skills\n * \n * @example\n * ```tsx\n * <AbilityList\n * abilities={[\n * { korean: \"급소격\", english: \"Vital Strike\" },\n * { korean: \"연격\", english: \"Chain Attack\" }\n * ]}\n * color={KOREAN_COLORS.PRIMARY_CYAN}\n * isMobile={false}\n * />\n * ```\n */\nexport const AbilityList: React.FC<AbilityListProps> = React.memo(\n ({ abilities, maxAbilities = 3, color = KOREAN_COLORS.ACCENT_GOLD, isMobile = false }) => {\n const { koreanTypography, calculateResponsiveSize, fontFamily } = useKoreanTheme({\n size: \"small\",\n isMobile,\n });\n\n const normalizedAbilities = useMemo(() => {\n return abilities.slice(0, maxAbilities).map((ability, index) => {\n if (typeof ability === \"string\") {\n return {\n id: `ability-${index}`,\n english: ability,\n korean: ability, // TEMPORARY: English used as Korean fallback\n };\n } else {\n return {\n id: `ability-${index}`,\n english: ability.english,\n korean: ability.korean,\n description: ability.description,\n };\n }\n });\n }, [abilities, maxAbilities]);\n\n const colors = useMemo(\n () => ({\n abilityBorder: hexToRgbaString(color, 0.5),\n abilityBackground: hexToRgbaString(\n KOREAN_COLORS.UI_BACKGROUND_MEDIUM,\n 0.7\n ),\n abilityText: hexColorToCSS(color),\n descriptionText: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n }),\n [color]\n );\n\n const fontSize = calculateResponsiveSize(isMobile ? 10 : 12);\n const descFontSize = calculateResponsiveSize(isMobile ? 8 : 10);\n const padding = isMobile ? `${calculateResponsiveSize(6)}px ${calculateResponsiveSize(10)}px` : `${calculateResponsiveSize(8)}px ${calculateResponsiveSize(12)}px`;\n\n if (normalizedAbilities.length === 0) {\n return null;\n }\n\n return (\n <div\n style={{\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(8)}px`,\n }}\n data-testid=\"ability-list\"\n >\n {/* Header with Korean typography */}\n <div\n style={{\n fontSize: `${calculateResponsiveSize(isMobile ? 12 : 14)}px`,\n fontWeight: \"bold\",\n fontFamily: fontFamily.KOREAN,\n color: colors.abilityText,\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n }}\n data-testid=\"ability-list-header\"\n >\n 특수 능력 | Special Abilities\n </div>\n\n {/* Ability items */}\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(6)}px`,\n }}\n >\n {normalizedAbilities.map((ability) => (\n <div\n key={ability.id}\n style={{\n padding,\n background: colors.abilityBackground,\n border: `1px solid ${colors.abilityBorder}`,\n borderRadius: \"4px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: `${calculateResponsiveSize(4)}px`,\n }}\n data-testid={ability.id}\n >\n {/* Ability name with Korean typography */}\n <div\n style={{\n fontSize: `${fontSize}px`,\n fontWeight: \"bold\",\n fontFamily: fontFamily.KOREAN,\n color: colors.abilityText,\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n wordBreak: koreanTypography.wordBreak,\n }}\n data-testid={`${ability.id}-name`}\n >\n {ability.korean} | {ability.english}\n </div>\n\n {/* Ability description (if available) */}\n {ability.description && (\n <div\n style={{\n fontSize: `${descFontSize}px`,\n fontStyle: \"italic\",\n fontFamily: fontFamily.KOREAN,\n color: colors.descriptionText,\n lineHeight: koreanTypography.lineHeight,\n letterSpacing: koreanTypography.letterSpacing,\n wordBreak: koreanTypography.wordBreak,\n }}\n data-testid={`${ability.id}-description`}\n >\n {ability.description.korean}\n {ability.description.english && (\n <>\n <br />\n {ability.description.english}\n </>\n )}\n </div>\n )}\n </div>\n ))}\n </div>\n </div>\n );\n }\n);\n\nAbilityList.displayName = \"AbilityList\";\n\nexport default AbilityList;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyDA,IAAa,cAA0C,MAAM,MAC1D,EAAE,WAAW,eAAe,GAAG,QAAQ,cAAc,aAAa,WAAW,YAAY;CACxF,MAAM,EAAE,kBAAkB,yBAAyB,eAAe,eAAe;EAC/E,MAAM;EACN;EACD,CAAC;CAEF,MAAM,sBAAsB,cAAc;EACxC,OAAO,UAAU,MAAM,GAAG,aAAa,CAAC,KAAK,SAAS,UAAU;GAC9D,IAAI,OAAO,YAAY,UACrB,OAAO;IACL,IAAI,WAAW;IACf,SAAS;IACT,QAAQ;IACT;QAED,OAAO;IACL,IAAI,WAAW;IACf,SAAS,QAAQ;IACjB,QAAQ,QAAQ;IAChB,aAAa,QAAQ;IACtB;IAEH;IACD,CAAC,WAAW,aAAa,CAAC;CAE7B,MAAM,SAAS,eACN;EACL,eAAe,gBAAgB,OAAO,GAAI;EAC1C,mBAAmB,gBACjB,cAAc,sBACd,GACD;EACD,aAAa,cAAc,MAAM;EACjC,iBAAiB,cAAc,cAAc,eAAe;EAC7D,GACD,CAAC,MAAM,CACR;CAED,MAAM,WAAW,wBAAwB,WAAW,KAAK,GAAG;CAC5D,MAAM,eAAe,wBAAwB,WAAW,IAAI,GAAG;CAC/D,MAAM,UAAU,WAAW,GAAG,wBAAwB,EAAE,CAAC,KAAK,wBAAwB,GAAG,CAAC,MAAM,GAAG,wBAAwB,EAAE,CAAC,KAAK,wBAAwB,GAAG,CAAC;CAE/J,IAAI,oBAAoB,WAAW,GACjC,OAAO;CAGT,OACE,qBAAC,OAAD;EACE,OAAO;GACL,OAAO;GACP,SAAS;GACT,eAAe;GACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;GACpC;EACD,eAAY;YAPd,CAUE,oBAAC,OAAD;GACE,OAAO;IACL,UAAU,GAAG,wBAAwB,WAAW,KAAK,GAAG,CAAC;IACzD,YAAY;IACZ,YAAY,WAAW;IACvB,OAAO,OAAO;IACd,YAAY,iBAAiB;IAC7B,eAAe,iBAAiB;IACjC;GACD,eAAY;aACb;GAEK,CAAA,EAGN,oBAAC,OAAD;GACE,OAAO;IACL,SAAS;IACT,eAAe;IACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;IACpC;aAEA,oBAAoB,KAAK,YACxB,qBAAC,OAAD;IAEE,OAAO;KACL;KACA,YAAY,OAAO;KACnB,QAAQ,aAAa,OAAO;KAC5B,cAAc;KACd,SAAS;KACT,eAAe;KACf,KAAK,GAAG,wBAAwB,EAAE,CAAC;KACpC;IACD,eAAa,QAAQ;cAXvB,CAcE,qBAAC,OAAD;KACE,OAAO;MACL,UAAU,GAAG,SAAS;MACtB,YAAY;MACZ,YAAY,WAAW;MACvB,OAAO,OAAO;MACd,YAAY,iBAAiB;MAC7B,eAAe,iBAAiB;MAChC,WAAW,iBAAiB;MAC7B;KACD,eAAa,GAAG,QAAQ,GAAG;eAV7B;MAYG,QAAQ;MAAO;MAAI,QAAQ;MACxB;QAGL,QAAQ,eACP,qBAAC,OAAD;KACE,OAAO;MACL,UAAU,GAAG,aAAa;MAC1B,WAAW;MACX,YAAY,WAAW;MACvB,OAAO,OAAO;MACd,YAAY,iBAAiB;MAC7B,eAAe,iBAAiB;MAChC,WAAW,iBAAiB;MAC7B;KACD,eAAa,GAAG,QAAQ,GAAG;eAV7B,CAYG,QAAQ,YAAY,QACpB,QAAQ,YAAY,WACnB,qBAAA,UAAA,EAAA,UAAA,CACE,oBAAC,MAAD,EAAM,CAAA,EACL,QAAQ,YAAY,QACpB,EAAA,CAAA,CAED;OAEJ;MAnDC,QAAQ,GAmDT,CACN;GACE,CAAA,CACF;;EAGX;AAED,YAAY,cAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"ArchetypeCardGridOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/ArchetypeCardGridOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG3D,OAAO,EAAiB,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,iBAAiB,EAAE,eAAe,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAmN9D,CAAC;AAIF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"ArchetypeCardGridOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/ArchetypeCardGridOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAG3D,OAAO,EAAiB,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAE9E,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAClD,QAAQ,CAAC,iBAAiB,EAAE,eAAe,CAAC;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACjE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAyM9D,CAAC;AAIF,eAAe,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ArchetypeCardGridOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/intro/components/ArchetypeCardGridOverlayHtml.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { PlayerArchetype } from \"../../../../types/common\";\nimport { FONT_FAMILY, KOREAN_COLORS } from \"../../../../types/constants\";\nimport { hexColorToCSS, hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { ArchetypeCard, ArchetypeCardData } from \"./ArchetypeCardOverlayHtml\";\n\nexport interface ArchetypeCardGridProps {\n readonly archetypes: readonly ArchetypeCardData[];\n readonly selectedArchetype: PlayerArchetype;\n readonly onArchetypeChange: (archetype: PlayerArchetype) => void;\n readonly onArchetypeConfirm?: (archetype: PlayerArchetype) => void;\n readonly onPlaySFX: (sound: string) => void;\n readonly width?: number;\n readonly height?: number;\n readonly isMobile?: boolean;\n}\n\n/**\n * ArchetypeCardGrid - Grid layout for displaying multiple archetype cards\n * Provides an enhanced selection interface with detailed preview cards\n */\nexport const ArchetypeCardGrid: React.FC<ArchetypeCardGridProps> = React.memo(\n ({\n archetypes,\n selectedArchetype,\n onArchetypeChange,\n onArchetypeConfirm,\n onPlaySFX,\n width = 900,\n height = 600,\n isMobile: _isMobile = false, // Kept for interface compatibility, layout uses width\n }) => {\n // Note: _isMobile intentionally unused - layout sizing uses width-based checks\n void _isMobile;\n\n // Use width for layout sizing decisions\n const isSmallScreen = width < 768;\n\n // Find selected archetype index\n const selectedIndex = useMemo(() => {\n return archetypes.findIndex((a) => a.archetype === selectedArchetype);\n }, [archetypes, selectedArchetype]);\n\n // Calculate card dimensions based on container and screen size\n const cardWidth = useMemo(() => {\n if (isSmallScreen) return Math.min(280, width - 40);\n const isLargeContainer = width >= 1100;\n return isLargeContainer ? 340 : 380;\n }, [isSmallScreen, width]);\n\n // Memoize colors\n const colors = useMemo(\n () => ({\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_DARK, 0.95),\n border: hexToRgbaString(KOREAN_COLORS.PRIMARY_CYAN, 0.7),\n headerColor: hexColorToCSS(KOREAN_COLORS.ACCENT_GOLD),\n }),\n [],\n );\n\n // Handle card selection\n const handleCardSelect = useCallback(\n (archetype: PlayerArchetype) => {\n onArchetypeChange(archetype);\n onPlaySFX(\"menu_hover\");\n },\n [onArchetypeChange, onPlaySFX],\n );\n\n // Handle card confirmation\n const handleCardConfirm = useCallback(\n (archetype: PlayerArchetype) => {\n onArchetypeConfirm?.(archetype);\n onPlaySFX(\"menu_select\");\n },\n [onArchetypeConfirm, onPlaySFX],\n );\n\n // Handle keyboard navigation (scoped to container)\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n const newIndex =\n selectedIndex === 0 ? archetypes.length - 1 : selectedIndex - 1;\n const newArchetype = archetypes[newIndex].archetype;\n handleCardSelect(newArchetype);\n } else if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n const newIndex = (selectedIndex + 1) % archetypes.length;\n const newArchetype = archetypes[newIndex].archetype;\n handleCardSelect(newArchetype);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n if (onArchetypeConfirm) {\n handleCardConfirm(selectedArchetype);\n }\n }\n },\n [\n selectedIndex,\n archetypes,\n selectedArchetype,\n handleCardSelect,\n handleCardConfirm,\n onArchetypeConfirm,\n ],\n );\n\n // Calculate grid layout\n const columnsCount = isSmallScreen ? 1 : width >= 1400 ? 3 : 2;\n const gap = isSmallScreen ? 16 : 20;\n\n // Custom focus style for keyboard navigation\n const [isFocused, setIsFocused] = React.useState(false);\n\n return (\n <div\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n style={{\n width: `${width}px`,\n minHeight: `${height}px`,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: `${gap}px`,\n background: colors.background,\n borderRadius: \"12px\",\n border: `2px solid ${colors.border}`,\n padding: isSmallScreen ? \"16px\" : \"24px\",\n overflow: \"auto\",\n maxHeight: `${height}px`,\n outline: isFocused ? `3px solid ${colors.headerColor}` : \"none\",\n outlineOffset: \"2px\",\n }}\n data-testid=\"archetype-card-grid\"\n role=\"region\"\n aria-label=\"Archetype selection grid\"\n >\n {/* Header */}\n <div\n style={{\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n marginBottom: `${gap / 2}px`,\n }}\n >\n <h2\n style={{\n fontSize: isSmallScreen ? \"20px\" : \"28px\",\n fontWeight: \"bold\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: colors.headerColor,\n margin: 0,\n textAlign: \"center\",\n }}\n data-testid=\"grid-header\"\n >\n 원형 선택 | Select Archetype\n </h2>\n\n <div\n style={{\n fontSize: isSmallScreen ? \"12px\" : \"14px\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n textAlign: \"center\",\n fontStyle: \"italic\",\n }}\n data-testid=\"grid-hint\"\n >\n {isSmallScreen\n ? \"카드를 탭하여 선택\"\n : \"화살표 키로 탐색, 엔터로 확인 | Arrow keys to navigate, Enter to confirm\"}\n </div>\n </div>\n\n {/* Card Grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${columnsCount}, 1fr)`,\n gap: `${gap}px`,\n width: \"100%\",\n justifyItems: \"center\",\n }}\n data-testid=\"card-grid-container\"\n >\n {archetypes.map((archetype) => (\n <ArchetypeCard\n key={archetype.id}\n data={archetype}\n isSelected={archetype.archetype === selectedArchetype}\n onSelect={() => handleCardSelect(archetype.archetype)}\n onConfirm={\n onArchetypeConfirm\n ? () => handleCardConfirm(archetype.archetype)\n : undefined\n }\n isMobile={isSmallScreen}\n width={cardWidth}\n showSelectButton={!!onArchetypeConfirm}\n />\n ))}\n </div>\n\n {/* Footer navigation hint */}\n {!isSmallScreen && (\n <div\n style={{\n marginTop: `${gap}px`,\n fontSize: \"12px\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n textAlign: \"center\",\n fontStyle: \"italic\",\n }}\n data-testid=\"grid-footer\"\n >\n ← → 또는 ↑ ↓ 키로 원형 변경 | Use ← → or ↑ ↓ keys to change\n archetype\n </div>\n )}\n </div>\n );\n },\n);\n\nArchetypeCardGrid.displayName = \"ArchetypeCardGrid\";\n\nexport default ArchetypeCardGrid;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ArchetypeCardGridOverlayHtml.js","names":[],"sources":["../../../../../src/components/screens/intro/components/ArchetypeCardGridOverlayHtml.tsx"],"sourcesContent":["import React, { useCallback, useMemo } from \"react\";\nimport { PlayerArchetype } from \"../../../../types/common\";\nimport { FONT_FAMILY, KOREAN_COLORS } from \"../../../../types/constants\";\nimport { hexColorToCSS, hexToRgbaString } from \"../../../../utils/colorUtils\";\nimport { ArchetypeCard, ArchetypeCardData } from \"./ArchetypeCardOverlayHtml\";\n\nexport interface ArchetypeCardGridProps {\n readonly archetypes: readonly ArchetypeCardData[];\n readonly selectedArchetype: PlayerArchetype;\n readonly onArchetypeChange: (archetype: PlayerArchetype) => void;\n readonly onArchetypeConfirm?: (archetype: PlayerArchetype) => void;\n readonly onPlaySFX: (sound: string) => void;\n readonly width?: number;\n readonly height?: number;\n readonly isMobile?: boolean;\n}\n\n/**\n * ArchetypeCardGrid - Grid layout for displaying multiple archetype cards\n * Provides an enhanced selection interface with detailed preview cards\n */\nexport const ArchetypeCardGrid: React.FC<ArchetypeCardGridProps> = React.memo(\n ({\n archetypes,\n selectedArchetype,\n onArchetypeChange,\n onArchetypeConfirm,\n onPlaySFX,\n width = 900,\n height = 600,\n isMobile: _isMobile = false, // Kept for interface compatibility, layout uses width\n }) => {\n void _isMobile;\n\n const isSmallScreen = width < 768;\n\n const selectedIndex = useMemo(() => {\n return archetypes.findIndex((a) => a.archetype === selectedArchetype);\n }, [archetypes, selectedArchetype]);\n\n const cardWidth = useMemo(() => {\n if (isSmallScreen) return Math.min(280, width - 40);\n const isLargeContainer = width >= 1100;\n return isLargeContainer ? 340 : 380;\n }, [isSmallScreen, width]);\n\n const colors = useMemo(\n () => ({\n background: hexToRgbaString(KOREAN_COLORS.UI_BACKGROUND_DARK, 0.95),\n border: hexToRgbaString(KOREAN_COLORS.PRIMARY_CYAN, 0.7),\n headerColor: hexColorToCSS(KOREAN_COLORS.ACCENT_GOLD),\n }),\n [],\n );\n\n const handleCardSelect = useCallback(\n (archetype: PlayerArchetype) => {\n onArchetypeChange(archetype);\n onPlaySFX(\"menu_hover\");\n },\n [onArchetypeChange, onPlaySFX],\n );\n\n const handleCardConfirm = useCallback(\n (archetype: PlayerArchetype) => {\n onArchetypeConfirm?.(archetype);\n onPlaySFX(\"menu_select\");\n },\n [onArchetypeConfirm, onPlaySFX],\n );\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n const newIndex =\n selectedIndex === 0 ? archetypes.length - 1 : selectedIndex - 1;\n const newArchetype = archetypes[newIndex].archetype;\n handleCardSelect(newArchetype);\n } else if (event.key === \"ArrowRight\" || event.key === \"ArrowDown\") {\n event.preventDefault();\n const newIndex = (selectedIndex + 1) % archetypes.length;\n const newArchetype = archetypes[newIndex].archetype;\n handleCardSelect(newArchetype);\n } else if (event.key === \"Enter\") {\n event.preventDefault();\n if (onArchetypeConfirm) {\n handleCardConfirm(selectedArchetype);\n }\n }\n },\n [\n selectedIndex,\n archetypes,\n selectedArchetype,\n handleCardSelect,\n handleCardConfirm,\n onArchetypeConfirm,\n ],\n );\n\n const columnsCount = isSmallScreen ? 1 : width >= 1400 ? 3 : 2;\n const gap = isSmallScreen ? 16 : 20;\n\n const [isFocused, setIsFocused] = React.useState(false);\n\n return (\n <div\n tabIndex={0}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n style={{\n width: `${width}px`,\n minHeight: `${height}px`,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: `${gap}px`,\n background: colors.background,\n borderRadius: \"12px\",\n border: `2px solid ${colors.border}`,\n padding: isSmallScreen ? \"16px\" : \"24px\",\n overflow: \"auto\",\n maxHeight: `${height}px`,\n outline: isFocused ? `3px solid ${colors.headerColor}` : \"none\",\n outlineOffset: \"2px\",\n }}\n data-testid=\"archetype-card-grid\"\n role=\"region\"\n aria-label=\"Archetype selection grid\"\n >\n {/* Header */}\n <div\n style={{\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n gap: \"8px\",\n marginBottom: `${gap / 2}px`,\n }}\n >\n <h2\n style={{\n fontSize: isSmallScreen ? \"20px\" : \"28px\",\n fontWeight: \"bold\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: colors.headerColor,\n margin: 0,\n textAlign: \"center\",\n }}\n data-testid=\"grid-header\"\n >\n 원형 선택 | Select Archetype\n </h2>\n\n <div\n style={{\n fontSize: isSmallScreen ? \"12px\" : \"14px\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n textAlign: \"center\",\n fontStyle: \"italic\",\n }}\n data-testid=\"grid-hint\"\n >\n {isSmallScreen\n ? \"카드를 탭하여 선택\"\n : \"화살표 키로 탐색, 엔터로 확인 | Arrow keys to navigate, Enter to confirm\"}\n </div>\n </div>\n\n {/* Card Grid */}\n <div\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${columnsCount}, 1fr)`,\n gap: `${gap}px`,\n width: \"100%\",\n justifyItems: \"center\",\n }}\n data-testid=\"card-grid-container\"\n >\n {archetypes.map((archetype) => (\n <ArchetypeCard\n key={archetype.id}\n data={archetype}\n isSelected={archetype.archetype === selectedArchetype}\n onSelect={() => handleCardSelect(archetype.archetype)}\n onConfirm={\n onArchetypeConfirm\n ? () => handleCardConfirm(archetype.archetype)\n : undefined\n }\n isMobile={isSmallScreen}\n width={cardWidth}\n showSelectButton={!!onArchetypeConfirm}\n />\n ))}\n </div>\n\n {/* Footer navigation hint */}\n {!isSmallScreen && (\n <div\n style={{\n marginTop: `${gap}px`,\n fontSize: \"12px\",\n fontFamily: FONT_FAMILY.KOREAN,\n color: hexColorToCSS(KOREAN_COLORS.TEXT_SECONDARY),\n textAlign: \"center\",\n fontStyle: \"italic\",\n }}\n data-testid=\"grid-footer\"\n >\n ← → 또는 ↑ ↓ 키로 원형 변경 | Use ← → or ↑ ↓ keys to change\n archetype\n </div>\n )}\n </div>\n );\n },\n);\n\nArchetypeCardGrid.displayName = \"ArchetypeCardGrid\";\n\nexport default ArchetypeCardGrid;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ArchetypeCardOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/ArchetypeCardOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAO3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA0StD,CAAC;AAIF,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"ArchetypeCardOverlayHtml.d.ts","sourceRoot":"","sources":["../../../../../src/components/screens/intro/components/ArchetypeCardOverlayHtml.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAO3D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE;QACd,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,QAAQ,CAAC,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,iBAAiB,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACrC;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAiStD,CAAC;AAIF,eAAe,aAAa,CAAC"}