blacktrigram 0.7.67 → 0.7.69

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 (219) hide show
  1. package/lib/App2.js.map +1 -1
  2. package/lib/assets/index.css +987 -987
  3. package/lib/audio/AudioAssetLoader.js.map +1 -1
  4. package/lib/audio/AudioAssetRegistry.js +2 -2
  5. package/lib/audio/AudioAssetRegistry.js.map +1 -1
  6. package/lib/audio/AudioCache.js.map +1 -1
  7. package/lib/audio/AudioManager.js +1 -1
  8. package/lib/audio/AudioManager.js.map +1 -1
  9. package/lib/audio/AudioMonitor.js.map +1 -1
  10. package/lib/audio/AudioPool.js.map +1 -1
  11. package/lib/audio/AudioProvider.js.map +1 -1
  12. package/lib/audio/AudioUtils.js.map +1 -1
  13. package/lib/audio/BoneImpactAudioMap.js.map +1 -1
  14. package/lib/components/screens/combat/CombatScreen3D.js +3 -3
  15. package/lib/components/screens/combat/CombatScreen3D.js.map +1 -1
  16. package/lib/components/screens/combat/components/controls/CombatControlsPanel.js.map +1 -1
  17. package/lib/components/screens/combat/components/controls/PauseMenu.js.map +1 -1
  18. package/lib/components/screens/combat/components/effects/BloodDecals3D.js.map +1 -1
  19. package/lib/components/screens/combat/components/effects/BloodParticles3D.js.map +1 -1
  20. package/lib/components/screens/combat/components/effects/BloodViscosity3D.js.map +1 -1
  21. package/lib/components/screens/combat/components/effects/CombatParticleEffects3D.js.map +1 -1
  22. package/lib/components/screens/combat/components/effects/InternalDamage3D.js.map +1 -1
  23. package/lib/components/screens/combat/components/effects/ParticleAudio3D.js.map +1 -1
  24. package/lib/components/screens/combat/components/hud/FPSMonitor.js.map +1 -1
  25. package/lib/components/screens/combat/components/indicators/BalanceIndicator.js.map +1 -1
  26. package/lib/components/screens/combat/hooks/useAICombat.js.map +1 -1
  27. package/lib/components/screens/combat/hooks/useCombatActions.js.map +1 -1
  28. package/lib/components/screens/combat/hooks/useCombatAttackMovement.js.map +1 -1
  29. package/lib/components/screens/controls/ControlsScreen3D.js.map +1 -1
  30. package/lib/components/screens/controls/components/ControlCategoryTabsOverlayHtml.js.map +1 -1
  31. package/lib/components/screens/endscreen/components/MatchStatisticsDisplayOverlayHtml.js.map +1 -1
  32. package/lib/components/screens/endscreen/components/PerformanceBreakdownOverlayHtml.js.map +1 -1
  33. package/lib/components/screens/endscreen/components/VictoryAnimation3D.js.map +1 -1
  34. package/lib/components/screens/intro/IntroScreen3D.js +1 -1
  35. package/lib/components/screens/intro/IntroScreen3D.js.map +1 -1
  36. package/lib/components/screens/intro/components/AbilityListOverlayHtml.js.map +1 -1
  37. package/lib/components/screens/intro/components/ArchetypeCardGridOverlayHtml.js.map +1 -1
  38. package/lib/components/screens/intro/components/ArchetypeDisplayOverlayHtml.js.map +1 -1
  39. package/lib/components/screens/intro/components/EnhancedArchetypeDisplayOverlayHtml.js.map +1 -1
  40. package/lib/components/screens/intro/components/MenuButtonsOverlayHtml.js.map +1 -1
  41. package/lib/components/screens/intro/components/MenuSectionOverlayHtml.js.map +1 -1
  42. package/lib/components/screens/intro/components/StatBarOverlayHtml.js.map +1 -1
  43. package/lib/components/screens/philosophy/PhilosophyScreen3D.js.map +1 -1
  44. package/lib/components/screens/training/TrainingScreen3D.js +1 -1
  45. package/lib/components/screens/training/TrainingScreen3D.js.map +1 -1
  46. package/lib/components/screens/training/components/AnatomyOverlay3D.js.map +1 -1
  47. package/lib/components/screens/training/components/FootworkDrillsOverlayHtml.js.map +1 -1
  48. package/lib/components/screens/training/components/HitFeedbackEffect3D.js.map +1 -1
  49. package/lib/components/screens/training/components/TrainingButtonsOverlayHtml.js.map +1 -1
  50. package/lib/components/screens/training/components/TrainingDummy3D.js.map +1 -1
  51. package/lib/components/screens/training/components/TrainingModeSelectorOverlayHtml.js.map +1 -1
  52. package/lib/components/screens/training/components/TrainingStatsOverlayHtml.js.map +1 -1
  53. package/lib/components/screens/training/components/VitalPointMarker3D.js.map +1 -1
  54. package/lib/components/screens/training/hooks/useAttackMovement.js.map +1 -1
  55. package/lib/components/screens/training/hooks/useTrainingActions.js.map +1 -1
  56. package/lib/components/shared/mobile/ActionButtons.js.map +1 -1
  57. package/lib/components/shared/mobile/GestureRecognizerPure.js.map +1 -1
  58. package/lib/components/shared/mobile/HapticController.js.map +1 -1
  59. package/lib/components/shared/mobile/StanceWheelPure.js.map +1 -1
  60. package/lib/components/shared/mobile/VirtualDPad.js.map +1 -1
  61. package/lib/components/shared/three/anatomy/BoneAttachedMuscles.js.map +1 -1
  62. package/lib/components/shared/three/anatomy/BoneClothing.js.map +1 -1
  63. package/lib/components/shared/three/anatomy/BoneRenderer.js.map +1 -1
  64. package/lib/components/shared/three/anatomy/Face3D.js.map +1 -1
  65. package/lib/components/shared/three/effects/ActionFeedback.js.map +1 -1
  66. package/lib/components/shared/three/effects/DamageNumbers.js.map +1 -1
  67. package/lib/components/shared/three/effects/HitEffects3D.js.map +1 -1
  68. package/lib/components/shared/three/effects/StanceTransitionEffect.js.map +1 -1
  69. package/lib/components/shared/three/effects/VitalPointMarkers3D.js.map +1 -1
  70. package/lib/components/shared/three/indicators/ElementalColorSystem.js.map +1 -1
  71. package/lib/components/shared/three/indicators/GuardIndicator.js.map +1 -1
  72. package/lib/components/shared/three/scene/CombatArena3D.js.map +1 -1
  73. package/lib/components/shared/three/ui/BodyPartHealthDisplay.js.map +1 -1
  74. package/lib/components/shared/three/ui/CombatReadinessBar.js.map +1 -1
  75. package/lib/components/shared/three/ui/HealthBar.js.map +1 -1
  76. package/lib/components/shared/three/ui/PlayerHUD.js.map +1 -1
  77. package/lib/components/shared/three/ui/SpeedIndicatorHUD.js.map +1 -1
  78. package/lib/components/shared/three/ui/StaminaBar.js.map +1 -1
  79. package/lib/components/shared/three/ui/TechniqueCard.js.map +1 -1
  80. package/lib/components/shared/three/ui/VitalPointOverlayControlsHtml.js.map +1 -1
  81. package/lib/components/shared/ui/SplashScreen.js +2 -2
  82. package/lib/components/shared/ui/VitalPointOverlayControlsPure.js.map +1 -1
  83. package/lib/components/ui/combat/BalanceIndicatorOverlayHtml.js.map +1 -1
  84. package/lib/data/techniques.js.map +1 -1
  85. package/lib/hooks/useCombatTimer.js.map +1 -1
  86. package/lib/hooks/useKeyboardControls.js.map +1 -1
  87. package/lib/hooks/useSkeletalAnimation.js +2 -2
  88. package/lib/hooks/useSkeletalAnimation.js.map +1 -1
  89. package/lib/hooks/useTechniqueSelection.js.map +1 -1
  90. package/lib/hooks/useWebGLContextLossHandler.js.map +1 -1
  91. package/lib/index.js +2 -2
  92. package/lib/systems/CombatSystem.js.map +1 -1
  93. package/lib/systems/EffectCalculator.js.map +1 -1
  94. package/lib/systems/ResponsiveScaling.js.map +1 -1
  95. package/lib/systems/TrigramSystem.js.map +1 -1
  96. package/lib/systems/ai/AIPersonality.js.map +1 -1
  97. package/lib/systems/ai/ArchetypeEnforcer.js.map +1 -1
  98. package/lib/systems/ai/DecisionTree.js.map +1 -1
  99. package/lib/systems/animation/builders/KeyframeConfig.js.map +1 -1
  100. package/lib/systems/animation/builders/KeyframeInterpolation.js.map +1 -1
  101. package/lib/systems/animation/builders/MartialArtsAnimationBuilder.js.map +1 -1
  102. package/lib/systems/animation/builders/SkeletonRig.js +1 -1
  103. package/lib/systems/animation/builders/SkeletonRig.js.map +1 -1
  104. package/lib/systems/animation/catalogs/AttackAnimations.js +1 -1
  105. package/lib/systems/animation/catalogs/AttackAnimations.js.map +1 -1
  106. package/lib/systems/animation/catalogs/BasicAnimations.js +1 -1
  107. package/lib/systems/animation/catalogs/BasicAnimations.js.map +1 -1
  108. package/lib/systems/animation/catalogs/ComboAnimations.js +1 -1
  109. package/lib/systems/animation/catalogs/ComboAnimations.js.map +1 -1
  110. package/lib/systems/animation/catalogs/DarkOpsAnimations.js +1 -1
  111. package/lib/systems/animation/catalogs/DarkOpsAnimations.js.map +1 -1
  112. package/lib/systems/animation/catalogs/DefensiveAnimations.js +2 -11
  113. package/lib/systems/animation/catalogs/DefensiveAnimations.js.map +1 -1
  114. package/lib/systems/animation/catalogs/ElbowKneeAnimations.js +1 -1
  115. package/lib/systems/animation/catalogs/ElbowKneeAnimations.js.map +1 -1
  116. package/lib/systems/animation/catalogs/FootworkSkeletalAnimations.js +1 -1
  117. package/lib/systems/animation/catalogs/FootworkSkeletalAnimations.js.map +1 -1
  118. package/lib/systems/animation/catalogs/GamRedirectionAnimations.js.map +1 -1
  119. package/lib/systems/animation/catalogs/GamStanceAnimations.js.map +1 -1
  120. package/lib/systems/animation/catalogs/GamTechniqueAnimations.js.map +1 -1
  121. package/lib/systems/animation/catalogs/GanStanceAnimations.js +1 -1
  122. package/lib/systems/animation/catalogs/GanStanceAnimations.js.map +1 -1
  123. package/lib/systems/animation/catalogs/GanTechniqueAnimations.js +1 -1
  124. package/lib/systems/animation/catalogs/GanTechniqueAnimations.js.map +1 -1
  125. package/lib/systems/animation/catalogs/GeonStanceAnimations.js +1 -1
  126. package/lib/systems/animation/catalogs/GeonStanceAnimations.js.map +1 -1
  127. package/lib/systems/animation/catalogs/GonTechniqueAnimations.js +1 -1
  128. package/lib/systems/animation/catalogs/GonTechniqueAnimations.js.map +1 -1
  129. package/lib/systems/animation/catalogs/GrapplingAnimations.js +1 -1
  130. package/lib/systems/animation/catalogs/GrapplingAnimations.js.map +1 -1
  131. package/lib/systems/animation/catalogs/JinStanceAnimations.js +1 -1
  132. package/lib/systems/animation/catalogs/JinStanceAnimations.js.map +1 -1
  133. package/lib/systems/animation/catalogs/JinTechniqueAnimations.js +1 -1
  134. package/lib/systems/animation/catalogs/JinTechniqueAnimations.js.map +1 -1
  135. package/lib/systems/animation/catalogs/KickAnimations.js +1 -1
  136. package/lib/systems/animation/catalogs/KickAnimations.js.map +1 -1
  137. package/lib/systems/animation/catalogs/LiStanceAnimations.js +1 -1
  138. package/lib/systems/animation/catalogs/LiStanceAnimations.js.map +1 -1
  139. package/lib/systems/animation/catalogs/LiTechniqueAnimations.js.map +1 -1
  140. package/lib/systems/animation/catalogs/MovementAnimations.js +1 -1
  141. package/lib/systems/animation/catalogs/MovementAnimations.js.map +1 -1
  142. package/lib/systems/animation/catalogs/PunchAnimations.js +1 -1
  143. package/lib/systems/animation/catalogs/PunchAnimations.js.map +1 -1
  144. package/lib/systems/animation/catalogs/SonStanceAnimations.js +1 -1
  145. package/lib/systems/animation/catalogs/SonStanceAnimations.js.map +1 -1
  146. package/lib/systems/animation/catalogs/SonTechniqueAnimations.js +1 -1
  147. package/lib/systems/animation/catalogs/SonTechniqueAnimations.js.map +1 -1
  148. package/lib/systems/animation/catalogs/SpecializedPunchAnimations.js +1 -1
  149. package/lib/systems/animation/catalogs/SpecializedPunchAnimations.js.map +1 -1
  150. package/lib/systems/animation/catalogs/StanceAnimations.js +1 -1
  151. package/lib/systems/animation/catalogs/StanceAnimations.js.map +1 -1
  152. package/lib/systems/animation/catalogs/StanceAttackAnimations.js +215 -272
  153. package/lib/systems/animation/catalogs/StanceAttackAnimations.js.map +1 -1
  154. package/lib/systems/animation/catalogs/StanceIdleAnimations.js +2 -11
  155. package/lib/systems/animation/catalogs/StanceIdleAnimations.js.map +1 -1
  156. package/lib/systems/animation/catalogs/StanceLocomotionAnimations.js +2 -2
  157. package/lib/systems/animation/catalogs/StanceLocomotionAnimations.js.map +1 -1
  158. package/lib/systems/animation/catalogs/StepSkeletalAnimations.js +1 -1
  159. package/lib/systems/animation/catalogs/StepSkeletalAnimations.js.map +1 -1
  160. package/lib/systems/animation/catalogs/TaeJointLockAnimations.js.map +1 -1
  161. package/lib/systems/animation/catalogs/TaeStanceAnimations.js +1 -1
  162. package/lib/systems/animation/catalogs/TaeStanceAnimations.js.map +1 -1
  163. package/lib/systems/animation/core/AnimationOptimizations.js +1 -1
  164. package/lib/systems/animation/core/AnimationOptimizations.js.map +1 -1
  165. package/lib/systems/animation/core/AnimationPriority.js.map +1 -1
  166. package/lib/systems/animation/core/AnimationRegistry.js +11 -209
  167. package/lib/systems/animation/core/AnimationRegistry.js.map +1 -1
  168. package/lib/systems/animation/core/AnimationStateMachine.js +2 -2
  169. package/lib/systems/animation/core/AnimationStateMachine.js.map +1 -1
  170. package/lib/systems/animation/core/TechniqueAnimationMapper.js +1 -1
  171. package/lib/systems/animation/core/TechniqueAnimationMapper.js.map +1 -1
  172. package/lib/systems/animation/core/TechniqueAnimationMapping.js +1 -1
  173. package/lib/systems/animation/core/TechniqueAnimationMapping.js.map +1 -1
  174. package/lib/systems/animation/systems/MuscleActivation.js.map +1 -1
  175. package/lib/systems/bodypart/BodyPartDamageIntegration.js.map +1 -1
  176. package/lib/systems/bodypart/BodyPartHealthSystem.js.map +1 -1
  177. package/lib/systems/bodypart/BodyPartPositionMapping.js.map +1 -1
  178. package/lib/systems/bodypart/InjuryTracker.js.map +1 -1
  179. package/lib/systems/breathing/BreathingDisruptionSystem.js.map +1 -1
  180. package/lib/systems/combat/BalanceSystem.js.map +1 -1
  181. package/lib/systems/combat/BreakingStatusEffects.js.map +1 -1
  182. package/lib/systems/combat/CombatStateSystem.js.map +1 -1
  183. package/lib/systems/combat/GrappleSystem.js.map +1 -1
  184. package/lib/systems/combat/painConsciousnessUtils.js.map +1 -1
  185. package/lib/systems/combat/typeGuards.js.map +1 -1
  186. package/lib/systems/index.js +2 -2
  187. package/lib/systems/movement/integration.js.map +1 -1
  188. package/lib/systems/physics/AttackMovementPhysics.js.map +1 -1
  189. package/lib/systems/physics/CollisionDetection.js +1 -1
  190. package/lib/systems/physics/CollisionDetection.js.map +1 -1
  191. package/lib/systems/physics/KnockbackPhysics.js.map +1 -1
  192. package/lib/systems/physics/MovementPhysics.js.map +1 -1
  193. package/lib/systems/physics/PhysicalReachCalculator.js.map +1 -1
  194. package/lib/systems/physics/SpeedModifierSystem.js.map +1 -1
  195. package/lib/systems/trigram/KoreanTechniques.js.map +1 -1
  196. package/lib/systems/trigram/StanceManager.js.map +1 -1
  197. package/lib/systems/trigram/TransitionCalculator.js.map +1 -1
  198. package/lib/systems/trigram/TrigramCalculator.js.map +1 -1
  199. package/lib/systems/trigram/techniques/TechniqueConfig.js.map +1 -1
  200. package/lib/systems/trigram/techniques/index.js.map +1 -1
  201. package/lib/systems/trigram/types.js.map +1 -1
  202. package/lib/systems/vitalpoint/DamageCalculator.js.map +1 -1
  203. package/lib/systems/vitalpoint/KoreanAnatomy.js.map +1 -1
  204. package/lib/systems/vitalpoint/KoreanVitalPoints.js.map +1 -1
  205. package/lib/systems/vitalpoint/MeridianVitalPointMapping.js.map +1 -1
  206. package/lib/types/constants/designSystem.js.map +1 -1
  207. package/lib/utils/colorHelpers.js.map +1 -1
  208. package/lib/utils/colorUtils.js.map +1 -1
  209. package/lib/utils/controlMapping.js.map +1 -1
  210. package/lib/utils/deviceDetection.js.map +1 -1
  211. package/lib/utils/effectUtils.js.map +1 -1
  212. package/lib/utils/fabricTextures.js.map +1 -1
  213. package/lib/utils/htmlOverlayHelpers.js.map +1 -1
  214. package/lib/utils/performance/PerformanceMonitor.js.map +1 -1
  215. package/lib/utils/performance/PerformanceOverlay3D.js.map +1 -1
  216. package/lib/utils/safeAreaUtils.js.map +1 -1
  217. package/lib/utils/stanceHelpers.js.map +1 -1
  218. package/lib/utils/visualEffects.js.map +1 -1
  219. package/package.json +9 -9
@@ -1 +1 @@
1
- {"version":3,"file":"TechniqueAnimationMapping.js","names":[],"sources":["../../../../src/systems/animation/core/TechniqueAnimationMapping.ts"],"sourcesContent":["/**\n * Technique Animation Mapping\n *\n * Maps technique IDs directly to animation types for reliable lookup.\n * This file is the source of truth for technique-to-animation relationships.\n *\n * 기술과 애니메이션의 직접 매핑\n * 기술 ID에서 애니메이션 타입으로의 확실한 조회를 위한 매핑 파일\n *\n * @module systems/animation/TechniqueAnimationMapping\n * @korean 기술애니메이션매핑\n */\n\nimport { AnimationType } from \"../builders/MartialArtsAnimationBuilder\";\n\n/**\n * Speed modifier for animation playback\n * Higher values = faster animation\n */\nexport interface AnimationConfig {\n readonly type: AnimationType;\n readonly speed: number;\n}\n\n/**\n * Default animation configurations by type\n */\nconst DEFAULT_CONFIGS: Partial<Record<AnimationType, AnimationConfig>> = {\n // Kicks (발차기)\n [AnimationType.FRONT_KICK]: { type: AnimationType.FRONT_KICK, speed: 1.0 },\n [AnimationType.ROUNDHOUSE_KICK]: {\n type: AnimationType.ROUNDHOUSE_KICK,\n speed: 1.0,\n },\n [AnimationType.SIDE_KICK]: { type: AnimationType.SIDE_KICK, speed: 1.0 },\n [AnimationType.AXE_KICK]: { type: AnimationType.AXE_KICK, speed: 0.9 },\n [AnimationType.BACK_KICK]: { type: AnimationType.BACK_KICK, speed: 1.0 },\n [AnimationType.TORNADO_KICK]: {\n type: AnimationType.TORNADO_KICK,\n speed: 1.1,\n },\n [AnimationType.JUMPING_KICK]: {\n type: AnimationType.JUMPING_KICK,\n speed: 1.0,\n },\n [AnimationType.LOW_KICK]: { type: AnimationType.LOW_KICK, speed: 1.1 },\n [AnimationType.CRESCENT_KICK]: {\n type: AnimationType.CRESCENT_KICK,\n speed: 1.0,\n },\n [AnimationType.PUSH_KICK]: { type: AnimationType.PUSH_KICK, speed: 1.1 },\n [AnimationType.SPINNING_HEEL_KICK]: {\n type: AnimationType.SPINNING_HEEL_KICK,\n speed: 0.95,\n },\n\n // Punches (주먹)\n [AnimationType.JAB]: { type: AnimationType.JAB, speed: 1.2 },\n [AnimationType.CROSS]: { type: AnimationType.CROSS, speed: 1.1 },\n [AnimationType.HOOK]: { type: AnimationType.HOOK, speed: 1.0 },\n [AnimationType.UPPERCUT]: { type: AnimationType.UPPERCUT, speed: 1.0 },\n [AnimationType.OVERHAND]: { type: AnimationType.OVERHAND, speed: 0.95 },\n [AnimationType.PALM_STRIKE]: { type: AnimationType.PALM_STRIKE, speed: 1.0 },\n [AnimationType.BACKFIST]: { type: AnimationType.BACKFIST, speed: 1.05 },\n [AnimationType.HAMMER_FIST]: { type: AnimationType.HAMMER_FIST, speed: 1.0 },\n\n // ═══ SPECIALIZED JAB VARIANTS (잽 변형) ═══\n [AnimationType.SPEAR_HAND_STRIKE]: {\n type: AnimationType.SPEAR_HAND_STRIKE,\n speed: 1.3,\n },\n [AnimationType.NERVE_STRIKE]: {\n type: AnimationType.NERVE_STRIKE,\n speed: 1.2,\n },\n [AnimationType.PRESSURE_POINT_STRIKE]: {\n type: AnimationType.PRESSURE_POINT_STRIKE,\n speed: 1.0,\n },\n [AnimationType.LIGHTNING_STRIKE]: {\n type: AnimationType.LIGHTNING_STRIKE,\n speed: 1.4,\n },\n [AnimationType.RAPID_BARRAGE]: {\n type: AnimationType.RAPID_BARRAGE,\n speed: 1.5,\n },\n [AnimationType.RHYTHMIC_STRIKES]: {\n type: AnimationType.RHYTHMIC_STRIKES,\n speed: 1.3,\n },\n [AnimationType.NERVE_PARALYSIS]: {\n type: AnimationType.NERVE_PARALYSIS,\n speed: 1.1,\n },\n [AnimationType.THROAT_STRIKE]: {\n type: AnimationType.THROAT_STRIKE,\n speed: 1.2,\n },\n [AnimationType.EYE_GOUGE]: { type: AnimationType.EYE_GOUGE, speed: 1.3 },\n\n // ═══ SPECIALIZED CROSS VARIANTS (크로스 변형) ═══\n [AnimationType.HEAVEN_STRIKE]: {\n type: AnimationType.HEAVEN_STRIKE,\n speed: 1.0,\n },\n [AnimationType.FLOWING_CROSS]: {\n type: AnimationType.FLOWING_CROSS,\n speed: 1.2,\n },\n\n // ═══ SPECIALIZED PALM STRIKES (장권 변형) ═══\n [AnimationType.SOLAR_PLEXUS_STRIKE]: {\n type: AnimationType.SOLAR_PLEXUS_STRIKE,\n speed: 1.1,\n },\n [AnimationType.FLOWING_PUSH]: {\n type: AnimationType.FLOWING_PUSH,\n speed: 1.1,\n },\n [AnimationType.LIVER_DISRUPTION]: {\n type: AnimationType.LIVER_DISRUPTION,\n speed: 1.0,\n },\n [AnimationType.EAR_STRIKE]: { type: AnimationType.EAR_STRIKE, speed: 1.2 },\n\n // Elbow/Knee (팔꿈치/무릎)\n [AnimationType.ELBOW_STRIKE]: {\n type: AnimationType.ELBOW_STRIKE,\n speed: 1.1,\n },\n [AnimationType.ELBOW_UPPERCUT]: {\n type: AnimationType.ELBOW_UPPERCUT,\n speed: 1.0,\n },\n [AnimationType.SPINNING_ELBOW]: {\n type: AnimationType.SPINNING_ELBOW,\n speed: 0.95,\n },\n [AnimationType.KNEE_STRIKE]: { type: AnimationType.KNEE_STRIKE, speed: 1.0 },\n [AnimationType.FLYING_KNEE]: { type: AnimationType.FLYING_KNEE, speed: 0.95 },\n\n // ═══ SPECIALIZED ELBOW VARIANTS (팔꿈치 변형) ═══\n [AnimationType.TEMPLE_ELBOW]: {\n type: AnimationType.TEMPLE_ELBOW,\n speed: 1.1,\n },\n [AnimationType.SPINNING_BACK_ELBOW]: {\n type: AnimationType.SPINNING_BACK_ELBOW,\n speed: 1.2,\n },\n [AnimationType.SPINAL_ELBOW]: {\n type: AnimationType.SPINAL_ELBOW,\n speed: 1.0,\n },\n [AnimationType.BRACHIAL_ELBOW]: {\n type: AnimationType.BRACHIAL_ELBOW,\n speed: 1.1,\n },\n\n // ═══ SPECIALIZED KNEE VARIANTS (무릎 변형) ═══\n [AnimationType.KIDNEY_KNEE]: { type: AnimationType.KIDNEY_KNEE, speed: 1.0 },\n [AnimationType.FEMORAL_KNEE]: {\n type: AnimationType.FEMORAL_KNEE,\n speed: 1.0,\n },\n\n // Grappling (잡기)\n [AnimationType.THROW]: { type: AnimationType.THROW, speed: 0.9 },\n [AnimationType.GRAPPLE]: { type: AnimationType.GRAPPLE, speed: 0.85 },\n [AnimationType.SWEEP]: { type: AnimationType.SWEEP, speed: 1.0 },\n [AnimationType.SLAM]: { type: AnimationType.SLAM, speed: 0.9 },\n [AnimationType.WRIST_LOCK]: { type: AnimationType.WRIST_LOCK, speed: 0.85 },\n [AnimationType.ARM_BAR]: { type: AnimationType.ARM_BAR, speed: 0.8 },\n [AnimationType.SHOULDER_LOCK]: {\n type: AnimationType.SHOULDER_LOCK,\n speed: 0.85,\n },\n [AnimationType.HIP_THROW]: { type: AnimationType.HIP_THROW, speed: 0.9 },\n [AnimationType.LEG_REAP]: { type: AnimationType.LEG_REAP, speed: 1.0 },\n\n // ═══ SPECIALIZED GRAPPLE VARIANTS (잡기 변형) ═══\n [AnimationType.SMALL_CIRCLE_LOCK]: {\n type: AnimationType.SMALL_CIRCLE_LOCK,\n speed: 0.85,\n },\n [AnimationType.FINGER_LOCK]: {\n type: AnimationType.FINGER_LOCK,\n speed: 0.9,\n },\n [AnimationType.ELBOW_LOCK]: { type: AnimationType.ELBOW_LOCK, speed: 0.8 },\n [AnimationType.SHOULDER_MANIPULATION]: {\n type: AnimationType.SHOULDER_MANIPULATION,\n speed: 0.8,\n },\n [AnimationType.MOUNTAIN_LOCK]: {\n type: AnimationType.MOUNTAIN_LOCK,\n speed: 0.8,\n },\n [AnimationType.EARTH_EMBRACE]: {\n type: AnimationType.EARTH_EMBRACE,\n speed: 0.85,\n },\n [AnimationType.CAROTID_CHOKE]: {\n type: AnimationType.CAROTID_CHOKE,\n speed: 0.9,\n },\n [AnimationType.REAR_NAKED_CHOKE]: {\n type: AnimationType.REAR_NAKED_CHOKE,\n speed: 0.8,\n },\n\n // ═══ SPECIALIZED THROW VARIANTS (던지기 변형) ═══\n [AnimationType.REDIRECT_THROW]: {\n type: AnimationType.REDIRECT_THROW,\n speed: 0.9,\n },\n [AnimationType.HIP_WHEEL_THROW]: {\n type: AnimationType.HIP_WHEEL_THROW,\n speed: 0.85,\n },\n [AnimationType.SSIREUM_THROW]: {\n type: AnimationType.SSIREUM_THROW,\n speed: 0.9,\n },\n [AnimationType.SACRIFICE_THROW]: {\n type: AnimationType.SACRIFICE_THROW,\n speed: 0.8,\n },\n\n // ═══ SPECIALIZED SWEEP VARIANTS (쓸기 변형) ═══\n [AnimationType.ANKLE_PICK]: { type: AnimationType.ANKLE_PICK, speed: 1.1 },\n [AnimationType.ACHILLES_ATTACK]: {\n type: AnimationType.ACHILLES_ATTACK,\n speed: 1.2,\n },\n\n // ═══ SPECIALIZED SLAM VARIANTS (슬램 변형) ═══\n [AnimationType.BODY_LOCK_SLAM]: {\n type: AnimationType.BODY_LOCK_SLAM,\n speed: 0.85,\n },\n\n // ═══ SPECIALIZED WRIST LOCK VARIANTS (손목꺾기 변형) ═══\n [AnimationType.WRIST_TWIST_COUNTER]: {\n type: AnimationType.WRIST_TWIST_COUNTER,\n speed: 0.9,\n },\n\n // Counters (반격)\n [AnimationType.COUNTER_ATTACK]: {\n type: AnimationType.COUNTER_ATTACK,\n speed: 1.1,\n },\n [AnimationType.COUNTER_STRIKE]: {\n type: AnimationType.COUNTER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.PARRY_COUNTER]: {\n type: AnimationType.PARRY_COUNTER,\n speed: 1.1,\n },\n\n // ═══ SPECIALIZED COUNTER VARIANTS (반격 변형) ═══\n [AnimationType.WATER_COUNTER]: {\n type: AnimationType.WATER_COUNTER,\n speed: 1.0,\n },\n [AnimationType.ROCK_COUNTER]: {\n type: AnimationType.ROCK_COUNTER,\n speed: 1.1,\n },\n\n // Defense (방어)\n [AnimationType.BLOCK]: { type: AnimationType.BLOCK, speed: 1.0 },\n [AnimationType.BLOCK_HIGH]: { type: AnimationType.BLOCK_HIGH, speed: 1.0 },\n [AnimationType.BLOCK_LOW]: { type: AnimationType.BLOCK_LOW, speed: 1.0 },\n [AnimationType.PARRY]: { type: AnimationType.PARRY, speed: 1.1 },\n\n // ═══ SPECIALIZED BLOCK VARIANTS (방어 변형) ═══\n [AnimationType.FLOWING_BLOCK]: {\n type: AnimationType.FLOWING_BLOCK,\n speed: 1.0,\n },\n [AnimationType.CIRCULAR_PARRY]: {\n type: AnimationType.CIRCULAR_PARRY,\n speed: 1.1,\n },\n [AnimationType.ROCK_DEFENSE]: {\n type: AnimationType.ROCK_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.IRON_BLOCK]: { type: AnimationType.IRON_BLOCK, speed: 0.85 },\n [AnimationType.FLOW_DEFENSE]: {\n type: AnimationType.FLOW_DEFENSE,\n speed: 1.0,\n },\n [AnimationType.IMMOVABLE_BLOCK]: {\n type: AnimationType.IMMOVABLE_BLOCK,\n speed: 0.85,\n },\n [AnimationType.EXPLOSIVE_BLOCK]: {\n type: AnimationType.EXPLOSIVE_BLOCK,\n speed: 1.1,\n },\n [AnimationType.CONTINUOUS_DEFLECTION]: {\n type: AnimationType.CONTINUOUS_DEFLECTION,\n speed: 1.2,\n },\n [AnimationType.PRECISION_PARRY]: {\n type: AnimationType.PRECISION_PARRY,\n speed: 1.1,\n },\n [AnimationType.JOINT_LOCK_DEFENSE]: {\n type: AnimationType.JOINT_LOCK_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.SWEEP_DEFENSE]: {\n type: AnimationType.SWEEP_DEFENSE,\n speed: 1.0,\n },\n [AnimationType.GROUNDING_DEFENSE]: {\n type: AnimationType.GROUNDING_DEFENSE,\n speed: 0.9,\n },\n\n // ═══ DARK OPS SPECIALIZED (암살 특수기) ═══\n [AnimationType.JAW_DISLOCATION]: {\n type: AnimationType.JAW_DISLOCATION,\n speed: 1.0,\n },\n [AnimationType.TEMPLE_STRIKE]: {\n type: AnimationType.TEMPLE_STRIKE,\n speed: 1.1,\n },\n [AnimationType.CERVICAL_TWIST]: {\n type: AnimationType.CERVICAL_TWIST,\n speed: 0.8,\n },\n [AnimationType.ELBOW_HYPEREXTEND]: {\n type: AnimationType.ELBOW_HYPEREXTEND,\n speed: 0.85,\n },\n [AnimationType.FINGER_BREAK]: {\n type: AnimationType.FINGER_BREAK,\n speed: 1.0,\n },\n [AnimationType.GUILLOTINE_CHOKE]: {\n type: AnimationType.GUILLOTINE_CHOKE,\n speed: 0.8,\n },\n [AnimationType.JUGULAR_STRIKE]: {\n type: AnimationType.JUGULAR_STRIKE,\n speed: 1.2,\n },\n [AnimationType.KNEECAP_STRIKE]: {\n type: AnimationType.KNEECAP_STRIKE,\n speed: 1.1,\n },\n [AnimationType.LARYNX_CRUSH]: {\n type: AnimationType.LARYNX_CRUSH,\n speed: 1.0,\n },\n [AnimationType.OCCIPITAL_STRIKE]: {\n type: AnimationType.OCCIPITAL_STRIKE,\n speed: 1.1,\n },\n [AnimationType.SCIATIC_NERVE_STRIKE]: {\n type: AnimationType.SCIATIC_NERVE_STRIKE,\n speed: 1.0,\n },\n [AnimationType.SILENT_TAKEDOWN]: {\n type: AnimationType.SILENT_TAKEDOWN,\n speed: 0.9,\n },\n [AnimationType.SLEEPER_HOLD]: {\n type: AnimationType.SLEEPER_HOLD,\n speed: 0.75,\n },\n [AnimationType.SPLEEN_RUPTURE]: {\n type: AnimationType.SPLEEN_RUPTURE,\n speed: 1.0,\n },\n [AnimationType.TRIANGLE_CHOKE]: {\n type: AnimationType.TRIANGLE_CHOKE,\n speed: 0.8,\n },\n [AnimationType.BRACHIAL_PLEXUS]: {\n type: AnimationType.BRACHIAL_PLEXUS,\n speed: 1.1,\n },\n [AnimationType.FEMORAL_NERVE]: {\n type: AnimationType.FEMORAL_NERVE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL GEON (건) TECHNIQUES ═══\n [AnimationType.HIGH_BLOCK]: { type: AnimationType.HIGH_BLOCK, speed: 1.0 },\n [AnimationType.CRUSHING_ELBOW]: {\n type: AnimationType.CRUSHING_ELBOW,\n speed: 1.0,\n },\n [AnimationType.THUNDEROUS_UPPERCUT]: {\n type: AnimationType.THUNDEROUS_UPPERCUT,\n speed: 1.1,\n },\n [AnimationType.GEON_COUNTER]: {\n type: AnimationType.GEON_COUNTER,\n speed: 1.1,\n },\n [AnimationType.GEON_ROUNDHOUSE]: {\n type: AnimationType.GEON_ROUNDHOUSE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL TAE (태) TECHNIQUES ═══\n [AnimationType.FLOWING_ARM_BAR]: {\n type: AnimationType.FLOWING_ARM_BAR,\n speed: 0.85,\n },\n [AnimationType.SPIRAL_SHOULDER_THROW]: {\n type: AnimationType.SPIRAL_SHOULDER_THROW,\n speed: 0.9,\n },\n [AnimationType.WRIST_LOCK_STRIKE]: {\n type: AnimationType.WRIST_LOCK_STRIKE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL LI (리) TECHNIQUES ═══\n [AnimationType.PHOENIX_EYE_STRIKE]: {\n type: AnimationType.PHOENIX_EYE_STRIKE,\n speed: 1.2,\n },\n [AnimationType.NERVE_STRIKE_COUNTER]: {\n type: AnimationType.NERVE_STRIKE_COUNTER,\n speed: 1.1,\n },\n [AnimationType.SOLAR_PLEXUS_SPEAR]: {\n type: AnimationType.SOLAR_PLEXUS_SPEAR,\n speed: 1.1,\n },\n [AnimationType.LI_SOLAR_PLEXUS]: {\n type: AnimationType.LI_SOLAR_PLEXUS,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL JIN (진) TECHNIQUES ═══\n [AnimationType.EXPLOSIVE_KNEE]: {\n type: AnimationType.EXPLOSIVE_KNEE,\n speed: 1.1,\n },\n [AnimationType.LIGHTNING_STRAIGHT]: {\n type: AnimationType.LIGHTNING_STRAIGHT,\n speed: 1.3,\n },\n [AnimationType.SHOCKING_COUNTER]: {\n type: AnimationType.SHOCKING_COUNTER,\n speed: 1.2,\n },\n [AnimationType.SHOCKING_HAMMER_FIST]: {\n type: AnimationType.SHOCKING_HAMMER_FIST,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL SON (손) TECHNIQUES ═══\n [AnimationType.PENETRATING_PALM_RUSH]: {\n type: AnimationType.PENETRATING_PALM_RUSH,\n speed: 1.3,\n },\n [AnimationType.PRESSURE_COUNTER]: {\n type: AnimationType.PRESSURE_COUNTER,\n speed: 1.2,\n },\n [AnimationType.PRESSURE_POINT_CHAIN]: {\n type: AnimationType.PRESSURE_POINT_CHAIN,\n speed: 1.4,\n },\n\n // ═══ ADDITIONAL GAM (감) TECHNIQUES ═══\n [AnimationType.FLOWING_RIVER_STRIKE]: {\n type: AnimationType.FLOWING_RIVER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.REDIRECTION_COUNTER]: {\n type: AnimationType.REDIRECTION_COUNTER,\n speed: 1.0,\n },\n [AnimationType.TIDAL_WAVE_PALM]: {\n type: AnimationType.TIDAL_WAVE_PALM,\n speed: 1.0,\n },\n [AnimationType.WHIRLPOOL_COUNTER]: {\n type: AnimationType.WHIRLPOOL_COUNTER,\n speed: 1.1,\n },\n\n // ═══ ADDITIONAL GAN (간) TECHNIQUES ═══\n [AnimationType.AVALANCHE_HAMMER]: {\n type: AnimationType.AVALANCHE_HAMMER,\n speed: 0.9,\n },\n [AnimationType.COUNTER_FORTRESS]: {\n type: AnimationType.COUNTER_FORTRESS,\n speed: 1.0,\n },\n [AnimationType.FORTRESS_COUNTER_STRIKE]: {\n type: AnimationType.FORTRESS_COUNTER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.STONE_WALL_THRUST]: {\n type: AnimationType.STONE_WALL_THRUST,\n speed: 0.95,\n },\n\n // ═══ ADDITIONAL GON (곤) TECHNIQUES ═══\n [AnimationType.EARTHQUAKE_STOMP]: {\n type: AnimationType.EARTHQUAKE_STOMP,\n speed: 0.9,\n },\n [AnimationType.GROUND_SWEEP_STRIKE]: {\n type: AnimationType.GROUND_SWEEP_STRIKE,\n speed: 1.0,\n },\n [AnimationType.ROOTING_TAKEDOWN]: {\n type: AnimationType.ROOTING_TAKEDOWN,\n speed: 0.85,\n },\n [AnimationType.TAKEDOWN_COUNTER]: {\n type: AnimationType.TAKEDOWN_COUNTER,\n speed: 1.0,\n },\n\n // ═══ ARCHETYPE TECHNIQUES (원형 기술) ═══\n // Musa (무사) - Traditional Warrior\n [AnimationType.DRAGON_FIST]: {\n type: AnimationType.DRAGON_FIST,\n speed: 1.0,\n },\n [AnimationType.IRON_DEFENSE]: {\n type: AnimationType.IRON_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.MOUNTAIN_BREAKER]: {\n type: AnimationType.MOUNTAIN_BREAKER,\n speed: 0.9,\n },\n [AnimationType.THUNDER_STRIKE]: {\n type: AnimationType.THUNDER_STRIKE,\n speed: 1.1,\n },\n\n // Amsalja (암살자) - Shadow Assassin\n [AnimationType.DEADLY_PRECISION]: {\n type: AnimationType.DEADLY_PRECISION,\n speed: 1.2,\n },\n [AnimationType.SHADOW_NERVE_STRIKE]: {\n type: AnimationType.SHADOW_NERVE_STRIKE,\n speed: 1.1,\n },\n [AnimationType.SHADOW_STRIKE]: {\n type: AnimationType.SHADOW_STRIKE,\n speed: 1.3,\n },\n [AnimationType.SILENT_DEATH]: {\n type: AnimationType.SILENT_DEATH,\n speed: 1.0,\n },\n\n // Hacker (해커) - Cyber Warrior\n [AnimationType.CYBER_OVERDRIVE]: {\n type: AnimationType.CYBER_OVERDRIVE,\n speed: 1.4,\n },\n [AnimationType.DATA_STRIKE]: {\n type: AnimationType.DATA_STRIKE,\n speed: 1.2,\n },\n [AnimationType.ELECTRIC_SHOCK]: {\n type: AnimationType.ELECTRIC_SHOCK,\n speed: 1.3,\n },\n [AnimationType.SYSTEM_CRASH]: {\n type: AnimationType.SYSTEM_CRASH,\n speed: 1.0,\n },\n\n // Jeongbo Yowon (정보요원) - Intelligence Operative\n [AnimationType.COUNTER_INTELLIGENCE]: {\n type: AnimationType.COUNTER_INTELLIGENCE,\n speed: 1.1,\n },\n [AnimationType.INTELLIGENCE_STRIKE]: {\n type: AnimationType.INTELLIGENCE_STRIKE,\n speed: 1.0,\n },\n [AnimationType.PSYCHOLOGICAL_WARFARE]: {\n type: AnimationType.PSYCHOLOGICAL_WARFARE,\n speed: 0.9,\n },\n [AnimationType.TACTICAL_STRIKE]: {\n type: AnimationType.TACTICAL_STRIKE,\n speed: 1.1,\n },\n\n // Jojik Pokryeokbae (조직폭력배) - Organized Crime\n [AnimationType.BRUTAL_TAKEDOWN]: {\n type: AnimationType.BRUTAL_TAKEDOWN,\n speed: 0.9,\n },\n [AnimationType.IMPROVISED_WEAPON]: {\n type: AnimationType.IMPROVISED_WEAPON,\n speed: 1.0,\n },\n [AnimationType.RUTHLESS_ASSAULT]: {\n type: AnimationType.RUTHLESS_ASSAULT,\n speed: 1.1,\n },\n [AnimationType.STREET_BRAWL]: {\n type: AnimationType.STREET_BRAWL,\n speed: 1.0,\n },\n\n // Movement (이동)\n [AnimationType.WALK]: { type: AnimationType.WALK, speed: 1.0 },\n [AnimationType.IDLE_STANCE]: { type: AnimationType.IDLE_STANCE, speed: 1.0 },\n [AnimationType.FORWARD_DASH]: {\n type: AnimationType.FORWARD_DASH,\n speed: 1.2,\n },\n [AnimationType.BACKWARD_RETREAT]: {\n type: AnimationType.BACKWARD_RETREAT,\n speed: 1.0,\n },\n [AnimationType.SIDE_STEP]: { type: AnimationType.SIDE_STEP, speed: 1.1 },\n [AnimationType.STEP_FORWARD]: {\n type: AnimationType.STEP_FORWARD,\n speed: 1.0,\n },\n [AnimationType.STEP_BACK]: { type: AnimationType.STEP_BACK, speed: 1.0 },\n [AnimationType.SIDESTEP]: { type: AnimationType.SIDESTEP, speed: 1.1 },\n [AnimationType.PIVOT]: { type: AnimationType.PIVOT, speed: 1.0 },\n [AnimationType.DUCK]: { type: AnimationType.DUCK, speed: 1.2 },\n [AnimationType.LEAN]: { type: AnimationType.LEAN, speed: 1.0 },\n\n // Recovery & Stance (복귀 및 자세)\n [AnimationType.RECOVERY]: { type: AnimationType.RECOVERY, speed: 1.0 },\n [AnimationType.IDLE]: { type: AnimationType.IDLE, speed: 1.0 },\n [AnimationType.STANCE]: { type: AnimationType.STANCE, speed: 1.0 },\n\n // Additional Kicks (추가 발차기)\n [AnimationType.SPINNING_HOOK]: {\n type: AnimationType.SPINNING_HOOK,\n speed: 0.95,\n },\n [AnimationType.KNEE_KICK]: { type: AnimationType.KNEE_KICK, speed: 1.0 },\n [AnimationType.FLYING_KICK]: { type: AnimationType.FLYING_KICK, speed: 0.95 },\n\n // Additional Knee/Elbow (추가 무릎/팔꿈치)\n [AnimationType.CLINCH_KNEE]: { type: AnimationType.CLINCH_KNEE, speed: 1.0 },\n\n // Additional Grappling (추가 잡기)\n [AnimationType.JOINT_LOCK]: { type: AnimationType.JOINT_LOCK, speed: 0.8 },\n [AnimationType.TAKEDOWN]: { type: AnimationType.TAKEDOWN, speed: 0.9 },\n [AnimationType.CLINCH]: { type: AnimationType.CLINCH, speed: 0.85 },\n};\n\n/**\n * Master technique-to-animation mapping\n *\n * Maps each technique ID to its animation configuration.\n * This is the canonical source of truth for animation selection.\n *\n * 기술 ID별 애니메이션 설정 마스터 매핑\n *\n * @korean 기술애니메이션매핑\n */\nexport const TECHNIQUE_ANIMATIONS: ReadonlyMap<string, AnimationConfig> =\n new Map([\n // ═══════════════════════════════════════════════════════════════════════\n // ☰ GEON (건) - HEAVEN: Direct Force (태권도 타격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"geon_heaven_strike\", { type: AnimationType.HEAVEN_STRIKE, speed: 1.0 }],\n [\"geon_heavenly_fist\", { type: AnimationType.JAB, speed: 1.1 }],\n [\"geon_frontal_kick\", { type: AnimationType.FRONT_KICK, speed: 1.0 }],\n [\n \"geon_roundhouse_kick\",\n { type: AnimationType.ROUNDHOUSE_KICK, speed: 1.0 },\n ],\n [\"geon_axe_kick\", { type: AnimationType.AXE_KICK, speed: 0.9 }],\n [\"geon_palm_strike\", { type: AnimationType.PALM_STRIKE, speed: 1.0 }],\n [\"geon_elbow_smash\", { type: AnimationType.ELBOW_STRIKE, speed: 1.1 }],\n [\"geon_high_block\", { type: AnimationType.HIGH_BLOCK, speed: 1.0 }],\n [\"geon_crushing_elbow\", { type: AnimationType.CRUSHING_ELBOW, speed: 1.0 }],\n [\n \"geon_thunderous_uppercut\",\n { type: AnimationType.THUNDEROUS_UPPERCUT, speed: 1.1 },\n ],\n [\"geon_counter_strike\", { type: AnimationType.GEON_COUNTER, speed: 1.1 }],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☱ TAE (태) - LAKE: Fluid Joint Manipulation (합기도)\n // ═══════════════════════════════════════════════════════════════════════\n [\"tae_flowing_strikes\", { type: AnimationType.FLOWING_CROSS, speed: 1.2 }],\n [\"tae_wrist_lock\", { type: AnimationType.WRIST_LOCK, speed: 0.85 }],\n [\n \"tae_small_circle\",\n { type: AnimationType.SMALL_CIRCLE_LOCK, speed: 0.85 },\n ],\n [\"tae_finger_lock\", { type: AnimationType.FINGER_LOCK, speed: 0.9 }],\n [\"tae_elbow_lock\", { type: AnimationType.ELBOW_LOCK, speed: 0.8 }],\n [\n \"tae_shoulder_lock\",\n { type: AnimationType.SHOULDER_MANIPULATION, speed: 0.8 },\n ],\n [\"tae_arm_bar\", { type: AnimationType.ARM_BAR, speed: 0.75 }],\n [\n \"tae_flowing_arm_bar\",\n { type: AnimationType.FLOWING_ARM_BAR, speed: 0.85 },\n ],\n [\n \"tae_joint_lock_defense\",\n { type: AnimationType.JOINT_LOCK_DEFENSE, speed: 0.9 },\n ],\n [\n \"tae_spiral_shoulder_throw\",\n { type: AnimationType.SPIRAL_SHOULDER_THROW, speed: 0.9 },\n ],\n [\"tae_sweep_defense\", { type: AnimationType.SWEEP_DEFENSE, speed: 1.0 }],\n [\n \"tae_wrist_lock_strike\",\n { type: AnimationType.WRIST_LOCK_STRIKE, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☲ LI (리) - FIRE: Precision Nerve Strikes (정밀 타격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"li_flame_spear\", { type: AnimationType.SPEAR_HAND_STRIKE, speed: 1.3 }],\n [\"li_temple_strike\", { type: AnimationType.TEMPLE_ELBOW, speed: 1.1 }],\n [\"li_nerve_strike\", { type: AnimationType.NERVE_STRIKE, speed: 1.2 }],\n [\"li_sidekick\", { type: AnimationType.SIDE_KICK, speed: 1.0 }],\n [\n \"li_pressure_point\",\n { type: AnimationType.PRESSURE_POINT_STRIKE, speed: 1.0 },\n ],\n [\n \"li_solar_plexus_strike\",\n { type: AnimationType.SOLAR_PLEXUS_STRIKE, speed: 1.1 },\n ],\n [\n \"li_phoenix_eye_strike\",\n { type: AnimationType.PHOENIX_EYE_STRIKE, speed: 1.2 },\n ],\n [\n \"li_nerve_strike_counter\",\n { type: AnimationType.NERVE_STRIKE_COUNTER, speed: 1.1 },\n ],\n [\"li_precision_parry\", { type: AnimationType.PRECISION_PARRY, speed: 1.1 }],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☳ JIN (진) - THUNDER: Explosive Power (폭발력)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"jin_lightning_flash\",\n { type: AnimationType.LIGHTNING_STRIKE, speed: 1.4 },\n ],\n [\n \"jin_jumping_front_kick\",\n { type: AnimationType.JUMPING_KICK, speed: 1.0 },\n ],\n [\"jin_tornado_kick\", { type: AnimationType.TORNADO_KICK, speed: 1.0 }],\n [\"jin_flying_sidekick\", { type: AnimationType.FLYING_KICK, speed: 1.1 }],\n [\"jin_back_kick\", { type: AnimationType.BACK_KICK, speed: 1.0 }],\n [\"jin_knee_strike\", { type: AnimationType.KNEE_STRIKE, speed: 1.1 }],\n [\n \"jin_explosive_block\",\n { type: AnimationType.EXPLOSIVE_BLOCK, speed: 1.1 },\n ],\n [\"jin_explosive_knee\", { type: AnimationType.EXPLOSIVE_KNEE, speed: 1.1 }],\n [\n \"jin_lightning_straight\",\n { type: AnimationType.LIGHTNING_STRAIGHT, speed: 1.3 },\n ],\n [\n \"jin_shocking_counter\",\n { type: AnimationType.SHOCKING_COUNTER, speed: 1.2 },\n ],\n [\n \"jin_shocking_hammer_fist\",\n { type: AnimationType.SHOCKING_HAMMER_FIST, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☴ SON (손) - WIND: Continuous Pressure (지속 공격)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"son_whirlwind_barrage\",\n { type: AnimationType.RAPID_BARRAGE, speed: 1.5 },\n ],\n [\"son_sweeping_low_kick\", { type: AnimationType.LOW_KICK, speed: 1.0 }],\n [\n \"son_rhythmic_strikes\",\n { type: AnimationType.RHYTHMIC_STRIKES, speed: 1.3 },\n ],\n [\"son_flowing_push\", { type: AnimationType.FLOWING_PUSH, speed: 1.1 }],\n [\n \"son_spinning_elbow\",\n { type: AnimationType.SPINNING_BACK_ELBOW, speed: 1.2 },\n ],\n [\"son_rapid_footwork\", { type: AnimationType.SIDE_STEP, speed: 1.3 }],\n [\n \"son_continuous_deflection\",\n { type: AnimationType.CONTINUOUS_DEFLECTION, speed: 1.2 },\n ],\n [\n \"son_penetrating_palm_rush\",\n { type: AnimationType.PENETRATING_PALM_RUSH, speed: 1.3 },\n ],\n [\n \"son_pressure_counter\",\n { type: AnimationType.PRESSURE_COUNTER, speed: 1.2 },\n ],\n [\n \"son_pressure_point_chain\",\n { type: AnimationType.PRESSURE_POINT_CHAIN, speed: 1.4 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☵ GAM (감) - WATER: Flow & Adaptation (유동 반격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gam_water_counter\", { type: AnimationType.WATER_COUNTER, speed: 1.0 }],\n [\"gam_redirect_throw\", { type: AnimationType.REDIRECT_THROW, speed: 0.9 }],\n [\"gam_flowing_block\", { type: AnimationType.FLOWING_BLOCK, speed: 1.0 }],\n [\"gam_circular_parry\", { type: AnimationType.CIRCULAR_PARRY, speed: 1.1 }],\n [\"gam_hip_throw\", { type: AnimationType.HIP_WHEEL_THROW, speed: 0.85 }],\n [\n \"gam_wrist_twist_counter\",\n { type: AnimationType.WRIST_TWIST_COUNTER, speed: 0.9 },\n ],\n [\"gam_flow_defense\", { type: AnimationType.FLOW_DEFENSE, speed: 1.0 }],\n [\n \"gam_flowing_river_strike\",\n { type: AnimationType.FLOWING_RIVER_STRIKE, speed: 1.1 },\n ],\n [\n \"gam_redirection_counter\",\n { type: AnimationType.REDIRECTION_COUNTER, speed: 1.0 },\n ],\n [\n \"gam_tidal_wave_palm\",\n { type: AnimationType.TIDAL_WAVE_PALM, speed: 1.0 },\n ],\n [\n \"gam_whirlpool_counter\",\n { type: AnimationType.WHIRLPOOL_COUNTER, speed: 1.1 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☶ GAN (간) - MOUNTAIN: Defensive Mastery (방어 마스터리)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gan_rock_defense\", { type: AnimationType.ROCK_DEFENSE, speed: 0.9 }],\n [\"gan_immovable_stance\", { type: AnimationType.IDLE_STANCE, speed: 0.8 }],\n [\"gan_iron_block\", { type: AnimationType.IRON_BLOCK, speed: 0.85 }],\n [\"gan_counter_strike\", { type: AnimationType.ROCK_COUNTER, speed: 1.1 }],\n [\n \"gan_mountain_stance_lock\",\n { type: AnimationType.MOUNTAIN_LOCK, speed: 0.8 },\n ],\n [\n \"gan_reversal_technique\",\n { type: AnimationType.COUNTER_ATTACK, speed: 1.0 },\n ],\n [\n \"gan_avalanche_hammer\",\n { type: AnimationType.AVALANCHE_HAMMER, speed: 0.9 },\n ],\n [\n \"gan_counter_fortress\",\n { type: AnimationType.COUNTER_FORTRESS, speed: 1.0 },\n ],\n [\n \"gan_fortress_counter_strike\",\n { type: AnimationType.FORTRESS_COUNTER_STRIKE, speed: 1.1 },\n ],\n [\n \"gan_immovable_block\",\n { type: AnimationType.IMMOVABLE_BLOCK, speed: 0.85 },\n ],\n [\n \"gan_stone_wall_thrust\",\n { type: AnimationType.STONE_WALL_THRUST, speed: 0.95 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☷ GON (곤) - EARTH: Grounding & Takedowns (넘어뜨리기)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gon_earth_embrace\", { type: AnimationType.EARTH_EMBRACE, speed: 0.85 }],\n [\"gon_leg_sweep\", { type: AnimationType.SWEEP, speed: 1.0 }],\n [\"gon_ssireum_throw\", { type: AnimationType.SSIREUM_THROW, speed: 0.9 }],\n [\"gon_ground_pound\", { type: AnimationType.SLAM, speed: 1.0 }],\n [\"gon_ankle_pick\", { type: AnimationType.ANKLE_PICK, speed: 1.1 }],\n [\n \"gon_body_lock_takedown\",\n { type: AnimationType.BODY_LOCK_SLAM, speed: 0.85 },\n ],\n [\n \"gon_sacrifice_throw\",\n { type: AnimationType.SACRIFICE_THROW, speed: 0.8 },\n ],\n [\n \"gon_earthquake_stomp\",\n { type: AnimationType.EARTHQUAKE_STOMP, speed: 0.9 },\n ],\n [\n \"gon_grounding_defense\",\n { type: AnimationType.GROUNDING_DEFENSE, speed: 0.9 },\n ],\n [\n \"gon_ground_sweep_strike\",\n { type: AnimationType.GROUND_SWEEP_STRIKE, speed: 1.0 },\n ],\n [\n \"gon_rooting_takedown\",\n { type: AnimationType.ROOTING_TAKEDOWN, speed: 0.85 },\n ],\n [\n \"gon_takedown_counter\",\n { type: AnimationType.TAKEDOWN_COUNTER, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // DARK OPS (암살자) - Lethal Techniques (치명 기술)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"darkops_silent_carotid\",\n { type: AnimationType.CAROTID_CHOKE, speed: 0.9 },\n ],\n [\n \"darkops_nerve_paralysis\",\n { type: AnimationType.NERVE_PARALYSIS, speed: 1.1 },\n ],\n [\n \"darkops_liver_disruption\",\n { type: AnimationType.LIVER_DISRUPTION, speed: 1.0 },\n ],\n [\"darkops_kidney_strike\", { type: AnimationType.KIDNEY_KNEE, speed: 1.0 }],\n [\n \"darkops_throat_strike\",\n { type: AnimationType.THROAT_STRIKE, speed: 1.2 },\n ],\n [\n \"darkops_solar_plexus_paralyze\",\n { type: AnimationType.HAMMER_FIST, speed: 1.1 },\n ],\n [\n \"darkops_brachial_plexus_strike\",\n { type: AnimationType.BRACHIAL_ELBOW, speed: 1.1 },\n ],\n [\n \"darkops_femoral_nerve_strike\",\n { type: AnimationType.FEMORAL_KNEE, speed: 1.0 },\n ],\n [\n \"darkops_rear_choke\",\n { type: AnimationType.REAR_NAKED_CHOKE, speed: 0.8 },\n ],\n [\"darkops_spinal_strike\", { type: AnimationType.SPINAL_ELBOW, speed: 1.0 }],\n [\n \"darkops_jaw_dislocation\",\n { type: AnimationType.JAW_DISLOCATION, speed: 1.0 },\n ],\n [\n \"darkops_temple_strike\",\n { type: AnimationType.TEMPLE_STRIKE, speed: 1.1 },\n ],\n [\n \"darkops_achilles_sever\",\n { type: AnimationType.ACHILLES_ATTACK, speed: 1.2 },\n ],\n [\"darkops_ear_strike\", { type: AnimationType.EAR_STRIKE, speed: 1.2 }],\n [\"darkops_eye_gouge\", { type: AnimationType.EYE_GOUGE, speed: 1.3 }],\n // Additional Dark Ops techniques (extended set for future use)\n [\n \"darkops_cervical_twist\",\n { type: AnimationType.CERVICAL_TWIST, speed: 0.8 },\n ],\n [\n \"darkops_elbow_hyperextend\",\n { type: AnimationType.ELBOW_HYPEREXTEND, speed: 0.85 },\n ],\n [\"darkops_finger_break\", { type: AnimationType.FINGER_BREAK, speed: 1.0 }],\n [\n \"darkops_guillotine\",\n { type: AnimationType.GUILLOTINE_CHOKE, speed: 0.8 },\n ],\n [\n \"darkops_jugular_strike\",\n { type: AnimationType.JUGULAR_STRIKE, speed: 1.2 },\n ],\n [\n \"darkops_kneecap_strike\",\n { type: AnimationType.KNEECAP_STRIKE, speed: 1.1 },\n ],\n [\"darkops_larynx_crush\", { type: AnimationType.LARYNX_CRUSH, speed: 1.0 }],\n [\n \"darkops_occipital_strike\",\n { type: AnimationType.OCCIPITAL_STRIKE, speed: 1.1 },\n ],\n [\n \"darkops_sciatic_nerve\",\n { type: AnimationType.SCIATIC_NERVE_STRIKE, speed: 1.0 },\n ],\n [\n \"darkops_silent_takedown\",\n { type: AnimationType.SILENT_TAKEDOWN, speed: 0.9 },\n ],\n [\"darkops_sleeper_hold\", { type: AnimationType.SLEEPER_HOLD, speed: 0.75 }],\n [\n \"darkops_spleen_rupture\",\n { type: AnimationType.SPLEEN_RUPTURE, speed: 1.0 },\n ],\n [\n \"darkops_triangle_choke\",\n { type: AnimationType.TRIANGLE_CHOKE, speed: 0.8 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ARCHETYPE TECHNIQUES (원형 기술)\n // ═══════════════════════════════════════════════════════════════════════\n\n // Musa (무사) - Traditional Warrior\n [\"musa_dragon_fist\", { type: AnimationType.DRAGON_FIST, speed: 1.0 }],\n [\"musa_iron_defense\", { type: AnimationType.IRON_DEFENSE, speed: 0.9 }],\n [\n \"musa_mountain_breaker\",\n { type: AnimationType.MOUNTAIN_BREAKER, speed: 0.9 },\n ],\n [\"musa_thunder_strike\", { type: AnimationType.THUNDER_STRIKE, speed: 1.1 }],\n\n // Amsalja (암살자) - Shadow Assassin\n [\n \"amsalja_deadly_precision\",\n { type: AnimationType.DEADLY_PRECISION, speed: 1.2 },\n ],\n [\n \"amsalja_nerve_strike\",\n { type: AnimationType.SHADOW_NERVE_STRIKE, speed: 1.1 },\n ],\n [\n \"amsalja_shadow_strike\",\n { type: AnimationType.SHADOW_STRIKE, speed: 1.3 },\n ],\n [\"amsalja_silent_death\", { type: AnimationType.SILENT_DEATH, speed: 1.0 }],\n\n // Hacker (해커) - Cyber Warrior\n [\n \"hacker_cyber_overdrive\",\n { type: AnimationType.CYBER_OVERDRIVE, speed: 1.4 },\n ],\n [\"hacker_data_strike\", { type: AnimationType.DATA_STRIKE, speed: 1.2 }],\n [\n \"hacker_electric_shock\",\n { type: AnimationType.ELECTRIC_SHOCK, speed: 1.3 },\n ],\n [\"hacker_system_crash\", { type: AnimationType.SYSTEM_CRASH, speed: 1.0 }],\n\n // Jeongbo Yowon (정보요원) - Intelligence Operative\n [\n \"jeongbo_counter_intelligence\",\n { type: AnimationType.COUNTER_INTELLIGENCE, speed: 1.1 },\n ],\n [\n \"jeongbo_intelligence_strike\",\n { type: AnimationType.INTELLIGENCE_STRIKE, speed: 1.0 },\n ],\n [\n \"jeongbo_psychological_warfare\",\n { type: AnimationType.PSYCHOLOGICAL_WARFARE, speed: 0.9 },\n ],\n [\n \"jeongbo_tactical_strike\",\n { type: AnimationType.TACTICAL_STRIKE, speed: 1.1 },\n ],\n\n // Jojik Pokryeokbae (조직폭력배) - Organized Crime\n [\n \"jojik_brutal_takedown\",\n { type: AnimationType.BRUTAL_TAKEDOWN, speed: 0.9 },\n ],\n [\n \"jojik_improvised_weapon\",\n { type: AnimationType.IMPROVISED_WEAPON, speed: 1.0 },\n ],\n [\n \"jojik_ruthless_assault\",\n { type: AnimationType.RUTHLESS_ASSAULT, speed: 1.1 },\n ],\n [\"jojik_street_brawl\", { type: AnimationType.STREET_BRAWL, speed: 1.0 }],\n ]);\n\n/**\n * Get animation configuration for a technique\n *\n * @param techniqueId - The technique identifier\n * @returns Animation configuration or undefined if not mapped\n *\n * @korean 기술별애니메이션설정조회\n */\nexport function getAnimationForTechnique(\n techniqueId: string,\n): AnimationConfig | undefined {\n return TECHNIQUE_ANIMATIONS.get(techniqueId);\n}\n\n/**\n * Get animation configuration with fallback\n *\n * @param techniqueId - The technique identifier\n * @param fallbackType - Fallback animation type if not found\n * @returns Animation configuration (never undefined)\n *\n * @korean 기술별애니메이션설정조회_기본값\n */\nexport function getAnimationForTechniqueOrDefault(\n techniqueId: string,\n fallbackType: AnimationType = AnimationType.JAB,\n): AnimationConfig {\n const mapped = TECHNIQUE_ANIMATIONS.get(techniqueId);\n if (mapped) return mapped;\n\n const fallbackConfig = DEFAULT_CONFIGS[fallbackType];\n return fallbackConfig ?? { type: fallbackType, speed: 1.0 };\n}\n\n/**\n * Check if technique has animation mapping\n *\n * @param techniqueId - The technique identifier\n * @returns True if technique has animation mapping\n *\n * @korean 애니메이션매핑여부확인\n */\nexport function hasAnimationMapping(techniqueId: string): boolean {\n return TECHNIQUE_ANIMATIONS.has(techniqueId);\n}\n\n/**\n * Get all technique IDs with a specific animation type\n *\n * @param animationType - The animation type to search for\n * @returns Array of technique IDs using this animation\n *\n * @korean 애니메이션타입별기술조회\n */\nexport function getTechniquesByAnimationType(\n animationType: AnimationType,\n): readonly string[] {\n const techniques: string[] = [];\n for (const [id, config] of TECHNIQUE_ANIMATIONS) {\n if (config.type === animationType) {\n techniques.push(id);\n }\n }\n return techniques;\n}\n\n/**\n * Animation statistics for debugging\n */\nexport function getAnimationStats(): Record<AnimationType, number> {\n const stats: Record<AnimationType, number> = {} as Record<\n AnimationType,\n number\n >;\n\n // Initialize all types to 0\n for (const type of Object.values(AnimationType)) {\n stats[type] = 0;\n }\n\n // Count techniques per animation type\n for (const [, config] of TECHNIQUE_ANIMATIONS) {\n stats[config.type]++;\n }\n\n return stats;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AA2BA,IAAM,kBAAmE;EAEtE,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,qBAAqB;EAClC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,MAAM;EAAE,MAAM,cAAc;EAAK,OAAO;CAAI;EAC1D,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAC9D,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAC5D,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAK;EACrE,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAC1E,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAK;EACrE,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAG1E,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EAGtE,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EAGxE,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAC1E,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAK;EAG3E,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAC1E,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAC9D,cAAc,UAAU;EAAE,MAAM,cAAc;EAAS,OAAO;CAAK;EACnE,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAC9D,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAC5D,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAK;EACzE,cAAc,UAAU;EAAE,MAAM,cAAc;EAAS,OAAO;CAAI;EAClE,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EAGpE,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,cAAc;EAC3B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAC9D,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAG9D,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAK;EACzE,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,qBAAqB;EAClC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,qBAAqB;EAClC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,qBAAqB;EAClC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,qBAAqB;EAClC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,0BAA0B;EACvC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EAIC,cAAc,cAAc;EAC3B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,cAAc;EAC3B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,iBAAiB;EAC9B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,uBAAuB;EACpC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,sBAAsB;EACnC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,wBAAwB;EACrC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,kBAAkB;EAC/B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,oBAAoB;EACjC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EAGC,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAC5D,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAC1E,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,mBAAmB;EAChC,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,eAAe;EAC5B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,QAAQ;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI;EAC9D,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAC5D,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAG5D,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,OAAO;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI;EAC5D,cAAc,SAAS;EAAE,MAAM,cAAc;EAAQ,OAAO;CAAI;EAGhE,cAAc,gBAAgB;EAC7B,MAAM,cAAc;EACpB,OAAO;CACT;EACC,cAAc,YAAY;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI;EACtE,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAK;EAG3E,cAAc,cAAc;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI;EAG1E,cAAc,aAAa;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI;EACxE,cAAc,WAAW;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI;EACpE,cAAc,SAAS;EAAE,MAAM,cAAc;EAAQ,OAAO;CAAK;AACpE;;;;;;;;;;;AAYA,IAAa,uBACX,IAAI,IAAI;CAIN,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACxE,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAK,OAAO;CAAI,CAAC;CAC9D,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI,CAAC;CACpE,CACE,wBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CAAC,iBAAiB;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI,CAAC;CAC9D,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACpE,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CAAC,mBAAmB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI,CAAC;CAClE,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CAAC;CAC1E,CACE,4BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CAKxE,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACzE,CAAC,kBAAkB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAK,CAAC;CAClE,CACE,oBACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAK,CACvD;CACA,CAAC,mBAAmB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACnE,CAAC,kBAAkB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI,CAAC;CACjE,CACE,qBACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CAAC,eAAe;EAAE,MAAM,cAAc;EAAS,OAAO;CAAK,CAAC;CAC5D,CACE,uBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAK,CACrD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAoB,OAAO;CAAI,CACvD;CACA,CACE,6BACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACvE,CACE,yBACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAI,CACtD;CAKA,CAAC,kBAAkB;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAI,CAAC;CACxE,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CAAC,mBAAmB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACpE,CAAC,eAAe;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI,CAAC;CAC7D,CACE,qBACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAoB,OAAO;CAAI,CACvD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CAAC;CAK1E,CACE,uBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CACjD;CACA,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACvE,CAAC,iBAAiB;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI,CAAC;CAC/D,CAAC,mBAAmB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACnE,CACE,uBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CAAC;CACzE,CACE,0BACA;EAAE,MAAM,cAAc;EAAoB,OAAO;CAAI,CACvD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,4BACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CAKA,CACE,yBACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CAAC,yBAAyB;EAAE,MAAM,cAAc;EAAU,OAAO;CAAI,CAAC;CACtE,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CACE,sBACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI,CAAC;CACpE,CACE,6BACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CACE,6BACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,4BACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CAKA,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACvE,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CAAC;CACzE,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACvE,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CAAC;CACzE,CAAC,iBAAiB;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAK,CAAC;CACtE,CACE,2BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CACE,4BACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CACE,uBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAI,CACtD;CAKA,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACrE,CAAC,wBAAwB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACxE,CAAC,kBAAkB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAK,CAAC;CAClE,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACvE,CACE,4BACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,+BACA;EAAE,MAAM,cAAc;EAAyB,OAAO;CAAI,CAC5D;CACA,CACE,uBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAK,CACrD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAK,CACvD;CAKA,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAK,CAAC;CACxE,CAAC,iBAAiB;EAAE,MAAM,cAAc;EAAO,OAAO;CAAI,CAAC;CAC3D,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAAC;CACvE,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAM,OAAO;CAAI,CAAC;CAC7D,CAAC,kBAAkB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI,CAAC;CACjE,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAK,CACpD;CACA,CACE,uBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAI,CACtD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAK,CACtD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CAKA,CACE,0BACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CACE,4BACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CAAC,yBAAyB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACzE,CACE,yBACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CACE,iCACA;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAChD;CACA,CACE,kCACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CACE,gCACA;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CACjD;CACA,CACE,sBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CAAC,yBAAyB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CAC1E,CACE,2BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAY,OAAO;CAAI,CAAC;CACrE,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAW,OAAO;CAAI,CAAC;CAEnE,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CACE,6BACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAK,CACvD;CACA,CAAC,wBAAwB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACzE,CACE,sBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CAAC,wBAAwB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACzE,CACE,4BACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CAAC,wBAAwB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAK,CAAC;CAC1E,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CAOA,CAAC,oBAAoB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACpE,CAAC,qBAAqB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CACtE,CACE,yBACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CAAC;CAG1E,CACE,4BACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CACE,wBACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CACE,yBACA;EAAE,MAAM,cAAc;EAAe,OAAO;CAAI,CAClD;CACA,CAAC,wBAAwB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CAGzE,CACE,0BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAa,OAAO;CAAI,CAAC;CACtE,CACE,yBACA;EAAE,MAAM,cAAc;EAAgB,OAAO;CAAI,CACnD;CACA,CAAC,uBAAuB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;CAGxE,CACE,gCACA;EAAE,MAAM,cAAc;EAAsB,OAAO;CAAI,CACzD;CACA,CACE,+BACA;EAAE,MAAM,cAAc;EAAqB,OAAO;CAAI,CACxD;CACA,CACE,iCACA;EAAE,MAAM,cAAc;EAAuB,OAAO;CAAI,CAC1D;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CAGA,CACE,yBACA;EAAE,MAAM,cAAc;EAAiB,OAAO;CAAI,CACpD;CACA,CACE,2BACA;EAAE,MAAM,cAAc;EAAmB,OAAO;CAAI,CACtD;CACA,CACE,0BACA;EAAE,MAAM,cAAc;EAAkB,OAAO;CAAI,CACrD;CACA,CAAC,sBAAsB;EAAE,MAAM,cAAc;EAAc,OAAO;CAAI,CAAC;AACzE,CAAC;;;;;;;;;;AAyBH,SAAgB,kCACd,aACA,eAA8B,cAAc,KAC3B;CACjB,MAAM,SAAS,qBAAqB,IAAI,WAAW;CACnD,IAAI,QAAQ,OAAO;CAGnB,OADuB,gBAAgB,iBACd;EAAE,MAAM;EAAc,OAAO;CAAI;AAC5D"}
1
+ {"version":3,"file":"TechniqueAnimationMapping.js","names":[],"sources":["../../../../src/systems/animation/core/TechniqueAnimationMapping.ts"],"sourcesContent":["/**\n * Technique Animation Mapping\n *\n * Maps technique IDs directly to animation types for reliable lookup.\n * This file is the source of truth for technique-to-animation relationships.\n *\n * 기술과 애니메이션의 직접 매핑\n * 기술 ID에서 애니메이션 타입으로의 확실한 조회를 위한 매핑 파일\n *\n * @module systems/animation/TechniqueAnimationMapping\n * @korean 기술애니메이션매핑\n */\n\nimport { AnimationType } from \"../builders/MartialArtsAnimationBuilder\";\n\n/**\n * Speed modifier for animation playback\n * Higher values = faster animation\n */\nexport interface AnimationConfig {\n readonly type: AnimationType;\n readonly speed: number;\n}\n\n/**\n * Default animation configurations by type\n */\nconst DEFAULT_CONFIGS: Partial<Record<AnimationType, AnimationConfig>> = {\n // Kicks (발차기)\n [AnimationType.FRONT_KICK]: { type: AnimationType.FRONT_KICK, speed: 1.0 },\n [AnimationType.ROUNDHOUSE_KICK]: {\n type: AnimationType.ROUNDHOUSE_KICK,\n speed: 1.0,\n },\n [AnimationType.SIDE_KICK]: { type: AnimationType.SIDE_KICK, speed: 1.0 },\n [AnimationType.AXE_KICK]: { type: AnimationType.AXE_KICK, speed: 0.9 },\n [AnimationType.BACK_KICK]: { type: AnimationType.BACK_KICK, speed: 1.0 },\n [AnimationType.TORNADO_KICK]: {\n type: AnimationType.TORNADO_KICK,\n speed: 1.1,\n },\n [AnimationType.JUMPING_KICK]: {\n type: AnimationType.JUMPING_KICK,\n speed: 1.0,\n },\n [AnimationType.LOW_KICK]: { type: AnimationType.LOW_KICK, speed: 1.1 },\n [AnimationType.CRESCENT_KICK]: {\n type: AnimationType.CRESCENT_KICK,\n speed: 1.0,\n },\n [AnimationType.PUSH_KICK]: { type: AnimationType.PUSH_KICK, speed: 1.1 },\n [AnimationType.SPINNING_HEEL_KICK]: {\n type: AnimationType.SPINNING_HEEL_KICK,\n speed: 0.95,\n },\n\n // Punches (주먹)\n [AnimationType.JAB]: { type: AnimationType.JAB, speed: 1.2 },\n [AnimationType.CROSS]: { type: AnimationType.CROSS, speed: 1.1 },\n [AnimationType.HOOK]: { type: AnimationType.HOOK, speed: 1.0 },\n [AnimationType.UPPERCUT]: { type: AnimationType.UPPERCUT, speed: 1.0 },\n [AnimationType.OVERHAND]: { type: AnimationType.OVERHAND, speed: 0.95 },\n [AnimationType.PALM_STRIKE]: { type: AnimationType.PALM_STRIKE, speed: 1.0 },\n [AnimationType.BACKFIST]: { type: AnimationType.BACKFIST, speed: 1.05 },\n [AnimationType.HAMMER_FIST]: { type: AnimationType.HAMMER_FIST, speed: 1.0 },\n\n // ═══ SPECIALIZED JAB VARIANTS (잽 변형) ═══\n [AnimationType.SPEAR_HAND_STRIKE]: {\n type: AnimationType.SPEAR_HAND_STRIKE,\n speed: 1.3,\n },\n [AnimationType.NERVE_STRIKE]: {\n type: AnimationType.NERVE_STRIKE,\n speed: 1.2,\n },\n [AnimationType.PRESSURE_POINT_STRIKE]: {\n type: AnimationType.PRESSURE_POINT_STRIKE,\n speed: 1.0,\n },\n [AnimationType.LIGHTNING_STRIKE]: {\n type: AnimationType.LIGHTNING_STRIKE,\n speed: 1.4,\n },\n [AnimationType.RAPID_BARRAGE]: {\n type: AnimationType.RAPID_BARRAGE,\n speed: 1.5,\n },\n [AnimationType.RHYTHMIC_STRIKES]: {\n type: AnimationType.RHYTHMIC_STRIKES,\n speed: 1.3,\n },\n [AnimationType.NERVE_PARALYSIS]: {\n type: AnimationType.NERVE_PARALYSIS,\n speed: 1.1,\n },\n [AnimationType.THROAT_STRIKE]: {\n type: AnimationType.THROAT_STRIKE,\n speed: 1.2,\n },\n [AnimationType.EYE_GOUGE]: { type: AnimationType.EYE_GOUGE, speed: 1.3 },\n\n // ═══ SPECIALIZED CROSS VARIANTS (크로스 변형) ═══\n [AnimationType.HEAVEN_STRIKE]: {\n type: AnimationType.HEAVEN_STRIKE,\n speed: 1.0,\n },\n [AnimationType.FLOWING_CROSS]: {\n type: AnimationType.FLOWING_CROSS,\n speed: 1.2,\n },\n\n // ═══ SPECIALIZED PALM STRIKES (장권 변형) ═══\n [AnimationType.SOLAR_PLEXUS_STRIKE]: {\n type: AnimationType.SOLAR_PLEXUS_STRIKE,\n speed: 1.1,\n },\n [AnimationType.FLOWING_PUSH]: {\n type: AnimationType.FLOWING_PUSH,\n speed: 1.1,\n },\n [AnimationType.LIVER_DISRUPTION]: {\n type: AnimationType.LIVER_DISRUPTION,\n speed: 1.0,\n },\n [AnimationType.EAR_STRIKE]: { type: AnimationType.EAR_STRIKE, speed: 1.2 },\n\n // Elbow/Knee (팔꿈치/무릎)\n [AnimationType.ELBOW_STRIKE]: {\n type: AnimationType.ELBOW_STRIKE,\n speed: 1.1,\n },\n [AnimationType.ELBOW_UPPERCUT]: {\n type: AnimationType.ELBOW_UPPERCUT,\n speed: 1.0,\n },\n [AnimationType.SPINNING_ELBOW]: {\n type: AnimationType.SPINNING_ELBOW,\n speed: 0.95,\n },\n [AnimationType.KNEE_STRIKE]: { type: AnimationType.KNEE_STRIKE, speed: 1.0 },\n [AnimationType.FLYING_KNEE]: { type: AnimationType.FLYING_KNEE, speed: 0.95 },\n\n // ═══ SPECIALIZED ELBOW VARIANTS (팔꿈치 변형) ═══\n [AnimationType.TEMPLE_ELBOW]: {\n type: AnimationType.TEMPLE_ELBOW,\n speed: 1.1,\n },\n [AnimationType.SPINNING_BACK_ELBOW]: {\n type: AnimationType.SPINNING_BACK_ELBOW,\n speed: 1.2,\n },\n [AnimationType.SPINAL_ELBOW]: {\n type: AnimationType.SPINAL_ELBOW,\n speed: 1.0,\n },\n [AnimationType.BRACHIAL_ELBOW]: {\n type: AnimationType.BRACHIAL_ELBOW,\n speed: 1.1,\n },\n\n // ═══ SPECIALIZED KNEE VARIANTS (무릎 변형) ═══\n [AnimationType.KIDNEY_KNEE]: { type: AnimationType.KIDNEY_KNEE, speed: 1.0 },\n [AnimationType.FEMORAL_KNEE]: {\n type: AnimationType.FEMORAL_KNEE,\n speed: 1.0,\n },\n\n // Grappling (잡기)\n [AnimationType.THROW]: { type: AnimationType.THROW, speed: 0.9 },\n [AnimationType.GRAPPLE]: { type: AnimationType.GRAPPLE, speed: 0.85 },\n [AnimationType.SWEEP]: { type: AnimationType.SWEEP, speed: 1.0 },\n [AnimationType.SLAM]: { type: AnimationType.SLAM, speed: 0.9 },\n [AnimationType.WRIST_LOCK]: { type: AnimationType.WRIST_LOCK, speed: 0.85 },\n [AnimationType.ARM_BAR]: { type: AnimationType.ARM_BAR, speed: 0.8 },\n [AnimationType.SHOULDER_LOCK]: {\n type: AnimationType.SHOULDER_LOCK,\n speed: 0.85,\n },\n [AnimationType.HIP_THROW]: { type: AnimationType.HIP_THROW, speed: 0.9 },\n [AnimationType.LEG_REAP]: { type: AnimationType.LEG_REAP, speed: 1.0 },\n\n // ═══ SPECIALIZED GRAPPLE VARIANTS (잡기 변형) ═══\n [AnimationType.SMALL_CIRCLE_LOCK]: {\n type: AnimationType.SMALL_CIRCLE_LOCK,\n speed: 0.85,\n },\n [AnimationType.FINGER_LOCK]: {\n type: AnimationType.FINGER_LOCK,\n speed: 0.9,\n },\n [AnimationType.ELBOW_LOCK]: { type: AnimationType.ELBOW_LOCK, speed: 0.8 },\n [AnimationType.SHOULDER_MANIPULATION]: {\n type: AnimationType.SHOULDER_MANIPULATION,\n speed: 0.8,\n },\n [AnimationType.MOUNTAIN_LOCK]: {\n type: AnimationType.MOUNTAIN_LOCK,\n speed: 0.8,\n },\n [AnimationType.EARTH_EMBRACE]: {\n type: AnimationType.EARTH_EMBRACE,\n speed: 0.85,\n },\n [AnimationType.CAROTID_CHOKE]: {\n type: AnimationType.CAROTID_CHOKE,\n speed: 0.9,\n },\n [AnimationType.REAR_NAKED_CHOKE]: {\n type: AnimationType.REAR_NAKED_CHOKE,\n speed: 0.8,\n },\n\n // ═══ SPECIALIZED THROW VARIANTS (던지기 변형) ═══\n [AnimationType.REDIRECT_THROW]: {\n type: AnimationType.REDIRECT_THROW,\n speed: 0.9,\n },\n [AnimationType.HIP_WHEEL_THROW]: {\n type: AnimationType.HIP_WHEEL_THROW,\n speed: 0.85,\n },\n [AnimationType.SSIREUM_THROW]: {\n type: AnimationType.SSIREUM_THROW,\n speed: 0.9,\n },\n [AnimationType.SACRIFICE_THROW]: {\n type: AnimationType.SACRIFICE_THROW,\n speed: 0.8,\n },\n\n // ═══ SPECIALIZED SWEEP VARIANTS (쓸기 변형) ═══\n [AnimationType.ANKLE_PICK]: { type: AnimationType.ANKLE_PICK, speed: 1.1 },\n [AnimationType.ACHILLES_ATTACK]: {\n type: AnimationType.ACHILLES_ATTACK,\n speed: 1.2,\n },\n\n // ═══ SPECIALIZED SLAM VARIANTS (슬램 변형) ═══\n [AnimationType.BODY_LOCK_SLAM]: {\n type: AnimationType.BODY_LOCK_SLAM,\n speed: 0.85,\n },\n\n // ═══ SPECIALIZED WRIST LOCK VARIANTS (손목꺾기 변형) ═══\n [AnimationType.WRIST_TWIST_COUNTER]: {\n type: AnimationType.WRIST_TWIST_COUNTER,\n speed: 0.9,\n },\n\n // Counters (반격)\n [AnimationType.COUNTER_ATTACK]: {\n type: AnimationType.COUNTER_ATTACK,\n speed: 1.1,\n },\n [AnimationType.COUNTER_STRIKE]: {\n type: AnimationType.COUNTER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.PARRY_COUNTER]: {\n type: AnimationType.PARRY_COUNTER,\n speed: 1.1,\n },\n\n // ═══ SPECIALIZED COUNTER VARIANTS (반격 변형) ═══\n [AnimationType.WATER_COUNTER]: {\n type: AnimationType.WATER_COUNTER,\n speed: 1.0,\n },\n [AnimationType.ROCK_COUNTER]: {\n type: AnimationType.ROCK_COUNTER,\n speed: 1.1,\n },\n\n // Defense (방어)\n [AnimationType.BLOCK]: { type: AnimationType.BLOCK, speed: 1.0 },\n [AnimationType.BLOCK_HIGH]: { type: AnimationType.BLOCK_HIGH, speed: 1.0 },\n [AnimationType.BLOCK_LOW]: { type: AnimationType.BLOCK_LOW, speed: 1.0 },\n [AnimationType.PARRY]: { type: AnimationType.PARRY, speed: 1.1 },\n\n // ═══ SPECIALIZED BLOCK VARIANTS (방어 변형) ═══\n [AnimationType.FLOWING_BLOCK]: {\n type: AnimationType.FLOWING_BLOCK,\n speed: 1.0,\n },\n [AnimationType.CIRCULAR_PARRY]: {\n type: AnimationType.CIRCULAR_PARRY,\n speed: 1.1,\n },\n [AnimationType.ROCK_DEFENSE]: {\n type: AnimationType.ROCK_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.IRON_BLOCK]: { type: AnimationType.IRON_BLOCK, speed: 0.85 },\n [AnimationType.FLOW_DEFENSE]: {\n type: AnimationType.FLOW_DEFENSE,\n speed: 1.0,\n },\n [AnimationType.IMMOVABLE_BLOCK]: {\n type: AnimationType.IMMOVABLE_BLOCK,\n speed: 0.85,\n },\n [AnimationType.EXPLOSIVE_BLOCK]: {\n type: AnimationType.EXPLOSIVE_BLOCK,\n speed: 1.1,\n },\n [AnimationType.CONTINUOUS_DEFLECTION]: {\n type: AnimationType.CONTINUOUS_DEFLECTION,\n speed: 1.2,\n },\n [AnimationType.PRECISION_PARRY]: {\n type: AnimationType.PRECISION_PARRY,\n speed: 1.1,\n },\n [AnimationType.JOINT_LOCK_DEFENSE]: {\n type: AnimationType.JOINT_LOCK_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.SWEEP_DEFENSE]: {\n type: AnimationType.SWEEP_DEFENSE,\n speed: 1.0,\n },\n [AnimationType.GROUNDING_DEFENSE]: {\n type: AnimationType.GROUNDING_DEFENSE,\n speed: 0.9,\n },\n\n // ═══ DARK OPS SPECIALIZED (암살 특수기) ═══\n [AnimationType.JAW_DISLOCATION]: {\n type: AnimationType.JAW_DISLOCATION,\n speed: 1.0,\n },\n [AnimationType.TEMPLE_STRIKE]: {\n type: AnimationType.TEMPLE_STRIKE,\n speed: 1.1,\n },\n [AnimationType.CERVICAL_TWIST]: {\n type: AnimationType.CERVICAL_TWIST,\n speed: 0.8,\n },\n [AnimationType.ELBOW_HYPEREXTEND]: {\n type: AnimationType.ELBOW_HYPEREXTEND,\n speed: 0.85,\n },\n [AnimationType.FINGER_BREAK]: {\n type: AnimationType.FINGER_BREAK,\n speed: 1.0,\n },\n [AnimationType.GUILLOTINE_CHOKE]: {\n type: AnimationType.GUILLOTINE_CHOKE,\n speed: 0.8,\n },\n [AnimationType.JUGULAR_STRIKE]: {\n type: AnimationType.JUGULAR_STRIKE,\n speed: 1.2,\n },\n [AnimationType.KNEECAP_STRIKE]: {\n type: AnimationType.KNEECAP_STRIKE,\n speed: 1.1,\n },\n [AnimationType.LARYNX_CRUSH]: {\n type: AnimationType.LARYNX_CRUSH,\n speed: 1.0,\n },\n [AnimationType.OCCIPITAL_STRIKE]: {\n type: AnimationType.OCCIPITAL_STRIKE,\n speed: 1.1,\n },\n [AnimationType.SCIATIC_NERVE_STRIKE]: {\n type: AnimationType.SCIATIC_NERVE_STRIKE,\n speed: 1.0,\n },\n [AnimationType.SILENT_TAKEDOWN]: {\n type: AnimationType.SILENT_TAKEDOWN,\n speed: 0.9,\n },\n [AnimationType.SLEEPER_HOLD]: {\n type: AnimationType.SLEEPER_HOLD,\n speed: 0.75,\n },\n [AnimationType.SPLEEN_RUPTURE]: {\n type: AnimationType.SPLEEN_RUPTURE,\n speed: 1.0,\n },\n [AnimationType.TRIANGLE_CHOKE]: {\n type: AnimationType.TRIANGLE_CHOKE,\n speed: 0.8,\n },\n [AnimationType.BRACHIAL_PLEXUS]: {\n type: AnimationType.BRACHIAL_PLEXUS,\n speed: 1.1,\n },\n [AnimationType.FEMORAL_NERVE]: {\n type: AnimationType.FEMORAL_NERVE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL GEON (건) TECHNIQUES ═══\n [AnimationType.HIGH_BLOCK]: { type: AnimationType.HIGH_BLOCK, speed: 1.0 },\n [AnimationType.CRUSHING_ELBOW]: {\n type: AnimationType.CRUSHING_ELBOW,\n speed: 1.0,\n },\n [AnimationType.THUNDEROUS_UPPERCUT]: {\n type: AnimationType.THUNDEROUS_UPPERCUT,\n speed: 1.1,\n },\n [AnimationType.GEON_COUNTER]: {\n type: AnimationType.GEON_COUNTER,\n speed: 1.1,\n },\n [AnimationType.GEON_ROUNDHOUSE]: {\n type: AnimationType.GEON_ROUNDHOUSE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL TAE (태) TECHNIQUES ═══\n [AnimationType.FLOWING_ARM_BAR]: {\n type: AnimationType.FLOWING_ARM_BAR,\n speed: 0.85,\n },\n [AnimationType.SPIRAL_SHOULDER_THROW]: {\n type: AnimationType.SPIRAL_SHOULDER_THROW,\n speed: 0.9,\n },\n [AnimationType.WRIST_LOCK_STRIKE]: {\n type: AnimationType.WRIST_LOCK_STRIKE,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL LI (리) TECHNIQUES ═══\n [AnimationType.PHOENIX_EYE_STRIKE]: {\n type: AnimationType.PHOENIX_EYE_STRIKE,\n speed: 1.2,\n },\n [AnimationType.NERVE_STRIKE_COUNTER]: {\n type: AnimationType.NERVE_STRIKE_COUNTER,\n speed: 1.1,\n },\n [AnimationType.SOLAR_PLEXUS_SPEAR]: {\n type: AnimationType.SOLAR_PLEXUS_SPEAR,\n speed: 1.1,\n },\n [AnimationType.LI_SOLAR_PLEXUS]: {\n type: AnimationType.LI_SOLAR_PLEXUS,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL JIN (진) TECHNIQUES ═══\n [AnimationType.EXPLOSIVE_KNEE]: {\n type: AnimationType.EXPLOSIVE_KNEE,\n speed: 1.1,\n },\n [AnimationType.LIGHTNING_STRAIGHT]: {\n type: AnimationType.LIGHTNING_STRAIGHT,\n speed: 1.3,\n },\n [AnimationType.SHOCKING_COUNTER]: {\n type: AnimationType.SHOCKING_COUNTER,\n speed: 1.2,\n },\n [AnimationType.SHOCKING_HAMMER_FIST]: {\n type: AnimationType.SHOCKING_HAMMER_FIST,\n speed: 1.0,\n },\n\n // ═══ ADDITIONAL SON (손) TECHNIQUES ═══\n [AnimationType.PENETRATING_PALM_RUSH]: {\n type: AnimationType.PENETRATING_PALM_RUSH,\n speed: 1.3,\n },\n [AnimationType.PRESSURE_COUNTER]: {\n type: AnimationType.PRESSURE_COUNTER,\n speed: 1.2,\n },\n [AnimationType.PRESSURE_POINT_CHAIN]: {\n type: AnimationType.PRESSURE_POINT_CHAIN,\n speed: 1.4,\n },\n\n // ═══ ADDITIONAL GAM (감) TECHNIQUES ═══\n [AnimationType.FLOWING_RIVER_STRIKE]: {\n type: AnimationType.FLOWING_RIVER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.REDIRECTION_COUNTER]: {\n type: AnimationType.REDIRECTION_COUNTER,\n speed: 1.0,\n },\n [AnimationType.TIDAL_WAVE_PALM]: {\n type: AnimationType.TIDAL_WAVE_PALM,\n speed: 1.0,\n },\n [AnimationType.WHIRLPOOL_COUNTER]: {\n type: AnimationType.WHIRLPOOL_COUNTER,\n speed: 1.1,\n },\n\n // ═══ ADDITIONAL GAN (간) TECHNIQUES ═══\n [AnimationType.AVALANCHE_HAMMER]: {\n type: AnimationType.AVALANCHE_HAMMER,\n speed: 0.9,\n },\n [AnimationType.COUNTER_FORTRESS]: {\n type: AnimationType.COUNTER_FORTRESS,\n speed: 1.0,\n },\n [AnimationType.FORTRESS_COUNTER_STRIKE]: {\n type: AnimationType.FORTRESS_COUNTER_STRIKE,\n speed: 1.1,\n },\n [AnimationType.STONE_WALL_THRUST]: {\n type: AnimationType.STONE_WALL_THRUST,\n speed: 0.95,\n },\n\n // ═══ ADDITIONAL GON (곤) TECHNIQUES ═══\n [AnimationType.EARTHQUAKE_STOMP]: {\n type: AnimationType.EARTHQUAKE_STOMP,\n speed: 0.9,\n },\n [AnimationType.GROUND_SWEEP_STRIKE]: {\n type: AnimationType.GROUND_SWEEP_STRIKE,\n speed: 1.0,\n },\n [AnimationType.ROOTING_TAKEDOWN]: {\n type: AnimationType.ROOTING_TAKEDOWN,\n speed: 0.85,\n },\n [AnimationType.TAKEDOWN_COUNTER]: {\n type: AnimationType.TAKEDOWN_COUNTER,\n speed: 1.0,\n },\n\n // ═══ ARCHETYPE TECHNIQUES (원형 기술) ═══\n // Musa (무사) - Traditional Warrior\n [AnimationType.DRAGON_FIST]: {\n type: AnimationType.DRAGON_FIST,\n speed: 1.0,\n },\n [AnimationType.IRON_DEFENSE]: {\n type: AnimationType.IRON_DEFENSE,\n speed: 0.9,\n },\n [AnimationType.MOUNTAIN_BREAKER]: {\n type: AnimationType.MOUNTAIN_BREAKER,\n speed: 0.9,\n },\n [AnimationType.THUNDER_STRIKE]: {\n type: AnimationType.THUNDER_STRIKE,\n speed: 1.1,\n },\n\n // Amsalja (암살자) - Shadow Assassin\n [AnimationType.DEADLY_PRECISION]: {\n type: AnimationType.DEADLY_PRECISION,\n speed: 1.2,\n },\n [AnimationType.SHADOW_NERVE_STRIKE]: {\n type: AnimationType.SHADOW_NERVE_STRIKE,\n speed: 1.1,\n },\n [AnimationType.SHADOW_STRIKE]: {\n type: AnimationType.SHADOW_STRIKE,\n speed: 1.3,\n },\n [AnimationType.SILENT_DEATH]: {\n type: AnimationType.SILENT_DEATH,\n speed: 1.0,\n },\n\n // Hacker (해커) - Cyber Warrior\n [AnimationType.CYBER_OVERDRIVE]: {\n type: AnimationType.CYBER_OVERDRIVE,\n speed: 1.4,\n },\n [AnimationType.DATA_STRIKE]: {\n type: AnimationType.DATA_STRIKE,\n speed: 1.2,\n },\n [AnimationType.ELECTRIC_SHOCK]: {\n type: AnimationType.ELECTRIC_SHOCK,\n speed: 1.3,\n },\n [AnimationType.SYSTEM_CRASH]: {\n type: AnimationType.SYSTEM_CRASH,\n speed: 1.0,\n },\n\n // Jeongbo Yowon (정보요원) - Intelligence Operative\n [AnimationType.COUNTER_INTELLIGENCE]: {\n type: AnimationType.COUNTER_INTELLIGENCE,\n speed: 1.1,\n },\n [AnimationType.INTELLIGENCE_STRIKE]: {\n type: AnimationType.INTELLIGENCE_STRIKE,\n speed: 1.0,\n },\n [AnimationType.PSYCHOLOGICAL_WARFARE]: {\n type: AnimationType.PSYCHOLOGICAL_WARFARE,\n speed: 0.9,\n },\n [AnimationType.TACTICAL_STRIKE]: {\n type: AnimationType.TACTICAL_STRIKE,\n speed: 1.1,\n },\n\n // Jojik Pokryeokbae (조직폭력배) - Organized Crime\n [AnimationType.BRUTAL_TAKEDOWN]: {\n type: AnimationType.BRUTAL_TAKEDOWN,\n speed: 0.9,\n },\n [AnimationType.IMPROVISED_WEAPON]: {\n type: AnimationType.IMPROVISED_WEAPON,\n speed: 1.0,\n },\n [AnimationType.RUTHLESS_ASSAULT]: {\n type: AnimationType.RUTHLESS_ASSAULT,\n speed: 1.1,\n },\n [AnimationType.STREET_BRAWL]: {\n type: AnimationType.STREET_BRAWL,\n speed: 1.0,\n },\n\n // Movement (이동)\n [AnimationType.WALK]: { type: AnimationType.WALK, speed: 1.0 },\n [AnimationType.IDLE_STANCE]: { type: AnimationType.IDLE_STANCE, speed: 1.0 },\n [AnimationType.FORWARD_DASH]: {\n type: AnimationType.FORWARD_DASH,\n speed: 1.2,\n },\n [AnimationType.BACKWARD_RETREAT]: {\n type: AnimationType.BACKWARD_RETREAT,\n speed: 1.0,\n },\n [AnimationType.SIDE_STEP]: { type: AnimationType.SIDE_STEP, speed: 1.1 },\n [AnimationType.STEP_FORWARD]: {\n type: AnimationType.STEP_FORWARD,\n speed: 1.0,\n },\n [AnimationType.STEP_BACK]: { type: AnimationType.STEP_BACK, speed: 1.0 },\n [AnimationType.SIDESTEP]: { type: AnimationType.SIDESTEP, speed: 1.1 },\n [AnimationType.PIVOT]: { type: AnimationType.PIVOT, speed: 1.0 },\n [AnimationType.DUCK]: { type: AnimationType.DUCK, speed: 1.2 },\n [AnimationType.LEAN]: { type: AnimationType.LEAN, speed: 1.0 },\n\n // Recovery & Stance (복귀 및 자세)\n [AnimationType.RECOVERY]: { type: AnimationType.RECOVERY, speed: 1.0 },\n [AnimationType.IDLE]: { type: AnimationType.IDLE, speed: 1.0 },\n [AnimationType.STANCE]: { type: AnimationType.STANCE, speed: 1.0 },\n\n // Additional Kicks (추가 발차기)\n [AnimationType.SPINNING_HOOK]: {\n type: AnimationType.SPINNING_HOOK,\n speed: 0.95,\n },\n [AnimationType.KNEE_KICK]: { type: AnimationType.KNEE_KICK, speed: 1.0 },\n [AnimationType.FLYING_KICK]: { type: AnimationType.FLYING_KICK, speed: 0.95 },\n\n // Additional Knee/Elbow (추가 무릎/팔꿈치)\n [AnimationType.CLINCH_KNEE]: { type: AnimationType.CLINCH_KNEE, speed: 1.0 },\n\n // Additional Grappling (추가 잡기)\n [AnimationType.JOINT_LOCK]: { type: AnimationType.JOINT_LOCK, speed: 0.8 },\n [AnimationType.TAKEDOWN]: { type: AnimationType.TAKEDOWN, speed: 0.9 },\n [AnimationType.CLINCH]: { type: AnimationType.CLINCH, speed: 0.85 },\n};\n\n/**\n * Master technique-to-animation mapping\n *\n * Maps each technique ID to its animation configuration.\n * This is the canonical source of truth for animation selection.\n *\n * 기술 ID별 애니메이션 설정 마스터 매핑\n *\n * @korean 기술애니메이션매핑\n */\nexport const TECHNIQUE_ANIMATIONS: ReadonlyMap<string, AnimationConfig> =\n new Map([\n // ═══════════════════════════════════════════════════════════════════════\n // ☰ GEON (건) - HEAVEN: Direct Force (태권도 타격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"geon_heaven_strike\", { type: AnimationType.HEAVEN_STRIKE, speed: 1.0 }],\n [\"geon_heavenly_fist\", { type: AnimationType.JAB, speed: 1.1 }],\n [\"geon_frontal_kick\", { type: AnimationType.FRONT_KICK, speed: 1.0 }],\n [\n \"geon_roundhouse_kick\",\n { type: AnimationType.ROUNDHOUSE_KICK, speed: 1.0 },\n ],\n [\"geon_axe_kick\", { type: AnimationType.AXE_KICK, speed: 0.9 }],\n [\"geon_palm_strike\", { type: AnimationType.PALM_STRIKE, speed: 1.0 }],\n [\"geon_elbow_smash\", { type: AnimationType.ELBOW_STRIKE, speed: 1.1 }],\n [\"geon_high_block\", { type: AnimationType.HIGH_BLOCK, speed: 1.0 }],\n [\"geon_crushing_elbow\", { type: AnimationType.CRUSHING_ELBOW, speed: 1.0 }],\n [\n \"geon_thunderous_uppercut\",\n { type: AnimationType.THUNDEROUS_UPPERCUT, speed: 1.1 },\n ],\n [\"geon_counter_strike\", { type: AnimationType.GEON_COUNTER, speed: 1.1 }],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☱ TAE (태) - LAKE: Fluid Joint Manipulation (합기도)\n // ═══════════════════════════════════════════════════════════════════════\n [\"tae_flowing_strikes\", { type: AnimationType.FLOWING_CROSS, speed: 1.2 }],\n [\"tae_wrist_lock\", { type: AnimationType.WRIST_LOCK, speed: 0.85 }],\n [\n \"tae_small_circle\",\n { type: AnimationType.SMALL_CIRCLE_LOCK, speed: 0.85 },\n ],\n [\"tae_finger_lock\", { type: AnimationType.FINGER_LOCK, speed: 0.9 }],\n [\"tae_elbow_lock\", { type: AnimationType.ELBOW_LOCK, speed: 0.8 }],\n [\n \"tae_shoulder_lock\",\n { type: AnimationType.SHOULDER_MANIPULATION, speed: 0.8 },\n ],\n [\"tae_arm_bar\", { type: AnimationType.ARM_BAR, speed: 0.75 }],\n [\n \"tae_flowing_arm_bar\",\n { type: AnimationType.FLOWING_ARM_BAR, speed: 0.85 },\n ],\n [\n \"tae_joint_lock_defense\",\n { type: AnimationType.JOINT_LOCK_DEFENSE, speed: 0.9 },\n ],\n [\n \"tae_spiral_shoulder_throw\",\n { type: AnimationType.SPIRAL_SHOULDER_THROW, speed: 0.9 },\n ],\n [\"tae_sweep_defense\", { type: AnimationType.SWEEP_DEFENSE, speed: 1.0 }],\n [\n \"tae_wrist_lock_strike\",\n { type: AnimationType.WRIST_LOCK_STRIKE, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☲ LI (리) - FIRE: Precision Nerve Strikes (정밀 타격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"li_flame_spear\", { type: AnimationType.SPEAR_HAND_STRIKE, speed: 1.3 }],\n [\"li_temple_strike\", { type: AnimationType.TEMPLE_ELBOW, speed: 1.1 }],\n [\"li_nerve_strike\", { type: AnimationType.NERVE_STRIKE, speed: 1.2 }],\n [\"li_sidekick\", { type: AnimationType.SIDE_KICK, speed: 1.0 }],\n [\n \"li_pressure_point\",\n { type: AnimationType.PRESSURE_POINT_STRIKE, speed: 1.0 },\n ],\n [\n \"li_solar_plexus_strike\",\n { type: AnimationType.SOLAR_PLEXUS_STRIKE, speed: 1.1 },\n ],\n [\n \"li_phoenix_eye_strike\",\n { type: AnimationType.PHOENIX_EYE_STRIKE, speed: 1.2 },\n ],\n [\n \"li_nerve_strike_counter\",\n { type: AnimationType.NERVE_STRIKE_COUNTER, speed: 1.1 },\n ],\n [\"li_precision_parry\", { type: AnimationType.PRECISION_PARRY, speed: 1.1 }],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☳ JIN (진) - THUNDER: Explosive Power (폭발력)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"jin_lightning_flash\",\n { type: AnimationType.LIGHTNING_STRIKE, speed: 1.4 },\n ],\n [\n \"jin_jumping_front_kick\",\n { type: AnimationType.JUMPING_KICK, speed: 1.0 },\n ],\n [\"jin_tornado_kick\", { type: AnimationType.TORNADO_KICK, speed: 1.0 }],\n [\"jin_flying_sidekick\", { type: AnimationType.FLYING_KICK, speed: 1.1 }],\n [\"jin_back_kick\", { type: AnimationType.BACK_KICK, speed: 1.0 }],\n [\"jin_knee_strike\", { type: AnimationType.KNEE_STRIKE, speed: 1.1 }],\n [\n \"jin_explosive_block\",\n { type: AnimationType.EXPLOSIVE_BLOCK, speed: 1.1 },\n ],\n [\"jin_explosive_knee\", { type: AnimationType.EXPLOSIVE_KNEE, speed: 1.1 }],\n [\n \"jin_lightning_straight\",\n { type: AnimationType.LIGHTNING_STRAIGHT, speed: 1.3 },\n ],\n [\n \"jin_shocking_counter\",\n { type: AnimationType.SHOCKING_COUNTER, speed: 1.2 },\n ],\n [\n \"jin_shocking_hammer_fist\",\n { type: AnimationType.SHOCKING_HAMMER_FIST, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☴ SON (손) - WIND: Continuous Pressure (지속 공격)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"son_whirlwind_barrage\",\n { type: AnimationType.RAPID_BARRAGE, speed: 1.5 },\n ],\n [\"son_sweeping_low_kick\", { type: AnimationType.LOW_KICK, speed: 1.0 }],\n [\n \"son_rhythmic_strikes\",\n { type: AnimationType.RHYTHMIC_STRIKES, speed: 1.3 },\n ],\n [\"son_flowing_push\", { type: AnimationType.FLOWING_PUSH, speed: 1.1 }],\n [\n \"son_spinning_elbow\",\n { type: AnimationType.SPINNING_BACK_ELBOW, speed: 1.2 },\n ],\n [\"son_rapid_footwork\", { type: AnimationType.SIDE_STEP, speed: 1.3 }],\n [\n \"son_continuous_deflection\",\n { type: AnimationType.CONTINUOUS_DEFLECTION, speed: 1.2 },\n ],\n [\n \"son_penetrating_palm_rush\",\n { type: AnimationType.PENETRATING_PALM_RUSH, speed: 1.3 },\n ],\n [\n \"son_pressure_counter\",\n { type: AnimationType.PRESSURE_COUNTER, speed: 1.2 },\n ],\n [\n \"son_pressure_point_chain\",\n { type: AnimationType.PRESSURE_POINT_CHAIN, speed: 1.4 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☵ GAM (감) - WATER: Flow & Adaptation (유동 반격)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gam_water_counter\", { type: AnimationType.WATER_COUNTER, speed: 1.0 }],\n [\"gam_redirect_throw\", { type: AnimationType.REDIRECT_THROW, speed: 0.9 }],\n [\"gam_flowing_block\", { type: AnimationType.FLOWING_BLOCK, speed: 1.0 }],\n [\"gam_circular_parry\", { type: AnimationType.CIRCULAR_PARRY, speed: 1.1 }],\n [\"gam_hip_throw\", { type: AnimationType.HIP_WHEEL_THROW, speed: 0.85 }],\n [\n \"gam_wrist_twist_counter\",\n { type: AnimationType.WRIST_TWIST_COUNTER, speed: 0.9 },\n ],\n [\"gam_flow_defense\", { type: AnimationType.FLOW_DEFENSE, speed: 1.0 }],\n [\n \"gam_flowing_river_strike\",\n { type: AnimationType.FLOWING_RIVER_STRIKE, speed: 1.1 },\n ],\n [\n \"gam_redirection_counter\",\n { type: AnimationType.REDIRECTION_COUNTER, speed: 1.0 },\n ],\n [\n \"gam_tidal_wave_palm\",\n { type: AnimationType.TIDAL_WAVE_PALM, speed: 1.0 },\n ],\n [\n \"gam_whirlpool_counter\",\n { type: AnimationType.WHIRLPOOL_COUNTER, speed: 1.1 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☶ GAN (간) - MOUNTAIN: Defensive Mastery (방어 마스터리)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gan_rock_defense\", { type: AnimationType.ROCK_DEFENSE, speed: 0.9 }],\n [\"gan_immovable_stance\", { type: AnimationType.IDLE_STANCE, speed: 0.8 }],\n [\"gan_iron_block\", { type: AnimationType.IRON_BLOCK, speed: 0.85 }],\n [\"gan_counter_strike\", { type: AnimationType.ROCK_COUNTER, speed: 1.1 }],\n [\n \"gan_mountain_stance_lock\",\n { type: AnimationType.MOUNTAIN_LOCK, speed: 0.8 },\n ],\n [\n \"gan_reversal_technique\",\n { type: AnimationType.COUNTER_ATTACK, speed: 1.0 },\n ],\n [\n \"gan_avalanche_hammer\",\n { type: AnimationType.AVALANCHE_HAMMER, speed: 0.9 },\n ],\n [\n \"gan_counter_fortress\",\n { type: AnimationType.COUNTER_FORTRESS, speed: 1.0 },\n ],\n [\n \"gan_fortress_counter_strike\",\n { type: AnimationType.FORTRESS_COUNTER_STRIKE, speed: 1.1 },\n ],\n [\n \"gan_immovable_block\",\n { type: AnimationType.IMMOVABLE_BLOCK, speed: 0.85 },\n ],\n [\n \"gan_stone_wall_thrust\",\n { type: AnimationType.STONE_WALL_THRUST, speed: 0.95 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ☷ GON (곤) - EARTH: Grounding & Takedowns (넘어뜨리기)\n // ═══════════════════════════════════════════════════════════════════════\n [\"gon_earth_embrace\", { type: AnimationType.EARTH_EMBRACE, speed: 0.85 }],\n [\"gon_leg_sweep\", { type: AnimationType.SWEEP, speed: 1.0 }],\n [\"gon_ssireum_throw\", { type: AnimationType.SSIREUM_THROW, speed: 0.9 }],\n [\"gon_ground_pound\", { type: AnimationType.SLAM, speed: 1.0 }],\n [\"gon_ankle_pick\", { type: AnimationType.ANKLE_PICK, speed: 1.1 }],\n [\n \"gon_body_lock_takedown\",\n { type: AnimationType.BODY_LOCK_SLAM, speed: 0.85 },\n ],\n [\n \"gon_sacrifice_throw\",\n { type: AnimationType.SACRIFICE_THROW, speed: 0.8 },\n ],\n [\n \"gon_earthquake_stomp\",\n { type: AnimationType.EARTHQUAKE_STOMP, speed: 0.9 },\n ],\n [\n \"gon_grounding_defense\",\n { type: AnimationType.GROUNDING_DEFENSE, speed: 0.9 },\n ],\n [\n \"gon_ground_sweep_strike\",\n { type: AnimationType.GROUND_SWEEP_STRIKE, speed: 1.0 },\n ],\n [\n \"gon_rooting_takedown\",\n { type: AnimationType.ROOTING_TAKEDOWN, speed: 0.85 },\n ],\n [\n \"gon_takedown_counter\",\n { type: AnimationType.TAKEDOWN_COUNTER, speed: 1.0 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // DARK OPS (암살자) - Lethal Techniques (치명 기술)\n // ═══════════════════════════════════════════════════════════════════════\n [\n \"darkops_silent_carotid\",\n { type: AnimationType.CAROTID_CHOKE, speed: 0.9 },\n ],\n [\n \"darkops_nerve_paralysis\",\n { type: AnimationType.NERVE_PARALYSIS, speed: 1.1 },\n ],\n [\n \"darkops_liver_disruption\",\n { type: AnimationType.LIVER_DISRUPTION, speed: 1.0 },\n ],\n [\"darkops_kidney_strike\", { type: AnimationType.KIDNEY_KNEE, speed: 1.0 }],\n [\n \"darkops_throat_strike\",\n { type: AnimationType.THROAT_STRIKE, speed: 1.2 },\n ],\n [\n \"darkops_solar_plexus_paralyze\",\n { type: AnimationType.HAMMER_FIST, speed: 1.1 },\n ],\n [\n \"darkops_brachial_plexus_strike\",\n { type: AnimationType.BRACHIAL_ELBOW, speed: 1.1 },\n ],\n [\n \"darkops_femoral_nerve_strike\",\n { type: AnimationType.FEMORAL_KNEE, speed: 1.0 },\n ],\n [\n \"darkops_rear_choke\",\n { type: AnimationType.REAR_NAKED_CHOKE, speed: 0.8 },\n ],\n [\"darkops_spinal_strike\", { type: AnimationType.SPINAL_ELBOW, speed: 1.0 }],\n [\n \"darkops_jaw_dislocation\",\n { type: AnimationType.JAW_DISLOCATION, speed: 1.0 },\n ],\n [\n \"darkops_temple_strike\",\n { type: AnimationType.TEMPLE_STRIKE, speed: 1.1 },\n ],\n [\n \"darkops_achilles_sever\",\n { type: AnimationType.ACHILLES_ATTACK, speed: 1.2 },\n ],\n [\"darkops_ear_strike\", { type: AnimationType.EAR_STRIKE, speed: 1.2 }],\n [\"darkops_eye_gouge\", { type: AnimationType.EYE_GOUGE, speed: 1.3 }],\n // Additional Dark Ops techniques (extended set for future use)\n [\n \"darkops_cervical_twist\",\n { type: AnimationType.CERVICAL_TWIST, speed: 0.8 },\n ],\n [\n \"darkops_elbow_hyperextend\",\n { type: AnimationType.ELBOW_HYPEREXTEND, speed: 0.85 },\n ],\n [\"darkops_finger_break\", { type: AnimationType.FINGER_BREAK, speed: 1.0 }],\n [\n \"darkops_guillotine\",\n { type: AnimationType.GUILLOTINE_CHOKE, speed: 0.8 },\n ],\n [\n \"darkops_jugular_strike\",\n { type: AnimationType.JUGULAR_STRIKE, speed: 1.2 },\n ],\n [\n \"darkops_kneecap_strike\",\n { type: AnimationType.KNEECAP_STRIKE, speed: 1.1 },\n ],\n [\"darkops_larynx_crush\", { type: AnimationType.LARYNX_CRUSH, speed: 1.0 }],\n [\n \"darkops_occipital_strike\",\n { type: AnimationType.OCCIPITAL_STRIKE, speed: 1.1 },\n ],\n [\n \"darkops_sciatic_nerve\",\n { type: AnimationType.SCIATIC_NERVE_STRIKE, speed: 1.0 },\n ],\n [\n \"darkops_silent_takedown\",\n { type: AnimationType.SILENT_TAKEDOWN, speed: 0.9 },\n ],\n [\"darkops_sleeper_hold\", { type: AnimationType.SLEEPER_HOLD, speed: 0.75 }],\n [\n \"darkops_spleen_rupture\",\n { type: AnimationType.SPLEEN_RUPTURE, speed: 1.0 },\n ],\n [\n \"darkops_triangle_choke\",\n { type: AnimationType.TRIANGLE_CHOKE, speed: 0.8 },\n ],\n\n // ═══════════════════════════════════════════════════════════════════════\n // ARCHETYPE TECHNIQUES (원형 기술)\n // ═══════════════════════════════════════════════════════════════════════\n\n // Musa (무사) - Traditional Warrior\n [\"musa_dragon_fist\", { type: AnimationType.DRAGON_FIST, speed: 1.0 }],\n [\"musa_iron_defense\", { type: AnimationType.IRON_DEFENSE, speed: 0.9 }],\n [\n \"musa_mountain_breaker\",\n { type: AnimationType.MOUNTAIN_BREAKER, speed: 0.9 },\n ],\n [\"musa_thunder_strike\", { type: AnimationType.THUNDER_STRIKE, speed: 1.1 }],\n\n // Amsalja (암살자) - Shadow Assassin\n [\n \"amsalja_deadly_precision\",\n { type: AnimationType.DEADLY_PRECISION, speed: 1.2 },\n ],\n [\n \"amsalja_nerve_strike\",\n { type: AnimationType.SHADOW_NERVE_STRIKE, speed: 1.1 },\n ],\n [\n \"amsalja_shadow_strike\",\n { type: AnimationType.SHADOW_STRIKE, speed: 1.3 },\n ],\n [\"amsalja_silent_death\", { type: AnimationType.SILENT_DEATH, speed: 1.0 }],\n\n // Hacker (해커) - Cyber Warrior\n [\n \"hacker_cyber_overdrive\",\n { type: AnimationType.CYBER_OVERDRIVE, speed: 1.4 },\n ],\n [\"hacker_data_strike\", { type: AnimationType.DATA_STRIKE, speed: 1.2 }],\n [\n \"hacker_electric_shock\",\n { type: AnimationType.ELECTRIC_SHOCK, speed: 1.3 },\n ],\n [\"hacker_system_crash\", { type: AnimationType.SYSTEM_CRASH, speed: 1.0 }],\n\n // Jeongbo Yowon (정보요원) - Intelligence Operative\n [\n \"jeongbo_counter_intelligence\",\n { type: AnimationType.COUNTER_INTELLIGENCE, speed: 1.1 },\n ],\n [\n \"jeongbo_intelligence_strike\",\n { type: AnimationType.INTELLIGENCE_STRIKE, speed: 1.0 },\n ],\n [\n \"jeongbo_psychological_warfare\",\n { type: AnimationType.PSYCHOLOGICAL_WARFARE, speed: 0.9 },\n ],\n [\n \"jeongbo_tactical_strike\",\n { type: AnimationType.TACTICAL_STRIKE, speed: 1.1 },\n ],\n\n // Jojik Pokryeokbae (조직폭력배) - Organized Crime\n [\n \"jojik_brutal_takedown\",\n { type: AnimationType.BRUTAL_TAKEDOWN, speed: 0.9 },\n ],\n [\n \"jojik_improvised_weapon\",\n { type: AnimationType.IMPROVISED_WEAPON, speed: 1.0 },\n ],\n [\n \"jojik_ruthless_assault\",\n { type: AnimationType.RUTHLESS_ASSAULT, speed: 1.1 },\n ],\n [\"jojik_street_brawl\", { type: AnimationType.STREET_BRAWL, speed: 1.0 }],\n ]);\n\n/**\n * Get animation configuration for a technique\n *\n * @param techniqueId - The technique identifier\n * @returns Animation configuration or undefined if not mapped\n *\n * @korean 기술별애니메이션설정조회\n */\nexport function getAnimationForTechnique(\n techniqueId: string,\n): AnimationConfig | undefined {\n return TECHNIQUE_ANIMATIONS.get(techniqueId);\n}\n\n/**\n * Get animation configuration with fallback\n *\n * @param techniqueId - The technique identifier\n * @param fallbackType - Fallback animation type if not found\n * @returns Animation configuration (never undefined)\n *\n * @korean 기술별애니메이션설정조회_기본값\n */\nexport function getAnimationForTechniqueOrDefault(\n techniqueId: string,\n fallbackType: AnimationType = AnimationType.JAB,\n): AnimationConfig {\n const mapped = TECHNIQUE_ANIMATIONS.get(techniqueId);\n if (mapped) return mapped;\n\n const fallbackConfig = DEFAULT_CONFIGS[fallbackType];\n return fallbackConfig ?? { type: fallbackType, speed: 1.0 };\n}\n\n/**\n * Check if technique has animation mapping\n *\n * @param techniqueId - The technique identifier\n * @returns True if technique has animation mapping\n *\n * @korean 애니메이션매핑여부확인\n */\nexport function hasAnimationMapping(techniqueId: string): boolean {\n return TECHNIQUE_ANIMATIONS.has(techniqueId);\n}\n\n/**\n * Get all technique IDs with a specific animation type\n *\n * @param animationType - The animation type to search for\n * @returns Array of technique IDs using this animation\n *\n * @korean 애니메이션타입별기술조회\n */\nexport function getTechniquesByAnimationType(\n animationType: AnimationType,\n): readonly string[] {\n const techniques: string[] = [];\n for (const [id, config] of TECHNIQUE_ANIMATIONS) {\n if (config.type === animationType) {\n techniques.push(id);\n }\n }\n return techniques;\n}\n\n/**\n * Animation statistics for debugging\n */\nexport function getAnimationStats(): Record<AnimationType, number> {\n const stats: Record<AnimationType, number> = {} as Record<\n AnimationType,\n number\n >;\n\n // Initialize all types to 0\n for (const type of Object.values(AnimationType)) {\n stats[type] = 0;\n }\n\n // Count techniques per animation type\n for (const [, config] of TECHNIQUE_ANIMATIONS) {\n stats[config.type]++;\n }\n\n return stats;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MuscleActivation.js","names":[],"sources":["../../../../src/systems/animation/systems/MuscleActivation.ts"],"sourcesContent":["/**\n * Muscle activation system for realistic combat physiology\n *\n * Maps Korean martial arts techniques to anatomically accurate muscle activation patterns.\n * Manages dynamic muscle tension, stamina effects, and smooth relaxation transitions.\n * Includes stance-specific leg muscle tension for isometric holds and weight-bearing.\n *\n * @module systems/animation/MuscleActivation\n * @category Combat Animation\n * @korean 근육활성화시스템\n */\n\nimport type { TrigramStance } from \"@/types/common\";\nimport type {\n MuscleActivationMap,\n MuscleActivationState,\n MuscleGroupName,\n MuscleSystemConfig,\n} from \"@/types/muscle\";\nimport { KOREAN_STANCE_BIOMECHANICS } from \"../builders/MartialArtsConstants\";\n\n/**\n * Type-safe mapping of TrigramStance to biomechanics keys\n * Defined at module level to avoid recreation at 60fps\n * @korean 자세생체역학매핑\n */\nconst STANCE_TO_BIOMECH_KEY = {\n geon: \"GEON_HEAVEN\",\n tae: \"TAE_LAKE\",\n li: \"LI_FIRE\",\n jin: \"JIN_THUNDER\",\n son: \"SON_WIND\",\n gam: \"GAM_WATER\",\n gan: \"GAN_MOUNTAIN\",\n gon: \"GON_EARTH\",\n} as const satisfies Record<\n TrigramStance,\n keyof typeof KOREAN_STANCE_BIOMECHANICS\n>;\n\n/**\n * Get leg muscle tension for a specific trigram stance\n *\n * Calculates realistic leg muscle activation based on stance biomechanics:\n * - Weight distribution (체중부하) - Which leg bears more load\n * - Knee flexion angles (무릎굽힘각도) - Deep stances require more tension\n * - Isometric contraction (등척성수축) - Holding positions activates muscles\n *\n * Based on authentic Korean martial arts stance mechanics:\n * - Deep stances (Jin 90°, Gon 80°) = High quad/calf tension\n * - Front-weighted (Geon 60/40) = Front leg emphasis\n * - Back-weighted (Tae 10/90, Gam 30/70) = Back leg emphasis\n *\n * @param stance - Trigram stance (e.g., TrigramStance.GEON)\n * @returns Map of leg muscle groups to tension levels (0-1)\n *\n * @example\n * ```typescript\n * const jinMuscles = getMuscleTensionForStance(TrigramStance.JIN);\n * // Returns: Map {\n * // \"QUAD_L\" => 0.90, // Deep 90° knee bend\n * // \"QUAD_R\" => 0.90, // Equal weight distribution\n * // \"CALF_L\" => 0.85, // Isometric hold\n * // \"CALF_R\" => 0.85,\n * // \"HAMSTRING_L\" => 0.45,\n * // \"HAMSTRING_R\" => 0.45,\n * // \"GLUTE_L\" => 0.40,\n * // \"GLUTE_R\" => 0.40\n * // }\n * ```\n *\n * @korean 자세다리근육긴장도\n */\nexport const getMuscleTensionForStance = (\n stance: TrigramStance,\n): MuscleActivationMap => {\n const activations = new Map<MuscleGroupName, number>();\n\n // Get biomechanical data for stance (type-safe lookup)\n const biomechKey = STANCE_TO_BIOMECH_KEY[stance];\n const biomech = KOREAN_STANCE_BIOMECHANICS[biomechKey];\n\n if (!biomech) {\n // This branch should never execute with proper typing, but kept for safety\n // Provide conservative defaults for all muscle groups to keep map consistent\n activations.set(\"QUAD_L\", 0.2);\n activations.set(\"QUAD_R\", 0.2);\n activations.set(\"CALF_L\", 0.1);\n activations.set(\"CALF_R\", 0.1);\n activations.set(\"HAMSTRING_L\", 0.1);\n activations.set(\"HAMSTRING_R\", 0.1);\n activations.set(\"GLUTE_L\", 0.1);\n activations.set(\"GLUTE_R\", 0.1);\n return activations;\n }\n\n // Calculate quadriceps tension based on knee flexion\n // Formula (base tension): baseTension = (180° - kneeAngle) / 110°\n // Range: 90° knee → 0.82 base tension, 180° knee → 0.0 base tension\n // This base value is then combined with weight distribution for final tension\n const frontQuadTensionFromBend = Math.max(\n 0,\n Math.min(1.0, (180 - biomech.frontKneeBend) / 110),\n );\n const backQuadTensionFromBend = Math.max(\n 0,\n Math.min(1.0, (180 - biomech.backKneeBend) / 110),\n );\n\n // Apply weight distribution to muscle tension\n // Front leg quadriceps (체중부하 + 등척성수축)\n // Base tension from bend + weight factor\n // Note: Even with 0% weight, deep knee flexion produces tension\n // (e.g., raised leg in crane stance requires quad engagement to hold position)\n const frontQuadTension = Math.min(\n 1.0,\n frontQuadTensionFromBend * 0.6 + biomech.weightDistribution.front * 0.4,\n );\n\n // Back leg quadriceps\n const backQuadTension = Math.min(\n 1.0,\n backQuadTensionFromBend * 0.6 + biomech.weightDistribution.back * 0.4,\n );\n\n // Set quadriceps tension (right = front, left = back in standard stance)\n activations.set(\"QUAD_R\", frontQuadTension);\n activations.set(\"QUAD_L\", backQuadTension);\n\n // Calculate hamstring tension (antagonist muscles, lower activation)\n // Hamstrings activate more in bent positions for stabilization\n const frontHamstringTension =\n frontQuadTensionFromBend * 0.5 * biomech.weightDistribution.front;\n const backHamstringTension =\n backQuadTensionFromBend * 0.5 * biomech.weightDistribution.back;\n\n activations.set(\"HAMSTRING_R\", Math.min(0.8, frontHamstringTension));\n activations.set(\"HAMSTRING_L\", Math.min(0.8, backHamstringTension));\n\n // Calculate calf tension for deep stances (isometric hold support)\n // Very deep stances (< 100° knee angle) require significant calf engagement\n const frontCalfTension =\n biomech.frontKneeBend < 100\n ? Math.min(0.9, 0.5 + ((100 - biomech.frontKneeBend) / 50) * 0.4) *\n biomech.weightDistribution.front\n : 0.25 * biomech.weightDistribution.front;\n\n const backCalfTension =\n biomech.backKneeBend < 100\n ? Math.min(0.9, 0.5 + ((100 - biomech.backKneeBend) / 50) * 0.4) *\n biomech.weightDistribution.back\n : 0.25 * biomech.weightDistribution.back;\n\n activations.set(\"CALF_R\", frontCalfTension);\n activations.set(\"CALF_L\", backCalfTension);\n\n // Calculate glute activation (hip extension support)\n // Glutes engage more in deep stances for posture maintenance\n const gluteBaseActivation = (1.0 - biomech.hipHeight) * 0.5;\n\n activations.set(\n \"GLUTE_R\",\n Math.min(\n 0.7,\n gluteBaseActivation +\n frontQuadTensionFromBend * 0.2 * biomech.weightDistribution.front,\n ),\n );\n activations.set(\n \"GLUTE_L\",\n Math.min(\n 0.7,\n gluteBaseActivation +\n backQuadTensionFromBend * 0.2 * biomech.weightDistribution.back,\n ),\n );\n\n return activations;\n};\n\n/**\n * Get muscle activation mapping for a specific Korean martial arts technique\n *\n * Maps technique names to muscle groups with tension levels (0-1 scale).\n * Based on authentic Korean martial arts (Taekwondo, Hapkido, Taekyon).\n *\n * @param technique - Technique name (e.g., \"jab\", \"cross\", \"front_kick\", \"block\")\n * @returns Map of muscle groups to target tension levels\n *\n * @example\n * ```typescript\n * const jabMuscles = getMuscleActivationForTechnique(\"jab\");\n * // Returns: Map {\n * // \"SHOULDER_R\" => 0.7,\n * // \"BICEP_R\" => 1.0,\n * // \"TRICEP_R\" => 0.8,\n * // \"CORE\" => 0.5\n * // }\n * ```\n *\n * @korean 기법근육활성화가져오기\n */\nexport const getMuscleActivationForTechnique = (\n technique: string,\n): MuscleActivationMap => {\n const activations = new Map<MuscleGroupName, number>();\n\n switch (technique.toLowerCase()) {\n // Punching techniques - 주먹 기술\n case \"jab\":\n case \"정권\": // Front jab\n activations.set(\"SHOULDER_R\", 0.8);\n activations.set(\"TRICEP_R\", 1.0); // Primary mover for arm extension\n activations.set(\"BICEP_R\", 0.3); // Antagonist - stabilization only\n activations.set(\"CORE\", 0.5);\n activations.set(\"PECTORALS\", 0.5); // Shoulder horizontal adduction\n break;\n\n case \"cross\":\n case \"역권\": // Reverse punch\n activations.set(\"SHOULDER_L\", 0.9);\n activations.set(\"TRICEP_L\", 1.0); // Primary mover for arm extension\n activations.set(\"BICEP_L\", 0.3); // Antagonist - stabilization only\n activations.set(\"CORE\", 0.8); // More core rotation\n activations.set(\"PECTORALS\", 0.7); // Chest drive for power\n activations.set(\"OBLIQUES\", 0.8); // Torso rotation for hip transfer\n break;\n\n case \"hook\":\n case \"갈고리주먹\": // Hook punch\n activations.set(\"SHOULDER_R\", 1.0); // Primary mover for horizontal arc\n activations.set(\"BICEP_R\", 0.8); // Maintains elbow angle during arc\n activations.set(\"FOREARM_R\", 0.8);\n activations.set(\"CORE\", 0.8); // Drives rotational power\n activations.set(\"OBLIQUES\", 0.9); // Primary torso rotation driver\n break;\n\n case \"uppercut\":\n case \"올려치기\": // Uppercut\n activations.set(\"SHOULDER_R\", 0.95); // Drives upward arc\n activations.set(\"BICEP_R\", 0.9); // Maintains elbow angle for upward drive\n activations.set(\"TRICEP_R\", 0.5); // Partial extension\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.8);\n activations.set(\"QUAD_R\", 0.7); // Lower body drive (legs push up)\n activations.set(\"GLUTE_R\", 0.6); // Hip extension for power\n break;\n\n // Kicking techniques - 발차기 기술\n case \"front_kick\":\n case \"앞차기\": // Mae Chagi\n activations.set(\"QUAD_R\", 1.0); // Kicking leg fully flexed\n activations.set(\"GLUTE_R\", 0.9);\n activations.set(\"CALF_R\", 0.7);\n activations.set(\"CORE\", 0.6); // Balance\n activations.set(\"ABS\", 0.7);\n activations.set(\"QUAD_L\", 0.4); // Support leg tensed\n activations.set(\"CALF_L\", 0.5);\n break;\n\n case \"roundhouse_kick\":\n case \"dollyeochagi\":\n case \"돌려차기\": // Dollyeo Chagi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.8);\n activations.set(\"GLUTE_R\", 0.95);\n activations.set(\"CORE\", 0.8);\n activations.set(\"OBLIQUES\", 0.9); // Hip rotation\n activations.set(\"QUAD_L\", 0.5);\n break;\n\n case \"side_kick\":\n case \"옆차기\": // Yeop Chagi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"GLUTE_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.85);\n activations.set(\"CALF_R\", 0.8);\n activations.set(\"CORE\", 0.7);\n activations.set(\"OBLIQUES\", 0.8);\n break;\n\n case \"back_kick\":\n case \"뒤차기\": // Dwi Chagi\n activations.set(\"GLUTE_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.95);\n activations.set(\"QUAD_R\", 0.8);\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.8);\n break;\n\n case \"axe_kick\":\n case \"내려차기\": // Naeryeo Chagi\n activations.set(\"QUAD_R\", 0.9);\n activations.set(\"HAMSTRING_R\", 1.0); // Maximum hamstring flex\n activations.set(\"GLUTE_R\", 0.85);\n activations.set(\"CORE\", 0.8);\n activations.set(\"ABS\", 0.9);\n break;\n\n // Defensive techniques - 방어 기술\n case \"block\":\n case \"makgi\":\n case \"막기\": // Block\n activations.set(\"SHOULDER_L\", 0.9);\n activations.set(\"SHOULDER_R\", 0.9);\n activations.set(\"BICEP_L\", 0.7);\n activations.set(\"BICEP_R\", 0.7);\n activations.set(\"FOREARM_L\", 0.8);\n activations.set(\"FOREARM_R\", 0.8);\n activations.set(\"CORE\", 0.8); // Brace for impact\n activations.set(\"ABS\", 0.7);\n break;\n\n case \"parry\":\n case \"흘려막기\": // Deflecting block\n activations.set(\"SHOULDER_R\", 0.6);\n activations.set(\"FOREARM_R\", 0.7);\n activations.set(\"CORE\", 0.5);\n break;\n\n // Elbow techniques - 팔꿈치 기술\n case \"elbow_strike\":\n case \"팔꿈치치기\": // Palkumchi Chigi\n activations.set(\"SHOULDER_R\", 1.0);\n activations.set(\"TRICEP_R\", 0.95);\n activations.set(\"FOREARM_R\", 0.9);\n activations.set(\"CORE\", 0.85);\n activations.set(\"OBLIQUES\", 0.8);\n break;\n\n // Knee techniques - 무릎 기술\n case \"knee_strike\":\n case \"무릎치기\": // Mureup Chigi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.9);\n activations.set(\"GLUTE_R\", 0.85);\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.85);\n break;\n\n // Grappling techniques - 잡기 기술 (Hapkido)\n case \"grab\":\n case \"잡기\":\n activations.set(\"FOREARM_L\", 0.9);\n activations.set(\"FOREARM_R\", 0.9);\n activations.set(\"BICEP_L\", 0.7);\n activations.set(\"BICEP_R\", 0.7);\n activations.set(\"CORE\", 0.6);\n break;\n\n // Stance changes - 자세 전환\n case \"stance_change\":\n case \"자세전환\":\n activations.set(\"CORE\", 0.7);\n activations.set(\"ABS\", 0.6);\n activations.set(\"QUAD_L\", 0.5);\n activations.set(\"QUAD_R\", 0.5);\n activations.set(\"CALF_L\", 0.5);\n activations.set(\"CALF_R\", 0.5);\n break;\n\n // Default - minimal activation\n default:\n activations.set(\"CORE\", 0.3);\n break;\n }\n\n return activations;\n};\n\n/**\n * Muscle activation manager for real-time combat physiology\n *\n * Manages 60fps muscle tension updates, stamina effects, and smooth transitions.\n * Optimized for performance with ref-based updates to avoid React re-renders.\n *\n * @korean 근육활성화관리자\n */\nexport class MuscleActivationManager {\n private activations: Map<MuscleGroupName, MuscleActivationState>;\n private config: MuscleSystemConfig;\n private scratchMap: Map<string, number>; // Reusable map for state sync to avoid allocations\n\n /**\n * Create a new muscle activation manager\n *\n * @param config - Optional configuration (uses defaults if not provided)\n * @korean 생성자\n */\n constructor(config: Partial<MuscleSystemConfig> = {}) {\n this.config = {\n maxFrameTime: 3,\n muscleCount: 20,\n useInstancing: false,\n relaxationDelay: 0.3,\n exhaustionThreshold: 20,\n shakeFrequency: 20,\n shakeAmplitude: 0.02,\n activationSpeed: 5.0,\n relaxationSpeed: 3.0,\n shakingTensionThreshold: 0.3,\n ...config,\n };\n\n // Initialize all muscle groups to relaxed state\n this.activations = new Map();\n // Initialize reusable scratch map for state sync\n this.scratchMap = new Map();\n const allMuscles: MuscleGroupName[] = [\n \"SHOULDER_L\",\n \"SHOULDER_R\",\n \"BICEP_L\",\n \"BICEP_R\",\n \"TRICEP_L\",\n \"TRICEP_R\",\n \"FOREARM_L\",\n \"FOREARM_R\",\n \"PECTORALS\",\n \"CORE\",\n \"ABS\",\n \"OBLIQUES\",\n \"QUAD_L\",\n \"QUAD_R\",\n \"HAMSTRING_L\",\n \"HAMSTRING_R\",\n \"CALF_L\",\n \"CALF_R\",\n \"GLUTE_L\",\n \"GLUTE_R\",\n ];\n\n allMuscles.forEach((muscle) => {\n this.activations.set(muscle, {\n muscleGroup: muscle,\n tension: 0,\n targetTension: 0,\n isShaking: false,\n });\n });\n }\n\n /**\n * Update muscle activations for a technique at 60fps\n *\n * @param technique - Technique name\n * @param stamina - Current stamina (0-100)\n * @param delta - Time since last frame in seconds\n *\n * @korean 업데이트\n */\n update(technique: string, stamina: number, delta: number): void {\n const targetActivations = getMuscleActivationForTechnique(technique);\n const isExhausted = stamina < this.config.exhaustionThreshold;\n\n // Update each muscle group\n this.activations.forEach((state, muscleGroup) => {\n const targetTension = targetActivations.get(muscleGroup) ?? 0;\n\n // Adjust tension based on stamina (exhaustion reduces muscle effectiveness)\n const staminaFactor = Math.max(0.3, stamina / 100); // Minimum 30% even when exhausted\n const adjustedTarget = targetTension * staminaFactor;\n\n // Smooth transition to target tension using lerp\n const lerp = (start: number, end: number, t: number) =>\n start + (end - start) * t;\n const newTension = lerp(\n state.tension,\n adjustedTarget,\n this.config.activationSpeed * delta,\n );\n\n // Update shaking state for exhaustion\n const isShaking =\n isExhausted && state.tension > this.config.shakingTensionThreshold;\n\n // Update state directly for performance\n state.tension = newTension;\n state.targetTension = adjustedTarget;\n state.isShaking = isShaking;\n });\n }\n\n /**\n * Gradually relax all muscles to idle state\n *\n * Used after technique completion with configurable delay.\n *\n * @param delta - Time since last frame in seconds\n *\n * @korean 근육이완\n */\n relaxAllMuscles(delta: number): void {\n this.activations.forEach((state) => {\n // Use configured relaxation speed (slower than activation for realism)\n const lerp = (start: number, end: number, t: number) =>\n start + (end - start) * t;\n const newTension = lerp(\n state.tension,\n 0,\n this.config.relaxationSpeed * delta,\n );\n\n state.tension = newTension;\n state.targetTension = 0;\n state.isShaking = false;\n });\n }\n\n /**\n * Get current tension for a specific muscle group\n *\n * @param muscleGroup - Muscle group name\n * @returns Current tension (0-1) or 0 if not found\n *\n * @korean 긴장도가져오기\n */\n getTension(muscleGroup: MuscleGroupName): number {\n return this.activations.get(muscleGroup)?.tension ?? 0;\n }\n\n /**\n * Get shaking state for a specific muscle group\n *\n * @param muscleGroup - Muscle group name\n * @returns Whether muscle is shaking\n *\n * @korean 흔들림상태가져오기\n */\n isShaking(muscleGroup: MuscleGroupName): boolean {\n return this.activations.get(muscleGroup)?.isShaking ?? false;\n }\n\n /**\n * Get all current muscle activations\n *\n * @returns Map of muscle groups to current states\n *\n * @korean 모든활성화가져오기\n */\n getAllActivations(): ReadonlyMap<MuscleGroupName, MuscleActivationState> {\n return this.activations;\n }\n\n /**\n * Get reusable scratch map with current tension values for state sync\n *\n * Populates and returns a reusable Map to avoid allocations during state sync.\n * This map is cleared and repopulated on each call.\n *\n * @returns Reusable Map with current tension values\n *\n * @korean 상태동기화맵가져오기\n */\n getScratchMapForSync(): Map<string, number> {\n this.scratchMap.clear();\n this.activations.forEach((state, name) => {\n this.scratchMap.set(name, state.tension);\n });\n return this.scratchMap;\n }\n\n /**\n * Reset all muscles to relaxed state immediately\n *\n * @korean 즉시이완\n */\n reset(): void {\n this.activations.forEach((state) => {\n state.tension = 0;\n state.targetTension = 0;\n state.isShaking = false;\n });\n this.scratchMap.clear();\n }\n\n /**\n * Dispose of the muscle activation system\n *\n * Clears all internal state and references to prevent memory leaks.\n * Should be called when the system is no longer needed (e.g., component unmount).\n *\n * @korean 근육시스템해제\n */\n dispose(): void {\n this.activations.clear();\n this.scratchMap.clear();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MuscleActivation.js","names":[],"sources":["../../../../src/systems/animation/systems/MuscleActivation.ts"],"sourcesContent":["/**\n * Muscle activation system for realistic combat physiology\n *\n * Maps Korean martial arts techniques to anatomically accurate muscle activation patterns.\n * Manages dynamic muscle tension, stamina effects, and smooth relaxation transitions.\n * Includes stance-specific leg muscle tension for isometric holds and weight-bearing.\n *\n * @module systems/animation/MuscleActivation\n * @category Combat Animation\n * @korean 근육활성화시스템\n */\n\nimport type { TrigramStance } from \"@/types/common\";\nimport type {\n MuscleActivationMap,\n MuscleActivationState,\n MuscleGroupName,\n MuscleSystemConfig,\n} from \"@/types/muscle\";\nimport { KOREAN_STANCE_BIOMECHANICS } from \"../builders/MartialArtsConstants\";\n\n/**\n * Type-safe mapping of TrigramStance to biomechanics keys\n * Defined at module level to avoid recreation at 60fps\n * @korean 자세생체역학매핑\n */\nconst STANCE_TO_BIOMECH_KEY = {\n geon: \"GEON_HEAVEN\",\n tae: \"TAE_LAKE\",\n li: \"LI_FIRE\",\n jin: \"JIN_THUNDER\",\n son: \"SON_WIND\",\n gam: \"GAM_WATER\",\n gan: \"GAN_MOUNTAIN\",\n gon: \"GON_EARTH\",\n} as const satisfies Record<\n TrigramStance,\n keyof typeof KOREAN_STANCE_BIOMECHANICS\n>;\n\n/**\n * Get leg muscle tension for a specific trigram stance\n *\n * Calculates realistic leg muscle activation based on stance biomechanics:\n * - Weight distribution (체중부하) - Which leg bears more load\n * - Knee flexion angles (무릎굽힘각도) - Deep stances require more tension\n * - Isometric contraction (등척성수축) - Holding positions activates muscles\n *\n * Based on authentic Korean martial arts stance mechanics:\n * - Deep stances (Jin 90°, Gon 80°) = High quad/calf tension\n * - Front-weighted (Geon 60/40) = Front leg emphasis\n * - Back-weighted (Tae 10/90, Gam 30/70) = Back leg emphasis\n *\n * @param stance - Trigram stance (e.g., TrigramStance.GEON)\n * @returns Map of leg muscle groups to tension levels (0-1)\n *\n * @example\n * ```typescript\n * const jinMuscles = getMuscleTensionForStance(TrigramStance.JIN);\n * // Returns: Map {\n * // \"QUAD_L\" => 0.90, // Deep 90° knee bend\n * // \"QUAD_R\" => 0.90, // Equal weight distribution\n * // \"CALF_L\" => 0.85, // Isometric hold\n * // \"CALF_R\" => 0.85,\n * // \"HAMSTRING_L\" => 0.45,\n * // \"HAMSTRING_R\" => 0.45,\n * // \"GLUTE_L\" => 0.40,\n * // \"GLUTE_R\" => 0.40\n * // }\n * ```\n *\n * @korean 자세다리근육긴장도\n */\nexport const getMuscleTensionForStance = (\n stance: TrigramStance,\n): MuscleActivationMap => {\n const activations = new Map<MuscleGroupName, number>();\n\n // Get biomechanical data for stance (type-safe lookup)\n const biomechKey = STANCE_TO_BIOMECH_KEY[stance];\n const biomech = KOREAN_STANCE_BIOMECHANICS[biomechKey];\n\n if (!biomech) {\n // This branch should never execute with proper typing, but kept for safety\n // Provide conservative defaults for all muscle groups to keep map consistent\n activations.set(\"QUAD_L\", 0.2);\n activations.set(\"QUAD_R\", 0.2);\n activations.set(\"CALF_L\", 0.1);\n activations.set(\"CALF_R\", 0.1);\n activations.set(\"HAMSTRING_L\", 0.1);\n activations.set(\"HAMSTRING_R\", 0.1);\n activations.set(\"GLUTE_L\", 0.1);\n activations.set(\"GLUTE_R\", 0.1);\n return activations;\n }\n\n // Calculate quadriceps tension based on knee flexion\n // Formula (base tension): baseTension = (180° - kneeAngle) / 110°\n // Range: 90° knee → 0.82 base tension, 180° knee → 0.0 base tension\n // This base value is then combined with weight distribution for final tension\n const frontQuadTensionFromBend = Math.max(\n 0,\n Math.min(1.0, (180 - biomech.frontKneeBend) / 110),\n );\n const backQuadTensionFromBend = Math.max(\n 0,\n Math.min(1.0, (180 - biomech.backKneeBend) / 110),\n );\n\n // Apply weight distribution to muscle tension\n // Front leg quadriceps (체중부하 + 등척성수축)\n // Base tension from bend + weight factor\n // Note: Even with 0% weight, deep knee flexion produces tension\n // (e.g., raised leg in crane stance requires quad engagement to hold position)\n const frontQuadTension = Math.min(\n 1.0,\n frontQuadTensionFromBend * 0.6 + biomech.weightDistribution.front * 0.4,\n );\n\n // Back leg quadriceps\n const backQuadTension = Math.min(\n 1.0,\n backQuadTensionFromBend * 0.6 + biomech.weightDistribution.back * 0.4,\n );\n\n // Set quadriceps tension (right = front, left = back in standard stance)\n activations.set(\"QUAD_R\", frontQuadTension);\n activations.set(\"QUAD_L\", backQuadTension);\n\n // Calculate hamstring tension (antagonist muscles, lower activation)\n // Hamstrings activate more in bent positions for stabilization\n const frontHamstringTension =\n frontQuadTensionFromBend * 0.5 * biomech.weightDistribution.front;\n const backHamstringTension =\n backQuadTensionFromBend * 0.5 * biomech.weightDistribution.back;\n\n activations.set(\"HAMSTRING_R\", Math.min(0.8, frontHamstringTension));\n activations.set(\"HAMSTRING_L\", Math.min(0.8, backHamstringTension));\n\n // Calculate calf tension for deep stances (isometric hold support)\n // Very deep stances (< 100° knee angle) require significant calf engagement\n const frontCalfTension =\n biomech.frontKneeBend < 100\n ? Math.min(0.9, 0.5 + ((100 - biomech.frontKneeBend) / 50) * 0.4) *\n biomech.weightDistribution.front\n : 0.25 * biomech.weightDistribution.front;\n\n const backCalfTension =\n biomech.backKneeBend < 100\n ? Math.min(0.9, 0.5 + ((100 - biomech.backKneeBend) / 50) * 0.4) *\n biomech.weightDistribution.back\n : 0.25 * biomech.weightDistribution.back;\n\n activations.set(\"CALF_R\", frontCalfTension);\n activations.set(\"CALF_L\", backCalfTension);\n\n // Calculate glute activation (hip extension support)\n // Glutes engage more in deep stances for posture maintenance\n const gluteBaseActivation = (1.0 - biomech.hipHeight) * 0.5;\n\n activations.set(\n \"GLUTE_R\",\n Math.min(\n 0.7,\n gluteBaseActivation +\n frontQuadTensionFromBend * 0.2 * biomech.weightDistribution.front,\n ),\n );\n activations.set(\n \"GLUTE_L\",\n Math.min(\n 0.7,\n gluteBaseActivation +\n backQuadTensionFromBend * 0.2 * biomech.weightDistribution.back,\n ),\n );\n\n return activations;\n};\n\n/**\n * Get muscle activation mapping for a specific Korean martial arts technique\n *\n * Maps technique names to muscle groups with tension levels (0-1 scale).\n * Based on authentic Korean martial arts (Taekwondo, Hapkido, Taekyon).\n *\n * @param technique - Technique name (e.g., \"jab\", \"cross\", \"front_kick\", \"block\")\n * @returns Map of muscle groups to target tension levels\n *\n * @example\n * ```typescript\n * const jabMuscles = getMuscleActivationForTechnique(\"jab\");\n * // Returns: Map {\n * // \"SHOULDER_R\" => 0.7,\n * // \"BICEP_R\" => 1.0,\n * // \"TRICEP_R\" => 0.8,\n * // \"CORE\" => 0.5\n * // }\n * ```\n *\n * @korean 기법근육활성화가져오기\n */\nexport const getMuscleActivationForTechnique = (\n technique: string,\n): MuscleActivationMap => {\n const activations = new Map<MuscleGroupName, number>();\n\n switch (technique.toLowerCase()) {\n // Punching techniques - 주먹 기술\n case \"jab\":\n case \"정권\": // Front jab\n activations.set(\"SHOULDER_R\", 0.8);\n activations.set(\"TRICEP_R\", 1.0); // Primary mover for arm extension\n activations.set(\"BICEP_R\", 0.3); // Antagonist - stabilization only\n activations.set(\"CORE\", 0.5);\n activations.set(\"PECTORALS\", 0.5); // Shoulder horizontal adduction\n break;\n\n case \"cross\":\n case \"역권\": // Reverse punch\n activations.set(\"SHOULDER_L\", 0.9);\n activations.set(\"TRICEP_L\", 1.0); // Primary mover for arm extension\n activations.set(\"BICEP_L\", 0.3); // Antagonist - stabilization only\n activations.set(\"CORE\", 0.8); // More core rotation\n activations.set(\"PECTORALS\", 0.7); // Chest drive for power\n activations.set(\"OBLIQUES\", 0.8); // Torso rotation for hip transfer\n break;\n\n case \"hook\":\n case \"갈고리주먹\": // Hook punch\n activations.set(\"SHOULDER_R\", 1.0); // Primary mover for horizontal arc\n activations.set(\"BICEP_R\", 0.8); // Maintains elbow angle during arc\n activations.set(\"FOREARM_R\", 0.8);\n activations.set(\"CORE\", 0.8); // Drives rotational power\n activations.set(\"OBLIQUES\", 0.9); // Primary torso rotation driver\n break;\n\n case \"uppercut\":\n case \"올려치기\": // Uppercut\n activations.set(\"SHOULDER_R\", 0.95); // Drives upward arc\n activations.set(\"BICEP_R\", 0.9); // Maintains elbow angle for upward drive\n activations.set(\"TRICEP_R\", 0.5); // Partial extension\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.8);\n activations.set(\"QUAD_R\", 0.7); // Lower body drive (legs push up)\n activations.set(\"GLUTE_R\", 0.6); // Hip extension for power\n break;\n\n // Kicking techniques - 발차기 기술\n case \"front_kick\":\n case \"앞차기\": // Mae Chagi\n activations.set(\"QUAD_R\", 1.0); // Kicking leg fully flexed\n activations.set(\"GLUTE_R\", 0.9);\n activations.set(\"CALF_R\", 0.7);\n activations.set(\"CORE\", 0.6); // Balance\n activations.set(\"ABS\", 0.7);\n activations.set(\"QUAD_L\", 0.4); // Support leg tensed\n activations.set(\"CALF_L\", 0.5);\n break;\n\n case \"roundhouse_kick\":\n case \"dollyeochagi\":\n case \"돌려차기\": // Dollyeo Chagi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.8);\n activations.set(\"GLUTE_R\", 0.95);\n activations.set(\"CORE\", 0.8);\n activations.set(\"OBLIQUES\", 0.9); // Hip rotation\n activations.set(\"QUAD_L\", 0.5);\n break;\n\n case \"side_kick\":\n case \"옆차기\": // Yeop Chagi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"GLUTE_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.85);\n activations.set(\"CALF_R\", 0.8);\n activations.set(\"CORE\", 0.7);\n activations.set(\"OBLIQUES\", 0.8);\n break;\n\n case \"back_kick\":\n case \"뒤차기\": // Dwi Chagi\n activations.set(\"GLUTE_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.95);\n activations.set(\"QUAD_R\", 0.8);\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.8);\n break;\n\n case \"axe_kick\":\n case \"내려차기\": // Naeryeo Chagi\n activations.set(\"QUAD_R\", 0.9);\n activations.set(\"HAMSTRING_R\", 1.0); // Maximum hamstring flex\n activations.set(\"GLUTE_R\", 0.85);\n activations.set(\"CORE\", 0.8);\n activations.set(\"ABS\", 0.9);\n break;\n\n // Defensive techniques - 방어 기술\n case \"block\":\n case \"makgi\":\n case \"막기\": // Block\n activations.set(\"SHOULDER_L\", 0.9);\n activations.set(\"SHOULDER_R\", 0.9);\n activations.set(\"BICEP_L\", 0.7);\n activations.set(\"BICEP_R\", 0.7);\n activations.set(\"FOREARM_L\", 0.8);\n activations.set(\"FOREARM_R\", 0.8);\n activations.set(\"CORE\", 0.8); // Brace for impact\n activations.set(\"ABS\", 0.7);\n break;\n\n case \"parry\":\n case \"흘려막기\": // Deflecting block\n activations.set(\"SHOULDER_R\", 0.6);\n activations.set(\"FOREARM_R\", 0.7);\n activations.set(\"CORE\", 0.5);\n break;\n\n // Elbow techniques - 팔꿈치 기술\n case \"elbow_strike\":\n case \"팔꿈치치기\": // Palkumchi Chigi\n activations.set(\"SHOULDER_R\", 1.0);\n activations.set(\"TRICEP_R\", 0.95);\n activations.set(\"FOREARM_R\", 0.9);\n activations.set(\"CORE\", 0.85);\n activations.set(\"OBLIQUES\", 0.8);\n break;\n\n // Knee techniques - 무릎 기술\n case \"knee_strike\":\n case \"무릎치기\": // Mureup Chigi\n activations.set(\"QUAD_R\", 1.0);\n activations.set(\"HAMSTRING_R\", 0.9);\n activations.set(\"GLUTE_R\", 0.85);\n activations.set(\"CORE\", 0.9);\n activations.set(\"ABS\", 0.85);\n break;\n\n // Grappling techniques - 잡기 기술 (Hapkido)\n case \"grab\":\n case \"잡기\":\n activations.set(\"FOREARM_L\", 0.9);\n activations.set(\"FOREARM_R\", 0.9);\n activations.set(\"BICEP_L\", 0.7);\n activations.set(\"BICEP_R\", 0.7);\n activations.set(\"CORE\", 0.6);\n break;\n\n // Stance changes - 자세 전환\n case \"stance_change\":\n case \"자세전환\":\n activations.set(\"CORE\", 0.7);\n activations.set(\"ABS\", 0.6);\n activations.set(\"QUAD_L\", 0.5);\n activations.set(\"QUAD_R\", 0.5);\n activations.set(\"CALF_L\", 0.5);\n activations.set(\"CALF_R\", 0.5);\n break;\n\n // Default - minimal activation\n default:\n activations.set(\"CORE\", 0.3);\n break;\n }\n\n return activations;\n};\n\n/**\n * Muscle activation manager for real-time combat physiology\n *\n * Manages 60fps muscle tension updates, stamina effects, and smooth transitions.\n * Optimized for performance with ref-based updates to avoid React re-renders.\n *\n * @korean 근육활성화관리자\n */\nexport class MuscleActivationManager {\n private activations: Map<MuscleGroupName, MuscleActivationState>;\n private config: MuscleSystemConfig;\n private scratchMap: Map<string, number>; // Reusable map for state sync to avoid allocations\n\n /**\n * Create a new muscle activation manager\n *\n * @param config - Optional configuration (uses defaults if not provided)\n * @korean 생성자\n */\n constructor(config: Partial<MuscleSystemConfig> = {}) {\n this.config = {\n maxFrameTime: 3,\n muscleCount: 20,\n useInstancing: false,\n relaxationDelay: 0.3,\n exhaustionThreshold: 20,\n shakeFrequency: 20,\n shakeAmplitude: 0.02,\n activationSpeed: 5.0,\n relaxationSpeed: 3.0,\n shakingTensionThreshold: 0.3,\n ...config,\n };\n\n // Initialize all muscle groups to relaxed state\n this.activations = new Map();\n // Initialize reusable scratch map for state sync\n this.scratchMap = new Map();\n const allMuscles: MuscleGroupName[] = [\n \"SHOULDER_L\",\n \"SHOULDER_R\",\n \"BICEP_L\",\n \"BICEP_R\",\n \"TRICEP_L\",\n \"TRICEP_R\",\n \"FOREARM_L\",\n \"FOREARM_R\",\n \"PECTORALS\",\n \"CORE\",\n \"ABS\",\n \"OBLIQUES\",\n \"QUAD_L\",\n \"QUAD_R\",\n \"HAMSTRING_L\",\n \"HAMSTRING_R\",\n \"CALF_L\",\n \"CALF_R\",\n \"GLUTE_L\",\n \"GLUTE_R\",\n ];\n\n allMuscles.forEach((muscle) => {\n this.activations.set(muscle, {\n muscleGroup: muscle,\n tension: 0,\n targetTension: 0,\n isShaking: false,\n });\n });\n }\n\n /**\n * Update muscle activations for a technique at 60fps\n *\n * @param technique - Technique name\n * @param stamina - Current stamina (0-100)\n * @param delta - Time since last frame in seconds\n *\n * @korean 업데이트\n */\n update(technique: string, stamina: number, delta: number): void {\n const targetActivations = getMuscleActivationForTechnique(technique);\n const isExhausted = stamina < this.config.exhaustionThreshold;\n\n // Update each muscle group\n this.activations.forEach((state, muscleGroup) => {\n const targetTension = targetActivations.get(muscleGroup) ?? 0;\n\n // Adjust tension based on stamina (exhaustion reduces muscle effectiveness)\n const staminaFactor = Math.max(0.3, stamina / 100); // Minimum 30% even when exhausted\n const adjustedTarget = targetTension * staminaFactor;\n\n // Smooth transition to target tension using lerp\n const lerp = (start: number, end: number, t: number) =>\n start + (end - start) * t;\n const newTension = lerp(\n state.tension,\n adjustedTarget,\n this.config.activationSpeed * delta,\n );\n\n // Update shaking state for exhaustion\n const isShaking =\n isExhausted && state.tension > this.config.shakingTensionThreshold;\n\n // Update state directly for performance\n state.tension = newTension;\n state.targetTension = adjustedTarget;\n state.isShaking = isShaking;\n });\n }\n\n /**\n * Gradually relax all muscles to idle state\n *\n * Used after technique completion with configurable delay.\n *\n * @param delta - Time since last frame in seconds\n *\n * @korean 근육이완\n */\n relaxAllMuscles(delta: number): void {\n this.activations.forEach((state) => {\n // Use configured relaxation speed (slower than activation for realism)\n const lerp = (start: number, end: number, t: number) =>\n start + (end - start) * t;\n const newTension = lerp(\n state.tension,\n 0,\n this.config.relaxationSpeed * delta,\n );\n\n state.tension = newTension;\n state.targetTension = 0;\n state.isShaking = false;\n });\n }\n\n /**\n * Get current tension for a specific muscle group\n *\n * @param muscleGroup - Muscle group name\n * @returns Current tension (0-1) or 0 if not found\n *\n * @korean 긴장도가져오기\n */\n getTension(muscleGroup: MuscleGroupName): number {\n return this.activations.get(muscleGroup)?.tension ?? 0;\n }\n\n /**\n * Get shaking state for a specific muscle group\n *\n * @param muscleGroup - Muscle group name\n * @returns Whether muscle is shaking\n *\n * @korean 흔들림상태가져오기\n */\n isShaking(muscleGroup: MuscleGroupName): boolean {\n return this.activations.get(muscleGroup)?.isShaking ?? false;\n }\n\n /**\n * Get all current muscle activations\n *\n * @returns Map of muscle groups to current states\n *\n * @korean 모든활성화가져오기\n */\n getAllActivations(): ReadonlyMap<MuscleGroupName, MuscleActivationState> {\n return this.activations;\n }\n\n /**\n * Get reusable scratch map with current tension values for state sync\n *\n * Populates and returns a reusable Map to avoid allocations during state sync.\n * This map is cleared and repopulated on each call.\n *\n * @returns Reusable Map with current tension values\n *\n * @korean 상태동기화맵가져오기\n */\n getScratchMapForSync(): Map<string, number> {\n this.scratchMap.clear();\n this.activations.forEach((state, name) => {\n this.scratchMap.set(name, state.tension);\n });\n return this.scratchMap;\n }\n\n /**\n * Reset all muscles to relaxed state immediately\n *\n * @korean 즉시이완\n */\n reset(): void {\n this.activations.forEach((state) => {\n state.tension = 0;\n state.targetTension = 0;\n state.isShaking = false;\n });\n this.scratchMap.clear();\n }\n\n /**\n * Dispose of the muscle activation system\n *\n * Clears all internal state and references to prevent memory leaks.\n * Should be called when the system is no longer needed (e.g., component unmount).\n *\n * @korean 근육시스템해제\n */\n dispose(): void {\n this.activations.clear();\n this.scratchMap.clear();\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BodyPartDamageIntegration.js","names":[],"sources":["../../../src/systems/bodypart/BodyPartDamageIntegration.ts"],"sourcesContent":["/**\n * Body Part Damage Integration for Combat System\n *\n * **Korean**: 신체부위 피해 통합\n *\n * Extends the damage calculation system to apply damage to specific body parts\n * based on vital point hits and attack locations. Integrates with the existing\n * VitalPointSystem and DamageCalculator.\n *\n * @module systems/bodypart/BodyPartDamageIntegration\n * @category Body Part System\n * @korean 신체부위피해통합\n */\n\nimport { BodyRegion } from \"@/types\";\nimport type { VitalPoint } from \"../vitalpoint/types\";\nimport { bodyPartHealthSystem } from \"./BodyPartHealthSystem\";\nimport { BodyPart, BodyPartHealth, BodyPartMaxHealth } from \"./types\";\n\n/**\n * Minimal player view needed for body part damage operations.\n */\nexport interface BodyPartDamageTarget {\n readonly health: number;\n readonly bodyPartHealth?: BodyPartHealth;\n readonly bodyPartMaxHealth?: BodyPartMaxHealth;\n}\n\n/**\n * Map vital point to its corresponding body region.\n *\n * **Korean**: 급소에서 신체 영역 매핑\n *\n * Analyzes a vital point's location and category to determine which\n * BodyRegion it belongs to, enabling proper damage distribution.\n *\n * @param vitalPoint - Vital point that was struck\n * @returns Corresponding body region\n *\n */\nexport function getBodyRegionFromVitalPoint(\n vitalPoint: VitalPoint\n): BodyRegion {\n const pointId = vitalPoint.id.toLowerCase();\n\n // Head region vital points\n if (\n pointId.includes(\"head_\") ||\n pointId.includes(\"temple\") ||\n pointId.includes(\"jaw\") ||\n pointId.includes(\"crown\") ||\n pointId.includes(\"forehead\") ||\n pointId.includes(\"eye\") ||\n pointId.includes(\"nose\") ||\n pointId.includes(\"ear\") ||\n pointId.includes(\"skull\")\n ) {\n return BodyRegion.HEAD;\n }\n\n // Neck region vital points\n if (\n pointId.includes(\"neck\") ||\n pointId.includes(\"throat\") ||\n pointId.includes(\"carotid\") ||\n pointId.includes(\"cervical\")\n ) {\n return BodyRegion.NECK;\n }\n\n // Torso region vital points\n if (\n pointId.includes(\"torso_\") ||\n pointId.includes(\"chest\") ||\n pointId.includes(\"solar_plexus\") ||\n pointId.includes(\"ribs\") ||\n pointId.includes(\"sternum\") ||\n pointId.includes(\"heart\") ||\n pointId.includes(\"lung\") ||\n pointId.includes(\"abdomen\")\n ) {\n return BodyRegion.TORSO;\n }\n\n // Core region vital points\n if (\n pointId.includes(\"core\") ||\n pointId.includes(\"dantian\") ||\n pointId.includes(\"kidney\") ||\n pointId.includes(\"liver\") ||\n pointId.includes(\"spleen\") ||\n pointId.includes(\"bladder\")\n ) {\n return BodyRegion.CORE;\n }\n\n // Left arm vital points\n if (\n pointId.includes(\"arm_left\") ||\n pointId.includes(\"left_shoulder\") ||\n pointId.includes(\"left_elbow\") ||\n pointId.includes(\"left_wrist\") ||\n pointId.includes(\"left_hand\")\n ) {\n return BodyRegion.LEFT_ARM;\n }\n\n // Right arm vital points\n if (\n pointId.includes(\"arm_right\") ||\n pointId.includes(\"right_shoulder\") ||\n pointId.includes(\"right_elbow\") ||\n pointId.includes(\"right_wrist\") ||\n pointId.includes(\"right_hand\")\n ) {\n return BodyRegion.RIGHT_ARM;\n }\n\n // Left leg vital points\n if (\n pointId.includes(\"leg_left\") ||\n pointId.includes(\"left_knee\") ||\n pointId.includes(\"left_ankle\") ||\n pointId.includes(\"left_foot\") ||\n pointId.includes(\"left_thigh\")\n ) {\n return BodyRegion.LEFT_LEG;\n }\n\n // Right leg vital points\n if (\n pointId.includes(\"leg_right\") ||\n pointId.includes(\"right_knee\") ||\n pointId.includes(\"right_ankle\") ||\n pointId.includes(\"right_foot\") ||\n pointId.includes(\"right_thigh\")\n ) {\n return BodyRegion.RIGHT_LEG;\n }\n\n // Default to torso for unmatched points\n return BodyRegion.TORSO;\n}\n\n/**\n * Apply damage to player's body parts based on hit location.\n *\n * **Korean**: 타격 위치 기반 신체부위 피해 적용\n *\n * Takes total damage and distributes it across body parts according to\n * the hit location. Updates both aggregate health and body part health.\n *\n * For combat compatibility, the aggregate health is directly reduced by\n * the damage amount (traditional behavior), while body part health is\n * updated proportionally for visualization purposes.\n *\n * @param player - Player receiving damage\n * @param totalDamage - Total damage amount\n * @param bodyRegion - Body region that was hit\n * @returns Updated player state with body part damage applied\n *\n */\nexport function applyDamageToBodyParts<T extends BodyPartDamageTarget>(\n player: T,\n totalDamage: number,\n bodyRegion: BodyRegion\n): T {\n // If body part health not initialized, initialize it\n const bodyPartHealth =\n player.bodyPartHealth ?? bodyPartHealthSystem.createDefaultBodyPartHealth();\n const bodyPartMaxHealth =\n player.bodyPartMaxHealth ?? bodyPartHealthSystem.createDefaultMaxHealth();\n\n // Apply distributed damage to body parts for visualization\n const updatedBodyPartHealth = bodyPartHealthSystem.applyDistributedDamage(\n bodyPartHealth,\n bodyRegion,\n totalDamage,\n bodyPartMaxHealth\n );\n\n // Calculate new aggregate health directly: traditional damage reduction\n // This ensures combat damage calculations remain consistent\n const newAggregateHealth = Math.max(0, player.health - totalDamage);\n\n // Update player state with new body part health and aggregate health\n return {\n ...player,\n bodyPartHealth: updatedBodyPartHealth,\n bodyPartMaxHealth,\n health: newAggregateHealth,\n };\n}\n\n/**\n * Apply damage from a vital point hit to appropriate body parts.\n *\n * **Korean**: 급소 타격 신체부위 피해 적용\n *\n * Specialized damage application for vital point strikes. Maps the vital\n * point to its body region and applies damage with appropriate distribution.\n *\n * @param player - Player receiving damage\n * @param totalDamage - Total damage amount\n * @param vitalPoint - Vital point that was struck\n * @returns Updated player state with vital point damage applied\n *\n */\nexport function applyVitalPointDamageToBodyParts<\n T extends BodyPartDamageTarget\n>(player: T, totalDamage: number, vitalPoint: VitalPoint): T {\n const bodyRegion = getBodyRegionFromVitalPoint(vitalPoint);\n return applyDamageToBodyParts(player, totalDamage, bodyRegion);\n}\n\n/**\n * Get combat capability modifiers from body part health.\n *\n * **Korean**: 신체부위 전투 능력 수정치 조회\n *\n * Calculates how body part damage affects combat capabilities.\n * Returns modifiers that should be applied to:\n * - Consciousness (awareness, reaction time)\n * - Stamina regeneration\n * - Attack damage output\n * - Movement speed\n * - Balance and stability\n * - Technique accuracy\n *\n * @param player - Player state to analyze\n * @returns Combat capability effect multipliers (0.0-1.0)\n *\n * @example\n * ```typescript\n * const effects = getBodyPartCombatEffects(player);\n * const actualDamage = baseDamage * effects.attackDamageModifier;\n * const actualSpeed = baseSpeed * effects.movementSpeedModifier;\n * ```\n *\n */\nexport function getBodyPartCombatEffects(player: BodyPartDamageTarget) {\n // If no body part health, return no effects\n if (!player.bodyPartHealth) {\n return {\n consciousnessModifier: 1.0,\n staminaRegenModifier: 1.0,\n attackDamageModifier: 1.0,\n movementSpeedModifier: 1.0,\n balanceModifier: 1.0,\n techniqueAccuracyModifier: 1.0,\n };\n }\n\n return bodyPartHealthSystem.calculateBodyPartEffects(\n player.bodyPartHealth,\n player.bodyPartMaxHealth\n );\n}\n\n/**\n * Check if player is incapacitated by body part damage.\n *\n * **Korean**: 신체부위 무력화 확인\n *\n * Determines if the player can continue fighting based on body part health.\n * Player is incapacitated if:\n * - Head is at 0 HP (unconscious)\n * - Both legs are at 0 HP (cannot stand)\n * - Aggregate health is below 10%\n *\n * @param player - Player state to check\n * @returns Whether player is incapacitated\n *\n */\nexport function isPlayerIncapacitatedByBodyDamage(\n player: BodyPartDamageTarget\n): boolean {\n if (!player.bodyPartHealth) {\n return false; // No body part system = use aggregate health only\n }\n\n return bodyPartHealthSystem.isIncapacitated(player.bodyPartHealth);\n}\n\n/**\n * Initialize body part health for a player.\n *\n * **Korean**: 플레이어 신체부위 체력 초기화\n *\n * Sets up body part health and max health for a player if not already present.\n * Uses the provided max health or defaults to 100 per part.\n *\n * @param player - Player state to initialize\n * @param maxHealthPerPart - Optional custom max health per part\n * @returns Player state with body part health initialized\n *\n */\nexport function initializeBodyPartHealthForPlayer<\n T extends BodyPartDamageTarget\n>(player: T, maxHealthPerPart: number = 100): T {\n // Skip if already initialized\n if (player.bodyPartHealth && player.bodyPartMaxHealth) {\n return player;\n }\n\n const bodyPartHealth =\n bodyPartHealthSystem.createDefaultBodyPartHealth(maxHealthPerPart);\n const bodyPartMaxHealth =\n bodyPartHealthSystem.createDefaultMaxHealth(maxHealthPerPart);\n\n return {\n ...player,\n bodyPartHealth,\n bodyPartMaxHealth,\n health: bodyPartHealthSystem.calculateAggregateHealth(bodyPartHealth),\n };\n}\n\n/**\n * Heal body parts proportionally based on total healing amount.\n *\n * **Korean**: 신체부위 비례 치유\n *\n * Distributes healing across all damaged body parts proportionally to\n * their damage level. Most damaged parts receive more healing.\n *\n * @param player - Player state to heal\n * @param totalHealAmount - Total healing to distribute\n * @returns Updated player state with healing applied\n *\n */\nexport function healBodyPartsProportionally<T extends BodyPartDamageTarget>(\n player: T,\n totalHealAmount: number\n): T {\n if (!player.bodyPartHealth || !player.bodyPartMaxHealth) {\n return player; // No body part system active\n }\n\n const bodyPartHealth = player.bodyPartHealth;\n const bodyPartMaxHealth = player.bodyPartMaxHealth;\n\n // Calculate total missing health across all parts\n const missingHealth = (Object.keys(bodyPartHealth) as BodyPart[]).reduce(\n (sum, part) => {\n return sum + (bodyPartMaxHealth[part] - bodyPartHealth[part]);\n },\n 0\n );\n\n // If no damage, return unchanged\n if (missingHealth <= 0) {\n return player;\n }\n\n // Heal each part proportionally to its damage\n let updatedHealth = { ...bodyPartHealth };\n\n (Object.keys(bodyPartHealth) as BodyPart[]).forEach((part) => {\n const partMissingHealth = bodyPartMaxHealth[part] - bodyPartHealth[part];\n if (partMissingHealth > 0) {\n const proportion = partMissingHealth / missingHealth;\n const healForThisPart = totalHealAmount * proportion;\n updatedHealth = bodyPartHealthSystem.healBodyPart(\n updatedHealth,\n part,\n healForThisPart,\n bodyPartMaxHealth\n );\n }\n });\n\n // Calculate new aggregate health\n const newAggregateHealth =\n bodyPartHealthSystem.calculateAggregateHealth(updatedHealth);\n\n return {\n ...player,\n bodyPartHealth: updatedHealth,\n health: newAggregateHealth,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"BodyPartDamageIntegration.js","names":[],"sources":["../../../src/systems/bodypart/BodyPartDamageIntegration.ts"],"sourcesContent":["/**\n * Body Part Damage Integration for Combat System\n *\n * **Korean**: 신체부위 피해 통합\n *\n * Extends the damage calculation system to apply damage to specific body parts\n * based on vital point hits and attack locations. Integrates with the existing\n * VitalPointSystem and DamageCalculator.\n *\n * @module systems/bodypart/BodyPartDamageIntegration\n * @category Body Part System\n * @korean 신체부위피해통합\n */\n\nimport { BodyRegion } from \"@/types\";\nimport type { VitalPoint } from \"../vitalpoint/types\";\nimport { bodyPartHealthSystem } from \"./BodyPartHealthSystem\";\nimport { BodyPart, BodyPartHealth, BodyPartMaxHealth } from \"./types\";\n\n/**\n * Minimal player view needed for body part damage operations.\n */\nexport interface BodyPartDamageTarget {\n readonly health: number;\n readonly bodyPartHealth?: BodyPartHealth;\n readonly bodyPartMaxHealth?: BodyPartMaxHealth;\n}\n\n/**\n * Map vital point to its corresponding body region.\n *\n * **Korean**: 급소에서 신체 영역 매핑\n *\n * Analyzes a vital point's location and category to determine which\n * BodyRegion it belongs to, enabling proper damage distribution.\n *\n * @param vitalPoint - Vital point that was struck\n * @returns Corresponding body region\n *\n */\nexport function getBodyRegionFromVitalPoint(\n vitalPoint: VitalPoint\n): BodyRegion {\n const pointId = vitalPoint.id.toLowerCase();\n\n // Head region vital points\n if (\n pointId.includes(\"head_\") ||\n pointId.includes(\"temple\") ||\n pointId.includes(\"jaw\") ||\n pointId.includes(\"crown\") ||\n pointId.includes(\"forehead\") ||\n pointId.includes(\"eye\") ||\n pointId.includes(\"nose\") ||\n pointId.includes(\"ear\") ||\n pointId.includes(\"skull\")\n ) {\n return BodyRegion.HEAD;\n }\n\n // Neck region vital points\n if (\n pointId.includes(\"neck\") ||\n pointId.includes(\"throat\") ||\n pointId.includes(\"carotid\") ||\n pointId.includes(\"cervical\")\n ) {\n return BodyRegion.NECK;\n }\n\n // Torso region vital points\n if (\n pointId.includes(\"torso_\") ||\n pointId.includes(\"chest\") ||\n pointId.includes(\"solar_plexus\") ||\n pointId.includes(\"ribs\") ||\n pointId.includes(\"sternum\") ||\n pointId.includes(\"heart\") ||\n pointId.includes(\"lung\") ||\n pointId.includes(\"abdomen\")\n ) {\n return BodyRegion.TORSO;\n }\n\n // Core region vital points\n if (\n pointId.includes(\"core\") ||\n pointId.includes(\"dantian\") ||\n pointId.includes(\"kidney\") ||\n pointId.includes(\"liver\") ||\n pointId.includes(\"spleen\") ||\n pointId.includes(\"bladder\")\n ) {\n return BodyRegion.CORE;\n }\n\n // Left arm vital points\n if (\n pointId.includes(\"arm_left\") ||\n pointId.includes(\"left_shoulder\") ||\n pointId.includes(\"left_elbow\") ||\n pointId.includes(\"left_wrist\") ||\n pointId.includes(\"left_hand\")\n ) {\n return BodyRegion.LEFT_ARM;\n }\n\n // Right arm vital points\n if (\n pointId.includes(\"arm_right\") ||\n pointId.includes(\"right_shoulder\") ||\n pointId.includes(\"right_elbow\") ||\n pointId.includes(\"right_wrist\") ||\n pointId.includes(\"right_hand\")\n ) {\n return BodyRegion.RIGHT_ARM;\n }\n\n // Left leg vital points\n if (\n pointId.includes(\"leg_left\") ||\n pointId.includes(\"left_knee\") ||\n pointId.includes(\"left_ankle\") ||\n pointId.includes(\"left_foot\") ||\n pointId.includes(\"left_thigh\")\n ) {\n return BodyRegion.LEFT_LEG;\n }\n\n // Right leg vital points\n if (\n pointId.includes(\"leg_right\") ||\n pointId.includes(\"right_knee\") ||\n pointId.includes(\"right_ankle\") ||\n pointId.includes(\"right_foot\") ||\n pointId.includes(\"right_thigh\")\n ) {\n return BodyRegion.RIGHT_LEG;\n }\n\n // Default to torso for unmatched points\n return BodyRegion.TORSO;\n}\n\n/**\n * Apply damage to player's body parts based on hit location.\n *\n * **Korean**: 타격 위치 기반 신체부위 피해 적용\n *\n * Takes total damage and distributes it across body parts according to\n * the hit location. Updates both aggregate health and body part health.\n *\n * For combat compatibility, the aggregate health is directly reduced by\n * the damage amount (traditional behavior), while body part health is\n * updated proportionally for visualization purposes.\n *\n * @param player - Player receiving damage\n * @param totalDamage - Total damage amount\n * @param bodyRegion - Body region that was hit\n * @returns Updated player state with body part damage applied\n *\n */\nexport function applyDamageToBodyParts<T extends BodyPartDamageTarget>(\n player: T,\n totalDamage: number,\n bodyRegion: BodyRegion\n): T {\n // If body part health not initialized, initialize it\n const bodyPartHealth =\n player.bodyPartHealth ?? bodyPartHealthSystem.createDefaultBodyPartHealth();\n const bodyPartMaxHealth =\n player.bodyPartMaxHealth ?? bodyPartHealthSystem.createDefaultMaxHealth();\n\n // Apply distributed damage to body parts for visualization\n const updatedBodyPartHealth = bodyPartHealthSystem.applyDistributedDamage(\n bodyPartHealth,\n bodyRegion,\n totalDamage,\n bodyPartMaxHealth\n );\n\n // Calculate new aggregate health directly: traditional damage reduction\n // This ensures combat damage calculations remain consistent\n const newAggregateHealth = Math.max(0, player.health - totalDamage);\n\n // Update player state with new body part health and aggregate health\n return {\n ...player,\n bodyPartHealth: updatedBodyPartHealth,\n bodyPartMaxHealth,\n health: newAggregateHealth,\n };\n}\n\n/**\n * Apply damage from a vital point hit to appropriate body parts.\n *\n * **Korean**: 급소 타격 신체부위 피해 적용\n *\n * Specialized damage application for vital point strikes. Maps the vital\n * point to its body region and applies damage with appropriate distribution.\n *\n * @param player - Player receiving damage\n * @param totalDamage - Total damage amount\n * @param vitalPoint - Vital point that was struck\n * @returns Updated player state with vital point damage applied\n *\n */\nexport function applyVitalPointDamageToBodyParts<\n T extends BodyPartDamageTarget\n>(player: T, totalDamage: number, vitalPoint: VitalPoint): T {\n const bodyRegion = getBodyRegionFromVitalPoint(vitalPoint);\n return applyDamageToBodyParts(player, totalDamage, bodyRegion);\n}\n\n/**\n * Get combat capability modifiers from body part health.\n *\n * **Korean**: 신체부위 전투 능력 수정치 조회\n *\n * Calculates how body part damage affects combat capabilities.\n * Returns modifiers that should be applied to:\n * - Consciousness (awareness, reaction time)\n * - Stamina regeneration\n * - Attack damage output\n * - Movement speed\n * - Balance and stability\n * - Technique accuracy\n *\n * @param player - Player state to analyze\n * @returns Combat capability effect multipliers (0.0-1.0)\n *\n * @example\n * ```typescript\n * const effects = getBodyPartCombatEffects(player);\n * const actualDamage = baseDamage * effects.attackDamageModifier;\n * const actualSpeed = baseSpeed * effects.movementSpeedModifier;\n * ```\n *\n */\nexport function getBodyPartCombatEffects(player: BodyPartDamageTarget) {\n // If no body part health, return no effects\n if (!player.bodyPartHealth) {\n return {\n consciousnessModifier: 1.0,\n staminaRegenModifier: 1.0,\n attackDamageModifier: 1.0,\n movementSpeedModifier: 1.0,\n balanceModifier: 1.0,\n techniqueAccuracyModifier: 1.0,\n };\n }\n\n return bodyPartHealthSystem.calculateBodyPartEffects(\n player.bodyPartHealth,\n player.bodyPartMaxHealth\n );\n}\n\n/**\n * Check if player is incapacitated by body part damage.\n *\n * **Korean**: 신체부위 무력화 확인\n *\n * Determines if the player can continue fighting based on body part health.\n * Player is incapacitated if:\n * - Head is at 0 HP (unconscious)\n * - Both legs are at 0 HP (cannot stand)\n * - Aggregate health is below 10%\n *\n * @param player - Player state to check\n * @returns Whether player is incapacitated\n *\n */\nexport function isPlayerIncapacitatedByBodyDamage(\n player: BodyPartDamageTarget\n): boolean {\n if (!player.bodyPartHealth) {\n return false; // No body part system = use aggregate health only\n }\n\n return bodyPartHealthSystem.isIncapacitated(player.bodyPartHealth);\n}\n\n/**\n * Initialize body part health for a player.\n *\n * **Korean**: 플레이어 신체부위 체력 초기화\n *\n * Sets up body part health and max health for a player if not already present.\n * Uses the provided max health or defaults to 100 per part.\n *\n * @param player - Player state to initialize\n * @param maxHealthPerPart - Optional custom max health per part\n * @returns Player state with body part health initialized\n *\n */\nexport function initializeBodyPartHealthForPlayer<\n T extends BodyPartDamageTarget\n>(player: T, maxHealthPerPart: number = 100): T {\n // Skip if already initialized\n if (player.bodyPartHealth && player.bodyPartMaxHealth) {\n return player;\n }\n\n const bodyPartHealth =\n bodyPartHealthSystem.createDefaultBodyPartHealth(maxHealthPerPart);\n const bodyPartMaxHealth =\n bodyPartHealthSystem.createDefaultMaxHealth(maxHealthPerPart);\n\n return {\n ...player,\n bodyPartHealth,\n bodyPartMaxHealth,\n health: bodyPartHealthSystem.calculateAggregateHealth(bodyPartHealth),\n };\n}\n\n/**\n * Heal body parts proportionally based on total healing amount.\n *\n * **Korean**: 신체부위 비례 치유\n *\n * Distributes healing across all damaged body parts proportionally to\n * their damage level. Most damaged parts receive more healing.\n *\n * @param player - Player state to heal\n * @param totalHealAmount - Total healing to distribute\n * @returns Updated player state with healing applied\n *\n */\nexport function healBodyPartsProportionally<T extends BodyPartDamageTarget>(\n player: T,\n totalHealAmount: number\n): T {\n if (!player.bodyPartHealth || !player.bodyPartMaxHealth) {\n return player; // No body part system active\n }\n\n const bodyPartHealth = player.bodyPartHealth;\n const bodyPartMaxHealth = player.bodyPartMaxHealth;\n\n // Calculate total missing health across all parts\n const missingHealth = (Object.keys(bodyPartHealth) as BodyPart[]).reduce(\n (sum, part) => {\n return sum + (bodyPartMaxHealth[part] - bodyPartHealth[part]);\n },\n 0\n );\n\n // If no damage, return unchanged\n if (missingHealth <= 0) {\n return player;\n }\n\n // Heal each part proportionally to its damage\n let updatedHealth = { ...bodyPartHealth };\n\n (Object.keys(bodyPartHealth) as BodyPart[]).forEach((part) => {\n const partMissingHealth = bodyPartMaxHealth[part] - bodyPartHealth[part];\n if (partMissingHealth > 0) {\n const proportion = partMissingHealth / missingHealth;\n const healForThisPart = totalHealAmount * proportion;\n updatedHealth = bodyPartHealthSystem.healBodyPart(\n updatedHealth,\n part,\n healForThisPart,\n bodyPartMaxHealth\n );\n }\n });\n\n // Calculate new aggregate health\n const newAggregateHealth =\n bodyPartHealthSystem.calculateAggregateHealth(updatedHealth);\n\n return {\n ...player,\n bodyPartHealth: updatedHealth,\n health: newAggregateHealth,\n };\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BodyPartHealthSystem.js","names":[],"sources":["../../../src/systems/bodypart/BodyPartHealthSystem.ts"],"sourcesContent":["/**\n * Body Part Health System\n * \n * **Korean**: 신체부위 체력 시스템\n * \n * Manages body part-specific health tracking, damage distribution, and combat\n * capability effects. Implements realistic localized damage mechanics based on\n * Korean martial arts vital point targeting principles.\n * \n * ## System Features\n * \n * - Independent health tracking for 8 body parts\n * - Automatic combat capability penalties based on damage\n * - Damage distribution from hit locations to body parts\n * - UI-friendly status information generation\n * - Performance-optimized calculations\n * \n * @module systems/bodypart/BodyPartHealthSystem\n * @category Body Part System\n * @korean 신체부위체력시스템\n */\n\nimport { BodyRegion, KOREAN_COLORS, KoreanText } from \"@/types\";\nimport {\n BodyPart,\n BodyPartDamageDistribution,\n BodyPartEffects,\n BodyPartHealth,\n BodyPartHealthConfig,\n BodyPartMaxHealth,\n BodyPartStatus,\n BODY_PART_EFFECT_CONSTANTS,\n DEFAULT_BODY_PART_CONFIG,\n} from \"./types\";\n\n/**\n * Body Part Health System class.\n * \n * **Korean**: 신체부위 체력 시스템 클래스\n * \n * Provides methods for managing body part health, calculating effects,\n * and distributing damage based on hit locations.\n * \n * @example\n * ```typescript\n * const system = new BodyPartHealthSystem();\n * \n * // Create initial body part health\n * const health = system.createDefaultBodyPartHealth();\n * \n * // Apply damage to head\n * const damaged = system.applyDamageToBodyPart(\n * health,\n * BodyPart.HEAD,\n * 25\n * );\n * \n * // Calculate combat effects\n * const effects = system.calculateBodyPartEffects(damaged);\n * ```\n * \n * @category Body Part System\n */\nexport class BodyPartHealthSystem {\n private config: BodyPartHealthConfig;\n\n constructor(config: BodyPartHealthConfig = DEFAULT_BODY_PART_CONFIG) {\n this.config = config;\n }\n\n /**\n * Create default body part health with all parts at maximum.\n * \n * **Korean**: 기본 신체부위 체력 생성\n * \n * @param maxHealth - Optional custom max health per part (default: 100)\n * @returns Body part health structure with all parts at max HP\n * \n */\n createDefaultBodyPartHealth(maxHealth: number = 100): BodyPartHealth {\n return {\n head: maxHealth,\n neck: maxHealth,\n torsoUpper: maxHealth,\n torsoLower: maxHealth,\n armLeft: maxHealth,\n armRight: maxHealth,\n legLeft: maxHealth,\n legRight: maxHealth,\n };\n }\n\n /**\n * Create default maximum health values for body parts.\n * \n * **Korean**: 기본 최대 체력 생성\n * \n * @param baseMaxHealth - Base maximum health per part\n * @returns Maximum health structure\n * \n */\n createDefaultMaxHealth(baseMaxHealth: number = 100): BodyPartMaxHealth {\n return {\n head: baseMaxHealth,\n neck: baseMaxHealth,\n torsoUpper: baseMaxHealth,\n torsoLower: baseMaxHealth,\n armLeft: baseMaxHealth,\n armRight: baseMaxHealth,\n legLeft: baseMaxHealth,\n legRight: baseMaxHealth,\n };\n }\n\n /**\n * Apply damage to a specific body part.\n * \n * **Korean**: 신체부위 피해 적용\n * \n * Reduces health of the specified body part by the damage amount.\n * Health is clamped to 0-maxHealth range.\n * \n * @param current - Current body part health\n * @param bodyPart - Body part to damage\n * @param damage - Damage amount to apply\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n applyDamageToBodyPart(\n current: BodyPartHealth,\n bodyPart: BodyPart,\n damage: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const newHealth = Math.max(0, current[bodyPart] - damage);\n const clampedHealth = maxHealth\n ? Math.min(newHealth, maxHealth[bodyPart])\n : newHealth;\n\n return {\n ...current,\n [bodyPart]: clampedHealth,\n };\n }\n\n /**\n * Distribute damage across body parts based on hit location.\n * \n * **Korean**: 피해 분배\n * \n * Maps a BodyRegion hit location to primary and secondary body parts,\n * distributing damage according to impact mechanics.\n * \n * @param bodyRegion - Hit location\n * @returns Damage distribution configuration\n * \n */\n getDamageDistribution(bodyRegion: BodyRegion): BodyPartDamageDistribution {\n switch (bodyRegion) {\n case BodyRegion.HEAD:\n return {\n primary: { part: BodyPart.HEAD, percentage: 0.9 },\n secondary: [{ part: BodyPart.NECK, percentage: 0.1 }],\n };\n\n case BodyRegion.NECK:\n return {\n primary: { part: BodyPart.NECK, percentage: 0.8 },\n secondary: [\n { part: BodyPart.HEAD, percentage: 0.1 },\n { part: BodyPart.TORSO_UPPER, percentage: 0.1 },\n ],\n };\n\n case BodyRegion.TORSO:\n return {\n primary: { part: BodyPart.TORSO_UPPER, percentage: 0.6 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.4 }],\n };\n\n case BodyRegion.CORE:\n return {\n primary: { part: BodyPart.TORSO_LOWER, percentage: 0.7 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.3 }],\n };\n\n case BodyRegion.LEFT_ARM:\n return {\n primary: { part: BodyPart.ARM_LEFT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.1 }],\n };\n\n case BodyRegion.RIGHT_ARM:\n return {\n primary: { part: BodyPart.ARM_RIGHT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.1 }],\n };\n\n case BodyRegion.LEFT_LEG:\n return {\n primary: { part: BodyPart.LEG_LEFT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.1 }],\n };\n\n case BodyRegion.RIGHT_LEG:\n return {\n primary: { part: BodyPart.LEG_RIGHT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.1 }],\n };\n\n default:\n // Default to torso upper for unknown regions\n return {\n primary: { part: BodyPart.TORSO_UPPER, percentage: 1.0 },\n secondary: [],\n };\n }\n }\n\n /**\n * Apply distributed damage to body parts from a hit.\n * \n * **Korean**: 분산 피해 적용\n * \n * Takes total damage and distributes it across primary and secondary\n * body parts based on the hit location.\n * \n * @param current - Current body part health\n * @param bodyRegion - Hit location\n * @param totalDamage - Total damage to distribute\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n applyDistributedDamage(\n current: BodyPartHealth,\n bodyRegion: BodyRegion,\n totalDamage: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const distribution = this.getDamageDistribution(bodyRegion);\n let updated = { ...current };\n\n // Apply primary damage\n updated = this.applyDamageToBodyPart(\n updated,\n distribution.primary.part,\n totalDamage * distribution.primary.percentage,\n maxHealth\n );\n\n // Apply secondary damage\n for (const secondary of distribution.secondary) {\n updated = this.applyDamageToBodyPart(\n updated,\n secondary.part,\n totalDamage * secondary.percentage,\n maxHealth\n );\n }\n\n return updated;\n }\n\n /**\n * Calculate combat capability effects from body part damage.\n * \n * **Korean**: 전투 능력 효과 계산\n * \n * Analyzes body part health and returns multipliers for various combat\n * capabilities. Implements acceptance criteria:\n * - Head <50%: Consciousness penalties\n * - Torso <50%: Stamina regen -50%\n * - Arms <50%: Attack damage -30%\n * - Legs <50%: Movement speed -40%\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @returns Combat capability effect multipliers\n * \n */\n calculateBodyPartEffects(\n health: BodyPartHealth,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartEffects {\n const max = maxHealth ?? this.createDefaultMaxHealth();\n\n // Calculate head/neck effects on consciousness\n const headPercentage = health.head / max.head;\n const neckPercentage = health.neck / max.neck;\n const minHeadNeck = Math.min(headPercentage, neckPercentage);\n \n let consciousnessModifier = 1.0;\n if (minHeadNeck < BODY_PART_EFFECT_CONSTANTS.HEAD.CRITICAL_THRESHOLD) {\n consciousnessModifier = BODY_PART_EFFECT_CONSTANTS.HEAD.CONSCIOUSNESS_PENALTY_AT_50;\n }\n\n // Calculate torso effects on stamina regeneration\n const torsoUpperPercentage = health.torsoUpper / max.torsoUpper;\n const torsoLowerPercentage = health.torsoLower / max.torsoLower;\n const avgTorso = (torsoUpperPercentage + torsoLowerPercentage) / 2;\n \n let staminaRegenModifier = 1.0;\n if (avgTorso < BODY_PART_EFFECT_CONSTANTS.TORSO.CRITICAL_THRESHOLD) {\n staminaRegenModifier = BODY_PART_EFFECT_CONSTANTS.TORSO.STAMINA_REGEN_PENALTY_AT_50;\n }\n\n // Calculate arm effects on attack damage\n const armLeftPercentage = health.armLeft / max.armLeft;\n const armRightPercentage = health.armRight / max.armRight;\n const avgArms = (armLeftPercentage + armRightPercentage) / 2;\n \n let attackDamageModifier = 1.0;\n if (avgArms < BODY_PART_EFFECT_CONSTANTS.ARMS.CRITICAL_THRESHOLD) {\n attackDamageModifier = BODY_PART_EFFECT_CONSTANTS.ARMS.ATTACK_DAMAGE_PENALTY_AT_50;\n }\n\n // Calculate leg effects on movement speed\n const legLeftPercentage = health.legLeft / max.legLeft;\n const legRightPercentage = health.legRight / max.legRight;\n const avgLegs = (legLeftPercentage + legRightPercentage) / 2;\n \n let movementSpeedModifier = 1.0;\n if (avgLegs < BODY_PART_EFFECT_CONSTANTS.LEGS.CRITICAL_THRESHOLD) {\n movementSpeedModifier = BODY_PART_EFFECT_CONSTANTS.LEGS.MOVEMENT_SPEED_PENALTY_AT_50;\n }\n\n // Balance affected by torso and legs\n const balanceModifier = Math.min(avgTorso, avgLegs);\n\n // Technique accuracy affected by head and arms\n const techniqueAccuracyModifier = Math.min(headPercentage, avgArms);\n\n return {\n consciousnessModifier,\n staminaRegenModifier,\n attackDamageModifier,\n movementSpeedModifier,\n balanceModifier,\n techniqueAccuracyModifier,\n };\n }\n\n /**\n * Calculate aggregate health from body parts.\n * \n * **Korean**: 종합 체력 계산\n * \n * Computes overall health as average of all body part health values.\n * This maintains backwards compatibility with single health bar systems.\n * \n * @param health - Body part health\n * @returns Aggregate health value (0-100)\n * \n */\n calculateAggregateHealth(health: BodyPartHealth): number {\n const sum =\n health.head +\n health.neck +\n health.torsoUpper +\n health.torsoLower +\n health.armLeft +\n health.armRight +\n health.legLeft +\n health.legRight;\n\n return sum / 8;\n }\n\n /**\n * Get body part status for UI display.\n * \n * **Korean**: 신체부위 상태 조회\n * \n * Provides UI-friendly status information including color coding,\n * status text, and critical/disabled flags.\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @param part - Body part to query\n * @returns Status information for display\n * \n */\n getBodyPartStatus(\n health: BodyPartHealth,\n maxHealth: BodyPartMaxHealth,\n part: BodyPart\n ): BodyPartStatus {\n const current = health[part];\n const max = maxHealth[part];\n const percentage = current / max;\n\n // Determine status and color\n let status: KoreanText;\n let color: number;\n let critical: boolean;\n let disabled: boolean;\n\n if (percentage === 0) {\n status = { korean: \"무력화\", english: \"Disabled\" };\n color = KOREAN_COLORS.NEGATIVE_RED;\n critical = true;\n disabled = true;\n } else if (percentage < this.config.criticalThreshold) {\n status = { korean: \"치명적\", english: \"Critical\" };\n color = KOREAN_COLORS.NEGATIVE_RED;\n critical = true;\n disabled = false;\n } else if (percentage < this.config.severePenaltyThreshold) {\n status = { korean: \"심각\", english: \"Severe\" };\n color = KOREAN_COLORS.WARNING_ORANGE;\n critical = false;\n disabled = false;\n } else if (percentage < this.config.majorPenaltyThreshold) {\n status = { korean: \"중상\", english: \"Major\" };\n color = KOREAN_COLORS.WARNING_YELLOW;\n critical = false;\n disabled = false;\n } else if (percentage < this.config.minorPenaltyThreshold) {\n status = { korean: \"경상\", english: \"Minor\" };\n color = KOREAN_COLORS.HEALTH_FULL;\n critical = false;\n disabled = false;\n } else {\n status = { korean: \"정상\", english: \"Normal\" };\n color = KOREAN_COLORS.HEALTH_FULL;\n critical = false;\n disabled = false;\n }\n\n return {\n part,\n health: current,\n maxHealth: max,\n percentage,\n status,\n color,\n critical,\n disabled,\n };\n }\n\n /**\n * Get all body part statuses for UI.\n * \n * **Korean**: 모든 신체부위 상태 조회\n * \n * Returns status information for all body parts in a single call.\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @returns Array of status information for all parts\n * \n */\n getAllBodyPartStatuses(\n health: BodyPartHealth,\n maxHealth: BodyPartMaxHealth\n ): BodyPartStatus[] {\n return Object.values(BodyPart).map((part) =>\n this.getBodyPartStatus(health, maxHealth, part)\n );\n }\n\n /**\n * Heal a specific body part.\n * \n * **Korean**: 신체부위 치유\n * \n * Increases health of the specified body part by the heal amount.\n * Health is clamped to 0-maxHealth range.\n * \n * @param current - Current body part health\n * @param bodyPart - Body part to heal\n * @param healAmount - Amount of health to restore\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n healBodyPart(\n current: BodyPartHealth,\n bodyPart: BodyPart,\n healAmount: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const max = maxHealth ?? this.createDefaultMaxHealth();\n const newHealth = Math.min(max[bodyPart], current[bodyPart] + healAmount);\n\n return {\n ...current,\n [bodyPart]: newHealth,\n };\n }\n\n /**\n * Check if player is incapacitated based on body part health.\n * \n * **Korean**: 무력화 상태 확인\n * \n * Player is incapacitated if:\n * - Head is at 0 HP (unconscious)\n * - Both legs are at 0 HP (cannot move)\n * - Aggregate health below 10%\n * \n * @param health - Current body part health\n * @returns Whether player is incapacitated\n * \n */\n isIncapacitated(health: BodyPartHealth): boolean {\n // Unconscious from head damage\n if (health.head <= 0) return true;\n\n // Cannot move from leg damage\n if (health.legLeft <= 0 && health.legRight <= 0) return true;\n\n // Aggregate health critical\n const aggregate = this.calculateAggregateHealth(health);\n if (aggregate < 10) return true;\n\n return false;\n }\n}\n\n/**\n * Singleton instance of Body Part Health System.\n * \n * **Korean**: 신체부위 체력 시스템 싱글톤\n * \n * Provides global access to the body part health system throughout the game.\n * \n */\nexport const bodyPartHealthSystem = new BodyPartHealthSystem();\n"],"mappings":"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"}
1
+ {"version":3,"file":"BodyPartHealthSystem.js","names":[],"sources":["../../../src/systems/bodypart/BodyPartHealthSystem.ts"],"sourcesContent":["/**\n * Body Part Health System\n * \n * **Korean**: 신체부위 체력 시스템\n * \n * Manages body part-specific health tracking, damage distribution, and combat\n * capability effects. Implements realistic localized damage mechanics based on\n * Korean martial arts vital point targeting principles.\n * \n * ## System Features\n * \n * - Independent health tracking for 8 body parts\n * - Automatic combat capability penalties based on damage\n * - Damage distribution from hit locations to body parts\n * - UI-friendly status information generation\n * - Performance-optimized calculations\n * \n * @module systems/bodypart/BodyPartHealthSystem\n * @category Body Part System\n * @korean 신체부위체력시스템\n */\n\nimport { BodyRegion, KOREAN_COLORS, KoreanText } from \"@/types\";\nimport {\n BodyPart,\n BodyPartDamageDistribution,\n BodyPartEffects,\n BodyPartHealth,\n BodyPartHealthConfig,\n BodyPartMaxHealth,\n BodyPartStatus,\n BODY_PART_EFFECT_CONSTANTS,\n DEFAULT_BODY_PART_CONFIG,\n} from \"./types\";\n\n/**\n * Body Part Health System class.\n * \n * **Korean**: 신체부위 체력 시스템 클래스\n * \n * Provides methods for managing body part health, calculating effects,\n * and distributing damage based on hit locations.\n * \n * @example\n * ```typescript\n * const system = new BodyPartHealthSystem();\n * \n * // Create initial body part health\n * const health = system.createDefaultBodyPartHealth();\n * \n * // Apply damage to head\n * const damaged = system.applyDamageToBodyPart(\n * health,\n * BodyPart.HEAD,\n * 25\n * );\n * \n * // Calculate combat effects\n * const effects = system.calculateBodyPartEffects(damaged);\n * ```\n * \n * @category Body Part System\n */\nexport class BodyPartHealthSystem {\n private config: BodyPartHealthConfig;\n\n constructor(config: BodyPartHealthConfig = DEFAULT_BODY_PART_CONFIG) {\n this.config = config;\n }\n\n /**\n * Create default body part health with all parts at maximum.\n * \n * **Korean**: 기본 신체부위 체력 생성\n * \n * @param maxHealth - Optional custom max health per part (default: 100)\n * @returns Body part health structure with all parts at max HP\n * \n */\n createDefaultBodyPartHealth(maxHealth: number = 100): BodyPartHealth {\n return {\n head: maxHealth,\n neck: maxHealth,\n torsoUpper: maxHealth,\n torsoLower: maxHealth,\n armLeft: maxHealth,\n armRight: maxHealth,\n legLeft: maxHealth,\n legRight: maxHealth,\n };\n }\n\n /**\n * Create default maximum health values for body parts.\n * \n * **Korean**: 기본 최대 체력 생성\n * \n * @param baseMaxHealth - Base maximum health per part\n * @returns Maximum health structure\n * \n */\n createDefaultMaxHealth(baseMaxHealth: number = 100): BodyPartMaxHealth {\n return {\n head: baseMaxHealth,\n neck: baseMaxHealth,\n torsoUpper: baseMaxHealth,\n torsoLower: baseMaxHealth,\n armLeft: baseMaxHealth,\n armRight: baseMaxHealth,\n legLeft: baseMaxHealth,\n legRight: baseMaxHealth,\n };\n }\n\n /**\n * Apply damage to a specific body part.\n * \n * **Korean**: 신체부위 피해 적용\n * \n * Reduces health of the specified body part by the damage amount.\n * Health is clamped to 0-maxHealth range.\n * \n * @param current - Current body part health\n * @param bodyPart - Body part to damage\n * @param damage - Damage amount to apply\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n applyDamageToBodyPart(\n current: BodyPartHealth,\n bodyPart: BodyPart,\n damage: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const newHealth = Math.max(0, current[bodyPart] - damage);\n const clampedHealth = maxHealth\n ? Math.min(newHealth, maxHealth[bodyPart])\n : newHealth;\n\n return {\n ...current,\n [bodyPart]: clampedHealth,\n };\n }\n\n /**\n * Distribute damage across body parts based on hit location.\n * \n * **Korean**: 피해 분배\n * \n * Maps a BodyRegion hit location to primary and secondary body parts,\n * distributing damage according to impact mechanics.\n * \n * @param bodyRegion - Hit location\n * @returns Damage distribution configuration\n * \n */\n getDamageDistribution(bodyRegion: BodyRegion): BodyPartDamageDistribution {\n switch (bodyRegion) {\n case BodyRegion.HEAD:\n return {\n primary: { part: BodyPart.HEAD, percentage: 0.9 },\n secondary: [{ part: BodyPart.NECK, percentage: 0.1 }],\n };\n\n case BodyRegion.NECK:\n return {\n primary: { part: BodyPart.NECK, percentage: 0.8 },\n secondary: [\n { part: BodyPart.HEAD, percentage: 0.1 },\n { part: BodyPart.TORSO_UPPER, percentage: 0.1 },\n ],\n };\n\n case BodyRegion.TORSO:\n return {\n primary: { part: BodyPart.TORSO_UPPER, percentage: 0.6 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.4 }],\n };\n\n case BodyRegion.CORE:\n return {\n primary: { part: BodyPart.TORSO_LOWER, percentage: 0.7 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.3 }],\n };\n\n case BodyRegion.LEFT_ARM:\n return {\n primary: { part: BodyPart.ARM_LEFT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.1 }],\n };\n\n case BodyRegion.RIGHT_ARM:\n return {\n primary: { part: BodyPart.ARM_RIGHT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_UPPER, percentage: 0.1 }],\n };\n\n case BodyRegion.LEFT_LEG:\n return {\n primary: { part: BodyPart.LEG_LEFT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.1 }],\n };\n\n case BodyRegion.RIGHT_LEG:\n return {\n primary: { part: BodyPart.LEG_RIGHT, percentage: 0.9 },\n secondary: [{ part: BodyPart.TORSO_LOWER, percentage: 0.1 }],\n };\n\n default:\n // Default to torso upper for unknown regions\n return {\n primary: { part: BodyPart.TORSO_UPPER, percentage: 1.0 },\n secondary: [],\n };\n }\n }\n\n /**\n * Apply distributed damage to body parts from a hit.\n * \n * **Korean**: 분산 피해 적용\n * \n * Takes total damage and distributes it across primary and secondary\n * body parts based on the hit location.\n * \n * @param current - Current body part health\n * @param bodyRegion - Hit location\n * @param totalDamage - Total damage to distribute\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n applyDistributedDamage(\n current: BodyPartHealth,\n bodyRegion: BodyRegion,\n totalDamage: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const distribution = this.getDamageDistribution(bodyRegion);\n let updated = { ...current };\n\n // Apply primary damage\n updated = this.applyDamageToBodyPart(\n updated,\n distribution.primary.part,\n totalDamage * distribution.primary.percentage,\n maxHealth\n );\n\n // Apply secondary damage\n for (const secondary of distribution.secondary) {\n updated = this.applyDamageToBodyPart(\n updated,\n secondary.part,\n totalDamage * secondary.percentage,\n maxHealth\n );\n }\n\n return updated;\n }\n\n /**\n * Calculate combat capability effects from body part damage.\n * \n * **Korean**: 전투 능력 효과 계산\n * \n * Analyzes body part health and returns multipliers for various combat\n * capabilities. Implements acceptance criteria:\n * - Head <50%: Consciousness penalties\n * - Torso <50%: Stamina regen -50%\n * - Arms <50%: Attack damage -30%\n * - Legs <50%: Movement speed -40%\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @returns Combat capability effect multipliers\n * \n */\n calculateBodyPartEffects(\n health: BodyPartHealth,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartEffects {\n const max = maxHealth ?? this.createDefaultMaxHealth();\n\n // Calculate head/neck effects on consciousness\n const headPercentage = health.head / max.head;\n const neckPercentage = health.neck / max.neck;\n const minHeadNeck = Math.min(headPercentage, neckPercentage);\n \n let consciousnessModifier = 1.0;\n if (minHeadNeck < BODY_PART_EFFECT_CONSTANTS.HEAD.CRITICAL_THRESHOLD) {\n consciousnessModifier = BODY_PART_EFFECT_CONSTANTS.HEAD.CONSCIOUSNESS_PENALTY_AT_50;\n }\n\n // Calculate torso effects on stamina regeneration\n const torsoUpperPercentage = health.torsoUpper / max.torsoUpper;\n const torsoLowerPercentage = health.torsoLower / max.torsoLower;\n const avgTorso = (torsoUpperPercentage + torsoLowerPercentage) / 2;\n \n let staminaRegenModifier = 1.0;\n if (avgTorso < BODY_PART_EFFECT_CONSTANTS.TORSO.CRITICAL_THRESHOLD) {\n staminaRegenModifier = BODY_PART_EFFECT_CONSTANTS.TORSO.STAMINA_REGEN_PENALTY_AT_50;\n }\n\n // Calculate arm effects on attack damage\n const armLeftPercentage = health.armLeft / max.armLeft;\n const armRightPercentage = health.armRight / max.armRight;\n const avgArms = (armLeftPercentage + armRightPercentage) / 2;\n \n let attackDamageModifier = 1.0;\n if (avgArms < BODY_PART_EFFECT_CONSTANTS.ARMS.CRITICAL_THRESHOLD) {\n attackDamageModifier = BODY_PART_EFFECT_CONSTANTS.ARMS.ATTACK_DAMAGE_PENALTY_AT_50;\n }\n\n // Calculate leg effects on movement speed\n const legLeftPercentage = health.legLeft / max.legLeft;\n const legRightPercentage = health.legRight / max.legRight;\n const avgLegs = (legLeftPercentage + legRightPercentage) / 2;\n \n let movementSpeedModifier = 1.0;\n if (avgLegs < BODY_PART_EFFECT_CONSTANTS.LEGS.CRITICAL_THRESHOLD) {\n movementSpeedModifier = BODY_PART_EFFECT_CONSTANTS.LEGS.MOVEMENT_SPEED_PENALTY_AT_50;\n }\n\n // Balance affected by torso and legs\n const balanceModifier = Math.min(avgTorso, avgLegs);\n\n // Technique accuracy affected by head and arms\n const techniqueAccuracyModifier = Math.min(headPercentage, avgArms);\n\n return {\n consciousnessModifier,\n staminaRegenModifier,\n attackDamageModifier,\n movementSpeedModifier,\n balanceModifier,\n techniqueAccuracyModifier,\n };\n }\n\n /**\n * Calculate aggregate health from body parts.\n * \n * **Korean**: 종합 체력 계산\n * \n * Computes overall health as average of all body part health values.\n * This maintains backwards compatibility with single health bar systems.\n * \n * @param health - Body part health\n * @returns Aggregate health value (0-100)\n * \n */\n calculateAggregateHealth(health: BodyPartHealth): number {\n const sum =\n health.head +\n health.neck +\n health.torsoUpper +\n health.torsoLower +\n health.armLeft +\n health.armRight +\n health.legLeft +\n health.legRight;\n\n return sum / 8;\n }\n\n /**\n * Get body part status for UI display.\n * \n * **Korean**: 신체부위 상태 조회\n * \n * Provides UI-friendly status information including color coding,\n * status text, and critical/disabled flags.\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @param part - Body part to query\n * @returns Status information for display\n * \n */\n getBodyPartStatus(\n health: BodyPartHealth,\n maxHealth: BodyPartMaxHealth,\n part: BodyPart\n ): BodyPartStatus {\n const current = health[part];\n const max = maxHealth[part];\n const percentage = current / max;\n\n // Determine status and color\n let status: KoreanText;\n let color: number;\n let critical: boolean;\n let disabled: boolean;\n\n if (percentage === 0) {\n status = { korean: \"무력화\", english: \"Disabled\" };\n color = KOREAN_COLORS.NEGATIVE_RED;\n critical = true;\n disabled = true;\n } else if (percentage < this.config.criticalThreshold) {\n status = { korean: \"치명적\", english: \"Critical\" };\n color = KOREAN_COLORS.NEGATIVE_RED;\n critical = true;\n disabled = false;\n } else if (percentage < this.config.severePenaltyThreshold) {\n status = { korean: \"심각\", english: \"Severe\" };\n color = KOREAN_COLORS.WARNING_ORANGE;\n critical = false;\n disabled = false;\n } else if (percentage < this.config.majorPenaltyThreshold) {\n status = { korean: \"중상\", english: \"Major\" };\n color = KOREAN_COLORS.WARNING_YELLOW;\n critical = false;\n disabled = false;\n } else if (percentage < this.config.minorPenaltyThreshold) {\n status = { korean: \"경상\", english: \"Minor\" };\n color = KOREAN_COLORS.HEALTH_FULL;\n critical = false;\n disabled = false;\n } else {\n status = { korean: \"정상\", english: \"Normal\" };\n color = KOREAN_COLORS.HEALTH_FULL;\n critical = false;\n disabled = false;\n }\n\n return {\n part,\n health: current,\n maxHealth: max,\n percentage,\n status,\n color,\n critical,\n disabled,\n };\n }\n\n /**\n * Get all body part statuses for UI.\n * \n * **Korean**: 모든 신체부위 상태 조회\n * \n * Returns status information for all body parts in a single call.\n * \n * @param health - Current body part health\n * @param maxHealth - Maximum health values\n * @returns Array of status information for all parts\n * \n */\n getAllBodyPartStatuses(\n health: BodyPartHealth,\n maxHealth: BodyPartMaxHealth\n ): BodyPartStatus[] {\n return Object.values(BodyPart).map((part) =>\n this.getBodyPartStatus(health, maxHealth, part)\n );\n }\n\n /**\n * Heal a specific body part.\n * \n * **Korean**: 신체부위 치유\n * \n * Increases health of the specified body part by the heal amount.\n * Health is clamped to 0-maxHealth range.\n * \n * @param current - Current body part health\n * @param bodyPart - Body part to heal\n * @param healAmount - Amount of health to restore\n * @param maxHealth - Optional maximum health limits\n * @returns Updated body part health\n * \n */\n healBodyPart(\n current: BodyPartHealth,\n bodyPart: BodyPart,\n healAmount: number,\n maxHealth?: BodyPartMaxHealth\n ): BodyPartHealth {\n const max = maxHealth ?? this.createDefaultMaxHealth();\n const newHealth = Math.min(max[bodyPart], current[bodyPart] + healAmount);\n\n return {\n ...current,\n [bodyPart]: newHealth,\n };\n }\n\n /**\n * Check if player is incapacitated based on body part health.\n * \n * **Korean**: 무력화 상태 확인\n * \n * Player is incapacitated if:\n * - Head is at 0 HP (unconscious)\n * - Both legs are at 0 HP (cannot move)\n * - Aggregate health below 10%\n * \n * @param health - Current body part health\n * @returns Whether player is incapacitated\n * \n */\n isIncapacitated(health: BodyPartHealth): boolean {\n // Unconscious from head damage\n if (health.head <= 0) return true;\n\n // Cannot move from leg damage\n if (health.legLeft <= 0 && health.legRight <= 0) return true;\n\n // Aggregate health critical\n const aggregate = this.calculateAggregateHealth(health);\n if (aggregate < 10) return true;\n\n return false;\n }\n}\n\n/**\n * Singleton instance of Body Part Health System.\n * \n * **Korean**: 신체부위 체력 시스템 싱글톤\n * \n * Provides global access to the body part health system throughout the game.\n * \n */\nexport const bodyPartHealthSystem = new BodyPartHealthSystem();\n"],"mappings":"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"}