blacktrigram 0.7.68 → 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 +5 -5
@@ -411,16 +411,7 @@ function createGonIdleAnimation() {
411
411
  * @korean 곤땅대기애니메이션
412
412
  */
413
413
  var GON_IDLE_ANIMATION = createGonIdleAnimation();
414
- new Map([
415
- [TrigramStance.GEON, GEON_IDLE_ANIMATION],
416
- [TrigramStance.TAE, TAE_IDLE_ANIMATION],
417
- [TrigramStance.LI, LI_IDLE_ANIMATION],
418
- [TrigramStance.JIN, JIN_IDLE_ANIMATION],
419
- [TrigramStance.SON, SON_IDLE_ANIMATION],
420
- [TrigramStance.GAM, GAM_IDLE_ANIMATION],
421
- [TrigramStance.GAN, GAN_IDLE_ANIMATION],
422
- [TrigramStance.GON, GON_IDLE_ANIMATION]
423
- ]);
414
+ TrigramStance.GEON, TrigramStance.TAE, TrigramStance.LI, TrigramStance.JIN, TrigramStance.SON, TrigramStance.GAM, TrigramStance.GAN, TrigramStance.GON;
424
415
  /**
425
416
  * Map of all 8 trigram stance idle animations by string name
426
417
  *
@@ -429,7 +420,7 @@ new Map([
429
420
  *
430
421
  * @korean 팔괘대기애니메이션문자열맵
431
422
  */
432
- var TRIGRAM_IDLE_ANIMATIONS_BY_NAME = new Map([
423
+ var TRIGRAM_IDLE_ANIMATIONS_BY_NAME = /* @__PURE__ */ new Map([
433
424
  ["stance_geon", GEON_IDLE_ANIMATION],
434
425
  ["stance_tae", TAE_IDLE_ANIMATION],
435
426
  ["stance_li", LI_IDLE_ANIMATION],
@@ -1 +1 @@
1
- {"version":3,"file":"StanceIdleAnimations.js","names":[],"sources":["../../../../src/systems/animation/catalogs/StanceIdleAnimations.ts"],"sourcesContent":["/**\n * Trigram Stance Idle Animations - Enhanced Breathing & Weight Shift System\n *\n * Defines complete idle animations for all 8 trigram stances (팔괘) with:\n * - Multi-keyframe breathing cycles (4-6 frames per stance)\n * - Subtle weight shifts for natural movement\n * - Stance-specific rhythms reflecting martial philosophy\n * - Proper guard positions from StanceGuardPoses\n *\n * Each trigram idle is the starting point for all techniques in that stance.\n * The breathing and weight shifts reflect the elemental nature:\n * - ☰ 건 (Heaven): Powerful, expansive chest breathing\n * - ☱ 태 (Lake): Fluid, rippling breath flow\n * - ☲ 리 (Fire): Sharp, controlled precision breathing\n * - ☳ 진 (Thunder): Deep coiled power breathing\n * - ☴ 손 (Wind): Rhythmic continuous flow\n * - ☵ 감 (Water): Deep flowing diaphragm breathing\n * - ☶ 간 (Mountain): Minimal steady breathing\n * - ☷ 곤 (Earth): Deep grounded diaphragm breathing\n *\n * @module systems/animation/catalogs/StanceIdleAnimations\n * @category Animation System\n * @korean 팔괘자세대기애니메이션\n */\n\nimport { TrigramStance } from \"@/types/common\";\nimport type { SkeletalAnimation, StanceGuardPose } from \"@/types/skeletal\";\nimport { BoneName } from \"@/types/skeletal\";\nimport type { KeyframeConfig } from \"../builders/KeyframeConfig\";\nimport { MartialArtsAnimationBuilder } from \"../builders/MartialArtsAnimationBuilder\";\nimport {\n GAM_WATER_GUARD_POSE,\n GAN_MOUNTAIN_GUARD_POSE,\n GEON_HIGH_GUARD_POSE,\n GON_EARTH_GUARD_POSE,\n JIN_THUNDER_GUARD_POSE,\n LI_FIRE_GUARD_POSE,\n SON_WIND_GUARD_POSE,\n STANCE_GUARD_CONFIGS,\n TAE_FLUID_GUARD_POSE,\n} from \"./StanceGuardPoses\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ANIMATION TIMING CONSTANTS (애니메이션 타이밍 상수)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Breathing cycle durations per stance (in seconds)\n * Each stance has characteristic breathing rhythm\n *\n * @korean 호흡주기지속시간\n */\nconst BREATHING_DURATIONS = {\n GEON: 2.4, // Powerful slow breathing\n TAE: 2.8, // Fluid flowing breath\n LI: 1.8, // Sharp controlled breathing\n JIN: 2.2, // Explosive ready breath\n SON: 2.0, // Rhythmic continuous flow\n GAM: 3.0, // Deep flowing breath\n GAN: 2.6, // Steady controlled breath\n GON: 2.6, // Grounded diaphragm breath\n} as const;\n\n/**\n * Weight shift amplitudes per stance (percentage of base)\n * Reflects stability vs. mobility of each stance\n * RESTORED to original values for better visual feedback and natural movement\n *\n * @korean 체중이동진폭\n */\nconst WEIGHT_SHIFT_AMPLITUDES = {\n GEON: 0.04, // Visible forward rocking - mobile power stance (파워 흔들림)\n TAE: 0.05, // Fluid flowing shifts clearly visible (유동적 흐름)\n LI: 0.02, // Small but visible - precision stance (정밀 제어)\n JIN: 0.06, // Large coiled spring bounce (폭발적 준비)\n SON: 0.045, // Rhythmic lateral shifts (연속 흐름)\n GAM: 0.055, // Flowing water adaptation (물 흐름)\n GAN: 0.015, // Minimal - mountain solid (산악 안정)\n GON: 0.03, // Grounded but visible shifts (대지 흔들림)\n} as const;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BREATHING ANIMATION HELPERS (호흡 애니메이션 헬퍼)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Calculates breathing scale at a given phase\n *\n * @param phase - Breathing phase (0-1, where 0.5 is peak inhale)\n * @param min - Minimum scale (exhale)\n * @param max - Maximum scale (inhale peak)\n * @returns Scale factor for chest/torso\n */\nfunction calculateBreathingScale(\n phase: number,\n min: number,\n max: number,\n): number {\n // Use cosine-based wave for natural breathing rhythm\n // Phase 0 = peak inhale, 0.5 = peak exhale\n const breathPhase = Math.cos(phase * Math.PI * 2);\n const amplitude = (max - min) / 2;\n const center = (max + min) / 2;\n return center + breathPhase * amplitude;\n}\n\n/**\n * Calculates torso expansion for breathing effect\n *\n * @param breathingScale - Current breathing scale (0.96-1.04)\n * @returns Torso rotation adjustment for breathing\n */\nfunction calculateTorsoBreathingOffset(breathingScale: number): number {\n // Chest expands forward more visibly on inhale\n // Multiplier 1.5 for clearly visible breathing (가슴 확장 시각화)\n return (breathingScale - 1) * 1.5;\n}\n\n/**\n * Calculates subtle knee bounce offset at a given phase\n *\n * DESIGN: Idle animations should have visible knee bounce for natural movement feel\n * - no pelvis position movement which creates a \"walking in place\" appearance.\n *\n * @param phase - Breathing/bounce phase (0-1)\n * @param amplitude - Maximum bounce amount (knee bend adjustment)\n * @returns Knee rotation adjustment for natural bounce\n */\nfunction calculateKneeBounce(phase: number, amplitude: number): number {\n // Visible knee flex synchronized with breathing for natural alive feel\n // Two bounces per breath cycle (one per inhale/exhale)\n // 호흡과 동기화된 무릎 굽힘으로 자연스러운 움직임\n const bouncePhase = Math.sin(phase * Math.PI * 4);\n return bouncePhase * amplitude * 0.5;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// GUARD POSE APPLICATION HELPERS (방어자세적용헬퍼)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Applies a complete guard pose to a KeyframeConfig with breathing and knee bounce\n *\n * DESIGN: Idle animations should only have:\n * - Chest breathing (torso expansion)\n * - Subtle knee bounce (slight knee flex variation)\n * NO pelvis X/Z position movement (causes \"walking in place\" appearance)\n *\n * @param kf - KeyframeConfig to apply pose to\n * @param pose - Guard pose to apply\n * @param breathingOffset - Torso breathing offset\n * @param kneeBounce - Subtle knee flex adjustment for bounce effect\n */\nfunction applyGuardPoseToKeyframe(\n kf: KeyframeConfig,\n pose: StanceGuardPose,\n breathingOffset: number,\n kneeBounce: number = 0,\n): void {\n // === ARM POSITIONS (팔 위치) ===\n // IMPORTANT: Use SHOULDER_L/R, ELBOW_L/R, WRIST_L/R bone names\n // NOT UPPER_ARM, FOREARM, HAND - those are different bones in the hierarchy!\n\n // Left arm - shoulder controls arm lift/rotation\n kf.rotate(\n BoneName.SHOULDER_L,\n pose.leftArm.shoulder.x,\n pose.leftArm.shoulder.y,\n pose.leftArm.shoulder.z,\n );\n // Elbow controls forearm bend\n kf.rotate(\n BoneName.ELBOW_L,\n pose.leftArm.elbow.x,\n pose.leftArm.elbow.y,\n pose.leftArm.elbow.z,\n );\n // Wrist controls hand rotation\n kf.rotate(\n BoneName.WRIST_L,\n pose.leftArm.wrist.x,\n pose.leftArm.wrist.y,\n pose.leftArm.wrist.z,\n );\n\n // Right arm - mirror bone hierarchy\n kf.rotate(\n BoneName.SHOULDER_R,\n pose.rightArm.shoulder.x,\n pose.rightArm.shoulder.y,\n pose.rightArm.shoulder.z,\n );\n kf.rotate(\n BoneName.ELBOW_R,\n pose.rightArm.elbow.x,\n pose.rightArm.elbow.y,\n pose.rightArm.elbow.z,\n );\n kf.rotate(\n BoneName.WRIST_R,\n pose.rightArm.wrist.x,\n pose.rightArm.wrist.y,\n pose.rightArm.wrist.z,\n );\n\n // === TORSO (몸통) - Full spine chain for proper rotation ===\n // SPINE_LOWER: Base torso twist (inherits from pelvis)\n kf.rotate(\n BoneName.SPINE_LOWER,\n pose.torso.x * 0.3,\n pose.torso.y * 0.4,\n pose.torso.z * 0.3,\n );\n // SPINE_MIDDLE: Mid-torso twist\n kf.rotate(\n BoneName.SPINE_MIDDLE,\n pose.torso.x * 0.3,\n pose.torso.y * 0.3,\n pose.torso.z * 0.3,\n );\n // SPINE_UPPER: Upper chest with breathing - gets most of the rotation\n kf.rotate(\n BoneName.SPINE_UPPER,\n pose.torso.x * 0.4 + breathingOffset,\n pose.torso.y * 0.3,\n pose.torso.z * 0.4,\n );\n\n // === LEG POSITIONS (다리 위치) ===\n // IMPORTANT: Use HIP_L/R for hip rotation, not THIGH!\n // HIP bone controls the leg's root rotation\n\n // Left leg - HIP controls leg lift/rotation at socket\n kf.rotate(\n BoneName.HIP_L,\n pose.leftLeg.hip.x,\n pose.leftLeg.hip.y,\n pose.leftLeg.hip.z,\n );\n // KNEE controls lower leg bend (primarily X axis flex)\n // Add subtle knee bounce for natural idle movement\n kf.rotate(\n BoneName.KNEE_L,\n pose.leftLeg.knee.x + kneeBounce,\n pose.leftLeg.knee.y,\n pose.leftLeg.knee.z,\n );\n // FOOT controls ankle rotation\n kf.rotate(\n BoneName.FOOT_L,\n pose.leftLeg.ankle.x,\n pose.leftLeg.ankle.y,\n pose.leftLeg.ankle.z,\n );\n\n // Right leg - mirror bone hierarchy\n kf.rotate(\n BoneName.HIP_R,\n pose.rightLeg.hip.x,\n pose.rightLeg.hip.y,\n pose.rightLeg.hip.z,\n );\n kf.rotate(\n BoneName.KNEE_R,\n pose.rightLeg.knee.x + kneeBounce,\n pose.rightLeg.knee.y,\n pose.rightLeg.knee.z,\n );\n kf.rotate(\n BoneName.FOOT_R,\n pose.rightLeg.ankle.x,\n pose.rightLeg.ankle.y,\n pose.rightLeg.ankle.z,\n );\n\n // === PELVIS (골반) - Root of entire body ===\n // Controls overall body rotation and position\n kf.rotate(BoneName.PELVIS, pose.pelvis.x, pose.pelvis.y, pose.pelvis.z);\n // Pelvis position: ONLY stance height drop (Y)\n // NO X/Z offset - this prevents \"walking in place\" appearance\n const pelvisHeight = pose.pelvisHeight ?? 0;\n kf.position(BoneName.PELVIS, 0, pelvisHeight, 0);\n\n // === FOOT POSITIONING (발 위치) ===\n // Position feet for stance width and depth\n const stanceDepth = pose.stanceDepth ?? 0;\n // Left foot: negative X (left side), negative Z (front for forward stances)\n kf.position(BoneName.FOOT_L, -pose.stanceWidth / 2, 0, -stanceDepth / 2);\n // Right foot: positive X (right side), positive Z (back for forward stances)\n kf.position(BoneName.FOOT_R, pose.stanceWidth / 2, 0, stanceDepth / 2);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☰ GEON HEAVEN IDLE (건 하늘 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Geon idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGeonIdleAnimation(): SkeletalAnimation {\n const pose = GEON_HIGH_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GEON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GEON;\n const frames = STANCE_GUARD_CONFIGS.geon.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_geon\",\n \"건 대기\",\n ).asIdle(duration, true);\n\n // Generate keyframes with breathing and subtle knee bounce\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☰ 건 (Geon) Heaven Idle Animation\n *\n * Powerful high guard stance with expansive chest breathing.\n * Boxing-style guard protecting chin and temples.\n *\n * **Breathing**: Slow powerful expansion (2.4s cycle)\n * **Weight**: Subtle forward shift for aggression\n * **Philosophy**: Heaven's creative force, direct power\n *\n * @korean 건하늘대기애니메이션\n */\nexport const GEON_IDLE_ANIMATION: SkeletalAnimation = createGeonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☱ TAE LAKE IDLE (태 연못 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Tae idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createTaeIdleAnimation(): SkeletalAnimation {\n const pose = TAE_FLUID_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.TAE;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.TAE;\n const frames = STANCE_GUARD_CONFIGS.tae.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_tae\",\n \"태 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☱ 태 (Tae) Lake Idle Animation\n *\n * Fluid mid-guard stance with flowing breath rhythm.\n * Lead hand ready for parrying, rear protects chin.\n *\n * **Breathing**: Flowing waves (2.8s cycle)\n * **Weight**: Circular flowing shifts\n * **Philosophy**: Lake's adaptability, fluid technique\n *\n * @korean 태연못대기애니메이션\n */\nexport const TAE_IDLE_ANIMATION: SkeletalAnimation = createTaeIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☲ LI FIRE IDLE (리 불 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Li idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createLiIdleAnimation(): SkeletalAnimation {\n const pose = LI_FIRE_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.LI;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.LI;\n const frames = STANCE_GUARD_CONFIGS.li.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_li\",\n \"리 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☲ 리 (Li) Fire Idle Animation\n *\n * Aggressive peekaboo guard with sharp controlled breathing.\n * Both hands high protecting face for precision striking.\n *\n * **Breathing**: Sharp controlled (1.8s cycle)\n * **Weight**: Minimal movement for precision\n * **Philosophy**: Fire's precision, vital point targeting\n *\n * @korean 리불대기애니메이션\n */\nexport const LI_IDLE_ANIMATION: SkeletalAnimation = createLiIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☳ JIN THUNDER IDLE (진 천둥 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Jin idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createJinIdleAnimation(): SkeletalAnimation {\n const pose = JIN_THUNDER_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.JIN;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.JIN;\n const frames = STANCE_GUARD_CONFIGS.jin.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_jin\",\n \"진 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Jin uses slightly larger bounce (coiled spring ready)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☳ 진 (Jin) Thunder Idle Animation\n *\n * Chambered explosive stance with deep power breathing.\n * Fists at ribs, coiled spring ready for explosive release.\n *\n * **Breathing**: Deep coiled power (2.2s cycle)\n * **Weight**: Back-loaded with subtle forward pulse\n * **Philosophy**: Thunder's explosive force, shocking power\n *\n * @korean 진천둥대기애니메이션\n */\nexport const JIN_IDLE_ANIMATION: SkeletalAnimation = createJinIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☴ SON WIND IDLE (손 바람 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Son idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createSonIdleAnimation(): SkeletalAnimation {\n const pose = SON_WIND_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.SON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.SON;\n const frames = STANCE_GUARD_CONFIGS.son.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_son\",\n \"손 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☴ 손 (Son) Wind Idle Animation\n *\n * Staggered flowing guard with rhythmic continuous breathing.\n * Lead hand extended, rear at chin for combo readiness.\n *\n * **Breathing**: Rhythmic flowing (2.0s cycle)\n * **Weight**: Lateral rhythmic shifts for mobility\n * **Philosophy**: Wind's continuous pressure, flowing attack\n *\n * @korean 손바람대기애니메이션\n */\nexport const SON_IDLE_ANIMATION: SkeletalAnimation = createSonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☵ GAM WATER IDLE (감 물 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gam idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGamIdleAnimation(): SkeletalAnimation {\n const pose = GAM_WATER_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GAM;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GAM;\n const frames = STANCE_GUARD_CONFIGS.gam.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gam\",\n \"감 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☵ 감 (Gam) Water Idle Animation\n *\n * Mid-level parrying guard with deep flowing breathing.\n * Hands ready at solar plexus for redirecting and countering.\n *\n * **Breathing**: Deep flowing diaphragm (3.0s cycle)\n * **Weight**: Circular flowing adaptation\n * **Philosophy**: Water's adaptation, flow-into-counter\n *\n * @korean 감물대기애니메이션\n */\nexport const GAM_IDLE_ANIMATION: SkeletalAnimation = createGamIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☶ GAN MOUNTAIN IDLE (간 산 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gan idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGanIdleAnimation(): SkeletalAnimation {\n const pose = GAN_MOUNTAIN_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GAN;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GAN;\n const frames = STANCE_GUARD_CONFIGS.gan.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gan\",\n \"간 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Gan uses minimal bounce (mountain stability)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☶ 간 (Gan) Mountain Idle Animation\n *\n * High cover defensive guard with steady controlled breathing.\n * Forearms crossed protecting face, immovable stance.\n *\n * **Breathing**: Steady minimal (2.6s cycle)\n * **Weight**: Minimal - mountain solid\n * **Philosophy**: Mountain's immovability, defensive mastery\n *\n * @korean 간산대기애니메이션\n */\nexport const GAN_IDLE_ANIMATION: SkeletalAnimation = createGanIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☷ GON EARTH IDLE (곤 땅 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gon idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGonIdleAnimation(): SkeletalAnimation {\n const pose = GON_EARTH_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GON;\n const frames = STANCE_GUARD_CONFIGS.gon.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gon\",\n \"곤 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Gon uses grounded knee bounce (wrestling ready)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☷ 곤 (Gon) Earth Idle Animation\n *\n * Low underhook wrestling guard with grounded breathing.\n * Hands at hip level, elbows protecting ribs for ground control.\n *\n * **Breathing**: Deep diaphragm (2.6s cycle)\n * **Weight**: Grounded subtle shifts\n * **Philosophy**: Earth's stability, grounding and takedowns\n *\n * @korean 곤땅대기애니메이션\n */\nexport const GON_IDLE_ANIMATION: SkeletalAnimation = createGonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TRIGRAM IDLE ANIMATION MAP (팔괘대기애니메이션맵)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Map of all 8 trigram stance idle animations\n *\n * Use this map for efficient lookup of stance-specific idle animations.\n * Each animation includes proper guard position, breathing, and weight shifts.\n *\n * @korean 팔괘대기애니메이션맵\n */\nexport const TRIGRAM_IDLE_ANIMATIONS: ReadonlyMap<\n TrigramStance,\n SkeletalAnimation\n> = new Map([\n [TrigramStance.GEON, GEON_IDLE_ANIMATION],\n [TrigramStance.TAE, TAE_IDLE_ANIMATION],\n [TrigramStance.LI, LI_IDLE_ANIMATION],\n [TrigramStance.JIN, JIN_IDLE_ANIMATION],\n [TrigramStance.SON, SON_IDLE_ANIMATION],\n [TrigramStance.GAM, GAM_IDLE_ANIMATION],\n [TrigramStance.GAN, GAN_IDLE_ANIMATION],\n [TrigramStance.GON, GON_IDLE_ANIMATION],\n]);\n\n/**\n * Map of all 8 trigram stance idle animations by string name\n *\n * This map provides string-keyed access to idle animations for registry integration.\n * Animation names match the pattern \"stance_X\" used in useSkeletalAnimation.\n *\n * @korean 팔괘대기애니메이션문자열맵\n */\nexport const TRIGRAM_IDLE_ANIMATIONS_BY_NAME: ReadonlyMap<\n string,\n SkeletalAnimation\n> = new Map([\n [\"stance_geon\", GEON_IDLE_ANIMATION],\n [\"stance_tae\", TAE_IDLE_ANIMATION],\n [\"stance_li\", LI_IDLE_ANIMATION],\n [\"stance_jin\", JIN_IDLE_ANIMATION],\n [\"stance_son\", SON_IDLE_ANIMATION],\n [\"stance_gam\", GAM_IDLE_ANIMATION],\n [\"stance_gan\", GAN_IDLE_ANIMATION],\n [\"stance_gon\", GON_IDLE_ANIMATION],\n]);\n\n/**\n * Get idle animation for a specific trigram stance\n *\n * @param stance - Trigram stance identifier\n * @returns Stance-specific idle animation with breathing and weight shifts\n *\n * @example\n * ```typescript\n * const geonIdle = getTrigramIdleAnimation(TrigramStance.GEON);\n * // Returns GEON_IDLE_ANIMATION with high guard, forward breathing\n *\n * const gamIdle = getTrigramIdleAnimation(TrigramStance.GAM);\n * // Returns GAM_IDLE_ANIMATION with flowing parry guard\n * ```\n *\n * @korean 팔괘대기애니메이션가져오기\n */\nexport function getTrigramIdleAnimation(\n stance: TrigramStance,\n): SkeletalAnimation | undefined {\n return TRIGRAM_IDLE_ANIMATIONS.get(stance);\n}\n\n/**\n * Get idle animation by stance name string\n *\n * Convenient accessor for string-based stance lookups.\n *\n * @param stanceName - Stance name (e.g., \"geon\", \"tae\", \"li\")\n * @returns Stance-specific idle animation or undefined\n *\n * @korean 문자열로대기애니메이션가져오기\n */\nexport function getTrigramIdleByName(\n stanceName: string,\n): SkeletalAnimation | undefined {\n const normalizedName = stanceName.toLowerCase();\n\n for (const [stance, animation] of TRIGRAM_IDLE_ANIMATIONS) {\n if (stance === normalizedName) {\n return animation;\n }\n }\n\n return undefined;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ANIMATION COLLECTION (애니메이션모음)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Array of all trigram idle animations for iteration\n *\n * @korean 모든팔괘대기애니메이션\n */\nexport const ALL_TRIGRAM_IDLE_ANIMATIONS: readonly SkeletalAnimation[] = [\n GEON_IDLE_ANIMATION,\n TAE_IDLE_ANIMATION,\n LI_IDLE_ANIMATION,\n JIN_IDLE_ANIMATION,\n SON_IDLE_ANIMATION,\n GAM_IDLE_ANIMATION,\n GAN_IDLE_ANIMATION,\n GON_IDLE_ANIMATION,\n];\n\n/**\n * Idle animation metadata for debugging and introspection\n *\n * @korean 대기애니메이션메타데이터\n */\nexport const TRIGRAM_IDLE_METADATA = {\n GEON: {\n name: \"stance_geon\",\n korean: \"건 대기\",\n english: \"Heaven Idle\",\n breathingDuration: BREATHING_DURATIONS.GEON,\n weightShiftType: \"forward\" as const,\n philosophy: \"Creative force, direct power\",\n },\n TAE: {\n name: \"stance_tae\",\n korean: \"태 대기\",\n english: \"Lake Idle\",\n breathingDuration: BREATHING_DURATIONS.TAE,\n weightShiftType: \"circular\" as const,\n philosophy: \"Adaptability, fluid technique\",\n },\n LI: {\n name: \"stance_li\",\n korean: \"리 대기\",\n english: \"Fire Idle\",\n breathingDuration: BREATHING_DURATIONS.LI,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Precision, vital point targeting\",\n },\n JIN: {\n name: \"stance_jin\",\n korean: \"진 대기\",\n english: \"Thunder Idle\",\n breathingDuration: BREATHING_DURATIONS.JIN,\n weightShiftType: \"forward\" as const,\n philosophy: \"Explosive force, shocking power\",\n },\n SON: {\n name: \"stance_son\",\n korean: \"손 대기\",\n english: \"Wind Idle\",\n breathingDuration: BREATHING_DURATIONS.SON,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Continuous pressure, flowing attack\",\n },\n GAM: {\n name: \"stance_gam\",\n korean: \"감 대기\",\n english: \"Water Idle\",\n breathingDuration: BREATHING_DURATIONS.GAM,\n weightShiftType: \"circular\" as const,\n philosophy: \"Adaptation, flow-into-counter\",\n },\n GAN: {\n name: \"stance_gan\",\n korean: \"간 대기\",\n english: \"Mountain Idle\",\n breathingDuration: BREATHING_DURATIONS.GAN,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Immovability, defensive mastery\",\n },\n GON: {\n name: \"stance_gon\",\n korean: \"곤 대기\",\n english: \"Earth Idle\",\n breathingDuration: BREATHING_DURATIONS.GON,\n weightShiftType: \"forward\" as const,\n philosophy: \"Stability, grounding and takedowns\",\n },\n} as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"StanceIdleAnimations.js","names":[],"sources":["../../../../src/systems/animation/catalogs/StanceIdleAnimations.ts"],"sourcesContent":["/**\n * Trigram Stance Idle Animations - Enhanced Breathing & Weight Shift System\n *\n * Defines complete idle animations for all 8 trigram stances (팔괘) with:\n * - Multi-keyframe breathing cycles (4-6 frames per stance)\n * - Subtle weight shifts for natural movement\n * - Stance-specific rhythms reflecting martial philosophy\n * - Proper guard positions from StanceGuardPoses\n *\n * Each trigram idle is the starting point for all techniques in that stance.\n * The breathing and weight shifts reflect the elemental nature:\n * - ☰ 건 (Heaven): Powerful, expansive chest breathing\n * - ☱ 태 (Lake): Fluid, rippling breath flow\n * - ☲ 리 (Fire): Sharp, controlled precision breathing\n * - ☳ 진 (Thunder): Deep coiled power breathing\n * - ☴ 손 (Wind): Rhythmic continuous flow\n * - ☵ 감 (Water): Deep flowing diaphragm breathing\n * - ☶ 간 (Mountain): Minimal steady breathing\n * - ☷ 곤 (Earth): Deep grounded diaphragm breathing\n *\n * @module systems/animation/catalogs/StanceIdleAnimations\n * @category Animation System\n * @korean 팔괘자세대기애니메이션\n */\n\nimport { TrigramStance } from \"@/types/common\";\nimport type { SkeletalAnimation, StanceGuardPose } from \"@/types/skeletal\";\nimport { BoneName } from \"@/types/skeletal\";\nimport type { KeyframeConfig } from \"../builders/KeyframeConfig\";\nimport { MartialArtsAnimationBuilder } from \"../builders/MartialArtsAnimationBuilder\";\nimport {\n GAM_WATER_GUARD_POSE,\n GAN_MOUNTAIN_GUARD_POSE,\n GEON_HIGH_GUARD_POSE,\n GON_EARTH_GUARD_POSE,\n JIN_THUNDER_GUARD_POSE,\n LI_FIRE_GUARD_POSE,\n SON_WIND_GUARD_POSE,\n STANCE_GUARD_CONFIGS,\n TAE_FLUID_GUARD_POSE,\n} from \"./StanceGuardPoses\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ANIMATION TIMING CONSTANTS (애니메이션 타이밍 상수)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Breathing cycle durations per stance (in seconds)\n * Each stance has characteristic breathing rhythm\n *\n * @korean 호흡주기지속시간\n */\nconst BREATHING_DURATIONS = {\n GEON: 2.4, // Powerful slow breathing\n TAE: 2.8, // Fluid flowing breath\n LI: 1.8, // Sharp controlled breathing\n JIN: 2.2, // Explosive ready breath\n SON: 2.0, // Rhythmic continuous flow\n GAM: 3.0, // Deep flowing breath\n GAN: 2.6, // Steady controlled breath\n GON: 2.6, // Grounded diaphragm breath\n} as const;\n\n/**\n * Weight shift amplitudes per stance (percentage of base)\n * Reflects stability vs. mobility of each stance\n * RESTORED to original values for better visual feedback and natural movement\n *\n * @korean 체중이동진폭\n */\nconst WEIGHT_SHIFT_AMPLITUDES = {\n GEON: 0.04, // Visible forward rocking - mobile power stance (파워 흔들림)\n TAE: 0.05, // Fluid flowing shifts clearly visible (유동적 흐름)\n LI: 0.02, // Small but visible - precision stance (정밀 제어)\n JIN: 0.06, // Large coiled spring bounce (폭발적 준비)\n SON: 0.045, // Rhythmic lateral shifts (연속 흐름)\n GAM: 0.055, // Flowing water adaptation (물 흐름)\n GAN: 0.015, // Minimal - mountain solid (산악 안정)\n GON: 0.03, // Grounded but visible shifts (대지 흔들림)\n} as const;\n\n// ═══════════════════════════════════════════════════════════════════════════\n// BREATHING ANIMATION HELPERS (호흡 애니메이션 헬퍼)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Calculates breathing scale at a given phase\n *\n * @param phase - Breathing phase (0-1, where 0.5 is peak inhale)\n * @param min - Minimum scale (exhale)\n * @param max - Maximum scale (inhale peak)\n * @returns Scale factor for chest/torso\n */\nfunction calculateBreathingScale(\n phase: number,\n min: number,\n max: number,\n): number {\n // Use cosine-based wave for natural breathing rhythm\n // Phase 0 = peak inhale, 0.5 = peak exhale\n const breathPhase = Math.cos(phase * Math.PI * 2);\n const amplitude = (max - min) / 2;\n const center = (max + min) / 2;\n return center + breathPhase * amplitude;\n}\n\n/**\n * Calculates torso expansion for breathing effect\n *\n * @param breathingScale - Current breathing scale (0.96-1.04)\n * @returns Torso rotation adjustment for breathing\n */\nfunction calculateTorsoBreathingOffset(breathingScale: number): number {\n // Chest expands forward more visibly on inhale\n // Multiplier 1.5 for clearly visible breathing (가슴 확장 시각화)\n return (breathingScale - 1) * 1.5;\n}\n\n/**\n * Calculates subtle knee bounce offset at a given phase\n *\n * DESIGN: Idle animations should have visible knee bounce for natural movement feel\n * - no pelvis position movement which creates a \"walking in place\" appearance.\n *\n * @param phase - Breathing/bounce phase (0-1)\n * @param amplitude - Maximum bounce amount (knee bend adjustment)\n * @returns Knee rotation adjustment for natural bounce\n */\nfunction calculateKneeBounce(phase: number, amplitude: number): number {\n // Visible knee flex synchronized with breathing for natural alive feel\n // Two bounces per breath cycle (one per inhale/exhale)\n // 호흡과 동기화된 무릎 굽힘으로 자연스러운 움직임\n const bouncePhase = Math.sin(phase * Math.PI * 4);\n return bouncePhase * amplitude * 0.5;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// GUARD POSE APPLICATION HELPERS (방어자세적용헬퍼)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Applies a complete guard pose to a KeyframeConfig with breathing and knee bounce\n *\n * DESIGN: Idle animations should only have:\n * - Chest breathing (torso expansion)\n * - Subtle knee bounce (slight knee flex variation)\n * NO pelvis X/Z position movement (causes \"walking in place\" appearance)\n *\n * @param kf - KeyframeConfig to apply pose to\n * @param pose - Guard pose to apply\n * @param breathingOffset - Torso breathing offset\n * @param kneeBounce - Subtle knee flex adjustment for bounce effect\n */\nfunction applyGuardPoseToKeyframe(\n kf: KeyframeConfig,\n pose: StanceGuardPose,\n breathingOffset: number,\n kneeBounce: number = 0,\n): void {\n // === ARM POSITIONS (팔 위치) ===\n // IMPORTANT: Use SHOULDER_L/R, ELBOW_L/R, WRIST_L/R bone names\n // NOT UPPER_ARM, FOREARM, HAND - those are different bones in the hierarchy!\n\n // Left arm - shoulder controls arm lift/rotation\n kf.rotate(\n BoneName.SHOULDER_L,\n pose.leftArm.shoulder.x,\n pose.leftArm.shoulder.y,\n pose.leftArm.shoulder.z,\n );\n // Elbow controls forearm bend\n kf.rotate(\n BoneName.ELBOW_L,\n pose.leftArm.elbow.x,\n pose.leftArm.elbow.y,\n pose.leftArm.elbow.z,\n );\n // Wrist controls hand rotation\n kf.rotate(\n BoneName.WRIST_L,\n pose.leftArm.wrist.x,\n pose.leftArm.wrist.y,\n pose.leftArm.wrist.z,\n );\n\n // Right arm - mirror bone hierarchy\n kf.rotate(\n BoneName.SHOULDER_R,\n pose.rightArm.shoulder.x,\n pose.rightArm.shoulder.y,\n pose.rightArm.shoulder.z,\n );\n kf.rotate(\n BoneName.ELBOW_R,\n pose.rightArm.elbow.x,\n pose.rightArm.elbow.y,\n pose.rightArm.elbow.z,\n );\n kf.rotate(\n BoneName.WRIST_R,\n pose.rightArm.wrist.x,\n pose.rightArm.wrist.y,\n pose.rightArm.wrist.z,\n );\n\n // === TORSO (몸통) - Full spine chain for proper rotation ===\n // SPINE_LOWER: Base torso twist (inherits from pelvis)\n kf.rotate(\n BoneName.SPINE_LOWER,\n pose.torso.x * 0.3,\n pose.torso.y * 0.4,\n pose.torso.z * 0.3,\n );\n // SPINE_MIDDLE: Mid-torso twist\n kf.rotate(\n BoneName.SPINE_MIDDLE,\n pose.torso.x * 0.3,\n pose.torso.y * 0.3,\n pose.torso.z * 0.3,\n );\n // SPINE_UPPER: Upper chest with breathing - gets most of the rotation\n kf.rotate(\n BoneName.SPINE_UPPER,\n pose.torso.x * 0.4 + breathingOffset,\n pose.torso.y * 0.3,\n pose.torso.z * 0.4,\n );\n\n // === LEG POSITIONS (다리 위치) ===\n // IMPORTANT: Use HIP_L/R for hip rotation, not THIGH!\n // HIP bone controls the leg's root rotation\n\n // Left leg - HIP controls leg lift/rotation at socket\n kf.rotate(\n BoneName.HIP_L,\n pose.leftLeg.hip.x,\n pose.leftLeg.hip.y,\n pose.leftLeg.hip.z,\n );\n // KNEE controls lower leg bend (primarily X axis flex)\n // Add subtle knee bounce for natural idle movement\n kf.rotate(\n BoneName.KNEE_L,\n pose.leftLeg.knee.x + kneeBounce,\n pose.leftLeg.knee.y,\n pose.leftLeg.knee.z,\n );\n // FOOT controls ankle rotation\n kf.rotate(\n BoneName.FOOT_L,\n pose.leftLeg.ankle.x,\n pose.leftLeg.ankle.y,\n pose.leftLeg.ankle.z,\n );\n\n // Right leg - mirror bone hierarchy\n kf.rotate(\n BoneName.HIP_R,\n pose.rightLeg.hip.x,\n pose.rightLeg.hip.y,\n pose.rightLeg.hip.z,\n );\n kf.rotate(\n BoneName.KNEE_R,\n pose.rightLeg.knee.x + kneeBounce,\n pose.rightLeg.knee.y,\n pose.rightLeg.knee.z,\n );\n kf.rotate(\n BoneName.FOOT_R,\n pose.rightLeg.ankle.x,\n pose.rightLeg.ankle.y,\n pose.rightLeg.ankle.z,\n );\n\n // === PELVIS (골반) - Root of entire body ===\n // Controls overall body rotation and position\n kf.rotate(BoneName.PELVIS, pose.pelvis.x, pose.pelvis.y, pose.pelvis.z);\n // Pelvis position: ONLY stance height drop (Y)\n // NO X/Z offset - this prevents \"walking in place\" appearance\n const pelvisHeight = pose.pelvisHeight ?? 0;\n kf.position(BoneName.PELVIS, 0, pelvisHeight, 0);\n\n // === FOOT POSITIONING (발 위치) ===\n // Position feet for stance width and depth\n const stanceDepth = pose.stanceDepth ?? 0;\n // Left foot: negative X (left side), negative Z (front for forward stances)\n kf.position(BoneName.FOOT_L, -pose.stanceWidth / 2, 0, -stanceDepth / 2);\n // Right foot: positive X (right side), positive Z (back for forward stances)\n kf.position(BoneName.FOOT_R, pose.stanceWidth / 2, 0, stanceDepth / 2);\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☰ GEON HEAVEN IDLE (건 하늘 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Geon idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGeonIdleAnimation(): SkeletalAnimation {\n const pose = GEON_HIGH_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GEON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GEON;\n const frames = STANCE_GUARD_CONFIGS.geon.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_geon\",\n \"건 대기\",\n ).asIdle(duration, true);\n\n // Generate keyframes with breathing and subtle knee bounce\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☰ 건 (Geon) Heaven Idle Animation\n *\n * Powerful high guard stance with expansive chest breathing.\n * Boxing-style guard protecting chin and temples.\n *\n * **Breathing**: Slow powerful expansion (2.4s cycle)\n * **Weight**: Subtle forward shift for aggression\n * **Philosophy**: Heaven's creative force, direct power\n *\n * @korean 건하늘대기애니메이션\n */\nexport const GEON_IDLE_ANIMATION: SkeletalAnimation = createGeonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☱ TAE LAKE IDLE (태 연못 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Tae idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createTaeIdleAnimation(): SkeletalAnimation {\n const pose = TAE_FLUID_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.TAE;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.TAE;\n const frames = STANCE_GUARD_CONFIGS.tae.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_tae\",\n \"태 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☱ 태 (Tae) Lake Idle Animation\n *\n * Fluid mid-guard stance with flowing breath rhythm.\n * Lead hand ready for parrying, rear protects chin.\n *\n * **Breathing**: Flowing waves (2.8s cycle)\n * **Weight**: Circular flowing shifts\n * **Philosophy**: Lake's adaptability, fluid technique\n *\n * @korean 태연못대기애니메이션\n */\nexport const TAE_IDLE_ANIMATION: SkeletalAnimation = createTaeIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☲ LI FIRE IDLE (리 불 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Li idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createLiIdleAnimation(): SkeletalAnimation {\n const pose = LI_FIRE_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.LI;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.LI;\n const frames = STANCE_GUARD_CONFIGS.li.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_li\",\n \"리 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☲ 리 (Li) Fire Idle Animation\n *\n * Aggressive peekaboo guard with sharp controlled breathing.\n * Both hands high protecting face for precision striking.\n *\n * **Breathing**: Sharp controlled (1.8s cycle)\n * **Weight**: Minimal movement for precision\n * **Philosophy**: Fire's precision, vital point targeting\n *\n * @korean 리불대기애니메이션\n */\nexport const LI_IDLE_ANIMATION: SkeletalAnimation = createLiIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☳ JIN THUNDER IDLE (진 천둥 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Jin idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createJinIdleAnimation(): SkeletalAnimation {\n const pose = JIN_THUNDER_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.JIN;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.JIN;\n const frames = STANCE_GUARD_CONFIGS.jin.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_jin\",\n \"진 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Jin uses slightly larger bounce (coiled spring ready)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☳ 진 (Jin) Thunder Idle Animation\n *\n * Chambered explosive stance with deep power breathing.\n * Fists at ribs, coiled spring ready for explosive release.\n *\n * **Breathing**: Deep coiled power (2.2s cycle)\n * **Weight**: Back-loaded with subtle forward pulse\n * **Philosophy**: Thunder's explosive force, shocking power\n *\n * @korean 진천둥대기애니메이션\n */\nexport const JIN_IDLE_ANIMATION: SkeletalAnimation = createJinIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☴ SON WIND IDLE (손 바람 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Son idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createSonIdleAnimation(): SkeletalAnimation {\n const pose = SON_WIND_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.SON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.SON;\n const frames = STANCE_GUARD_CONFIGS.son.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_son\",\n \"손 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☴ 손 (Son) Wind Idle Animation\n *\n * Staggered flowing guard with rhythmic continuous breathing.\n * Lead hand extended, rear at chin for combo readiness.\n *\n * **Breathing**: Rhythmic flowing (2.0s cycle)\n * **Weight**: Lateral rhythmic shifts for mobility\n * **Philosophy**: Wind's continuous pressure, flowing attack\n *\n * @korean 손바람대기애니메이션\n */\nexport const SON_IDLE_ANIMATION: SkeletalAnimation = createSonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☵ GAM WATER IDLE (감 물 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gam idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGamIdleAnimation(): SkeletalAnimation {\n const pose = GAM_WATER_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GAM;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GAM;\n const frames = STANCE_GUARD_CONFIGS.gam.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gam\",\n \"감 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☵ 감 (Gam) Water Idle Animation\n *\n * Mid-level parrying guard with deep flowing breathing.\n * Hands ready at solar plexus for redirecting and countering.\n *\n * **Breathing**: Deep flowing diaphragm (3.0s cycle)\n * **Weight**: Circular flowing adaptation\n * **Philosophy**: Water's adaptation, flow-into-counter\n *\n * @korean 감물대기애니메이션\n */\nexport const GAM_IDLE_ANIMATION: SkeletalAnimation = createGamIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☶ GAN MOUNTAIN IDLE (간 산 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gan idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGanIdleAnimation(): SkeletalAnimation {\n const pose = GAN_MOUNTAIN_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GAN;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GAN;\n const frames = STANCE_GUARD_CONFIGS.gan.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gan\",\n \"간 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Gan uses minimal bounce (mountain stability)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☶ 간 (Gan) Mountain Idle Animation\n *\n * High cover defensive guard with steady controlled breathing.\n * Forearms crossed protecting face, immovable stance.\n *\n * **Breathing**: Steady minimal (2.6s cycle)\n * **Weight**: Minimal - mountain solid\n * **Philosophy**: Mountain's immovability, defensive mastery\n *\n * @korean 간산대기애니메이션\n */\nexport const GAN_IDLE_ANIMATION: SkeletalAnimation = createGanIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ☷ GON EARTH IDLE (곤 땅 대기)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Creates Gon idle animation with breathing and subtle knee bounce\n * NO pelvis position movement - only breathing and knee flex\n */\nfunction createGonIdleAnimation(): SkeletalAnimation {\n const pose = GON_EARTH_GUARD_POSE;\n const { min, max } = pose.breathingRange;\n const duration = BREATHING_DURATIONS.GON;\n const amplitude = WEIGHT_SHIFT_AMPLITUDES.GON;\n const frames = STANCE_GUARD_CONFIGS.gon.breathingFrames;\n\n const builder = MartialArtsAnimationBuilder.create(\n \"stance_gon\",\n \"곤 대기\",\n ).asIdle(duration, true);\n\n for (let i = 0; i <= frames; i++) {\n const phase = i / frames;\n const frameTime = phase * duration;\n const breathingScale = calculateBreathingScale(phase, min, max);\n const breathingOffset = calculateTorsoBreathingOffset(breathingScale);\n // Gon uses grounded knee bounce (wrestling ready)\n const kneeBounce = calculateKneeBounce(phase, amplitude);\n\n const kf = builder.at(frameTime);\n applyGuardPoseToKeyframe(kf, pose, breathingOffset, kneeBounce);\n kf.done<MartialArtsAnimationBuilder>();\n }\n\n return builder.build();\n}\n\n/**\n * ☷ 곤 (Gon) Earth Idle Animation\n *\n * Low underhook wrestling guard with grounded breathing.\n * Hands at hip level, elbows protecting ribs for ground control.\n *\n * **Breathing**: Deep diaphragm (2.6s cycle)\n * **Weight**: Grounded subtle shifts\n * **Philosophy**: Earth's stability, grounding and takedowns\n *\n * @korean 곤땅대기애니메이션\n */\nexport const GON_IDLE_ANIMATION: SkeletalAnimation = createGonIdleAnimation();\n\n// ═══════════════════════════════════════════════════════════════════════════\n// TRIGRAM IDLE ANIMATION MAP (팔괘대기애니메이션맵)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Map of all 8 trigram stance idle animations\n *\n * Use this map for efficient lookup of stance-specific idle animations.\n * Each animation includes proper guard position, breathing, and weight shifts.\n *\n * @korean 팔괘대기애니메이션맵\n */\nexport const TRIGRAM_IDLE_ANIMATIONS: ReadonlyMap<\n TrigramStance,\n SkeletalAnimation\n> = new Map([\n [TrigramStance.GEON, GEON_IDLE_ANIMATION],\n [TrigramStance.TAE, TAE_IDLE_ANIMATION],\n [TrigramStance.LI, LI_IDLE_ANIMATION],\n [TrigramStance.JIN, JIN_IDLE_ANIMATION],\n [TrigramStance.SON, SON_IDLE_ANIMATION],\n [TrigramStance.GAM, GAM_IDLE_ANIMATION],\n [TrigramStance.GAN, GAN_IDLE_ANIMATION],\n [TrigramStance.GON, GON_IDLE_ANIMATION],\n]);\n\n/**\n * Map of all 8 trigram stance idle animations by string name\n *\n * This map provides string-keyed access to idle animations for registry integration.\n * Animation names match the pattern \"stance_X\" used in useSkeletalAnimation.\n *\n * @korean 팔괘대기애니메이션문자열맵\n */\nexport const TRIGRAM_IDLE_ANIMATIONS_BY_NAME: ReadonlyMap<\n string,\n SkeletalAnimation\n> = new Map([\n [\"stance_geon\", GEON_IDLE_ANIMATION],\n [\"stance_tae\", TAE_IDLE_ANIMATION],\n [\"stance_li\", LI_IDLE_ANIMATION],\n [\"stance_jin\", JIN_IDLE_ANIMATION],\n [\"stance_son\", SON_IDLE_ANIMATION],\n [\"stance_gam\", GAM_IDLE_ANIMATION],\n [\"stance_gan\", GAN_IDLE_ANIMATION],\n [\"stance_gon\", GON_IDLE_ANIMATION],\n]);\n\n/**\n * Get idle animation for a specific trigram stance\n *\n * @param stance - Trigram stance identifier\n * @returns Stance-specific idle animation with breathing and weight shifts\n *\n * @example\n * ```typescript\n * const geonIdle = getTrigramIdleAnimation(TrigramStance.GEON);\n * // Returns GEON_IDLE_ANIMATION with high guard, forward breathing\n *\n * const gamIdle = getTrigramIdleAnimation(TrigramStance.GAM);\n * // Returns GAM_IDLE_ANIMATION with flowing parry guard\n * ```\n *\n * @korean 팔괘대기애니메이션가져오기\n */\nexport function getTrigramIdleAnimation(\n stance: TrigramStance,\n): SkeletalAnimation | undefined {\n return TRIGRAM_IDLE_ANIMATIONS.get(stance);\n}\n\n/**\n * Get idle animation by stance name string\n *\n * Convenient accessor for string-based stance lookups.\n *\n * @param stanceName - Stance name (e.g., \"geon\", \"tae\", \"li\")\n * @returns Stance-specific idle animation or undefined\n *\n * @korean 문자열로대기애니메이션가져오기\n */\nexport function getTrigramIdleByName(\n stanceName: string,\n): SkeletalAnimation | undefined {\n const normalizedName = stanceName.toLowerCase();\n\n for (const [stance, animation] of TRIGRAM_IDLE_ANIMATIONS) {\n if (stance === normalizedName) {\n return animation;\n }\n }\n\n return undefined;\n}\n\n// ═══════════════════════════════════════════════════════════════════════════\n// ANIMATION COLLECTION (애니메이션모음)\n// ═══════════════════════════════════════════════════════════════════════════\n\n/**\n * Array of all trigram idle animations for iteration\n *\n * @korean 모든팔괘대기애니메이션\n */\nexport const ALL_TRIGRAM_IDLE_ANIMATIONS: readonly SkeletalAnimation[] = [\n GEON_IDLE_ANIMATION,\n TAE_IDLE_ANIMATION,\n LI_IDLE_ANIMATION,\n JIN_IDLE_ANIMATION,\n SON_IDLE_ANIMATION,\n GAM_IDLE_ANIMATION,\n GAN_IDLE_ANIMATION,\n GON_IDLE_ANIMATION,\n];\n\n/**\n * Idle animation metadata for debugging and introspection\n *\n * @korean 대기애니메이션메타데이터\n */\nexport const TRIGRAM_IDLE_METADATA = {\n GEON: {\n name: \"stance_geon\",\n korean: \"건 대기\",\n english: \"Heaven Idle\",\n breathingDuration: BREATHING_DURATIONS.GEON,\n weightShiftType: \"forward\" as const,\n philosophy: \"Creative force, direct power\",\n },\n TAE: {\n name: \"stance_tae\",\n korean: \"태 대기\",\n english: \"Lake Idle\",\n breathingDuration: BREATHING_DURATIONS.TAE,\n weightShiftType: \"circular\" as const,\n philosophy: \"Adaptability, fluid technique\",\n },\n LI: {\n name: \"stance_li\",\n korean: \"리 대기\",\n english: \"Fire Idle\",\n breathingDuration: BREATHING_DURATIONS.LI,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Precision, vital point targeting\",\n },\n JIN: {\n name: \"stance_jin\",\n korean: \"진 대기\",\n english: \"Thunder Idle\",\n breathingDuration: BREATHING_DURATIONS.JIN,\n weightShiftType: \"forward\" as const,\n philosophy: \"Explosive force, shocking power\",\n },\n SON: {\n name: \"stance_son\",\n korean: \"손 대기\",\n english: \"Wind Idle\",\n breathingDuration: BREATHING_DURATIONS.SON,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Continuous pressure, flowing attack\",\n },\n GAM: {\n name: \"stance_gam\",\n korean: \"감 대기\",\n english: \"Water Idle\",\n breathingDuration: BREATHING_DURATIONS.GAM,\n weightShiftType: \"circular\" as const,\n philosophy: \"Adaptation, flow-into-counter\",\n },\n GAN: {\n name: \"stance_gan\",\n korean: \"간 대기\",\n english: \"Mountain Idle\",\n breathingDuration: BREATHING_DURATIONS.GAN,\n weightShiftType: \"lateral\" as const,\n philosophy: \"Immovability, defensive mastery\",\n },\n GON: {\n name: \"stance_gon\",\n korean: \"곤 대기\",\n english: \"Earth Idle\",\n breathingDuration: BREATHING_DURATIONS.GON,\n weightShiftType: \"forward\" as const,\n philosophy: \"Stability, grounding and takedowns\",\n },\n} as const;\n"],"mappings":"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"}
@@ -274,7 +274,7 @@ var GON_RUN_ANIMATION = (() => {
274
274
  * Map of all stance-specific walk animations
275
275
  * @korean 자세별걷기애니메이션맵
276
276
  */
277
- var STANCE_WALK_ANIMATIONS = new Map([
277
+ var STANCE_WALK_ANIMATIONS = /* @__PURE__ */ new Map([
278
278
  ["walk_geon", GEON_WALK_ANIMATION],
279
279
  ["walk_tae", TAE_WALK_ANIMATION],
280
280
  ["walk_li", LI_WALK_ANIMATION],
@@ -288,7 +288,7 @@ var STANCE_WALK_ANIMATIONS = new Map([
288
288
  * Map of all stance-specific run animations
289
289
  * @korean 자세별달리기애니메이션맵
290
290
  */
291
- var STANCE_RUN_ANIMATIONS = new Map([
291
+ var STANCE_RUN_ANIMATIONS = /* @__PURE__ */ new Map([
292
292
  ["run_geon", GEON_RUN_ANIMATION],
293
293
  ["run_tae", TAE_RUN_ANIMATION],
294
294
  ["run_li", LI_RUN_ANIMATION],