blacktrigram 0.7.39 → 0.7.41
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.
- package/lib/App2.js.map +1 -1
- package/lib/audio/AudioAssetLoader.js.map +1 -1
- package/lib/audio/AudioAssetRegistry.js.map +1 -1
- package/lib/audio/AudioCache.js.map +1 -1
- package/lib/audio/AudioManager.js.map +1 -1
- package/lib/audio/AudioMonitor.js.map +1 -1
- package/lib/audio/AudioPool.js.map +1 -1
- package/lib/audio/AudioProvider.js.map +1 -1
- package/lib/audio/AudioUtils.js.map +1 -1
- package/lib/audio/BoneImpactAudioMap.js.map +1 -1
- package/lib/audio/VariantSelector.js.map +1 -1
- package/lib/audio/types.js.map +1 -1
- package/lib/components/screens/combat/CombatScreen3D.js.map +1 -1
- package/lib/components/screens/combat/components/controls/CombatButtons.js.map +1 -1
- package/lib/components/screens/combat/components/controls/CombatControlsPanel.js.map +1 -1
- package/lib/components/screens/combat/components/controls/ControlsGuide.js.map +1 -1
- package/lib/components/screens/combat/components/controls/KeyboardHints.js.map +1 -1
- package/lib/components/screens/combat/components/controls/PauseMenu.js.map +1 -1
- package/lib/components/screens/combat/components/controls/PauseMenuButton.js.map +1 -1
- package/lib/components/screens/combat/components/controls/QuickSettings.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodDecals3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodLossOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodParticles3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/BloodViscosity3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/CombatParticleEffects3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/ConsciousnessBlur.js.map +1 -1
- package/lib/components/screens/combat/components/effects/InternalDamage3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/PainVignette.js.map +1 -1
- package/lib/components/screens/combat/components/effects/ParticleAudio3D.js.map +1 -1
- package/lib/components/screens/combat/components/effects/TraumaOverlay3D.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/MatchCountdown.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundAnnouncementOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundDisplayStatus.js.map +1 -1
- package/lib/components/screens/combat/components/feedback/RoundStartAnnouncementOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatBottomHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatLeftHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatPortraitStatusStrip.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatRightHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/CombatTopHUD.js.map +1 -1
- package/lib/components/screens/combat/components/hud/DifficultyIndicator.js.map +1 -1
- package/lib/components/screens/combat/components/hud/FPSMonitor.js.map +1 -1
- package/lib/components/screens/combat/components/hud/MobileControlsWrapper.js.map +1 -1
- package/lib/components/screens/combat/components/hud/PlayerStateOverlayHtml.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/BalanceIndicator.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/InputBufferDisplay.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/StaminaWarning.js.map +1 -1
- package/lib/components/screens/combat/components/indicators/TechniqueNameDisplay.js.map +1 -1
- package/lib/components/screens/combat/helpers/AnimationUpdater.js.map +1 -1
- package/lib/components/screens/combat/helpers/combatHelpers.js.map +1 -1
- package/lib/components/screens/combat/hooks/useAICombat.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatActions.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatAttackMovement.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatAudio.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatLayout.js.map +1 -1
- package/lib/components/screens/combat/hooks/useCombatState.js.map +1 -1
- package/lib/components/screens/controls/ControlsScreen3D.js.map +1 -1
- package/lib/components/screens/controls/components/ControlBindingsOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/ControlCategoryTabsOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/GamepadVisualization3D.js.map +1 -1
- package/lib/components/screens/controls/components/InteractiveControlDemoOverlayHtml.js.map +1 -1
- package/lib/components/screens/controls/components/Key3D.js.map +1 -1
- package/lib/components/screens/controls/components/VisualKeyboard3D.js.map +1 -1
- package/lib/components/screens/controls/constants/ControlsConstants.js.map +1 -1
- package/lib/components/screens/controls/hooks/useControlsState.js.map +1 -1
- package/lib/components/screens/endscreen/EndScreen3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/DefeatAnimation3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/MatchStatisticsDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/NavigationButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/PerformanceBreakdownOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/PerformanceRatingOverlayHtml.js.map +1 -1
- package/lib/components/screens/endscreen/components/VictoryAnimation3D.js.map +1 -1
- package/lib/components/screens/endscreen/components/WinnerDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/IntroScreen3D.js +1 -1
- package/lib/components/screens/intro/IntroScreen3D.js.map +1 -1
- package/lib/components/screens/intro/components/AbilityListOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeCardGridOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeCardOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/ArchetypeDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/EnhancedArchetypeDisplayOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/MenuButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/MenuSectionOverlayHtml.js.map +1 -1
- package/lib/components/screens/intro/components/StatBarOverlayHtml.js.map +1 -1
- package/lib/components/screens/philosophy/PhilosophyScreen3D.js.map +1 -1
- package/lib/components/screens/training/TrainingScreen3D.js.map +1 -1
- package/lib/components/screens/training/components/AnatomyControlsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/AnatomyOverlay3D.js.map +1 -1
- package/lib/components/screens/training/components/FootPlacementMarkers3D.js.map +1 -1
- package/lib/components/screens/training/components/FootworkDrillsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/HitFeedbackEffect3D.js.map +1 -1
- package/lib/components/screens/training/components/TrainingButtonsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingControlsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingDummy3D.js.map +1 -1
- package/lib/components/screens/training/components/TrainingFeedbackOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingModeSelectorOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/TrainingStatsOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/VitalPointMarker3D.js.map +1 -1
- package/lib/components/screens/training/components/VitalPointTrainingOverlayHtml.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingBottomHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingLeftHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingRightHUD.js.map +1 -1
- package/lib/components/screens/training/components/hud/TrainingTopHUD.js.map +1 -1
- package/lib/components/screens/training/hooks/useAttackMovement.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingActions.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingLayout.js.map +1 -1
- package/lib/components/screens/training/hooks/useTrainingState.js.map +1 -1
- package/lib/components/shared/base/BaseButton.js.map +1 -1
- package/lib/components/shared/base/BaseButtonOverlayHtml.js.map +1 -1
- package/lib/components/shared/base/BasePanel.js.map +1 -1
- package/lib/components/shared/base/BaseText.js.map +1 -1
- package/lib/components/shared/base/useKoreanTheme.js.map +1 -1
- package/lib/components/shared/debug/PerformanceDebugOverlayHtml.js.map +1 -1
- package/lib/components/shared/mobile/ActionButtons.js.map +1 -1
- package/lib/components/shared/mobile/GestureRecognizerPure.js.map +1 -1
- package/lib/components/shared/mobile/HapticController.js.map +1 -1
- package/lib/components/shared/mobile/MobileControlsPure.js.map +1 -1
- package/lib/components/shared/mobile/StanceWheelPure.js.map +1 -1
- package/lib/components/shared/mobile/TouchOptimizer.js.map +1 -1
- package/lib/components/shared/mobile/VirtualDPad.js.map +1 -1
- package/lib/components/shared/three/anatomy/BodySurface.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneAttachedMuscles.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneClothing.js.map +1 -1
- package/lib/components/shared/three/anatomy/BoneRenderer.js.map +1 -1
- package/lib/components/shared/three/anatomy/Face3D.js.map +1 -1
- package/lib/components/shared/three/anatomy/Foot3D.js.map +1 -1
- package/lib/components/shared/three/anatomy/Hand3D.js.map +1 -1
- package/lib/components/shared/three/effects/ActionFeedback.js.map +1 -1
- package/lib/components/shared/three/effects/DamageNumbers.js.map +1 -1
- package/lib/components/shared/three/effects/HitEffects3D.js.map +1 -1
- package/lib/components/shared/three/effects/PlayerStateIndicators.js.map +1 -1
- package/lib/components/shared/three/effects/StanceSymbol3D.js.map +1 -1
- package/lib/components/shared/three/effects/StanceTransitionEffect.js.map +1 -1
- package/lib/components/shared/three/effects/VitalPointMarkers3D.js.map +1 -1
- package/lib/components/shared/three/indicators/ElementalColorSystem.js.map +1 -1
- package/lib/components/shared/three/indicators/GuardIndicator.js.map +1 -1
- package/lib/components/shared/three/indicators/HapticFeedback.js.map +1 -1
- package/lib/components/shared/three/indicators/StanceChangeIndicator.js.map +1 -1
- package/lib/components/shared/three/models/Player3DWithTransitions.js.map +1 -1
- package/lib/components/shared/three/models/SkeletalPlayer3D.js.map +1 -1
- package/lib/components/shared/three/optimization/AdaptiveQuality.js.map +1 -1
- package/lib/components/shared/three/scene/AtmosphericParticles3D.js.map +1 -1
- package/lib/components/shared/three/scene/BackgroundScene3D.js.map +1 -1
- package/lib/components/shared/three/scene/CombatArena3D.js.map +1 -1
- package/lib/components/shared/three/scene/KoreanSignage3D.js.map +1 -1
- package/lib/components/shared/three/ui/ArchetypeCard.js.map +1 -1
- package/lib/components/shared/three/ui/BodyPartHealthDisplay.js.map +1 -1
- package/lib/components/shared/three/ui/BreathingIndicator2.js.map +1 -1
- package/lib/components/shared/three/ui/CombatReadinessBar.js.map +1 -1
- package/lib/components/shared/three/ui/ComboCounter.js.map +1 -1
- package/lib/components/shared/three/ui/HealthBar.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanButton.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanPanel.js.map +1 -1
- package/lib/components/shared/three/ui/KoreanText.js.map +1 -1
- package/lib/components/shared/three/ui/MenuList.js.map +1 -1
- package/lib/components/shared/three/ui/PlayerHUD.js.map +1 -1
- package/lib/components/shared/three/ui/ProgressBar.js.map +1 -1
- package/lib/components/shared/three/ui/SpeedIndicatorHUD.js.map +1 -1
- package/lib/components/shared/three/ui/StaminaBar.js.map +1 -1
- package/lib/components/shared/three/ui/TechniqueBar.js.map +1 -1
- package/lib/components/shared/three/ui/TechniqueCard.js.map +1 -1
- package/lib/components/shared/three/ui/VitalPointOverlayControlsHtml.js.map +1 -1
- package/lib/components/shared/ui/BackButton.js.map +1 -1
- package/lib/components/shared/ui/BaseHUDContainer.js.map +1 -1
- package/lib/components/shared/ui/CombatTimer.js.map +1 -1
- package/lib/components/shared/ui/ErrorModal.js.map +1 -1
- package/lib/components/shared/ui/LoadingState.js.map +1 -1
- package/lib/components/shared/ui/SplashScreen.js +2 -2
- package/lib/components/shared/ui/SplashScreen.js.map +1 -1
- package/lib/components/shared/ui/VitalPointOverlayControlsPure.js.map +1 -1
- package/lib/components/shared/ui/VolumeControl.js.map +1 -1
- package/lib/components/shared/ui/shared/ConfirmDialog.js.map +1 -1
- package/lib/components/ui/combat/BalanceIndicatorOverlayHtml.js.map +1 -1
- package/lib/constants/bodyDimensions.js.map +1 -1
- package/lib/constants/bodyRenderingConstants.js.map +1 -1
- package/lib/data/archetypeClothing.js.map +1 -1
- package/lib/data/archetypePhysicalAttributes.js.map +1 -1
- package/lib/data/techniqueMappings.js.map +1 -1
- package/lib/data/techniques.js.map +1 -1
- package/lib/hooks/useActionFeedback.js.map +1 -1
- package/lib/hooks/useBalanceAnimations.js.map +1 -1
- package/lib/hooks/useCombatTimer.js.map +1 -1
- package/lib/hooks/useDebounce.js.map +1 -1
- package/lib/hooks/useHUDLayout.js.map +1 -1
- package/lib/hooks/useHandPoseTransitions.js.map +1 -1
- package/lib/hooks/useKeyboardControls.js.map +1 -1
- package/lib/hooks/useMatchCountdown.js.map +1 -1
- package/lib/hooks/useMuscleActivation.js.map +1 -1
- package/lib/hooks/usePauseMenu.js.map +1 -1
- package/lib/hooks/usePlayerAnimation.js.map +1 -1
- package/lib/hooks/useResponsiveLayout.js.map +1 -1
- package/lib/hooks/useRoundTransition.js.map +1 -1
- package/lib/hooks/useSkeletalAnimation.js.map +1 -1
- package/lib/hooks/useTechniqueSelection.js.map +1 -1
- package/lib/hooks/useThrottle.js.map +1 -1
- package/lib/hooks/useTouchControls.js.map +1 -1
- package/lib/hooks/useWebGLContextLossHandler.js.map +1 -1
- package/lib/hooks/useWindowSize.js.map +1 -1
- package/lib/systems/CombatSystem.js.map +1 -1
- package/lib/systems/EffectCalculator.js.map +1 -1
- package/lib/systems/LayoutSystem.js.map +1 -1
- package/lib/systems/PlayerEffectManager.js.map +1 -1
- package/lib/systems/ResponsiveScaling.js.map +1 -1
- package/lib/systems/TrigramSystem.js.map +1 -1
- package/lib/systems/VitalPointSystem.js.map +1 -1
- package/lib/systems/ai/AIPersonality.js.map +1 -1
- package/lib/systems/ai/AdaptiveDifficulty.js.map +1 -1
- package/lib/systems/ai/ArchetypeEnforcer.js.map +1 -1
- package/lib/systems/ai/ComboSystem.js.map +1 -1
- package/lib/systems/ai/DecisionTree.js.map +1 -1
- package/lib/systems/ai/TrainingAI.js.map +1 -1
- package/lib/systems/ai/types.js.map +1 -1
- package/lib/systems/animation/builders/AnimationBuilder.js.map +1 -1
- package/lib/systems/animation/builders/HandPoseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/HandPoses.js.map +1 -1
- package/lib/systems/animation/builders/KeyframeConfig.js.map +1 -1
- package/lib/systems/animation/builders/KeyframeInterpolation.js +3 -90
- package/lib/systems/animation/builders/KeyframeInterpolation.js.map +1 -1
- package/lib/systems/animation/builders/KickPhaseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/KoreanGuardPositions.js.map +1 -1
- package/lib/systems/animation/builders/MartialArtsAnimationBuilder.js.map +1 -1
- package/lib/systems/animation/builders/MartialArtsConstants.js.map +1 -1
- package/lib/systems/animation/builders/MartialPoseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/PunchPhaseApplicator.js.map +1 -1
- package/lib/systems/animation/builders/SkeletonRig.js.map +1 -1
- package/lib/systems/animation/builders/TrigramGuardApplicator.js.map +1 -1
- package/lib/systems/animation/catalogs/DefensiveAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/FootworkSkeletalAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/RecoveryAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceAttackAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceGuardPoses.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceIdleAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StanceLocomotionAnimations.js.map +1 -1
- package/lib/systems/animation/catalogs/StepSkeletalAnimations.js.map +1 -1
- package/lib/systems/animation/core/AnimationHitTiming.js.map +1 -1
- package/lib/systems/animation/core/AnimationOptimizations.js.map +1 -1
- package/lib/systems/animation/core/AnimationPriority.js.map +1 -1
- package/lib/systems/animation/core/AnimationRegistry.js.map +1 -1
- package/lib/systems/animation/core/AnimationStateMachine.js.map +1 -1
- package/lib/systems/animation/core/AnimationTransitions.js.map +1 -1
- package/lib/systems/animation/core/LateralityTransform.js.map +1 -1
- package/lib/systems/animation/core/RecoveryPhaseEnhancer.js.map +1 -1
- package/lib/systems/animation/core/TechniqueAnimationMapper.js.map +1 -1
- package/lib/systems/animation/core/TechniqueAnimationMapping.js.map +1 -1
- package/lib/systems/animation/core/types.js.map +1 -1
- package/lib/systems/animation/systems/AdvancedJointMovements.js.map +1 -1
- package/lib/systems/animation/systems/BodyFacingSystem.js.map +1 -1
- package/lib/systems/animation/systems/FacialExpressions.js.map +1 -1
- package/lib/systems/animation/systems/FallAnimations.js.map +1 -1
- package/lib/systems/animation/systems/MuscleActivation.js.map +1 -1
- package/lib/systems/bodypart/BodyPartDamageIntegration.js.map +1 -1
- package/lib/systems/bodypart/BodyPartHealthSystem.js.map +1 -1
- package/lib/systems/bodypart/BodyPartPositionMapping.js.map +1 -1
- package/lib/systems/bodypart/CombatInjuryIntegration.js.map +1 -1
- package/lib/systems/bodypart/InjuryIntegration.js.map +1 -1
- package/lib/systems/bodypart/InjuryTracker.js.map +1 -1
- package/lib/systems/bodypart/MovementPenaltySystem.js.map +1 -1
- package/lib/systems/bodypart/PlayerInjuryTrackingManager.js.map +1 -1
- package/lib/systems/bodypart/types.js.map +1 -1
- package/lib/systems/breathing/BreathingDisruptionSystem.js.map +1 -1
- package/lib/systems/breathing/feedback.js.map +1 -1
- package/lib/systems/breathing/integration.js.map +1 -1
- package/lib/systems/combat/BalanceSystem.js.map +1 -1
- package/lib/systems/combat/BreakingStatusEffects.js.map +1 -1
- package/lib/systems/combat/CombatStateSystem.js.map +1 -1
- package/lib/systems/combat/ConsciousnessSystem.js.map +1 -1
- package/lib/systems/combat/FallIntegration.js.map +1 -1
- package/lib/systems/combat/GrappleSystem.js.map +1 -1
- package/lib/systems/combat/LimbExposureSystem.js.map +1 -1
- package/lib/systems/combat/PainResponseSystem.js.map +1 -1
- package/lib/systems/combat/TrainingCombatSystem.js.map +1 -1
- package/lib/systems/combat/painConsciousnessUtils.js.map +1 -1
- package/lib/systems/combat/typeGuards.js.map +1 -1
- package/lib/systems/effects.js.map +1 -1
- package/lib/systems/game.js.map +1 -1
- package/lib/systems/movement/InjuryMovementModifier.js.map +1 -1
- package/lib/systems/movement/helpers/AccelerationUpdater.js.map +1 -1
- package/lib/systems/movement/helpers/accelerationUtils.js.map +1 -1
- package/lib/systems/movement/integration.js.map +1 -1
- package/lib/systems/physics/AttackMovementPhysics.js.map +1 -1
- package/lib/systems/physics/CollisionDetection.js.map +1 -1
- package/lib/systems/physics/CoordinateMapper.js.map +1 -1
- package/lib/systems/physics/KnockbackPhysics.js.map +1 -1
- package/lib/systems/physics/MovementPhysics.js.map +1 -1
- package/lib/systems/physics/PhysicalReachCalculator.js.map +1 -1
- package/lib/systems/physics/SpeedModifierSystem.js.map +1 -1
- package/lib/systems/trigram/KoreanCulture.js.map +1 -1
- package/lib/systems/trigram/KoreanTechniques.js.map +1 -1
- package/lib/systems/trigram/StanceManager.js.map +1 -1
- package/lib/systems/trigram/TransitionCalculator.js.map +1 -1
- package/lib/systems/trigram/TrigramCalculator.js.map +1 -1
- package/lib/systems/trigram/techniques/DarkOpsTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GamTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GanTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/GonTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/SonTechniques.js.map +1 -1
- package/lib/systems/trigram/techniques/TechniqueConfig.js.map +1 -1
- package/lib/systems/trigram/techniques/index.js.map +1 -1
- package/lib/systems/trigram/types/GonTechniqueExtensions.js.map +1 -1
- package/lib/systems/trigram/types.js.map +1 -1
- package/lib/systems/types.js.map +1 -1
- package/lib/systems/vitalpoint/DamageCalculator.js.map +1 -1
- package/lib/systems/vitalpoint/HitDetection.js.map +1 -1
- package/lib/systems/vitalpoint/KoreanAnatomy.js.map +1 -1
- package/lib/systems/vitalpoint/KoreanVitalPoints.js.map +1 -1
- package/lib/systems/vitalpoint/MeridianVitalPointMapping.js.map +1 -1
- package/lib/types/AccessibilityTypes.js.map +1 -1
- package/lib/types/PhysicsTypes.js.map +1 -1
- package/lib/types/common.js.map +1 -1
- package/lib/types/constants/colors.js.map +1 -1
- package/lib/types/constants/designSystem.js.map +1 -1
- package/lib/types/constants/layout.js.map +1 -1
- package/lib/types/constants/performance.js.map +1 -1
- package/lib/types/constants/typography.js.map +1 -1
- package/lib/types/facial.js.map +1 -1
- package/lib/types/hand-animation.js.map +1 -1
- package/lib/types/injury.js.map +1 -1
- package/lib/types/physics.js.map +1 -1
- package/lib/types/skeletal.js.map +1 -1
- package/lib/types/techniqueId.js.map +1 -1
- package/lib/utils/accessibility.js.map +1 -1
- package/lib/utils/arenaWorldDimensions.js.map +1 -1
- package/lib/utils/assetConfig.js.map +1 -1
- package/lib/utils/characterScaling.js.map +1 -1
- package/lib/utils/colorHelpers.js.map +1 -1
- package/lib/utils/colorUtils.js.map +1 -1
- package/lib/utils/combatReadiness.js.map +1 -1
- package/lib/utils/controlMapping.js.map +1 -1
- package/lib/utils/deviceDetection.js.map +1 -1
- package/lib/utils/effectUtils.js.map +1 -1
- package/lib/utils/fabricTextures.js.map +1 -1
- package/lib/utils/hapticFeedback.js.map +1 -1
- package/lib/utils/haptics.js.map +1 -1
- package/lib/utils/htmlOverlayHelpers.js.map +1 -1
- package/lib/utils/inputSystem.js.map +1 -1
- package/lib/utils/koreanThemeHelpers.js.map +1 -1
- package/lib/utils/math.js.map +1 -1
- package/lib/utils/mobileLayoutHelpers.js.map +1 -1
- package/lib/utils/mobileUIUtils.js.map +1 -1
- package/lib/utils/performance/PerformanceMonitor.js.map +1 -1
- package/lib/utils/performance/PerformanceOverlay3D.js.map +1 -1
- package/lib/utils/performance/usePerformanceMonitor.js.map +1 -1
- package/lib/utils/performanceOptimization.js.map +1 -1
- package/lib/utils/player3DHelpers.js.map +1 -1
- package/lib/utils/playerUtils.js.map +1 -1
- package/lib/utils/responsiveLayout.js.map +1 -1
- package/lib/utils/responsiveLayoutHelpers.js.map +1 -1
- package/lib/utils/responsiveOrientationConstants.js.map +1 -1
- package/lib/utils/safeAreaUtils.js.map +1 -1
- package/lib/utils/sharedPhysicsConfig.js.map +1 -1
- package/lib/utils/skeletonScaling.js.map +1 -1
- package/lib/utils/stanceHelpers.js.map +1 -1
- package/lib/utils/threeObjectPool.js.map +1 -1
- package/lib/utils/visualEffects.js.map +1 -1
- package/package.json +8 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PhysicsTypes.js","names":[],"sources":["../../src/types/PhysicsTypes.ts"],"sourcesContent":["/**\n * Physics-based type definitions for Black Trigram (흑괘)\n * \n * This module defines physics-first types where all positions, distances,\n * and measurements are in **meters** or **centimeters**, never pixels.\n * Pixel conversions happen ONLY at render time.\n * \n * @module types/PhysicsTypes\n * @category Type Definitions\n * @korean 물리타입\n */\n\nimport * as THREE from \"three\";\nimport type { Position3D } from \"./physics\";\n\n/**\n * Arena bounds with both pixel dimensions (for rendering) and \n * world dimensions (for physics calculations).\n * \n * This allows proper conversion between screen space (pixels) and\n * physics space (meters) without fixed constants.\n * \n * **Korean**: 경기장 경계 (Arena Bounds)\n * \n * @public\n * @category Physics Types\n */\nexport interface PhysicsArenaBounds {\n /** X coordinate of arena top-left corner (pixels, for rendering) */\n readonly x: number;\n /** Y coordinate of arena top-left corner (pixels, for rendering) */\n readonly y: number;\n /** Arena width in pixels (for rendering) */\n readonly width: number;\n /** Arena height in pixels (for rendering) */\n readonly height: number;\n /** Arena scale factor (1.0 = desktop, <1.0 = mobile, for 3D scene scaling) */\n readonly scale: number;\n \n /**\n * Physical arena width in meters.\n * \n * This is the actual size of the combat arena in the game world.\n * Combined with width (pixels), this gives pixels-per-meter ratio:\n * `pixelsPerMeter = width / worldWidthMeters`\n * \n * Example: Desktop 960px / 10m = 96 px/m, Mobile 300px / 6m = 50 px/m\n */\n readonly worldWidthMeters: number;\n \n /**\n * Physical arena depth in meters.\n * \n * Typically same as worldWidthMeters for square arenas.\n * For rectangular arenas, may differ.\n * \n * Example: 10m × 10m square arena\n */\n readonly worldDepthMeters: number;\n}\n\n/**\n * Default arena bounds used across visual effect components.\n * \n * Represents a standard 10m × 7.5m arena at desktop resolution (1200×800px).\n * Components should use this as their default to ensure consistency.\n * \n * **Korean**: 기본경기장경계 (Default Arena Bounds)\n * \n * @public\n * @category Physics Types\n */\nexport const DEFAULT_PHYSICS_ARENA_BOUNDS: PhysicsArenaBounds = {\n x: 0,\n y: 0,\n width: 1200,\n height: 800,\n scale: 1.0,\n worldWidthMeters: 10,\n worldDepthMeters: 7.5,\n} as const;\n\n/**\n * Validates if a value is a valid Position3D or THREE.Vector3.\n * \n * @param pos - Value to check\n * @returns True if valid position with x, y, z properties\n * @internal\n */\nfunction isValidPosition(pos: unknown): pos is Position3D | THREE.Vector3 {\n return (\n pos !== null &&\n pos !== undefined &&\n typeof pos === \"object\" &&\n \"x\" in pos &&\n \"y\" in pos &&\n \"z\" in pos &&\n typeof (pos as Position3D).x === \"number\" &&\n typeof (pos as Position3D).y === \"number\" &&\n typeof (pos as Position3D).z === \"number\" &&\n Number.isFinite((pos as Position3D).x) &&\n Number.isFinite((pos as Position3D).y) &&\n Number.isFinite((pos as Position3D).z)\n );\n}\n\n/**\n * Calculate pixels-per-meter ratio from arena bounds.\n * \n * This is the fundamental conversion factor between screen space (pixels)\n * and physics space (meters). It varies by device resolution and arena size.\n * \n * **Korean**: 픽셀당미터비율 (Pixels Per Meter Ratio)\n * \n * @param bounds - Arena bounds with pixel and meter dimensions\n * @returns Conversion ratio (pixels per meter)\n * @throws Error if worldWidthMeters is not positive\n * \n * @example\n * ```typescript\n * // Desktop: 960px arena, 10m world\n * const desktopPxPerM = getPixelsPerMeter({ width: 960, worldWidthMeters: 10, ... });\n * // Result: 96 px/m\n * \n * // Mobile: 300px arena, 6m world \n * const mobilePxPerM = getPixelsPerMeter({ width: 300, worldWidthMeters: 6, ... });\n * // Result: 50 px/m\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function getPixelsPerMeter(bounds: PhysicsArenaBounds): number {\n if (bounds.worldWidthMeters <= 0) {\n throw new Error(\n `worldWidthMeters must be positive, got: ${bounds.worldWidthMeters}`\n );\n }\n return bounds.width / bounds.worldWidthMeters;\n}\n\n/**\n * Convert physics position (meters) to screen position (pixels).\n * \n * **IMPORTANT**: This function only handles scaling conversion between\n * meters and pixels. It does NOT account for arena position offsets\n * (bounds.x and bounds.y). Callers must add these offsets separately\n * when rendering to screen.\n * \n * Example:\n * ```typescript\n * const pixelPos = metersToPixels(physicsPos, bounds);\n * const screenX = bounds.x + pixelPos.x; // Add arena offset\n * const screenY = bounds.y + pixelPos.y; // Add arena offset\n * ```\n * \n * This conversion should ONLY be used at render time.\n * Internal game logic should always work in meters.\n * \n * **Korean**: 미터를픽셀로 (Meters To Pixels)\n * \n * @param positionMeters - Position in meters\n * @param bounds - Arena bounds for conversion\n * @returns Position in pixels RELATIVE to arena origin (add bounds.x/y for screen position)\n * @throws Error if position is invalid\n * \n * @public\n * @category Physics Types\n */\nexport function metersToPixels(\n positionMeters: Position3D | THREE.Vector3,\n bounds: PhysicsArenaBounds\n): { x: number; y: number } {\n if (!isValidPosition(positionMeters)) {\n throw new Error(\n \"Invalid position: must be Vector3 or Position3D with numeric x, y, z properties\"\n );\n }\n \n const pixelsPerMeter = getPixelsPerMeter(bounds);\n \n return {\n x: positionMeters.x * pixelsPerMeter,\n y: positionMeters.z * pixelsPerMeter, // Z axis maps to screen Y\n };\n}\n\n/**\n * Convert screen position (pixels) to physics position (meters).\n * \n * **IMPORTANT**: This function only handles scaling conversion between\n * pixels and meters. If you're converting from screen coordinates, you\n * must first subtract arena position offsets (bounds.x and bounds.y).\n * \n * Example:\n * ```typescript\n * const arenaRelativeX = screenX - bounds.x; // Remove arena offset\n * const arenaRelativeY = screenY - bounds.y; // Remove arena offset\n * const physicsPos = pixelsToMeters({ x: arenaRelativeX, y: arenaRelativeY }, bounds);\n * ```\n * \n * Use this when converting user input or initial positions.\n * After conversion, work entirely in meters.\n * \n * **Korean**: 픽셀을미터로 (Pixels To Meters)\n * \n * @param pixelPosition - Position in pixels RELATIVE to arena origin (subtract bounds.x/y first)\n * @param bounds - Arena bounds for conversion\n * @returns Position in meters\n * @throws Error if pixel coordinates are not finite numbers\n * \n * @public\n * @category Physics Types\n */\nexport function pixelsToMeters(\n pixelPosition: { x: number; y: number },\n bounds: PhysicsArenaBounds\n): Position3D {\n if (!Number.isFinite(pixelPosition.x) || !Number.isFinite(pixelPosition.y)) {\n throw new Error(\n `Invalid pixel coordinates: x=${pixelPosition.x}, y=${pixelPosition.y}`\n );\n }\n \n const pixelsPerMeter = getPixelsPerMeter(bounds);\n \n return {\n x: pixelPosition.x / pixelsPerMeter,\n y: 0, // Ground plane\n z: pixelPosition.y / pixelsPerMeter, // Screen Y maps to Z axis\n };\n}\n\n/**\n * Calculate distance between two positions in meters.\n * \n * This is the correct way to calculate distance - always in meters,\n * never in pixels.\n * \n * **Korean**: 거리계산 (Distance Calculation)\n * \n * @param pos1 - First position in meters\n * @param pos2 - Second position in meters\n * @returns Distance in meters\n * @throws Error if either position is invalid\n * \n * @public\n * @category Physics Types\n */\nexport function calculateDistanceMeters(\n pos1: Position3D | THREE.Vector3,\n pos2: Position3D | THREE.Vector3\n): number {\n if (!isValidPosition(pos1) || !isValidPosition(pos2)) {\n throw new Error(\n \"Invalid positions for distance calculation: both positions must be valid Vector3 or Position3D objects\"\n );\n }\n \n const dx = pos2.x - pos1.x;\n const dy = pos2.y - pos1.y;\n const dz = pos2.z - pos1.z;\n \n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Movement-specific arena bounds in world coordinates (meters).\n * \n * Defines the playable area boundaries for player/AI movement.\n * All arenas are centered at origin (0, 0) and extend symmetrically.\n * \n * **Korean**: 이동 경기장 경계 (Movement Arena Bounds)\n * \n * @remarks\n * This is distinct from `ArenaBounds` interfaces in layout/test code\n * which include pixel-based screen coordinates. MovementArenaBounds\n * only contains world-space meter coordinates for physics calculations.\n * \n * @public\n * @category Physics Types\n */\nexport interface MovementArenaBounds {\n /** Minimum X position in meters (left edge) */\n readonly minX: number;\n /** Maximum X position in meters (right edge) */\n readonly maxX: number;\n /** Minimum Z position in meters (back edge) */\n readonly minZ: number;\n /** Maximum Z position in meters (front edge) */\n readonly maxZ: number;\n /** Arena center X in meters (typically 0) */\n readonly centerX: number;\n /** Arena center Z in meters (typically 0) */\n readonly centerZ: number;\n /** Arena width in meters */\n readonly widthMeters: number;\n /** Arena depth in meters */\n readonly depthMeters: number;\n}\n\n/**\n * Calculate arena bounds from arena configuration.\n * \n * Creates bounds with a margin to account for character radius,\n * preventing characters from walking through edges.\n * \n * **Korean**: 경기장 경계 계산 (Calculate Arena Bounds)\n * \n * @param bounds - Arena configuration with meter dimensions (can be partial with just worldWidthMeters/worldDepthMeters)\n * @param margin - Character radius/margin in meters (default: 0.3m - half character width)\n * @returns Arena bounds for physics calculations\n * @throws Error if dimensions are invalid (non-positive or non-finite) or margin is invalid\n * \n * @example\n * ```typescript\n * const config = { worldWidthMeters: 10, worldDepthMeters: 7.5 };\n * const arenaBounds = calculateArenaBounds(config, 0.3);\n * // Result: { minX: -4.7, maxX: 4.7, minZ: -3.45, maxZ: 3.45, ... }\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function calculateArenaBounds(\n bounds: Pick<PhysicsArenaBounds, 'worldWidthMeters' | 'worldDepthMeters'>,\n margin: number = 0.3\n): MovementArenaBounds {\n // Validate arena dimensions\n if (!Number.isFinite(bounds.worldWidthMeters) || bounds.worldWidthMeters <= 0) {\n throw new Error(\n `worldWidthMeters must be a positive finite number, got: ${bounds.worldWidthMeters}`\n );\n }\n if (!Number.isFinite(bounds.worldDepthMeters) || bounds.worldDepthMeters <= 0) {\n throw new Error(\n `worldDepthMeters must be a positive finite number, got: ${bounds.worldDepthMeters}`\n );\n }\n \n // Validate margin\n if (!Number.isFinite(margin) || margin < 0) {\n throw new Error(\n `margin must be a non-negative finite number, got: ${margin}`\n );\n }\n \n const halfWidth = bounds.worldWidthMeters / 2;\n const halfDepth = bounds.worldDepthMeters / 2;\n \n // Validate margin is not larger than arena dimensions\n if (margin >= halfWidth) {\n throw new Error(\n `margin (${margin}m) must be less than half the arena width (${halfWidth}m)`\n );\n }\n if (margin >= halfDepth) {\n throw new Error(\n `margin (${margin}m) must be less than half the arena depth (${halfDepth}m)`\n );\n }\n \n return {\n minX: -halfWidth + margin,\n maxX: halfWidth - margin,\n minZ: -halfDepth + margin,\n maxZ: halfDepth - margin,\n centerX: 0,\n centerZ: 0,\n widthMeters: bounds.worldWidthMeters,\n depthMeters: bounds.worldDepthMeters,\n };\n}\n\n/**\n * Clamp a 3D position to stay within arena boundaries.\n * \n * Only clamps X and Z axes (horizontal plane). Y axis (height) is unchanged.\n * Arena is centered at origin with bounds extending ±width/2 and ±depth/2.\n * \n * **Korean**: 위치를 경기장 경계로 제한 (Clamp Position To Bounds)\n * \n * @param position - 3D position in meters (THREE.Vector3 or Position3D)\n * @param bounds - Arena bounds with min/max values\n * @returns Clamped position as new THREE.Vector3\n * \n * @example\n * ```typescript\n * const position = new THREE.Vector3(6, 0, 4); // Outside bounds\n * const bounds = calculateArenaBounds(config);\n * const clamped = clampPositionToBounds(position, bounds);\n * // Result: Vector3(4.7, 0, 3.45) - clamped to edges\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function clampPositionToBounds(\n position: THREE.Vector3 | Position3D,\n bounds: MovementArenaBounds\n): THREE.Vector3 {\n return new THREE.Vector3(\n Math.max(bounds.minX, Math.min(bounds.maxX, position.x)),\n position.y, // Y is height, not bounds-checked\n Math.max(bounds.minZ, Math.min(bounds.maxZ, position.z))\n );\n}\n\n/**\n * Check if a position is within arena boundaries.\n * \n * Only checks X and Z axes (horizontal plane). Y axis (height) is ignored.\n * \n * For 2D positions, accepts `{ x, y }` where `y` maps to world Z (depth),\n * consistent with `clampToArenaBounds` and other 2D arena position APIs.\n * \n * **Korean**: 경기장 경계 내 위치 확인 (Check Position In Bounds)\n * \n * @param position - Position to check (2D {x,y} where y=depth, or 3D Vector3/Position3D)\n * @param bounds - Arena bounds\n * @returns True if position is within bounds\n * \n * @example\n * ```typescript\n * // 2D position (y maps to Z/depth)\n * const position = { x: 5, y: 2 };\n * const bounds = calculateArenaBounds(config);\n * const inBounds = isPositionInBounds(position, bounds);\n * \n * // 3D position (uses z directly)\n * const position3D = new THREE.Vector3(5, 1.8, 2);\n * const inBounds3D = isPositionInBounds(position3D, bounds);\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function isPositionInBounds(\n position: { x: number; y: number } | THREE.Vector3 | Position3D,\n bounds: MovementArenaBounds\n): boolean {\n const x = position.x;\n // For 2D positions {x,y}, y maps to world Z (depth)\n // For 3D positions, use z directly\n const z = 'z' in position ? position.z : position.y;\n \n return (\n x >= bounds.minX &&\n x <= bounds.maxX &&\n z >= bounds.minZ &&\n z <= bounds.maxZ\n );\n}\n\n/**\n * Clamp a 2D position to stay within arena boundaries in meters.\n * \n * This function works in a projected 2D arena space where:\n * - `position.x` corresponds to world **X** (horizontal)\n * - `position.y` corresponds to world **Z** (depth)\n * \n * Arena coordinates are centered at origin (0, 0) and extend from\n * -worldWidthMeters/2 to +worldWidthMeters/2 in X (position.x),\n * -worldDepthMeters/2 to +worldDepthMeters/2 in Z/depth (position.y).\n * \n * This is used for physics calculations like knockback to ensure\n * players stay within the playable area.\n * \n * @param position - 2D projected position in meters (X, depth-as-Y), which may exceed arena bounds\n * @param bounds - Arena bounds with meter dimensions\n * @returns Position clamped to arena boundaries in the same 2D projection\n * \n * @example\n * ```typescript\n * const bounds = { worldWidthMeters: 10, worldDepthMeters: 7.5, ... };\n * const position = { x: 6, y: 4 }; // Outside arena in X/Z-projected space\n * const clamped = clampToArenaBounds(position, bounds);\n * // Result: { x: 5, y: 3.75 } - clamped to boundaries\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function clampToArenaBounds(\n position: { x: number; y: number },\n bounds: PhysicsArenaBounds\n): { x: number; y: number } {\n const halfWidth = bounds.worldWidthMeters / 2;\n const halfDepth = bounds.worldDepthMeters / 2;\n \n return {\n x: Math.max(-halfWidth, Math.min(halfWidth, position.x)),\n y: Math.max(-halfDepth, Math.min(halfDepth, position.y)),\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PhysicsTypes.js","names":[],"sources":["../../src/types/PhysicsTypes.ts"],"sourcesContent":["/**\n * Physics-based type definitions for Black Trigram (흑괘)\n * \n * This module defines physics-first types where all positions, distances,\n * and measurements are in **meters** or **centimeters**, never pixels.\n * Pixel conversions happen ONLY at render time.\n * \n * @module types/PhysicsTypes\n * @category Type Definitions\n * @korean 물리타입\n */\n\nimport * as THREE from \"three\";\nimport type { Position3D } from \"./physics\";\n\n/**\n * Arena bounds with both pixel dimensions (for rendering) and \n * world dimensions (for physics calculations).\n * \n * This allows proper conversion between screen space (pixels) and\n * physics space (meters) without fixed constants.\n * \n * **Korean**: 경기장 경계 (Arena Bounds)\n * \n * @public\n * @category Physics Types\n */\nexport interface PhysicsArenaBounds {\n /** X coordinate of arena top-left corner (pixels, for rendering) */\n readonly x: number;\n /** Y coordinate of arena top-left corner (pixels, for rendering) */\n readonly y: number;\n /** Arena width in pixels (for rendering) */\n readonly width: number;\n /** Arena height in pixels (for rendering) */\n readonly height: number;\n /** Arena scale factor (1.0 = desktop, <1.0 = mobile, for 3D scene scaling) */\n readonly scale: number;\n \n /**\n * Physical arena width in meters.\n * \n * This is the actual size of the combat arena in the game world.\n * Combined with width (pixels), this gives pixels-per-meter ratio:\n * `pixelsPerMeter = width / worldWidthMeters`\n * \n * Example: Desktop 960px / 10m = 96 px/m, Mobile 300px / 6m = 50 px/m\n */\n readonly worldWidthMeters: number;\n \n /**\n * Physical arena depth in meters.\n * \n * Typically same as worldWidthMeters for square arenas.\n * For rectangular arenas, may differ.\n * \n * Example: 10m × 10m square arena\n */\n readonly worldDepthMeters: number;\n}\n\n/**\n * Default arena bounds used across visual effect components.\n * \n * Represents a standard 10m × 7.5m arena at desktop resolution (1200×800px).\n * Components should use this as their default to ensure consistency.\n * \n * **Korean**: 기본경기장경계 (Default Arena Bounds)\n * \n * @public\n * @category Physics Types\n */\nexport const DEFAULT_PHYSICS_ARENA_BOUNDS: PhysicsArenaBounds = {\n x: 0,\n y: 0,\n width: 1200,\n height: 800,\n scale: 1.0,\n worldWidthMeters: 10,\n worldDepthMeters: 7.5,\n} as const;\n\n/**\n * Validates if a value is a valid Position3D or THREE.Vector3.\n * \n * @param pos - Value to check\n * @returns True if valid position with x, y, z properties\n * @internal\n */\nfunction isValidPosition(pos: unknown): pos is Position3D | THREE.Vector3 {\n return (\n pos !== null &&\n pos !== undefined &&\n typeof pos === \"object\" &&\n \"x\" in pos &&\n \"y\" in pos &&\n \"z\" in pos &&\n typeof (pos as Position3D).x === \"number\" &&\n typeof (pos as Position3D).y === \"number\" &&\n typeof (pos as Position3D).z === \"number\" &&\n Number.isFinite((pos as Position3D).x) &&\n Number.isFinite((pos as Position3D).y) &&\n Number.isFinite((pos as Position3D).z)\n );\n}\n\n/**\n * Calculate pixels-per-meter ratio from arena bounds.\n * \n * This is the fundamental conversion factor between screen space (pixels)\n * and physics space (meters). It varies by device resolution and arena size.\n * \n * **Korean**: 픽셀당미터비율 (Pixels Per Meter Ratio)\n * \n * @param bounds - Arena bounds with pixel and meter dimensions\n * @returns Conversion ratio (pixels per meter)\n * @throws Error if worldWidthMeters is not positive\n * \n * @example\n * ```typescript\n * // Desktop: 960px arena, 10m world\n * const desktopPxPerM = getPixelsPerMeter({ width: 960, worldWidthMeters: 10, ... });\n * // Result: 96 px/m\n * \n * // Mobile: 300px arena, 6m world \n * const mobilePxPerM = getPixelsPerMeter({ width: 300, worldWidthMeters: 6, ... });\n * // Result: 50 px/m\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function getPixelsPerMeter(bounds: PhysicsArenaBounds): number {\n if (bounds.worldWidthMeters <= 0) {\n throw new Error(\n `worldWidthMeters must be positive, got: ${bounds.worldWidthMeters}`\n );\n }\n return bounds.width / bounds.worldWidthMeters;\n}\n\n/**\n * Convert physics position (meters) to screen position (pixels).\n * \n * **IMPORTANT**: This function only handles scaling conversion between\n * meters and pixels. It does NOT account for arena position offsets\n * (bounds.x and bounds.y). Callers must add these offsets separately\n * when rendering to screen.\n * \n * Example:\n * ```typescript\n * const pixelPos = metersToPixels(physicsPos, bounds);\n * const screenX = bounds.x + pixelPos.x; // Add arena offset\n * const screenY = bounds.y + pixelPos.y; // Add arena offset\n * ```\n * \n * This conversion should ONLY be used at render time.\n * Internal game logic should always work in meters.\n * \n * **Korean**: 미터를픽셀로 (Meters To Pixels)\n * \n * @param positionMeters - Position in meters\n * @param bounds - Arena bounds for conversion\n * @returns Position in pixels RELATIVE to arena origin (add bounds.x/y for screen position)\n * @throws Error if position is invalid\n * \n * @public\n * @category Physics Types\n */\nexport function metersToPixels(\n positionMeters: Position3D | THREE.Vector3,\n bounds: PhysicsArenaBounds\n): { x: number; y: number } {\n if (!isValidPosition(positionMeters)) {\n throw new Error(\n \"Invalid position: must be Vector3 or Position3D with numeric x, y, z properties\"\n );\n }\n \n const pixelsPerMeter = getPixelsPerMeter(bounds);\n \n return {\n x: positionMeters.x * pixelsPerMeter,\n y: positionMeters.z * pixelsPerMeter, // Z axis maps to screen Y\n };\n}\n\n/**\n * Convert screen position (pixels) to physics position (meters).\n * \n * **IMPORTANT**: This function only handles scaling conversion between\n * pixels and meters. If you're converting from screen coordinates, you\n * must first subtract arena position offsets (bounds.x and bounds.y).\n * \n * Example:\n * ```typescript\n * const arenaRelativeX = screenX - bounds.x; // Remove arena offset\n * const arenaRelativeY = screenY - bounds.y; // Remove arena offset\n * const physicsPos = pixelsToMeters({ x: arenaRelativeX, y: arenaRelativeY }, bounds);\n * ```\n * \n * Use this when converting user input or initial positions.\n * After conversion, work entirely in meters.\n * \n * **Korean**: 픽셀을미터로 (Pixels To Meters)\n * \n * @param pixelPosition - Position in pixels RELATIVE to arena origin (subtract bounds.x/y first)\n * @param bounds - Arena bounds for conversion\n * @returns Position in meters\n * @throws Error if pixel coordinates are not finite numbers\n * \n * @public\n * @category Physics Types\n */\nexport function pixelsToMeters(\n pixelPosition: { x: number; y: number },\n bounds: PhysicsArenaBounds\n): Position3D {\n if (!Number.isFinite(pixelPosition.x) || !Number.isFinite(pixelPosition.y)) {\n throw new Error(\n `Invalid pixel coordinates: x=${pixelPosition.x}, y=${pixelPosition.y}`\n );\n }\n \n const pixelsPerMeter = getPixelsPerMeter(bounds);\n \n return {\n x: pixelPosition.x / pixelsPerMeter,\n y: 0, // Ground plane\n z: pixelPosition.y / pixelsPerMeter, // Screen Y maps to Z axis\n };\n}\n\n/**\n * Calculate distance between two positions in meters.\n * \n * This is the correct way to calculate distance - always in meters,\n * never in pixels.\n * \n * **Korean**: 거리계산 (Distance Calculation)\n * \n * @param pos1 - First position in meters\n * @param pos2 - Second position in meters\n * @returns Distance in meters\n * @throws Error if either position is invalid\n * \n * @public\n * @category Physics Types\n */\nexport function calculateDistanceMeters(\n pos1: Position3D | THREE.Vector3,\n pos2: Position3D | THREE.Vector3\n): number {\n if (!isValidPosition(pos1) || !isValidPosition(pos2)) {\n throw new Error(\n \"Invalid positions for distance calculation: both positions must be valid Vector3 or Position3D objects\"\n );\n }\n \n const dx = pos2.x - pos1.x;\n const dy = pos2.y - pos1.y;\n const dz = pos2.z - pos1.z;\n \n return Math.sqrt(dx * dx + dy * dy + dz * dz);\n}\n\n/**\n * Movement-specific arena bounds in world coordinates (meters).\n * \n * Defines the playable area boundaries for player/AI movement.\n * All arenas are centered at origin (0, 0) and extend symmetrically.\n * \n * **Korean**: 이동 경기장 경계 (Movement Arena Bounds)\n * \n * @remarks\n * This is distinct from `ArenaBounds` interfaces in layout/test code\n * which include pixel-based screen coordinates. MovementArenaBounds\n * only contains world-space meter coordinates for physics calculations.\n * \n * @public\n * @category Physics Types\n */\nexport interface MovementArenaBounds {\n /** Minimum X position in meters (left edge) */\n readonly minX: number;\n /** Maximum X position in meters (right edge) */\n readonly maxX: number;\n /** Minimum Z position in meters (back edge) */\n readonly minZ: number;\n /** Maximum Z position in meters (front edge) */\n readonly maxZ: number;\n /** Arena center X in meters (typically 0) */\n readonly centerX: number;\n /** Arena center Z in meters (typically 0) */\n readonly centerZ: number;\n /** Arena width in meters */\n readonly widthMeters: number;\n /** Arena depth in meters */\n readonly depthMeters: number;\n}\n\n/**\n * Calculate arena bounds from arena configuration.\n * \n * Creates bounds with a margin to account for character radius,\n * preventing characters from walking through edges.\n * \n * **Korean**: 경기장 경계 계산 (Calculate Arena Bounds)\n * \n * @param bounds - Arena configuration with meter dimensions (can be partial with just worldWidthMeters/worldDepthMeters)\n * @param margin - Character radius/margin in meters (default: 0.3m - half character width)\n * @returns Arena bounds for physics calculations\n * @throws Error if dimensions are invalid (non-positive or non-finite) or margin is invalid\n * \n * @example\n * ```typescript\n * const config = { worldWidthMeters: 10, worldDepthMeters: 7.5 };\n * const arenaBounds = calculateArenaBounds(config, 0.3);\n * // Result: { minX: -4.7, maxX: 4.7, minZ: -3.45, maxZ: 3.45, ... }\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function calculateArenaBounds(\n bounds: Pick<PhysicsArenaBounds, 'worldWidthMeters' | 'worldDepthMeters'>,\n margin: number = 0.3\n): MovementArenaBounds {\n // Validate arena dimensions\n if (!Number.isFinite(bounds.worldWidthMeters) || bounds.worldWidthMeters <= 0) {\n throw new Error(\n `worldWidthMeters must be a positive finite number, got: ${bounds.worldWidthMeters}`\n );\n }\n if (!Number.isFinite(bounds.worldDepthMeters) || bounds.worldDepthMeters <= 0) {\n throw new Error(\n `worldDepthMeters must be a positive finite number, got: ${bounds.worldDepthMeters}`\n );\n }\n \n // Validate margin\n if (!Number.isFinite(margin) || margin < 0) {\n throw new Error(\n `margin must be a non-negative finite number, got: ${margin}`\n );\n }\n \n const halfWidth = bounds.worldWidthMeters / 2;\n const halfDepth = bounds.worldDepthMeters / 2;\n \n // Validate margin is not larger than arena dimensions\n if (margin >= halfWidth) {\n throw new Error(\n `margin (${margin}m) must be less than half the arena width (${halfWidth}m)`\n );\n }\n if (margin >= halfDepth) {\n throw new Error(\n `margin (${margin}m) must be less than half the arena depth (${halfDepth}m)`\n );\n }\n \n return {\n minX: -halfWidth + margin,\n maxX: halfWidth - margin,\n minZ: -halfDepth + margin,\n maxZ: halfDepth - margin,\n centerX: 0,\n centerZ: 0,\n widthMeters: bounds.worldWidthMeters,\n depthMeters: bounds.worldDepthMeters,\n };\n}\n\n/**\n * Clamp a 3D position to stay within arena boundaries.\n * \n * Only clamps X and Z axes (horizontal plane). Y axis (height) is unchanged.\n * Arena is centered at origin with bounds extending ±width/2 and ±depth/2.\n * \n * **Korean**: 위치를 경기장 경계로 제한 (Clamp Position To Bounds)\n * \n * @param position - 3D position in meters (THREE.Vector3 or Position3D)\n * @param bounds - Arena bounds with min/max values\n * @returns Clamped position as new THREE.Vector3\n * \n * @example\n * ```typescript\n * const position = new THREE.Vector3(6, 0, 4); // Outside bounds\n * const bounds = calculateArenaBounds(config);\n * const clamped = clampPositionToBounds(position, bounds);\n * // Result: Vector3(4.7, 0, 3.45) - clamped to edges\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function clampPositionToBounds(\n position: THREE.Vector3 | Position3D,\n bounds: MovementArenaBounds\n): THREE.Vector3 {\n return new THREE.Vector3(\n Math.max(bounds.minX, Math.min(bounds.maxX, position.x)),\n position.y, // Y is height, not bounds-checked\n Math.max(bounds.minZ, Math.min(bounds.maxZ, position.z))\n );\n}\n\n/**\n * Check if a position is within arena boundaries.\n * \n * Only checks X and Z axes (horizontal plane). Y axis (height) is ignored.\n * \n * For 2D positions, accepts `{ x, y }` where `y` maps to world Z (depth),\n * consistent with `clampToArenaBounds` and other 2D arena position APIs.\n * \n * **Korean**: 경기장 경계 내 위치 확인 (Check Position In Bounds)\n * \n * @param position - Position to check (2D {x,y} where y=depth, or 3D Vector3/Position3D)\n * @param bounds - Arena bounds\n * @returns True if position is within bounds\n * \n * @example\n * ```typescript\n * // 2D position (y maps to Z/depth)\n * const position = { x: 5, y: 2 };\n * const bounds = calculateArenaBounds(config);\n * const inBounds = isPositionInBounds(position, bounds);\n * \n * // 3D position (uses z directly)\n * const position3D = new THREE.Vector3(5, 1.8, 2);\n * const inBounds3D = isPositionInBounds(position3D, bounds);\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function isPositionInBounds(\n position: { x: number; y: number } | THREE.Vector3 | Position3D,\n bounds: MovementArenaBounds\n): boolean {\n const x = position.x;\n // For 2D positions {x,y}, y maps to world Z (depth)\n // For 3D positions, use z directly\n const z = 'z' in position ? position.z : position.y;\n \n return (\n x >= bounds.minX &&\n x <= bounds.maxX &&\n z >= bounds.minZ &&\n z <= bounds.maxZ\n );\n}\n\n/**\n * Clamp a 2D position to stay within arena boundaries in meters.\n * \n * This function works in a projected 2D arena space where:\n * - `position.x` corresponds to world **X** (horizontal)\n * - `position.y` corresponds to world **Z** (depth)\n * \n * Arena coordinates are centered at origin (0, 0) and extend from\n * -worldWidthMeters/2 to +worldWidthMeters/2 in X (position.x),\n * -worldDepthMeters/2 to +worldDepthMeters/2 in Z/depth (position.y).\n * \n * This is used for physics calculations like knockback to ensure\n * players stay within the playable area.\n * \n * @param position - 2D projected position in meters (X, depth-as-Y), which may exceed arena bounds\n * @param bounds - Arena bounds with meter dimensions\n * @returns Position clamped to arena boundaries in the same 2D projection\n * \n * @example\n * ```typescript\n * const bounds = { worldWidthMeters: 10, worldDepthMeters: 7.5, ... };\n * const position = { x: 6, y: 4 }; // Outside arena in X/Z-projected space\n * const clamped = clampToArenaBounds(position, bounds);\n * // Result: { x: 5, y: 3.75 } - clamped to boundaries\n * ```\n * \n * @public\n * @category Physics Types\n */\nexport function clampToArenaBounds(\n position: { x: number; y: number },\n bounds: PhysicsArenaBounds\n): { x: number; y: number } {\n const halfWidth = bounds.worldWidthMeters / 2;\n const halfDepth = bounds.worldDepthMeters / 2;\n \n return {\n x: Math.max(-halfWidth, Math.min(halfWidth, position.x)),\n y: Math.max(-halfDepth, Math.min(halfDepth, position.y)),\n };\n}\n"],"mappings":"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"}
|
package/lib/types/common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../../src/types/common.ts"],"sourcesContent":["/**\n * Common utility types for Korean martial arts game.\n *\n * This module provides foundational types used throughout the Black Trigram (흑괘) game,\n * including geometric types, Korean text support, and utility type helpers.\n *\n * @module types/common\n * @category Type Definitions\n * @korean 공통타입\n */\n\n/**\n * Represents a position in 2D space.\n *\n * **Unit Handling**: The coordinate units depend on the system using this type:\n * - **Combat System**: Coordinates are in **meters** (physics-first architecture)\n * - **Rendering System**: Coordinates are in **pixels** (screen rendering)\n * - **Legacy Systems**: May use pixels or other units\n *\n * When working with combat/physics, positions are in meters relative to arena center (0, 0).\n * Arena boundaries extend from ±worldWidthMeters/2 in X and ±worldDepthMeters/2 in Z (mapped to y).\n *\n * @example\n * ```typescript\n * // Combat position (meters, centered at origin)\n * const playerPos: Position = { x: 2.5, y: -1.0 }; // 2.5m right, 1m back from center\n *\n * // Rendering position (pixels, top-left origin)\n * const screenPos: Position = { x: 640, y: 480 }; // 640px right, 480px down\n * ```\n *\n * @public\n * @category Core Types\n */\nexport interface Position {\n /** X coordinate (meters in combat, pixels in rendering) */\n x: number;\n /** Y coordinate (meters in combat, pixels in rendering) */\n y: number;\n}\n\n/**\n * Represents size dimensions for game objects.\n *\n * @public\n * @category Core Types\n */\nexport interface Size {\n /** Width in pixels */\n readonly width: number;\n /** Height in pixels */\n readonly height: number;\n}\n\n/**\n * Represents rectangle bounds combining position and size.\n *\n * @public\n * @category Core Types\n */\nexport interface Bounds extends Position, Size {}\n\n/**\n * Color represented as a hexadecimal number (e.g., 0xFF0000 for red).\n *\n * @example\n * ```typescript\n * const primaryCyan: Color = 0x00FFFF;\n * const accentGold: Color = 0xFFAA00;\n * ```\n *\n * @public\n * @category Core Types\n */\nexport type Color = number;\n\n/**\n * Time duration in milliseconds.\n *\n * @public\n * @category Core Types\n */\nexport type Duration = number;\n\n/**\n * Percentage value represented as a decimal (0.0 to 1.0).\n *\n * @example\n * ```typescript\n * const halfHealth: Percentage = 0.5;\n * const fullAccuracy: Percentage = 1.0;\n * ```\n *\n * @public\n * @category Core Types\n */\nexport type Percentage = number;\n\n/**\n * Unique identifier string.\n *\n * @public\n * @category Core Types\n */\nexport type ID = string;\n\n/**\n * Generic callback function type.\n *\n * @typeParam T - Return type of the callback, defaults to void\n *\n * @public\n * @category Core Types\n */\nexport type Callback<T = void> = () => T;\n\n/**\n * Event handler function type.\n *\n * @typeParam T - Type of event data, defaults to any\n *\n * @public\n * @category Core Types\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic default allows flexible event handling\nexport type EventHandler<T = any> = (event: T) => void;\n\n/**\n * Utility type to make specific properties optional.\n *\n * @typeParam T - The base type\n * @typeParam K - Keys of T to make optional\n *\n * @public\n * @category Utility Types\n */\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\n/**\n * Utility type to make specific properties required.\n *\n * @typeParam T - The base type\n * @typeParam K - Keys of T to make required\n *\n * @public\n * @category Utility Types\n */\nexport type Required<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\n/**\n * Utility type to make all properties deeply readonly.\n *\n * @typeParam T - The type to make deeply readonly\n *\n * @public\n * @category Utility Types\n */\nexport type DeepReadonly<T> = {\n readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];\n};\n\n/**\n * Represents bilingual Korean-English text content.\n *\n * Used throughout the game to provide authentic Korean terminology with English translations,\n * supporting the cultural authenticity of the Korean martial arts theme.\n *\n * @example\n * ```typescript\n * const techniqueName: KoreanText = {\n * korean: \"천둥벽력\",\n * english: \"Thunder Strike\",\n * romanized: \"cheondu byeokryeok\"\n * };\n * ```\n *\n * @public\n * @category Korean Martial Arts\n * @korean 한글텍스트\n */\nexport interface KoreanText {\n /** Korean text in Hangul */\n readonly korean: string;\n /** English translation */\n readonly english: string;\n /** Optional romanized Korean pronunciation */\n readonly romanized?: string;\n}\n\n/**\n * Base entity interface with Korean naming support.\n *\n * Provides a foundation for game entities with bilingual identification.\n *\n * @public\n * @category Korean Martial Arts\n * @korean 한글개체\n */\nexport interface KoreanEntity {\n /** Unique identifier */\n readonly id: ID;\n /** Bilingual name */\n readonly name: KoreanText;\n /** Optional bilingual description */\n readonly description?: KoreanText;\n}\n\n/**\n * Font sizes for Korean text rendering.\n *\n * Provides consistent typography sizing across the game interface.\n *\n * @public\n * @category UI\n * @korean 글자크기\n */\nexport enum KoreanTextSize {\n /** Extra small: 10px */\n XSMALL = \"xsmall\",\n /** Tiny: 12px */\n TINY = \"tiny\",\n /** Small: 14px */\n SMALL = \"small\",\n /** Medium: 16px */\n MEDIUM = \"medium\",\n /** Large: 18px */\n LARGE = \"large\",\n /** Extra large: 20px */\n XLARGE = \"xlarge\",\n /** Double extra large: 24px */\n XXLARGE = \"xxlarge\",\n /** Huge: 32px */\n HUGE = \"huge\",\n /** Title: 48px */\n TITLE = \"title\",\n}\n\n/**\n * Font weights for Korean text rendering.\n *\n * Provides consistent typography weights for Korean Hangul characters.\n *\n * @public\n * @category UI\n * @korean 글자무게\n */\nexport enum KoreanTextWeight {\n /** Light weight: 300 */\n LIGHT = \"light\",\n /** Normal weight: 400 */\n NORMAL = \"normal\",\n /** Regular weight: 400 (alias for NORMAL) */\n REGULAR = \"regular\",\n /** Medium weight: 500 */\n MEDIUM = \"medium\",\n /** Semi-bold weight: 600 */\n SEMIBOLD = \"semibold\",\n /** Bold weight: 700 */\n BOLD = \"bold\",\n /** Heavy weight: 900 */\n HEAVY = \"heavy\",\n}\n\n/**\n * Text alignment options for Korean text.\n *\n * @public\n * @category UI\n */\nexport type KoreanTextAlignment = \"left\" | \"center\" | \"right\";\n\n/**\n * Styling configuration for Korean text rendering.\n *\n * @public\n * @category UI\n * @korean 글자스타일\n */\nexport interface KoreanTextStyle {\n /** Text size */\n readonly size: KoreanTextSize;\n /** Font weight */\n readonly weight: KoreanTextWeight;\n /** Text color as hex number */\n readonly color: number;\n /** Horizontal alignment */\n readonly alignment: KoreanTextAlignment;\n}\n\n/**\n * Represents a range of damage values for combat calculations.\n *\n * Used for techniques and vital point strikes to define variable damage output.\n *\n * @public\n * @category Combat\n * @korean 피해범위\n */\nexport interface DamageRange {\n /** Minimum damage value */\n readonly min: number;\n /** Maximum damage value */\n readonly max: number;\n /** Type of damage dealt */\n readonly type?: DamageType;\n /** Pre-calculated average damage */\n readonly average?: number;\n}\n\n/**\n * Game settings configuration interface for UI controls.\n *\n * Manages volume, graphics quality, control schemes, and language preferences.\n *\n * @public\n * @category UI\n * @korean 게임설정\n */\nexport interface UIGameSettings {\n /** Audio volume settings */\n readonly volume: {\n /** Master volume (0.0 - 1.0) */\n readonly master: number;\n /** Music volume (0.0 - 1.0) */\n readonly music: number;\n /** Sound effects volume (0.0 - 1.0) */\n readonly sfx: number;\n };\n /** Graphics settings */\n readonly graphics: {\n /** Graphics quality preset */\n readonly quality: \"low\" | \"medium\" | \"high\";\n /** Fullscreen mode enabled */\n readonly fullscreen: boolean;\n /** Vertical sync enabled */\n readonly vsync: boolean;\n };\n /** Control settings */\n readonly controls: {\n /** Keyboard layout preference */\n readonly keyboardLayout: \"qwerty\" | \"dvorak\" | \"colemak\";\n /** Mouse sensitivity multiplier */\n readonly mouseSensitivity: number;\n };\n /** Language preference */\n readonly language: \"korean\" | \"english\" | \"both\";\n}\n\n/**\n * Duration tracking for status effects.\n *\n * Tracks when an effect started, when it ends, and its total duration.\n *\n * @public\n * @category Combat\n * @korean 효과지속시간\n */\nexport interface EffectDuration {\n /** Effect start timestamp (milliseconds) */\n readonly startTime: number;\n /** Effect end timestamp (milliseconds) */\n readonly endTime: number;\n /** Total duration (milliseconds) */\n readonly duration: number;\n}\n\n/**\n * Generic game entity with positioning and visibility.\n *\n * Extends {@link KoreanEntity} with spatial and state properties.\n *\n * @public\n * @category Core Types\n * @korean 게임개체\n */\nexport interface GameEntity extends KoreanEntity {\n /** Position in game world */\n readonly position?: Position;\n /** Size dimensions */\n readonly size?: Size;\n /** Whether entity is active */\n readonly active?: boolean;\n /** Whether entity is visible */\n readonly visible?: boolean;\n}\n\n/**\n * Animation transition configuration.\n *\n * Defines how to transition between two states with timing and easing.\n *\n * @public\n * @category UI\n * @korean 전환\n */\nexport interface Transition {\n /** Starting state identifier */\n readonly from: string;\n /** Target state identifier */\n readonly to: string;\n /** Transition duration in milliseconds */\n readonly duration: Duration;\n /** Optional easing function name */\n readonly easing?: string;\n}\n\n/**\n * Theme color configuration.\n *\n * Defines primary colors used throughout the game UI.\n *\n * @public\n * @category UI\n * @korean 테마\n */\nexport interface Theme {\n /** Primary color */\n readonly primary: Color;\n /** Secondary color */\n readonly secondary: Color;\n /** Accent color */\n readonly accent?: Color;\n /** Background color */\n readonly background?: Color;\n /** Text color */\n readonly text?: Color;\n}\n\n/**\n * Generic configuration object.\n *\n * @public\n * @category Core Types\n */\nexport interface Config {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Config values can be of various types\n readonly [key: string]: any;\n}\n\n/**\n * Generic result wrapper for operations that may succeed or fail.\n *\n * @typeParam T - Type of successful result data\n * @typeParam E - Type of error, defaults to Error\n *\n * @example\n * ```typescript\n * const result: Result<PlayerState> = {\n * success: true,\n * data: playerState\n * };\n * ```\n *\n * @public\n * @category Core Types\n */\nexport interface Result<T, E = Error> {\n /** Whether operation succeeded */\n readonly success: boolean;\n /** Result data if successful */\n readonly data?: T;\n /** Error if operation failed */\n readonly error?: E;\n /** Optional message */\n readonly message?: string;\n}\n\n/**\n * Validation result with errors and warnings.\n *\n * @public\n * @category Core Types\n */\nexport interface ValidationResult {\n /** Whether validation passed */\n readonly valid: boolean;\n /** List of validation errors */\n readonly errors: readonly string[];\n /** Optional list of warnings */\n readonly warnings?: readonly string[];\n}\n\n/**\n * Game modes available in Black Trigram.\n *\n * Each mode offers different gameplay experiences and training opportunities.\n *\n * @public\n * @category Game Systems\n * @korean 게임모드\n */\nexport enum GameMode {\n /** Versus mode: Player vs AI or Player vs Player */\n VERSUS = \"versus\",\n /** Training mode: Practice techniques against training dummy */\n TRAINING = \"training\",\n /** Tutorial mode: Learn game mechanics and controls */\n TUTORIAL = \"tutorial\",\n /** Practice mode: Free form combat practice */\n PRACTICE = \"practice\",\n /** Story mode: Campaign with narrative */\n STORY = \"story\",\n /** Arcade mode: Progressive difficulty challenges */\n ARCADE = \"arcade\",\n /** Controls screen: View and customize controls */\n CONTROLS = \"controls\",\n /** Philosophy screen: Learn about Korean martial arts philosophy */\n PHILOSOPHY = \"philosophy\",\n}\n\n/**\n * Game phases representing the current state of the game.\n *\n * Controls which screen is displayed and what game logic is active.\n *\n * @public\n * @category Game Systems\n * @korean 게임단계\n */\nexport enum GamePhase {\n /** Intro/splash screen */\n INTRO = \"intro\",\n /** Main menu */\n MENU = \"menu\",\n /** Character selection screen */\n CHARACTER_SELECT = \"character_select\",\n /** Active combat */\n COMBAT = \"combat\",\n /** Training mode */\n TRAINING = \"training\",\n /** Victory screen */\n VICTORY = \"victory\",\n /** Defeat screen */\n DEFEAT = \"defeat\",\n /** Game paused */\n PAUSED = \"paused\",\n /** Game over screen */\n GAME_OVER = \"game_over\",\n /** Loading screen */\n LOADING = \"loading\",\n}\n\n/**\n * Player archetypes representing Korean martial arts combat specialists.\n *\n * **Korean**: 플레이어 원형 (Player Archetypes)\n *\n * Each archetype has unique combat styles, favored stances, and philosophical approaches\n * rooted in Korean martial arts traditions and modern cyberpunk adaptation.\n *\n * @example\n * ```typescript\n * const player = createPlayer({\n * archetype: PlayerArchetype.MUSA,\n * name: { korean: \"이순신\", english: \"Yi Sun-sin\" }\n * });\n * ```\n *\n * @public\n * @category Player & Archetypes\n * @korean 플레이어원형\n */\nexport enum PlayerArchetype {\n /**\n * 무사 (Musa) - Traditional Warrior\n *\n * Honor-bound martial artist following traditional Korean warrior codes.\n * Favors direct confrontation and disciplined techniques.\n */\n MUSA = \"musa\",\n\n /**\n * 암살자 (Amsalja) - Shadow Assassin\n *\n * Precision striker focused on vital point targeting and silent elimination.\n * Specializes in nerve strikes and pressure point techniques.\n */\n AMSALJA = \"amsalja\",\n\n /**\n * 해커 (Hacker) - Cyber Warrior\n *\n * Technology-enhanced combatant blending modern cybernetics with traditional techniques.\n * Uses augmented reflexes and data-driven combat analysis.\n */\n HACKER = \"hacker\",\n\n /**\n * 정보요원 (Jeongbo Yowon) - Intelligence Operative\n *\n * Strategic analyst who uses combat intelligence and tactical advantage.\n * Excels at reading opponent patterns and exploiting weaknesses.\n */\n JEONGBO_YOWON = \"jeongbo_yowon\",\n\n /**\n * 조직폭력배 (Jojik Pokryeokbae) - Organized Crime\n *\n * Ruthless pragmatist who ignores traditional honor codes.\n * Uses brutal, efficient techniques with no concern for ethics.\n */\n JOJIK_POKRYEOKBAE = \"jojik_pokryeokbae\",\n}\n\n/**\n * Physical attributes representing realistic body dimensions and composition.\n *\n * **Korean**: 신체 속성 (Body Attributes)\n *\n * These attributes affect combat calculations including reach, movement speed,\n * damage output, defense capability, and stamina. Based on realistic human\n * physiology and Korean martial arts biomechanics.\n *\n * ## Combat Impact\n *\n * - **Weight**: Affects movement speed, knockback resistance, and throw effectiveness\n * - **Leg Length**: Determines kick range and movement speed base\n * - **Arm Length**: Determines punch/strike range and grappling reach\n * - **Muscle Mass**: Affects base damage output and stamina pool\n * - **Fat Mass**: Affects defense absorption and stamina drain rate\n * - **Age**: Affects stamina recovery speed and Ki regeneration\n *\n * @example\n * ```typescript\n * const musaPhysical: PhysicalAttributes = {\n * weight: 75, // kg - balanced warrior\n * legLength: 95, // cm - average leg reach\n * armLength: 75, // cm - average arm reach\n * muscleMass: 38, // kg - high muscle for power\n * fatMass: 12, // kg - low fat for mobility\n * age: 32, // years - prime combat age\n * };\n * ```\n *\n * @public\n * @category Player & Archetypes\n * @korean 신체속성\n */\nexport interface PhysicalAttributes {\n /**\n * Body weight in kilograms.\n *\n * **Korean**: 체중 (Body Weight)\n *\n * Typical Range: 55-95 kg for combatants\n * - Affects movement speed (inversely)\n * - Affects knockback resistance (positively)\n * - Affects throw effectiveness (positively)\n * - Affects ground control (positively)\n */\n readonly weight: number;\n\n /**\n * Leg length in centimeters (hip to ankle).\n *\n * **Korean**: 다리 길이 (Leg Length)\n *\n * Typical Range: 85-105 cm\n * - Determines kick technique maximum range\n * - Affects base movement speed\n * - Affects sweep technique effectiveness\n * - Affects jumping attack height\n */\n readonly legLength: number;\n\n /**\n * Arm length in centimeters (shoulder to wrist).\n *\n * **Korean**: 팔 길이 (Arm Length)\n *\n * Typical Range: 65-85 cm\n * - Determines punch/strike technique range\n * - Affects grappling and throw range\n * - Affects block coverage area\n * - Affects elbow strike effectiveness\n */\n readonly armLength: number;\n\n /**\n * Muscle mass in kilograms.\n *\n * **Korean**: 근육량 (Muscle Mass)\n *\n * Typical Range: 25-45 kg\n * - Affects base damage output (positively)\n * - Affects maximum stamina pool (positively)\n * - Affects grappling and throw power\n * - Affects movement acceleration\n */\n readonly muscleMass: number;\n\n /**\n * Fat mass in kilograms.\n *\n * **Korean**: 지방량 (Fat Mass)\n *\n * Typical Range: 8-20 kg for combatants\n * - Affects blunt damage absorption (positively)\n * - Affects stamina drain rate (negatively)\n * - Affects movement speed (negatively)\n * - Affects recovery time between actions\n */\n readonly fatMass: number;\n\n /**\n * Age in years.\n *\n * **Korean**: 나이 (Age)\n *\n * Typical Range: 22-45 years for peak combatants\n * - Affects stamina recovery speed (optimal 25-35)\n * - Affects Ki regeneration rate (wisdom with age)\n * - Affects injury recovery time (slower with age)\n * - Affects technique execution speed (prime 28-35)\n */\n readonly age: number;\n\n /**\n * Total body height in centimeters.\n *\n * **Korean**: 키 (Height)\n *\n * Typical Range: 160-195 cm\n * - Scales entire skeleton proportionally\n * - Affects reach calculations (combined with limb ratios)\n * - Affects center of gravity positioning\n * - Determines visual body model scaling\n * - Influences balance and stability in stances\n */\n readonly totalHeight: number;\n\n /**\n * Torso length in centimeters (pelvis to shoulders).\n *\n * **Korean**: 몸통 길이 (Torso Length)\n *\n * Typical Range: 50-65 cm\n * - Affects core hitbox size and vital point positioning\n * - Influences breath control and stamina capacity\n * - Affects spinal rotation range in techniques\n * - Determines torso vital point target area\n * - Impacts center of mass calculations\n */\n readonly torsoLength: number;\n\n /**\n * Head size (diameter) in centimeters.\n *\n * **Korean**: 머리 크기 (Head Size)\n *\n * Typical Range: 20-24 cm\n * - Affects head vital point targeting precision\n * - Determines head hitbox size for strikes\n * - Influences helmet/headgear fit (if applicable)\n * - Affects visual skull scaling in 3D model\n * - Impacts consciousness vulnerability to head trauma\n */\n readonly headSize: number;\n\n /**\n * Neck length in centimeters (skull base to shoulders).\n *\n * **Korean**: 목 길이 (Neck Length)\n *\n * Typical Range: 8-12 cm\n * - Affects vulnerability to chokes and strangles\n * - Determines neck vital point target area\n * - Influences blood choke effectiveness\n * - Affects guillotine and rear naked choke mechanics\n * - Impacts head mobility and evasion capability\n */\n readonly neckLength: number;\n\n /**\n * Shoulder width in centimeters (shoulder to shoulder).\n *\n * **Korean**: 어깨 너비 (Shoulder Width)\n *\n * Typical Range: 38-48 cm\n * - Affects defense coverage area (blocking)\n * - Determines upper body strike zone width\n * - Influences grappling control positions\n * - Affects visual upper body model scaling\n * - Impacts balance and stability in wide stances\n */\n readonly shoulderWidth: number;\n\n /**\n * Base walking speed in meters per second.\n *\n * **Korean**: 걷기 속도 (Walk Speed)\n *\n * Typical Range: 5.0-6.5 m/s for combat movement\n * - Determines tactical repositioning speed\n * - Affected by weight and leg length\n * - Base speed for defensive movement\n * - Modified by stance and combat state\n */\n readonly walkSpeed: number;\n\n /**\n * Base running speed in meters per second.\n *\n * **Korean**: 달리기 속도 (Run Speed)\n *\n * Typical Range: 8.0-11.0 m/s for sprint movement\n * - Determines rapid repositioning speed\n * - Affected by muscle mass and conditioning\n * - Base speed for aggressive approach\n * - Consumes stamina during use\n */\n readonly runSpeed: number;\n\n /**\n * Base acceleration in meters per second squared.\n *\n * **Korean**: 가속도 (Acceleration)\n *\n * Typical Range: 9.0-15.0 m/s² for combat movement\n * - Determines how quickly fighter reaches max speed\n * - Based on muscle-to-weight ratio (explosiveness)\n * - Higher = more explosive starts and direction changes\n * - Affects combat responsiveness and evasion\n */\n readonly acceleration: number;\n}\n\n/**\n * Eight Trigram stances (팔괘) representing fundamental combat principles.\n *\n * **Korean**: 팔괘 자세 (Eight Trigram Stances)\n * **Origin**: I Ching (易經 / Yijing) divination system adapted for Korean martial arts\n *\n * The Eight Trigrams (Bagua / 八卦) form the foundation of the combat system.\n * Each trigram represents a natural element and combat philosophy, influencing\n * available techniques, movement patterns, and strategic advantages.\n *\n * ## Trigram Philosophy\n *\n * - **☰ 건 (Geon)** - Heaven: Yang energy, direct aggression, overwhelming force\n * - **☱ 태 (Tae)** - Lake: Joy and fluidity, joint locks and flow techniques\n * - **☲ 리 (Li)** - Fire: Precision and speed, nerve strikes and rapid attacks\n * - **☳ 진 (Jin)** - Thunder: Explosive power, shocking techniques\n * - **☴ 손 (Son)** - Wind: Continuous pressure, evasion and mobility\n * - **☵ 감 (Gam)** - Water: Adaptive flow, counters and redirection\n * - **☶ 간 (Gan)** - Mountain: Immovable defense, endurance and patience\n * - **☷ 곤 (Gon)** - Earth: Grounding techniques, takedowns and throws\n *\n * @example\n * ```typescript\n * // Change to Heaven stance for aggressive attack\n * player.currentStance = TrigramStance.GEON;\n *\n * // Execute heaven-aligned technique\n * const technique = getTrigramTechniques(TrigramStance.GEON)[0];\n * executeTechnique(player, opponent, technique);\n * ```\n *\n * @see {@link https://en.wikipedia.org/wiki/Bagua | Bagua (Eight Trigrams) - Wikipedia}\n * @see {@link https://en.wikipedia.org/wiki/I_Ching | I Ching - Wikipedia}\n *\n * @public\n * @category Trigram System\n * @category Korean Martial Arts\n * @korean 팔괘\n */\nexport enum TrigramStance {\n /**\n * ☰ 건 (Geon) - Heaven Stance\n *\n * **Element**: Heaven / Sky (天)\n * **Nature**: Yang, creative, strong\n * **Combat Style**: Direct force, aggressive techniques, overwhelming power\n * **Philosophy**: \"The creative principle - pure yang energy that drives forward\"\n *\n * Techniques emphasize straight attacks, powerful strikes, and dominant positioning.\n */\n GEON = \"geon\",\n\n /**\n * ☱ 태 (Tae) - Lake Stance\n *\n * **Element**: Lake / Marsh (澤)\n * **Nature**: Yin exterior, Yang interior - joyful movement\n * **Combat Style**: Fluid joint manipulation, flowing techniques, adaptable responses\n * **Philosophy**: \"The joyful - water above earth, freedom of movement\"\n *\n * Techniques focus on joint locks, throws, and using opponent's momentum.\n */\n TAE = \"tae\",\n\n /**\n * ☲ 리 (Li) - Fire Stance\n *\n * **Element**: Fire / Flame (火)\n * **Nature**: Yang exterior, Yin interior - bright and precise\n * **Combat Style**: Precise nerve strikes, rapid attacks, speed techniques\n * **Philosophy**: \"The clinging - illuminating and consuming\"\n *\n * Techniques emphasize vital point targeting, quick combinations, and precision.\n */\n LI = \"li\",\n\n /**\n * ☳ 진 (Jin) - Thunder Stance\n *\n * **Element**: Thunder / Arousing (雷)\n * **Nature**: Yang moving, sudden and shocking\n * **Combat Style**: Explosive power, shocking techniques, sudden movements\n * **Philosophy**: \"The arousing - thunder brings shock and awakening\"\n *\n * Techniques feature explosive bursts, stunning strikes, and overwhelming force.\n */\n JIN = \"jin\",\n\n /**\n * ☴ 손 (Son) - Wind Stance\n *\n * **Element**: Wind / Wood (風)\n * **Nature**: Yin, gentle but penetrating\n * **Combat Style**: Continuous pressure, evasion techniques, mobility\n * **Philosophy**: \"The gentle - penetrating like wind, persistent like wood\"\n *\n * Techniques emphasize movement, pressure point chains, and wearing down opponents.\n */\n SON = \"son\",\n\n /**\n * ☵ 감 (Gam) - Water Stance\n *\n * **Element**: Water / Abyss (水)\n * **Nature**: Yang surrounded by Yin - dangerous depths\n * **Combat Style**: Flow and adaptation, counter techniques, redirection\n * **Philosophy**: \"The abysmal - water flows around obstacles and fills voids\"\n *\n * Techniques focus on counters, deflections, and adaptive responses.\n */\n GAM = \"gam\",\n\n /**\n * ☶ 간 (Gan) - Mountain Stance\n *\n * **Element**: Mountain / Stillness (山)\n * **Nature**: Yang above Yin - firm and unyielding\n * **Combat Style**: Defensive mastery, immovable stance, endurance\n * **Philosophy**: \"The keeping still - mountains are firm and unmoving\"\n *\n * Techniques emphasize blocks, parries, and defensive positioning.\n */\n GAN = \"gan\",\n\n /**\n * ☷ 곤 (Gon) - Earth Stance\n *\n * **Element**: Earth / Receptive (地)\n * **Nature**: Pure Yin - receptive and yielding\n * **Combat Style**: Grounding techniques, takedowns, throws\n * **Philosophy**: \"The receptive - earth receives and supports all\"\n *\n * Techniques focus on sweeps, trips, takedowns, and ground control.\n */\n GON = \"gon\",\n}\n\n/**\n * Combat attack types available in the game.\n *\n * Defines the mechanical type of attack being performed, which affects\n * damage calculation, vital point targeting, and defensive options.\n *\n * @public\n * @category Combat System\n * @korean 공격타입\n */\nexport enum CombatAttackType {\n /** Standard striking attack */\n STRIKE = \"strike\",\n /** Thrusting attack with focused force */\n THRUST = \"thrust\",\n /** Defensive blocking action */\n BLOCK = \"block\",\n /** Counter-attack performed after successful defense */\n COUNTER_ATTACK = \"counter_attack\",\n /** Throwing technique to off-balance opponent */\n THROW = \"throw\",\n /** Grappling and joint control technique */\n GRAPPLE = \"grapple\",\n /** Precise pressure point strike */\n PRESSURE_POINT = \"pressure_point\",\n /** Nerve disruption strike */\n NERVE_STRIKE = \"nerve_strike\",\n /** Closed fist punch */\n PUNCH = \"punch\",\n /** Leg kick attack */\n KICK = \"kick\",\n /** Elbow strike */\n ELBOW = \"elbow\",\n /** Knee strike */\n KNEE = \"knee\",\n}\n\n/**\n * Damage types representing different methods of inflicting harm.\n *\n * Each damage type interacts differently with vital points and defensive techniques.\n * Some types are more effective against specific body regions or defense styles.\n *\n * @public\n * @category Combat System\n * @korean 피해타입\n */\nexport enum DamageType {\n /** Blunt force trauma */\n BLUNT = \"blunt\",\n /** Piercing damage penetrating tissue */\n PIERCING = \"piercing\",\n /** Slashing cuts */\n SLASHING = \"slashing\",\n /** Pressure point manipulation */\n PRESSURE = \"pressure\",\n /** Nerve disruption */\n NERVE = \"nerve\",\n /** Joint manipulation and locks */\n JOINT = \"joint\",\n /** Internal organ damage */\n INTERNAL = \"internal\",\n /** Impact shock */\n IMPACT = \"impact\",\n /** Crushing force */\n CRUSHING = \"crushing\",\n /** Sharp edge damage */\n SHARP = \"sharp\",\n /** Electric shock */\n ELECTRIC = \"electric\",\n /** Fire/heat damage */\n FIRE = \"fire\",\n /** Cold/freeze damage */\n ICE = \"ice\",\n /** Poison/toxin damage */\n POISON = \"poison\",\n /** Psychic/mental damage */\n PSYCHIC = \"psychic\",\n /** Blood loss damage */\n BLOOD = \"blood\",\n}\n\n/**\n * Vital point categories representing anatomical targeting systems.\n *\n * **Korean**: 급소 범주 (Vital Point Categories)\n *\n * The game features 70 Korean vital points (급소) based on traditional martial arts\n * knowledge and modern anatomical understanding. Each category represents different\n * physiological systems that can be targeted for combat effectiveness.\n *\n * @example\n * ```typescript\n * const vitalPoint: VitalPoint = {\n * id: \"GB-20\",\n * category: VitalPointCategory.NEUROLOGICAL,\n * severity: VitalPointSeverity.CRITICAL,\n * name: { korean: \"풍지\", english: \"Wind Pool\" }\n * };\n * ```\n *\n * @public\n * @category Vital Point System\n * @korean 급소범주\n */\nexport enum VitalPointCategory {\n /** Neurological system - nerve clusters and neural pathways */\n NEUROLOGICAL = \"neurological\",\n /** Vascular system - major blood vessels and circulation */\n VASCULAR = \"vascular\",\n /** Respiratory system - airways and breathing mechanisms */\n RESPIRATORY = \"respiratory\",\n /** Muscular system - muscle groups and tendons */\n MUSCULAR = \"muscular\",\n /** Skeletal system - bones and structural supports */\n SKELETAL = \"skeletal\",\n /** Organ system - internal organs */\n ORGAN = \"organ\",\n /** Circulatory system - heart and blood flow */\n CIRCULATORY = \"circulatory\",\n /** Lymphatic system - lymph nodes and immune response */\n LYMPHATIC = \"lymphatic\",\n /** Endocrine system - hormonal glands */\n ENDOCRINE = \"endocrine\",\n /** Joint system - articulation points */\n JOINT = \"joint\",\n /** Nerve system - peripheral nerves */\n NERVE = \"nerve\",\n /** Pressure system - pressure-sensitive areas */\n PRESSURE = \"pressure\",\n}\n\n/**\n * Vital point severity levels indicating potential impact.\n *\n * Determines the damage multiplier and status effects applied when\n * a vital point is successfully struck.\n *\n * ## Severity Guidelines\n *\n * - **MINOR**: 1.1-1.3x damage, temporary discomfort\n * - **MODERATE**: 1.5-2.0x damage, brief incapacitation\n * - **MAJOR**: 2.5-3.5x damage, significant impairment\n * - **CRITICAL**: 4.0-5.0x damage, severe trauma\n * - **LETHAL**: 6.0-10.0x damage, immediate incapacitation\n *\n * @public\n * @category Vital Point System\n * @korean 급소심각도\n */\nexport enum VitalPointSeverity {\n /** Minor impact - temporary pain or discomfort */\n MINOR = \"minor\",\n /** Moderate impact - brief stunning or reduced effectiveness */\n MODERATE = \"moderate\",\n /** Major impact - significant damage and impairment */\n MAJOR = \"major\",\n /** Critical impact - severe trauma requiring immediate response */\n CRITICAL = \"critical\",\n /** Lethal impact - immediate incapacitation or death */\n LETHAL = \"lethal\",\n}\n\n/**\n * Status effects that can result from vital point strikes.\n *\n * Each effect type represents a physiological response to targeting\n * specific anatomical structures. Effects stack and interact with\n * combat mechanics.\n *\n * @public\n * @category Vital Point System\n * @korean 급소효과\n */\nexport enum VitalPointEffectType {\n /** Loss of consciousness */\n UNCONSCIOUSNESS = \"unconsciousness\",\n /** Inability to breathe properly */\n BREATHLESSNESS = \"breathlessness\",\n /** Intense pain reducing combat effectiveness */\n PAIN = \"pain\",\n /** Temporary or permanent paralysis */\n PARALYSIS = \"paralysis\",\n /** Brief stunning preventing action */\n STUN = \"stun\",\n /** Reduced strength and effectiveness */\n WEAKNESS = \"weakness\",\n /** Confusion and impaired targeting */\n DISORIENTATION = \"disorientation\",\n /** Restricted blood flow to area */\n BLOOD_FLOW_RESTRICTION = \"blood_flow_restriction\",\n /** Nerve pathway interruption */\n NERVE_DISRUPTION = \"nerve_disruption\",\n /** Internal organ malfunction */\n ORGAN_DISRUPTION = \"organ_disruption\",\n}\n\n/**\n * Combat states representing the current action phase of a fighter.\n *\n * Determines available actions, defensive capabilities, and animation states.\n * State transitions follow combat flow logic and timing windows.\n *\n * @public\n * @category Combat System\n * @korean 전투상태\n */\nexport enum CombatState {\n /** Neutral state, all actions available */\n IDLE = \"idle\",\n /** Executing an attack, vulnerable to counters */\n ATTACKING = \"attacking\",\n /** In defensive stance, reduced offensive capability */\n DEFENDING = \"defending\",\n /** Temporarily incapacitated, cannot act */\n STUNNED = \"stunned\",\n /** Recovering from action, limited options */\n RECOVERING = \"recovering\",\n /** Executing a counter-attack */\n COUNTERING = \"countering\",\n /** Transitioning between stances */\n TRANSITIONING = \"transitioning\",\n /** Grappling/controlling opponent */\n GRAPPLING = \"grappling\",\n /** Being grappled/controlled */\n GRAPPLED = \"grappled\",\n}\n\n/**\n * Body regions for anatomical targeting in combat.\n *\n * Each region contains multiple vital points and has different\n * defensive properties and vulnerability profiles.\n *\n * @public\n * @category Combat System\n * @korean 신체부위\n */\nexport enum BodyRegion {\n /** Head region - contains critical neurological targets */\n HEAD = \"head\",\n /** Neck region - contains vascular and respiratory targets */\n NECK = \"neck\",\n /** Torso region - contains organ targets */\n TORSO = \"torso\",\n /** Left arm region - contains nerve and joint targets */\n LEFT_ARM = \"left_arm\",\n /** Right arm region - contains nerve and joint targets */\n RIGHT_ARM = \"right_arm\",\n /** Left leg region - contains structural and mobility targets */\n LEFT_LEG = \"left_leg\",\n /** Right leg region - contains structural and mobility targets */\n RIGHT_LEG = \"right_leg\",\n /** Core/center region - contains balance and power centers */\n CORE = \"core\",\n}\n\n/**\n * Grappling state representing control and hold status.\n *\n * **Korean**: 잡기 상태 (Grapple State)\n *\n * Tracks the current phase of a grappling exchange based on Hapkido\n * and Ssireum techniques. State transitions follow realistic grappling\n * flow where control must be established before manipulation.\n *\n * @public\n * @category Combat System\n * @korean 잡기상태\n */\nexport enum GrappleState {\n /** Not in grapple - normal combat */\n NONE = \"none\",\n /** Initiating grab attempt */\n GRABBING = \"grabbing\",\n /** Successfully controlling opponent */\n CONTROLLING = \"controlling\",\n /** Attempting to escape control */\n ESCAPING = \"escaping\",\n /** Transitioning to throw or takedown */\n THROWING = \"throwing\",\n /** Applying joint lock technique */\n LOCKING = \"locking\",\n}\n\n/**\n * Target for grappling techniques.\n *\n * **Korean**: 잡기 목표 (Grapple Target)\n *\n * Specifies which body part is being controlled in a grapple.\n * Different targets allow different follow-up techniques and\n * have different escape difficulties.\n *\n * @public\n * @category Combat System\n * @korean 잡기목표\n */\nexport enum GrappleTarget {\n /** Hand/wrist control - 손목잡기 */\n HAND = \"hand\",\n /** Arm control - 팔잡기 */\n ARM = \"arm\",\n /** Leg control - 다리잡기 */\n LEG = \"leg\",\n /** Torso/body control - 몸통잡기 */\n TORSO = \"torso\",\n /** Neck control - 목잡기 */\n NECK = \"neck\",\n /** Both arms control - 양팔잡기 */\n BOTH_ARMS = \"both_arms\",\n}\n\n/**\n * Grappling control information.\n *\n * **Korean**: 잡기 제어 (Grapple Control)\n *\n * Tracks active grappling state between combatants, including\n * control duration, grip strength, and target limb.\n *\n * @public\n * @category Combat System\n * @korean 잡기제어\n */\nexport interface GrappleControl {\n /** Current grapple state */\n readonly state: GrappleState;\n /** Body part being controlled */\n readonly target: GrappleTarget;\n /** ID of controlling player */\n readonly controllerId: string;\n /** ID of controlled player */\n readonly targetId: string;\n /** Grip strength (0-100) affecting escape difficulty */\n readonly gripStrength: number;\n /** Duration of control in milliseconds */\n readonly duration: number;\n /** Timestamp when grapple was initiated */\n readonly startTime: number;\n /** Whether control can be broken this frame */\n readonly canEscape: boolean;\n /** Stamina cost per second to maintain control */\n readonly staminaCostPerSecond: number;\n}\n\nexport default {};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../../src/types/common.ts"],"sourcesContent":["/**\n * Common utility types for Korean martial arts game.\n *\n * This module provides foundational types used throughout the Black Trigram (흑괘) game,\n * including geometric types, Korean text support, and utility type helpers.\n *\n * @module types/common\n * @category Type Definitions\n * @korean 공통타입\n */\n\n/**\n * Represents a position in 2D space.\n *\n * **Unit Handling**: The coordinate units depend on the system using this type:\n * - **Combat System**: Coordinates are in **meters** (physics-first architecture)\n * - **Rendering System**: Coordinates are in **pixels** (screen rendering)\n * - **Legacy Systems**: May use pixels or other units\n *\n * When working with combat/physics, positions are in meters relative to arena center (0, 0).\n * Arena boundaries extend from ±worldWidthMeters/2 in X and ±worldDepthMeters/2 in Z (mapped to y).\n *\n * @example\n * ```typescript\n * // Combat position (meters, centered at origin)\n * const playerPos: Position = { x: 2.5, y: -1.0 }; // 2.5m right, 1m back from center\n *\n * // Rendering position (pixels, top-left origin)\n * const screenPos: Position = { x: 640, y: 480 }; // 640px right, 480px down\n * ```\n *\n * @public\n * @category Core Types\n */\nexport interface Position {\n /** X coordinate (meters in combat, pixels in rendering) */\n x: number;\n /** Y coordinate (meters in combat, pixels in rendering) */\n y: number;\n}\n\n/**\n * Represents size dimensions for game objects.\n *\n * @public\n * @category Core Types\n */\nexport interface Size {\n /** Width in pixels */\n readonly width: number;\n /** Height in pixels */\n readonly height: number;\n}\n\n/**\n * Represents rectangle bounds combining position and size.\n *\n * @public\n * @category Core Types\n */\nexport interface Bounds extends Position, Size {}\n\n/**\n * Color represented as a hexadecimal number (e.g., 0xFF0000 for red).\n *\n * @example\n * ```typescript\n * const primaryCyan: Color = 0x00FFFF;\n * const accentGold: Color = 0xFFAA00;\n * ```\n *\n * @public\n * @category Core Types\n */\nexport type Color = number;\n\n/**\n * Time duration in milliseconds.\n *\n * @public\n * @category Core Types\n */\nexport type Duration = number;\n\n/**\n * Percentage value represented as a decimal (0.0 to 1.0).\n *\n * @example\n * ```typescript\n * const halfHealth: Percentage = 0.5;\n * const fullAccuracy: Percentage = 1.0;\n * ```\n *\n * @public\n * @category Core Types\n */\nexport type Percentage = number;\n\n/**\n * Unique identifier string.\n *\n * @public\n * @category Core Types\n */\nexport type ID = string;\n\n/**\n * Generic callback function type.\n *\n * @typeParam T - Return type of the callback, defaults to void\n *\n * @public\n * @category Core Types\n */\nexport type Callback<T = void> = () => T;\n\n/**\n * Event handler function type.\n *\n * @typeParam T - Type of event data, defaults to any\n *\n * @public\n * @category Core Types\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Generic default allows flexible event handling\nexport type EventHandler<T = any> = (event: T) => void;\n\n/**\n * Utility type to make specific properties optional.\n *\n * @typeParam T - The base type\n * @typeParam K - Keys of T to make optional\n *\n * @public\n * @category Utility Types\n */\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\n/**\n * Utility type to make specific properties required.\n *\n * @typeParam T - The base type\n * @typeParam K - Keys of T to make required\n *\n * @public\n * @category Utility Types\n */\nexport type Required<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\n/**\n * Utility type to make all properties deeply readonly.\n *\n * @typeParam T - The type to make deeply readonly\n *\n * @public\n * @category Utility Types\n */\nexport type DeepReadonly<T> = {\n readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];\n};\n\n/**\n * Represents bilingual Korean-English text content.\n *\n * Used throughout the game to provide authentic Korean terminology with English translations,\n * supporting the cultural authenticity of the Korean martial arts theme.\n *\n * @example\n * ```typescript\n * const techniqueName: KoreanText = {\n * korean: \"천둥벽력\",\n * english: \"Thunder Strike\",\n * romanized: \"cheondu byeokryeok\"\n * };\n * ```\n *\n * @public\n * @category Korean Martial Arts\n * @korean 한글텍스트\n */\nexport interface KoreanText {\n /** Korean text in Hangul */\n readonly korean: string;\n /** English translation */\n readonly english: string;\n /** Optional romanized Korean pronunciation */\n readonly romanized?: string;\n}\n\n/**\n * Base entity interface with Korean naming support.\n *\n * Provides a foundation for game entities with bilingual identification.\n *\n * @public\n * @category Korean Martial Arts\n * @korean 한글개체\n */\nexport interface KoreanEntity {\n /** Unique identifier */\n readonly id: ID;\n /** Bilingual name */\n readonly name: KoreanText;\n /** Optional bilingual description */\n readonly description?: KoreanText;\n}\n\n/**\n * Font sizes for Korean text rendering.\n *\n * Provides consistent typography sizing across the game interface.\n *\n * @public\n * @category UI\n * @korean 글자크기\n */\nexport enum KoreanTextSize {\n /** Extra small: 10px */\n XSMALL = \"xsmall\",\n /** Tiny: 12px */\n TINY = \"tiny\",\n /** Small: 14px */\n SMALL = \"small\",\n /** Medium: 16px */\n MEDIUM = \"medium\",\n /** Large: 18px */\n LARGE = \"large\",\n /** Extra large: 20px */\n XLARGE = \"xlarge\",\n /** Double extra large: 24px */\n XXLARGE = \"xxlarge\",\n /** Huge: 32px */\n HUGE = \"huge\",\n /** Title: 48px */\n TITLE = \"title\",\n}\n\n/**\n * Font weights for Korean text rendering.\n *\n * Provides consistent typography weights for Korean Hangul characters.\n *\n * @public\n * @category UI\n * @korean 글자무게\n */\nexport enum KoreanTextWeight {\n /** Light weight: 300 */\n LIGHT = \"light\",\n /** Normal weight: 400 */\n NORMAL = \"normal\",\n /** Regular weight: 400 (alias for NORMAL) */\n REGULAR = \"regular\",\n /** Medium weight: 500 */\n MEDIUM = \"medium\",\n /** Semi-bold weight: 600 */\n SEMIBOLD = \"semibold\",\n /** Bold weight: 700 */\n BOLD = \"bold\",\n /** Heavy weight: 900 */\n HEAVY = \"heavy\",\n}\n\n/**\n * Text alignment options for Korean text.\n *\n * @public\n * @category UI\n */\nexport type KoreanTextAlignment = \"left\" | \"center\" | \"right\";\n\n/**\n * Styling configuration for Korean text rendering.\n *\n * @public\n * @category UI\n * @korean 글자스타일\n */\nexport interface KoreanTextStyle {\n /** Text size */\n readonly size: KoreanTextSize;\n /** Font weight */\n readonly weight: KoreanTextWeight;\n /** Text color as hex number */\n readonly color: number;\n /** Horizontal alignment */\n readonly alignment: KoreanTextAlignment;\n}\n\n/**\n * Represents a range of damage values for combat calculations.\n *\n * Used for techniques and vital point strikes to define variable damage output.\n *\n * @public\n * @category Combat\n * @korean 피해범위\n */\nexport interface DamageRange {\n /** Minimum damage value */\n readonly min: number;\n /** Maximum damage value */\n readonly max: number;\n /** Type of damage dealt */\n readonly type?: DamageType;\n /** Pre-calculated average damage */\n readonly average?: number;\n}\n\n/**\n * Game settings configuration interface for UI controls.\n *\n * Manages volume, graphics quality, control schemes, and language preferences.\n *\n * @public\n * @category UI\n * @korean 게임설정\n */\nexport interface UIGameSettings {\n /** Audio volume settings */\n readonly volume: {\n /** Master volume (0.0 - 1.0) */\n readonly master: number;\n /** Music volume (0.0 - 1.0) */\n readonly music: number;\n /** Sound effects volume (0.0 - 1.0) */\n readonly sfx: number;\n };\n /** Graphics settings */\n readonly graphics: {\n /** Graphics quality preset */\n readonly quality: \"low\" | \"medium\" | \"high\";\n /** Fullscreen mode enabled */\n readonly fullscreen: boolean;\n /** Vertical sync enabled */\n readonly vsync: boolean;\n };\n /** Control settings */\n readonly controls: {\n /** Keyboard layout preference */\n readonly keyboardLayout: \"qwerty\" | \"dvorak\" | \"colemak\";\n /** Mouse sensitivity multiplier */\n readonly mouseSensitivity: number;\n };\n /** Language preference */\n readonly language: \"korean\" | \"english\" | \"both\";\n}\n\n/**\n * Duration tracking for status effects.\n *\n * Tracks when an effect started, when it ends, and its total duration.\n *\n * @public\n * @category Combat\n * @korean 효과지속시간\n */\nexport interface EffectDuration {\n /** Effect start timestamp (milliseconds) */\n readonly startTime: number;\n /** Effect end timestamp (milliseconds) */\n readonly endTime: number;\n /** Total duration (milliseconds) */\n readonly duration: number;\n}\n\n/**\n * Generic game entity with positioning and visibility.\n *\n * Extends {@link KoreanEntity} with spatial and state properties.\n *\n * @public\n * @category Core Types\n * @korean 게임개체\n */\nexport interface GameEntity extends KoreanEntity {\n /** Position in game world */\n readonly position?: Position;\n /** Size dimensions */\n readonly size?: Size;\n /** Whether entity is active */\n readonly active?: boolean;\n /** Whether entity is visible */\n readonly visible?: boolean;\n}\n\n/**\n * Animation transition configuration.\n *\n * Defines how to transition between two states with timing and easing.\n *\n * @public\n * @category UI\n * @korean 전환\n */\nexport interface Transition {\n /** Starting state identifier */\n readonly from: string;\n /** Target state identifier */\n readonly to: string;\n /** Transition duration in milliseconds */\n readonly duration: Duration;\n /** Optional easing function name */\n readonly easing?: string;\n}\n\n/**\n * Theme color configuration.\n *\n * Defines primary colors used throughout the game UI.\n *\n * @public\n * @category UI\n * @korean 테마\n */\nexport interface Theme {\n /** Primary color */\n readonly primary: Color;\n /** Secondary color */\n readonly secondary: Color;\n /** Accent color */\n readonly accent?: Color;\n /** Background color */\n readonly background?: Color;\n /** Text color */\n readonly text?: Color;\n}\n\n/**\n * Generic configuration object.\n *\n * @public\n * @category Core Types\n */\nexport interface Config {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Config values can be of various types\n readonly [key: string]: any;\n}\n\n/**\n * Generic result wrapper for operations that may succeed or fail.\n *\n * @typeParam T - Type of successful result data\n * @typeParam E - Type of error, defaults to Error\n *\n * @example\n * ```typescript\n * const result: Result<PlayerState> = {\n * success: true,\n * data: playerState\n * };\n * ```\n *\n * @public\n * @category Core Types\n */\nexport interface Result<T, E = Error> {\n /** Whether operation succeeded */\n readonly success: boolean;\n /** Result data if successful */\n readonly data?: T;\n /** Error if operation failed */\n readonly error?: E;\n /** Optional message */\n readonly message?: string;\n}\n\n/**\n * Validation result with errors and warnings.\n *\n * @public\n * @category Core Types\n */\nexport interface ValidationResult {\n /** Whether validation passed */\n readonly valid: boolean;\n /** List of validation errors */\n readonly errors: readonly string[];\n /** Optional list of warnings */\n readonly warnings?: readonly string[];\n}\n\n/**\n * Game modes available in Black Trigram.\n *\n * Each mode offers different gameplay experiences and training opportunities.\n *\n * @public\n * @category Game Systems\n * @korean 게임모드\n */\nexport enum GameMode {\n /** Versus mode: Player vs AI or Player vs Player */\n VERSUS = \"versus\",\n /** Training mode: Practice techniques against training dummy */\n TRAINING = \"training\",\n /** Tutorial mode: Learn game mechanics and controls */\n TUTORIAL = \"tutorial\",\n /** Practice mode: Free form combat practice */\n PRACTICE = \"practice\",\n /** Story mode: Campaign with narrative */\n STORY = \"story\",\n /** Arcade mode: Progressive difficulty challenges */\n ARCADE = \"arcade\",\n /** Controls screen: View and customize controls */\n CONTROLS = \"controls\",\n /** Philosophy screen: Learn about Korean martial arts philosophy */\n PHILOSOPHY = \"philosophy\",\n}\n\n/**\n * Game phases representing the current state of the game.\n *\n * Controls which screen is displayed and what game logic is active.\n *\n * @public\n * @category Game Systems\n * @korean 게임단계\n */\nexport enum GamePhase {\n /** Intro/splash screen */\n INTRO = \"intro\",\n /** Main menu */\n MENU = \"menu\",\n /** Character selection screen */\n CHARACTER_SELECT = \"character_select\",\n /** Active combat */\n COMBAT = \"combat\",\n /** Training mode */\n TRAINING = \"training\",\n /** Victory screen */\n VICTORY = \"victory\",\n /** Defeat screen */\n DEFEAT = \"defeat\",\n /** Game paused */\n PAUSED = \"paused\",\n /** Game over screen */\n GAME_OVER = \"game_over\",\n /** Loading screen */\n LOADING = \"loading\",\n}\n\n/**\n * Player archetypes representing Korean martial arts combat specialists.\n *\n * **Korean**: 플레이어 원형 (Player Archetypes)\n *\n * Each archetype has unique combat styles, favored stances, and philosophical approaches\n * rooted in Korean martial arts traditions and modern cyberpunk adaptation.\n *\n * @example\n * ```typescript\n * const player = createPlayer({\n * archetype: PlayerArchetype.MUSA,\n * name: { korean: \"이순신\", english: \"Yi Sun-sin\" }\n * });\n * ```\n *\n * @public\n * @category Player & Archetypes\n * @korean 플레이어원형\n */\nexport enum PlayerArchetype {\n /**\n * 무사 (Musa) - Traditional Warrior\n *\n * Honor-bound martial artist following traditional Korean warrior codes.\n * Favors direct confrontation and disciplined techniques.\n */\n MUSA = \"musa\",\n\n /**\n * 암살자 (Amsalja) - Shadow Assassin\n *\n * Precision striker focused on vital point targeting and silent elimination.\n * Specializes in nerve strikes and pressure point techniques.\n */\n AMSALJA = \"amsalja\",\n\n /**\n * 해커 (Hacker) - Cyber Warrior\n *\n * Technology-enhanced combatant blending modern cybernetics with traditional techniques.\n * Uses augmented reflexes and data-driven combat analysis.\n */\n HACKER = \"hacker\",\n\n /**\n * 정보요원 (Jeongbo Yowon) - Intelligence Operative\n *\n * Strategic analyst who uses combat intelligence and tactical advantage.\n * Excels at reading opponent patterns and exploiting weaknesses.\n */\n JEONGBO_YOWON = \"jeongbo_yowon\",\n\n /**\n * 조직폭력배 (Jojik Pokryeokbae) - Organized Crime\n *\n * Ruthless pragmatist who ignores traditional honor codes.\n * Uses brutal, efficient techniques with no concern for ethics.\n */\n JOJIK_POKRYEOKBAE = \"jojik_pokryeokbae\",\n}\n\n/**\n * Physical attributes representing realistic body dimensions and composition.\n *\n * **Korean**: 신체 속성 (Body Attributes)\n *\n * These attributes affect combat calculations including reach, movement speed,\n * damage output, defense capability, and stamina. Based on realistic human\n * physiology and Korean martial arts biomechanics.\n *\n * ## Combat Impact\n *\n * - **Weight**: Affects movement speed, knockback resistance, and throw effectiveness\n * - **Leg Length**: Determines kick range and movement speed base\n * - **Arm Length**: Determines punch/strike range and grappling reach\n * - **Muscle Mass**: Affects base damage output and stamina pool\n * - **Fat Mass**: Affects defense absorption and stamina drain rate\n * - **Age**: Affects stamina recovery speed and Ki regeneration\n *\n * @example\n * ```typescript\n * const musaPhysical: PhysicalAttributes = {\n * weight: 75, // kg - balanced warrior\n * legLength: 95, // cm - average leg reach\n * armLength: 75, // cm - average arm reach\n * muscleMass: 38, // kg - high muscle for power\n * fatMass: 12, // kg - low fat for mobility\n * age: 32, // years - prime combat age\n * };\n * ```\n *\n * @public\n * @category Player & Archetypes\n * @korean 신체속성\n */\nexport interface PhysicalAttributes {\n /**\n * Body weight in kilograms.\n *\n * **Korean**: 체중 (Body Weight)\n *\n * Typical Range: 55-95 kg for combatants\n * - Affects movement speed (inversely)\n * - Affects knockback resistance (positively)\n * - Affects throw effectiveness (positively)\n * - Affects ground control (positively)\n */\n readonly weight: number;\n\n /**\n * Leg length in centimeters (hip to ankle).\n *\n * **Korean**: 다리 길이 (Leg Length)\n *\n * Typical Range: 85-105 cm\n * - Determines kick technique maximum range\n * - Affects base movement speed\n * - Affects sweep technique effectiveness\n * - Affects jumping attack height\n */\n readonly legLength: number;\n\n /**\n * Arm length in centimeters (shoulder to wrist).\n *\n * **Korean**: 팔 길이 (Arm Length)\n *\n * Typical Range: 65-85 cm\n * - Determines punch/strike technique range\n * - Affects grappling and throw range\n * - Affects block coverage area\n * - Affects elbow strike effectiveness\n */\n readonly armLength: number;\n\n /**\n * Muscle mass in kilograms.\n *\n * **Korean**: 근육량 (Muscle Mass)\n *\n * Typical Range: 25-45 kg\n * - Affects base damage output (positively)\n * - Affects maximum stamina pool (positively)\n * - Affects grappling and throw power\n * - Affects movement acceleration\n */\n readonly muscleMass: number;\n\n /**\n * Fat mass in kilograms.\n *\n * **Korean**: 지방량 (Fat Mass)\n *\n * Typical Range: 8-20 kg for combatants\n * - Affects blunt damage absorption (positively)\n * - Affects stamina drain rate (negatively)\n * - Affects movement speed (negatively)\n * - Affects recovery time between actions\n */\n readonly fatMass: number;\n\n /**\n * Age in years.\n *\n * **Korean**: 나이 (Age)\n *\n * Typical Range: 22-45 years for peak combatants\n * - Affects stamina recovery speed (optimal 25-35)\n * - Affects Ki regeneration rate (wisdom with age)\n * - Affects injury recovery time (slower with age)\n * - Affects technique execution speed (prime 28-35)\n */\n readonly age: number;\n\n /**\n * Total body height in centimeters.\n *\n * **Korean**: 키 (Height)\n *\n * Typical Range: 160-195 cm\n * - Scales entire skeleton proportionally\n * - Affects reach calculations (combined with limb ratios)\n * - Affects center of gravity positioning\n * - Determines visual body model scaling\n * - Influences balance and stability in stances\n */\n readonly totalHeight: number;\n\n /**\n * Torso length in centimeters (pelvis to shoulders).\n *\n * **Korean**: 몸통 길이 (Torso Length)\n *\n * Typical Range: 50-65 cm\n * - Affects core hitbox size and vital point positioning\n * - Influences breath control and stamina capacity\n * - Affects spinal rotation range in techniques\n * - Determines torso vital point target area\n * - Impacts center of mass calculations\n */\n readonly torsoLength: number;\n\n /**\n * Head size (diameter) in centimeters.\n *\n * **Korean**: 머리 크기 (Head Size)\n *\n * Typical Range: 20-24 cm\n * - Affects head vital point targeting precision\n * - Determines head hitbox size for strikes\n * - Influences helmet/headgear fit (if applicable)\n * - Affects visual skull scaling in 3D model\n * - Impacts consciousness vulnerability to head trauma\n */\n readonly headSize: number;\n\n /**\n * Neck length in centimeters (skull base to shoulders).\n *\n * **Korean**: 목 길이 (Neck Length)\n *\n * Typical Range: 8-12 cm\n * - Affects vulnerability to chokes and strangles\n * - Determines neck vital point target area\n * - Influences blood choke effectiveness\n * - Affects guillotine and rear naked choke mechanics\n * - Impacts head mobility and evasion capability\n */\n readonly neckLength: number;\n\n /**\n * Shoulder width in centimeters (shoulder to shoulder).\n *\n * **Korean**: 어깨 너비 (Shoulder Width)\n *\n * Typical Range: 38-48 cm\n * - Affects defense coverage area (blocking)\n * - Determines upper body strike zone width\n * - Influences grappling control positions\n * - Affects visual upper body model scaling\n * - Impacts balance and stability in wide stances\n */\n readonly shoulderWidth: number;\n\n /**\n * Base walking speed in meters per second.\n *\n * **Korean**: 걷기 속도 (Walk Speed)\n *\n * Typical Range: 5.0-6.5 m/s for combat movement\n * - Determines tactical repositioning speed\n * - Affected by weight and leg length\n * - Base speed for defensive movement\n * - Modified by stance and combat state\n */\n readonly walkSpeed: number;\n\n /**\n * Base running speed in meters per second.\n *\n * **Korean**: 달리기 속도 (Run Speed)\n *\n * Typical Range: 8.0-11.0 m/s for sprint movement\n * - Determines rapid repositioning speed\n * - Affected by muscle mass and conditioning\n * - Base speed for aggressive approach\n * - Consumes stamina during use\n */\n readonly runSpeed: number;\n\n /**\n * Base acceleration in meters per second squared.\n *\n * **Korean**: 가속도 (Acceleration)\n *\n * Typical Range: 9.0-15.0 m/s² for combat movement\n * - Determines how quickly fighter reaches max speed\n * - Based on muscle-to-weight ratio (explosiveness)\n * - Higher = more explosive starts and direction changes\n * - Affects combat responsiveness and evasion\n */\n readonly acceleration: number;\n}\n\n/**\n * Eight Trigram stances (팔괘) representing fundamental combat principles.\n *\n * **Korean**: 팔괘 자세 (Eight Trigram Stances)\n * **Origin**: I Ching (易經 / Yijing) divination system adapted for Korean martial arts\n *\n * The Eight Trigrams (Bagua / 八卦) form the foundation of the combat system.\n * Each trigram represents a natural element and combat philosophy, influencing\n * available techniques, movement patterns, and strategic advantages.\n *\n * ## Trigram Philosophy\n *\n * - **☰ 건 (Geon)** - Heaven: Yang energy, direct aggression, overwhelming force\n * - **☱ 태 (Tae)** - Lake: Joy and fluidity, joint locks and flow techniques\n * - **☲ 리 (Li)** - Fire: Precision and speed, nerve strikes and rapid attacks\n * - **☳ 진 (Jin)** - Thunder: Explosive power, shocking techniques\n * - **☴ 손 (Son)** - Wind: Continuous pressure, evasion and mobility\n * - **☵ 감 (Gam)** - Water: Adaptive flow, counters and redirection\n * - **☶ 간 (Gan)** - Mountain: Immovable defense, endurance and patience\n * - **☷ 곤 (Gon)** - Earth: Grounding techniques, takedowns and throws\n *\n * @example\n * ```typescript\n * // Change to Heaven stance for aggressive attack\n * player.currentStance = TrigramStance.GEON;\n *\n * // Execute heaven-aligned technique\n * const technique = getTrigramTechniques(TrigramStance.GEON)[0];\n * executeTechnique(player, opponent, technique);\n * ```\n *\n * @see {@link https://en.wikipedia.org/wiki/Bagua | Bagua (Eight Trigrams) - Wikipedia}\n * @see {@link https://en.wikipedia.org/wiki/I_Ching | I Ching - Wikipedia}\n *\n * @public\n * @category Trigram System\n * @category Korean Martial Arts\n * @korean 팔괘\n */\nexport enum TrigramStance {\n /**\n * ☰ 건 (Geon) - Heaven Stance\n *\n * **Element**: Heaven / Sky (天)\n * **Nature**: Yang, creative, strong\n * **Combat Style**: Direct force, aggressive techniques, overwhelming power\n * **Philosophy**: \"The creative principle - pure yang energy that drives forward\"\n *\n * Techniques emphasize straight attacks, powerful strikes, and dominant positioning.\n */\n GEON = \"geon\",\n\n /**\n * ☱ 태 (Tae) - Lake Stance\n *\n * **Element**: Lake / Marsh (澤)\n * **Nature**: Yin exterior, Yang interior - joyful movement\n * **Combat Style**: Fluid joint manipulation, flowing techniques, adaptable responses\n * **Philosophy**: \"The joyful - water above earth, freedom of movement\"\n *\n * Techniques focus on joint locks, throws, and using opponent's momentum.\n */\n TAE = \"tae\",\n\n /**\n * ☲ 리 (Li) - Fire Stance\n *\n * **Element**: Fire / Flame (火)\n * **Nature**: Yang exterior, Yin interior - bright and precise\n * **Combat Style**: Precise nerve strikes, rapid attacks, speed techniques\n * **Philosophy**: \"The clinging - illuminating and consuming\"\n *\n * Techniques emphasize vital point targeting, quick combinations, and precision.\n */\n LI = \"li\",\n\n /**\n * ☳ 진 (Jin) - Thunder Stance\n *\n * **Element**: Thunder / Arousing (雷)\n * **Nature**: Yang moving, sudden and shocking\n * **Combat Style**: Explosive power, shocking techniques, sudden movements\n * **Philosophy**: \"The arousing - thunder brings shock and awakening\"\n *\n * Techniques feature explosive bursts, stunning strikes, and overwhelming force.\n */\n JIN = \"jin\",\n\n /**\n * ☴ 손 (Son) - Wind Stance\n *\n * **Element**: Wind / Wood (風)\n * **Nature**: Yin, gentle but penetrating\n * **Combat Style**: Continuous pressure, evasion techniques, mobility\n * **Philosophy**: \"The gentle - penetrating like wind, persistent like wood\"\n *\n * Techniques emphasize movement, pressure point chains, and wearing down opponents.\n */\n SON = \"son\",\n\n /**\n * ☵ 감 (Gam) - Water Stance\n *\n * **Element**: Water / Abyss (水)\n * **Nature**: Yang surrounded by Yin - dangerous depths\n * **Combat Style**: Flow and adaptation, counter techniques, redirection\n * **Philosophy**: \"The abysmal - water flows around obstacles and fills voids\"\n *\n * Techniques focus on counters, deflections, and adaptive responses.\n */\n GAM = \"gam\",\n\n /**\n * ☶ 간 (Gan) - Mountain Stance\n *\n * **Element**: Mountain / Stillness (山)\n * **Nature**: Yang above Yin - firm and unyielding\n * **Combat Style**: Defensive mastery, immovable stance, endurance\n * **Philosophy**: \"The keeping still - mountains are firm and unmoving\"\n *\n * Techniques emphasize blocks, parries, and defensive positioning.\n */\n GAN = \"gan\",\n\n /**\n * ☷ 곤 (Gon) - Earth Stance\n *\n * **Element**: Earth / Receptive (地)\n * **Nature**: Pure Yin - receptive and yielding\n * **Combat Style**: Grounding techniques, takedowns, throws\n * **Philosophy**: \"The receptive - earth receives and supports all\"\n *\n * Techniques focus on sweeps, trips, takedowns, and ground control.\n */\n GON = \"gon\",\n}\n\n/**\n * Combat attack types available in the game.\n *\n * Defines the mechanical type of attack being performed, which affects\n * damage calculation, vital point targeting, and defensive options.\n *\n * @public\n * @category Combat System\n * @korean 공격타입\n */\nexport enum CombatAttackType {\n /** Standard striking attack */\n STRIKE = \"strike\",\n /** Thrusting attack with focused force */\n THRUST = \"thrust\",\n /** Defensive blocking action */\n BLOCK = \"block\",\n /** Counter-attack performed after successful defense */\n COUNTER_ATTACK = \"counter_attack\",\n /** Throwing technique to off-balance opponent */\n THROW = \"throw\",\n /** Grappling and joint control technique */\n GRAPPLE = \"grapple\",\n /** Precise pressure point strike */\n PRESSURE_POINT = \"pressure_point\",\n /** Nerve disruption strike */\n NERVE_STRIKE = \"nerve_strike\",\n /** Closed fist punch */\n PUNCH = \"punch\",\n /** Leg kick attack */\n KICK = \"kick\",\n /** Elbow strike */\n ELBOW = \"elbow\",\n /** Knee strike */\n KNEE = \"knee\",\n}\n\n/**\n * Damage types representing different methods of inflicting harm.\n *\n * Each damage type interacts differently with vital points and defensive techniques.\n * Some types are more effective against specific body regions or defense styles.\n *\n * @public\n * @category Combat System\n * @korean 피해타입\n */\nexport enum DamageType {\n /** Blunt force trauma */\n BLUNT = \"blunt\",\n /** Piercing damage penetrating tissue */\n PIERCING = \"piercing\",\n /** Slashing cuts */\n SLASHING = \"slashing\",\n /** Pressure point manipulation */\n PRESSURE = \"pressure\",\n /** Nerve disruption */\n NERVE = \"nerve\",\n /** Joint manipulation and locks */\n JOINT = \"joint\",\n /** Internal organ damage */\n INTERNAL = \"internal\",\n /** Impact shock */\n IMPACT = \"impact\",\n /** Crushing force */\n CRUSHING = \"crushing\",\n /** Sharp edge damage */\n SHARP = \"sharp\",\n /** Electric shock */\n ELECTRIC = \"electric\",\n /** Fire/heat damage */\n FIRE = \"fire\",\n /** Cold/freeze damage */\n ICE = \"ice\",\n /** Poison/toxin damage */\n POISON = \"poison\",\n /** Psychic/mental damage */\n PSYCHIC = \"psychic\",\n /** Blood loss damage */\n BLOOD = \"blood\",\n}\n\n/**\n * Vital point categories representing anatomical targeting systems.\n *\n * **Korean**: 급소 범주 (Vital Point Categories)\n *\n * The game features 70 Korean vital points (급소) based on traditional martial arts\n * knowledge and modern anatomical understanding. Each category represents different\n * physiological systems that can be targeted for combat effectiveness.\n *\n * @example\n * ```typescript\n * const vitalPoint: VitalPoint = {\n * id: \"GB-20\",\n * category: VitalPointCategory.NEUROLOGICAL,\n * severity: VitalPointSeverity.CRITICAL,\n * name: { korean: \"풍지\", english: \"Wind Pool\" }\n * };\n * ```\n *\n * @public\n * @category Vital Point System\n * @korean 급소범주\n */\nexport enum VitalPointCategory {\n /** Neurological system - nerve clusters and neural pathways */\n NEUROLOGICAL = \"neurological\",\n /** Vascular system - major blood vessels and circulation */\n VASCULAR = \"vascular\",\n /** Respiratory system - airways and breathing mechanisms */\n RESPIRATORY = \"respiratory\",\n /** Muscular system - muscle groups and tendons */\n MUSCULAR = \"muscular\",\n /** Skeletal system - bones and structural supports */\n SKELETAL = \"skeletal\",\n /** Organ system - internal organs */\n ORGAN = \"organ\",\n /** Circulatory system - heart and blood flow */\n CIRCULATORY = \"circulatory\",\n /** Lymphatic system - lymph nodes and immune response */\n LYMPHATIC = \"lymphatic\",\n /** Endocrine system - hormonal glands */\n ENDOCRINE = \"endocrine\",\n /** Joint system - articulation points */\n JOINT = \"joint\",\n /** Nerve system - peripheral nerves */\n NERVE = \"nerve\",\n /** Pressure system - pressure-sensitive areas */\n PRESSURE = \"pressure\",\n}\n\n/**\n * Vital point severity levels indicating potential impact.\n *\n * Determines the damage multiplier and status effects applied when\n * a vital point is successfully struck.\n *\n * ## Severity Guidelines\n *\n * - **MINOR**: 1.1-1.3x damage, temporary discomfort\n * - **MODERATE**: 1.5-2.0x damage, brief incapacitation\n * - **MAJOR**: 2.5-3.5x damage, significant impairment\n * - **CRITICAL**: 4.0-5.0x damage, severe trauma\n * - **LETHAL**: 6.0-10.0x damage, immediate incapacitation\n *\n * @public\n * @category Vital Point System\n * @korean 급소심각도\n */\nexport enum VitalPointSeverity {\n /** Minor impact - temporary pain or discomfort */\n MINOR = \"minor\",\n /** Moderate impact - brief stunning or reduced effectiveness */\n MODERATE = \"moderate\",\n /** Major impact - significant damage and impairment */\n MAJOR = \"major\",\n /** Critical impact - severe trauma requiring immediate response */\n CRITICAL = \"critical\",\n /** Lethal impact - immediate incapacitation or death */\n LETHAL = \"lethal\",\n}\n\n/**\n * Status effects that can result from vital point strikes.\n *\n * Each effect type represents a physiological response to targeting\n * specific anatomical structures. Effects stack and interact with\n * combat mechanics.\n *\n * @public\n * @category Vital Point System\n * @korean 급소효과\n */\nexport enum VitalPointEffectType {\n /** Loss of consciousness */\n UNCONSCIOUSNESS = \"unconsciousness\",\n /** Inability to breathe properly */\n BREATHLESSNESS = \"breathlessness\",\n /** Intense pain reducing combat effectiveness */\n PAIN = \"pain\",\n /** Temporary or permanent paralysis */\n PARALYSIS = \"paralysis\",\n /** Brief stunning preventing action */\n STUN = \"stun\",\n /** Reduced strength and effectiveness */\n WEAKNESS = \"weakness\",\n /** Confusion and impaired targeting */\n DISORIENTATION = \"disorientation\",\n /** Restricted blood flow to area */\n BLOOD_FLOW_RESTRICTION = \"blood_flow_restriction\",\n /** Nerve pathway interruption */\n NERVE_DISRUPTION = \"nerve_disruption\",\n /** Internal organ malfunction */\n ORGAN_DISRUPTION = \"organ_disruption\",\n}\n\n/**\n * Combat states representing the current action phase of a fighter.\n *\n * Determines available actions, defensive capabilities, and animation states.\n * State transitions follow combat flow logic and timing windows.\n *\n * @public\n * @category Combat System\n * @korean 전투상태\n */\nexport enum CombatState {\n /** Neutral state, all actions available */\n IDLE = \"idle\",\n /** Executing an attack, vulnerable to counters */\n ATTACKING = \"attacking\",\n /** In defensive stance, reduced offensive capability */\n DEFENDING = \"defending\",\n /** Temporarily incapacitated, cannot act */\n STUNNED = \"stunned\",\n /** Recovering from action, limited options */\n RECOVERING = \"recovering\",\n /** Executing a counter-attack */\n COUNTERING = \"countering\",\n /** Transitioning between stances */\n TRANSITIONING = \"transitioning\",\n /** Grappling/controlling opponent */\n GRAPPLING = \"grappling\",\n /** Being grappled/controlled */\n GRAPPLED = \"grappled\",\n}\n\n/**\n * Body regions for anatomical targeting in combat.\n *\n * Each region contains multiple vital points and has different\n * defensive properties and vulnerability profiles.\n *\n * @public\n * @category Combat System\n * @korean 신체부위\n */\nexport enum BodyRegion {\n /** Head region - contains critical neurological targets */\n HEAD = \"head\",\n /** Neck region - contains vascular and respiratory targets */\n NECK = \"neck\",\n /** Torso region - contains organ targets */\n TORSO = \"torso\",\n /** Left arm region - contains nerve and joint targets */\n LEFT_ARM = \"left_arm\",\n /** Right arm region - contains nerve and joint targets */\n RIGHT_ARM = \"right_arm\",\n /** Left leg region - contains structural and mobility targets */\n LEFT_LEG = \"left_leg\",\n /** Right leg region - contains structural and mobility targets */\n RIGHT_LEG = \"right_leg\",\n /** Core/center region - contains balance and power centers */\n CORE = \"core\",\n}\n\n/**\n * Grappling state representing control and hold status.\n *\n * **Korean**: 잡기 상태 (Grapple State)\n *\n * Tracks the current phase of a grappling exchange based on Hapkido\n * and Ssireum techniques. State transitions follow realistic grappling\n * flow where control must be established before manipulation.\n *\n * @public\n * @category Combat System\n * @korean 잡기상태\n */\nexport enum GrappleState {\n /** Not in grapple - normal combat */\n NONE = \"none\",\n /** Initiating grab attempt */\n GRABBING = \"grabbing\",\n /** Successfully controlling opponent */\n CONTROLLING = \"controlling\",\n /** Attempting to escape control */\n ESCAPING = \"escaping\",\n /** Transitioning to throw or takedown */\n THROWING = \"throwing\",\n /** Applying joint lock technique */\n LOCKING = \"locking\",\n}\n\n/**\n * Target for grappling techniques.\n *\n * **Korean**: 잡기 목표 (Grapple Target)\n *\n * Specifies which body part is being controlled in a grapple.\n * Different targets allow different follow-up techniques and\n * have different escape difficulties.\n *\n * @public\n * @category Combat System\n * @korean 잡기목표\n */\nexport enum GrappleTarget {\n /** Hand/wrist control - 손목잡기 */\n HAND = \"hand\",\n /** Arm control - 팔잡기 */\n ARM = \"arm\",\n /** Leg control - 다리잡기 */\n LEG = \"leg\",\n /** Torso/body control - 몸통잡기 */\n TORSO = \"torso\",\n /** Neck control - 목잡기 */\n NECK = \"neck\",\n /** Both arms control - 양팔잡기 */\n BOTH_ARMS = \"both_arms\",\n}\n\n/**\n * Grappling control information.\n *\n * **Korean**: 잡기 제어 (Grapple Control)\n *\n * Tracks active grappling state between combatants, including\n * control duration, grip strength, and target limb.\n *\n * @public\n * @category Combat System\n * @korean 잡기제어\n */\nexport interface GrappleControl {\n /** Current grapple state */\n readonly state: GrappleState;\n /** Body part being controlled */\n readonly target: GrappleTarget;\n /** ID of controlling player */\n readonly controllerId: string;\n /** ID of controlled player */\n readonly targetId: string;\n /** Grip strength (0-100) affecting escape difficulty */\n readonly gripStrength: number;\n /** Duration of control in milliseconds */\n readonly duration: number;\n /** Timestamp when grapple was initiated */\n readonly startTime: number;\n /** Whether control can be broken this frame */\n readonly canEscape: boolean;\n /** Stamina cost per second to maintain control */\n readonly staminaCostPerSecond: number;\n}\n\nexport default {};\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"colors.js","names":[],"sources":["../../../src/types/constants/colors.ts"],"sourcesContent":["/**\n * Color palette for Black Trigram Korean martial arts game\n * Cyberpunk aesthetic with Korean traditional influences\n * \n * WCAG 2.1 Level AA Compliance:\n * - Text colors meet 4.5:1 contrast ratio on dark backgrounds\n * - UI elements meet 3:1 contrast ratio\n * - Focus indicators use 2px borders with high contrast\n * \n * @see https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html\n */\n\n// Primary color palette\nexport const KOREAN_COLORS = {\n // Primary colors (Cyberpunk neon) - WCAG AA compliant on dark backgrounds\n PRIMARY_CYAN: 0x00e6e6, // Increased brightness for better contrast (was 0x00ffff)\n PRIMARY_BLUE: 0x0066ff,\n PRIMARY_BLUE_DARK: 0x003399,\n\n // Fix: Add missing PRIMARY_RED color\n PRIMARY_RED: 0xff4444, // Increased brightness for contrast (was 0xff3333)\n\n // Secondary colors - WCAG AA compliant\n SECONDARY_MAGENTA: 0xff33ff, // Increased brightness\n SECONDARY_PURPLE: 0xaa44ff, // Increased brightness (was 0x9900ff)\n SECONDARY_YELLOW: 0xffff33, // Slightly reduced for better visibility\n SECONDARY_ORANGE: 0xff7733, // Increased brightness (was 0xff6600)\n SECONDARY_BROWN_DARK: 0x8b4513,\n\n // Accent colors - WCAG AA compliant\n ACCENT_GOLD: 0xffc400, // Increased brightness for contrast (was 0xffd700)\n ACCENT_RED: 0xff4444, // Increased brightness (was 0xff3333)\n ACCENT_GREEN: 0x44ff44, // Increased brightness (was 0x00ff33)\n ACCENT_PRIMARY: 0x00d4ff,\n ACCENT_YELLOW: 0xffff33, // Slightly reduced for visibility (was 0xffff00)\n ACCENT_PURPLE: 0xaa44ff, // Increased brightness (was 0x9900ff)\n ACCENT_CYAN: 0x00e6e6, // Increased brightness (was 0x00ffff)\n ACCENT_ORANGE: 0xff8833,\n ACCENT_BLUE: 0x3399ff,\n\n // Korean traditional colors\n KOREAN_RED: 0xc8102e,\n KOREAN_BLUE: 0x003478,\n KOREAN_WHITE: 0xffffff,\n KOREAN_BLACK: 0x000000,\n\n // Text colors - WCAG AA compliant (4.5:1 on dark backgrounds)\n TEXT_PRIMARY: 0xffffff, // White text - maximum contrast (20.3:1 on 0x0a0a0a)\n TEXT_SECONDARY: 0xcccccc, // Light gray - 3:1 contrast for large text (13.1:1 on 0x0a0a0a)\n TEXT_TERTIARY: 0xaaaaaa, // Medium gray - increased brightness (8.5:1 on 0x0a0a0a)\n TEXT_ACCENT: 0x00e6e6, // Bright cyan for emphasis (15.8:1 on 0x0a0a0a)\n TEXT_WARNING: 0xffbb00, // Increased brightness (13.4:1 on 0x0a0a0a)\n TEXT_ERROR: 0xff4444, // Increased brightness (8.2:1 on 0x0a0a0a)\n TEXT_BRIGHT: 0xffffff,\n\n // UI background colors - Very dark for maximum contrast with bright text\n UI_BACKGROUND_DARK: 0x0a0a0a, // Very dark background for WCAG AA (was 0x1a1a2e)\n UI_BACKGROUND_MEDIUM: 0x1a1a1a, // Dark gray for panels (was 0x16213e)\n UI_BACKGROUND_LIGHT: 0x2a2a2a, // Medium dark for cards (was 0x0f0f23)\n UI_STEEL_GRAY: 0x5a6578, // Increased brightness for borders (was 0x4a5568)\n UI_STEEL_GRAY_DARK: 0x3d4758, // Increased brightness (was 0x2d3748)\n UI_BORDER: 0x5a6578, // Increased brightness for 3:1 contrast (was 0x4a5568)\n UI_BORDER_LIGHT: 0x6a6a8a, // Increased brightness (was 0x4a4a6a)\n UI_GRAY: 0x909090, // Increased brightness for disabled states (was 0x808080)\n UI_DISABLED_FILL: 0x3d4758, // Increased brightness (was 0x2d3748)\n UI_DISABLED_BORDER: 0x2a2a3e, // Increased brightness (was 0x1a1a2e)\n UI_DISABLED_BG: 0x444444, // Increased brightness (was 0x333333)\n UI_DISABLED_TEXT: 0x777777, // Increased brightness for readability (was 0x666666)\n\n // Combat effect colors - High contrast for visibility\n CRITICAL_HIT: 0xff4444, // Bright red for critical hits (was 0xff0000)\n BLOCKED_ATTACK: 0x909090, // Increased brightness for blocked attacks (was 0x808080)\n PERFECT_STRIKE: 0xffc400, // Bright gold for perfect strikes (was 0xffd700)\n VITAL_POINT_HIT: 0xff33ff, // Bright magenta for vital points (was 0xff00ff)\n\n // Warning colors - WCAG AA compliant\n WARNING_ORANGE: 0xff7733, // Increased brightness (was 0xff6600)\n WARNING_YELLOW: 0xffff33, // Slightly reduced for visibility (was 0xffff00)\n\n // Additional UI colors - Focus and active states\n ACTIVE_BORDER: 0x00e6e6, // Bright cyan for active states (was 0x00ffff)\n\n // Stance-specific colors (Trigram colors)\n TRIGRAM_GEON_PRIMARY: 0xffd700, // Heaven - White\n TRIGRAM_TAE_PRIMARY: 0x87ceeb, // Lake - Sky Blue\n TRIGRAM_LI_PRIMARY: 0xff4500, // Fire - Orange Red\n TRIGRAM_JIN_PRIMARY: 0x9370db, // Thunder - Yellow\n TRIGRAM_SON_PRIMARY: 0x32cd32, // Wind - Light Green\n TRIGRAM_GAM_PRIMARY: 0x1e90ff, // Water - Blue\n TRIGRAM_GAN_PRIMARY: 0x8b4513, // Mountain - Brown\n TRIGRAM_GON_PRIMARY: 0x2f4f4f, // Earth - Dark Khaki\n\n // Status colors\n POSITIVE_GREEN: 0x00ff00,\n POSITIVE_GREEN_DARK: 0x006600,\n NEGATIVE_RED: 0xff0000,\n NEGATIVE_RED_DARK: 0x990000,\n NEGATIVE_RED_LIGHT: 0xff4444, // Fix: Add missing NEGATIVE_RED_LIGHT\n NEUTRAL_GRAY: 0x808080,\n\n // Solid colors\n WHITE_SOLID: 0xffffff,\n BLACK_SOLID: 0x000000,\n BLACK: 0x000000, // Fix: Add missing BLACK\n TRANSPARENT: 0x000000, // With alpha 0\n\n // Health bar colors\n HEALTH_FULL: 0x00ff00,\n HEALTH_MEDIUM: 0xffff00,\n HEALTH_LOW: 0xff6600,\n HEALTH_CRITICAL: 0xff0000,\n\n // Ki/Energy colors\n KI_FULL: 0x00ffff,\n KI_MEDIUM: 0x0099cc,\n KI_LOW: 0x006699,\n KI_EMPTY: 0x003366,\n\n // Stamina colors\n STAMINA_FULL: 0xffff00,\n STAMINA_MEDIUM: 0xffcc00,\n STAMINA_LOW: 0xff9900,\n STAMINA_EMPTY: 0xff6600,\n\n // Consciousness colors\n CONSCIOUSNESS_PURPLE: 0x9370db,\n \n // Pain indicator colors\n PAIN_INDICATOR: 0xff6b6b,\n \n // Blood loss colors\n BLOODLOSS_INDICATOR: 0xcc0000,\n\n // Muscle system colors (근육 시스템 색상)\n MUSCLE_TONE: 0xd4a373, // Base muscle tone - tan/brown\n MUSCLE_FLEXED: 0xe8b896, // Flexed muscle - lighter tan\n MUSCLE_EXHAUSTED: 0xa67856, // Exhausted muscle - darker brown\n SKIN_TONE: 0xf5d7b1, // Skin/fat layer - light peachy tone\n\n // Fix: Add missing color constants for game components\n ARENA_BACKGROUND: 0x1a1a2e,\n PLAYER_1_COLOR: 0x00ccff, // Cyan for player 1\n PLAYER_2_COLOR: 0xff6b35, // Orange for player 2\n SECONDARY_BLUE: 0x3366cc,\n SECONDARY_BLUE_LIGHT: 0x5588ee,\n SECONDARY_BLUE_DARK: 0x1144aa,\n\n // Cyberpunk neon colors (add for NEON_CYAN and others)\n NEON_CYAN: 0x00ffff, // Neon cyan for cyberpunk UI\n NEON_PURPLE: 0xff00ff,\n NEON_GREEN: 0x00ff00,\n NEON_PINK: 0xff1493,\n} as const;\n\n// Cyberpunk color palette\nexport const CYBERPUNK_COLORS = {\n // Primary neon colors - 사이버펑크 네온 색상\n NEON_CYAN: 0x00ffff, // 네온 시안 - Primary UI\n NEON_PURPLE: 0xff00ff, // 네온 보라 - Secondary accents\n NEON_GREEN: 0x00ff00, // 네온 초록 - Success states\n NEON_PINK: 0xff1493, // 네온 핑크 - Special effects\n\n // Accent colors - 강조 색상\n ACCENT_BLUE: 0x0080ff, // 강조 파랑 - Interactive elements\n ACCENT_ORANGE: 0xff8000, // 강조 주황 - Warning/action\n ACCENT_YELLOW: 0xffff00, // 강조 노랑 - Highlights\n\n // Status colors - 상태 색상\n WARNING_RED: 0xff4444, // 경고 빨강 - Danger/error\n SUCCESS_GREEN: 0x44ff44, // 성공 초록 - Positive feedback\n INFO_BLUE: 0x4444ff, // 정보 파랑 - Information\n\n // Text colors - 텍스트 색상\n TEXT_PRIMARY: 0xffffff, // 주요 텍스트 - High contrast\n TEXT_SECONDARY: 0xcccccc, // 보조 텍스트 - Medium contrast\n TEXT_MUTED: 0x888888, // 음소거 텍스트 - Low contrast\n\n // Background colors - 배경 색상\n BG_DARK: 0x0a0a0a, // 어두운 배경 - Main background\n BG_DARKER: 0x050505, // 더 어두운 배경 - Deep background\n BG_PANEL: 0x1a1a1a, // 패널 배경 - UI panels\n\n // Neutral colors - 중성 색상\n NEUTRAL_GRAY: 0x666666, // 중성 회색 - Disabled states\n NEUTRAL_LIGHT: 0x999999, // 밝은 회색 - Borders\n NEUTRAL_DARK: 0x333333, // 어두운 회색 - Separators\n\n // Special effects - 특수 효과\n SHADOW: 0x000000, // 그림자 - Drop shadows\n GLOW: 0xffffff, // 글로우 - Glow effects\n HIGHLIGHT: 0xffff80, // 하이라이트 - Selection highlight\n} as const;\n\n// Color utility functions\nexport const colorUtils = {\n /**\n * Convert hex color to RGB components\n */\n hexToRgb: (hex: number) => ({\n r: (hex >> 16) & 255,\n g: (hex >> 8) & 255,\n b: hex & 255,\n }),\n\n /**\n * Convert RGB to hex color\n */\n rgbToHex: (r: number, g: number, b: number) => {\n return (r << 16) | (g << 8) | b;\n },\n\n /**\n * Blend two colors\n */\n blend: (color1: number, color2: number, factor: number) => {\n const rgb1 = colorUtils.hexToRgb(color1);\n const rgb2 = colorUtils.hexToRgb(color2);\n\n const r = Math.round(rgb1.r + (rgb2.r - rgb1.r) * factor);\n const g = Math.round(rgb1.g + (rgb2.g - rgb1.g) * factor);\n const b = Math.round(rgb1.b + (rgb2.b - rgb1.b) * factor);\n\n return colorUtils.rgbToHex(r, g, b);\n },\n};\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,gBAAgB;CAE3B,cAAc;CACd,cAAc;CACd,mBAAmB;CAGnB,aAAa;CAGb,mBAAmB;CACnB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,sBAAsB;CAGtB,aAAa;CACb,YAAY;CACZ,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,eAAe;CACf,aAAa;CACb,eAAe;CACf,aAAa;CAGb,YAAY;CACZ,aAAa;CACb,cAAc;CACd,cAAc;CAGd,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,aAAa;CACb,cAAc;CACd,YAAY;CACZ,aAAa;CAGb,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACrB,eAAe;CACf,oBAAoB;CACpB,WAAW;CACX,iBAAiB;CACjB,SAAS;CACT,kBAAkB;CAClB,oBAAoB;CACpB,gBAAgB;CAChB,kBAAkB;CAGlB,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,iBAAiB;CAGjB,gBAAgB;CAChB,gBAAgB;CAGhB,eAAe;CAGf,sBAAsB;CACtB,qBAAqB;CACrB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CAGrB,gBAAgB;CAChB,qBAAqB;CACrB,cAAc;CACd,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CAGd,aAAa;CACb,aAAa;CACb,OAAO;CACP,aAAa;CAGb,aAAa;CACb,eAAe;CACf,YAAY;CACZ,iBAAiB;CAGjB,SAAS;CACT,WAAW;CACX,QAAQ;CACR,UAAU;CAGV,cAAc;CACd,gBAAgB;CAChB,aAAa;CACb,eAAe;CAGf,sBAAsB;CAGtB,gBAAgB;CAGhB,qBAAqB;CAGrB,aAAa;CACb,eAAe;CACf,kBAAkB;CAClB,WAAW;CAGX,kBAAkB;CAClB,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CAGrB,WAAW;CACX,aAAa;CACb,YAAY;CACZ,WAAW;CACZ;AAGD,IAAa,mBAAmB;CAE9B,WAAW;CACX,aAAa;CACb,YAAY;CACZ,WAAW;CAGX,aAAa;CACb,eAAe;CACf,eAAe;CAGf,aAAa;CACb,eAAe;CACf,WAAW;CAGX,cAAc;CACd,gBAAgB;CAChB,YAAY;CAGZ,SAAS;CACT,WAAW;CACX,UAAU;CAGV,cAAc;CACd,eAAe;CACf,cAAc;CAGd,QAAQ;CACR,MAAM;CACN,WAAW;CACZ;AAGD,IAAa,aAAa;;;;CAIxB,WAAW,SAAiB;EAC1B,GAAI,OAAO,KAAM;EACjB,GAAI,OAAO,IAAK;EAChB,GAAG,MAAM;EACV;;;;CAKD,WAAW,GAAW,GAAW,MAAc;AAC7C,SAAQ,KAAK,KAAO,KAAK,IAAK;;;;;CAMhC,QAAQ,QAAgB,QAAgB,WAAmB;EACzD,MAAM,OAAO,WAAW,SAAS,OAAO;EACxC,MAAM,OAAO,WAAW,SAAS,OAAO;EAExC,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;EACzD,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;EACzD,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;AAEzD,SAAO,WAAW,SAAS,GAAG,GAAG,EAAE;;CAEtC"}
|
|
1
|
+
{"version":3,"file":"colors.js","names":[],"sources":["../../../src/types/constants/colors.ts"],"sourcesContent":["/**\n * Color palette for Black Trigram Korean martial arts game\n * Cyberpunk aesthetic with Korean traditional influences\n * \n * WCAG 2.1 Level AA Compliance:\n * - Text colors meet 4.5:1 contrast ratio on dark backgrounds\n * - UI elements meet 3:1 contrast ratio\n * - Focus indicators use 2px borders with high contrast\n * \n * @see https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html\n */\n\n// Primary color palette\nexport const KOREAN_COLORS = {\n // Primary colors (Cyberpunk neon) - WCAG AA compliant on dark backgrounds\n PRIMARY_CYAN: 0x00e6e6, // Increased brightness for better contrast (was 0x00ffff)\n PRIMARY_BLUE: 0x0066ff,\n PRIMARY_BLUE_DARK: 0x003399,\n\n // Fix: Add missing PRIMARY_RED color\n PRIMARY_RED: 0xff4444, // Increased brightness for contrast (was 0xff3333)\n\n // Secondary colors - WCAG AA compliant\n SECONDARY_MAGENTA: 0xff33ff, // Increased brightness\n SECONDARY_PURPLE: 0xaa44ff, // Increased brightness (was 0x9900ff)\n SECONDARY_YELLOW: 0xffff33, // Slightly reduced for better visibility\n SECONDARY_ORANGE: 0xff7733, // Increased brightness (was 0xff6600)\n SECONDARY_BROWN_DARK: 0x8b4513,\n\n // Accent colors - WCAG AA compliant\n ACCENT_GOLD: 0xffc400, // Increased brightness for contrast (was 0xffd700)\n ACCENT_RED: 0xff4444, // Increased brightness (was 0xff3333)\n ACCENT_GREEN: 0x44ff44, // Increased brightness (was 0x00ff33)\n ACCENT_PRIMARY: 0x00d4ff,\n ACCENT_YELLOW: 0xffff33, // Slightly reduced for visibility (was 0xffff00)\n ACCENT_PURPLE: 0xaa44ff, // Increased brightness (was 0x9900ff)\n ACCENT_CYAN: 0x00e6e6, // Increased brightness (was 0x00ffff)\n ACCENT_ORANGE: 0xff8833,\n ACCENT_BLUE: 0x3399ff,\n\n // Korean traditional colors\n KOREAN_RED: 0xc8102e,\n KOREAN_BLUE: 0x003478,\n KOREAN_WHITE: 0xffffff,\n KOREAN_BLACK: 0x000000,\n\n // Text colors - WCAG AA compliant (4.5:1 on dark backgrounds)\n TEXT_PRIMARY: 0xffffff, // White text - maximum contrast (20.3:1 on 0x0a0a0a)\n TEXT_SECONDARY: 0xcccccc, // Light gray - 3:1 contrast for large text (13.1:1 on 0x0a0a0a)\n TEXT_TERTIARY: 0xaaaaaa, // Medium gray - increased brightness (8.5:1 on 0x0a0a0a)\n TEXT_ACCENT: 0x00e6e6, // Bright cyan for emphasis (15.8:1 on 0x0a0a0a)\n TEXT_WARNING: 0xffbb00, // Increased brightness (13.4:1 on 0x0a0a0a)\n TEXT_ERROR: 0xff4444, // Increased brightness (8.2:1 on 0x0a0a0a)\n TEXT_BRIGHT: 0xffffff,\n\n // UI background colors - Very dark for maximum contrast with bright text\n UI_BACKGROUND_DARK: 0x0a0a0a, // Very dark background for WCAG AA (was 0x1a1a2e)\n UI_BACKGROUND_MEDIUM: 0x1a1a1a, // Dark gray for panels (was 0x16213e)\n UI_BACKGROUND_LIGHT: 0x2a2a2a, // Medium dark for cards (was 0x0f0f23)\n UI_STEEL_GRAY: 0x5a6578, // Increased brightness for borders (was 0x4a5568)\n UI_STEEL_GRAY_DARK: 0x3d4758, // Increased brightness (was 0x2d3748)\n UI_BORDER: 0x5a6578, // Increased brightness for 3:1 contrast (was 0x4a5568)\n UI_BORDER_LIGHT: 0x6a6a8a, // Increased brightness (was 0x4a4a6a)\n UI_GRAY: 0x909090, // Increased brightness for disabled states (was 0x808080)\n UI_DISABLED_FILL: 0x3d4758, // Increased brightness (was 0x2d3748)\n UI_DISABLED_BORDER: 0x2a2a3e, // Increased brightness (was 0x1a1a2e)\n UI_DISABLED_BG: 0x444444, // Increased brightness (was 0x333333)\n UI_DISABLED_TEXT: 0x777777, // Increased brightness for readability (was 0x666666)\n\n // Combat effect colors - High contrast for visibility\n CRITICAL_HIT: 0xff4444, // Bright red for critical hits (was 0xff0000)\n BLOCKED_ATTACK: 0x909090, // Increased brightness for blocked attacks (was 0x808080)\n PERFECT_STRIKE: 0xffc400, // Bright gold for perfect strikes (was 0xffd700)\n VITAL_POINT_HIT: 0xff33ff, // Bright magenta for vital points (was 0xff00ff)\n\n // Warning colors - WCAG AA compliant\n WARNING_ORANGE: 0xff7733, // Increased brightness (was 0xff6600)\n WARNING_YELLOW: 0xffff33, // Slightly reduced for visibility (was 0xffff00)\n\n // Additional UI colors - Focus and active states\n ACTIVE_BORDER: 0x00e6e6, // Bright cyan for active states (was 0x00ffff)\n\n // Stance-specific colors (Trigram colors)\n TRIGRAM_GEON_PRIMARY: 0xffd700, // Heaven - White\n TRIGRAM_TAE_PRIMARY: 0x87ceeb, // Lake - Sky Blue\n TRIGRAM_LI_PRIMARY: 0xff4500, // Fire - Orange Red\n TRIGRAM_JIN_PRIMARY: 0x9370db, // Thunder - Yellow\n TRIGRAM_SON_PRIMARY: 0x32cd32, // Wind - Light Green\n TRIGRAM_GAM_PRIMARY: 0x1e90ff, // Water - Blue\n TRIGRAM_GAN_PRIMARY: 0x8b4513, // Mountain - Brown\n TRIGRAM_GON_PRIMARY: 0x2f4f4f, // Earth - Dark Khaki\n\n // Status colors\n POSITIVE_GREEN: 0x00ff00,\n POSITIVE_GREEN_DARK: 0x006600,\n NEGATIVE_RED: 0xff0000,\n NEGATIVE_RED_DARK: 0x990000,\n NEGATIVE_RED_LIGHT: 0xff4444, // Fix: Add missing NEGATIVE_RED_LIGHT\n NEUTRAL_GRAY: 0x808080,\n\n // Solid colors\n WHITE_SOLID: 0xffffff,\n BLACK_SOLID: 0x000000,\n BLACK: 0x000000, // Fix: Add missing BLACK\n TRANSPARENT: 0x000000, // With alpha 0\n\n // Health bar colors\n HEALTH_FULL: 0x00ff00,\n HEALTH_MEDIUM: 0xffff00,\n HEALTH_LOW: 0xff6600,\n HEALTH_CRITICAL: 0xff0000,\n\n // Ki/Energy colors\n KI_FULL: 0x00ffff,\n KI_MEDIUM: 0x0099cc,\n KI_LOW: 0x006699,\n KI_EMPTY: 0x003366,\n\n // Stamina colors\n STAMINA_FULL: 0xffff00,\n STAMINA_MEDIUM: 0xffcc00,\n STAMINA_LOW: 0xff9900,\n STAMINA_EMPTY: 0xff6600,\n\n // Consciousness colors\n CONSCIOUSNESS_PURPLE: 0x9370db,\n \n // Pain indicator colors\n PAIN_INDICATOR: 0xff6b6b,\n \n // Blood loss colors\n BLOODLOSS_INDICATOR: 0xcc0000,\n\n // Muscle system colors (근육 시스템 색상)\n MUSCLE_TONE: 0xd4a373, // Base muscle tone - tan/brown\n MUSCLE_FLEXED: 0xe8b896, // Flexed muscle - lighter tan\n MUSCLE_EXHAUSTED: 0xa67856, // Exhausted muscle - darker brown\n SKIN_TONE: 0xf5d7b1, // Skin/fat layer - light peachy tone\n\n // Fix: Add missing color constants for game components\n ARENA_BACKGROUND: 0x1a1a2e,\n PLAYER_1_COLOR: 0x00ccff, // Cyan for player 1\n PLAYER_2_COLOR: 0xff6b35, // Orange for player 2\n SECONDARY_BLUE: 0x3366cc,\n SECONDARY_BLUE_LIGHT: 0x5588ee,\n SECONDARY_BLUE_DARK: 0x1144aa,\n\n // Cyberpunk neon colors (add for NEON_CYAN and others)\n NEON_CYAN: 0x00ffff, // Neon cyan for cyberpunk UI\n NEON_PURPLE: 0xff00ff,\n NEON_GREEN: 0x00ff00,\n NEON_PINK: 0xff1493,\n} as const;\n\n// Cyberpunk color palette\nexport const CYBERPUNK_COLORS = {\n // Primary neon colors - 사이버펑크 네온 색상\n NEON_CYAN: 0x00ffff, // 네온 시안 - Primary UI\n NEON_PURPLE: 0xff00ff, // 네온 보라 - Secondary accents\n NEON_GREEN: 0x00ff00, // 네온 초록 - Success states\n NEON_PINK: 0xff1493, // 네온 핑크 - Special effects\n\n // Accent colors - 강조 색상\n ACCENT_BLUE: 0x0080ff, // 강조 파랑 - Interactive elements\n ACCENT_ORANGE: 0xff8000, // 강조 주황 - Warning/action\n ACCENT_YELLOW: 0xffff00, // 강조 노랑 - Highlights\n\n // Status colors - 상태 색상\n WARNING_RED: 0xff4444, // 경고 빨강 - Danger/error\n SUCCESS_GREEN: 0x44ff44, // 성공 초록 - Positive feedback\n INFO_BLUE: 0x4444ff, // 정보 파랑 - Information\n\n // Text colors - 텍스트 색상\n TEXT_PRIMARY: 0xffffff, // 주요 텍스트 - High contrast\n TEXT_SECONDARY: 0xcccccc, // 보조 텍스트 - Medium contrast\n TEXT_MUTED: 0x888888, // 음소거 텍스트 - Low contrast\n\n // Background colors - 배경 색상\n BG_DARK: 0x0a0a0a, // 어두운 배경 - Main background\n BG_DARKER: 0x050505, // 더 어두운 배경 - Deep background\n BG_PANEL: 0x1a1a1a, // 패널 배경 - UI panels\n\n // Neutral colors - 중성 색상\n NEUTRAL_GRAY: 0x666666, // 중성 회색 - Disabled states\n NEUTRAL_LIGHT: 0x999999, // 밝은 회색 - Borders\n NEUTRAL_DARK: 0x333333, // 어두운 회색 - Separators\n\n // Special effects - 특수 효과\n SHADOW: 0x000000, // 그림자 - Drop shadows\n GLOW: 0xffffff, // 글로우 - Glow effects\n HIGHLIGHT: 0xffff80, // 하이라이트 - Selection highlight\n} as const;\n\n// Color utility functions\nexport const colorUtils = {\n /**\n * Convert hex color to RGB components\n */\n hexToRgb: (hex: number) => ({\n r: (hex >> 16) & 255,\n g: (hex >> 8) & 255,\n b: hex & 255,\n }),\n\n /**\n * Convert RGB to hex color\n */\n rgbToHex: (r: number, g: number, b: number) => {\n return (r << 16) | (g << 8) | b;\n },\n\n /**\n * Blend two colors\n */\n blend: (color1: number, color2: number, factor: number) => {\n const rgb1 = colorUtils.hexToRgb(color1);\n const rgb2 = colorUtils.hexToRgb(color2);\n\n const r = Math.round(rgb1.r + (rgb2.r - rgb1.r) * factor);\n const g = Math.round(rgb1.g + (rgb2.g - rgb1.g) * factor);\n const b = Math.round(rgb1.b + (rgb2.b - rgb1.b) * factor);\n\n return colorUtils.rgbToHex(r, g, b);\n },\n};\n"],"mappings":";;;;;;;;;;;;AAaA,IAAa,gBAAgB;CAE3B,cAAc;CACd,cAAc;CACd,mBAAmB;CAGnB,aAAa;CAGb,mBAAmB;CACnB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,sBAAsB;CAGtB,aAAa;CACb,YAAY;CACZ,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,eAAe;CACf,aAAa;CACb,eAAe;CACf,aAAa;CAGb,YAAY;CACZ,aAAa;CACb,cAAc;CACd,cAAc;CAGd,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,aAAa;CACb,cAAc;CACd,YAAY;CACZ,aAAa;CAGb,oBAAoB;CACpB,sBAAsB;CACtB,qBAAqB;CACrB,eAAe;CACf,oBAAoB;CACpB,WAAW;CACX,iBAAiB;CACjB,SAAS;CACT,kBAAkB;CAClB,oBAAoB;CACpB,gBAAgB;CAChB,kBAAkB;CAGlB,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,iBAAiB;CAGjB,gBAAgB;CAChB,gBAAgB;CAGhB,eAAe;CAGf,sBAAsB;CACtB,qBAAqB;CACrB,oBAAoB;CACpB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CAGrB,gBAAgB;CAChB,qBAAqB;CACrB,cAAc;CACd,mBAAmB;CACnB,oBAAoB;CACpB,cAAc;CAGd,aAAa;CACb,aAAa;CACb,OAAO;CACP,aAAa;CAGb,aAAa;CACb,eAAe;CACf,YAAY;CACZ,iBAAiB;CAGjB,SAAS;CACT,WAAW;CACX,QAAQ;CACR,UAAU;CAGV,cAAc;CACd,gBAAgB;CAChB,aAAa;CACb,eAAe;CAGf,sBAAsB;CAGtB,gBAAgB;CAGhB,qBAAqB;CAGrB,aAAa;CACb,eAAe;CACf,kBAAkB;CAClB,WAAW;CAGX,kBAAkB;CAClB,gBAAgB;CAChB,gBAAgB;CAChB,gBAAgB;CAChB,sBAAsB;CACtB,qBAAqB;CAGrB,WAAW;CACX,aAAa;CACb,YAAY;CACZ,WAAW;CACZ;AAGD,IAAa,mBAAmB;CAE9B,WAAW;CACX,aAAa;CACb,YAAY;CACZ,WAAW;CAGX,aAAa;CACb,eAAe;CACf,eAAe;CAGf,aAAa;CACb,eAAe;CACf,WAAW;CAGX,cAAc;CACd,gBAAgB;CAChB,YAAY;CAGZ,SAAS;CACT,WAAW;CACX,UAAU;CAGV,cAAc;CACd,eAAe;CACf,cAAc;CAGd,QAAQ;CACR,MAAM;CACN,WAAW;CACZ;AAGD,IAAa,aAAa;;;;CAIxB,WAAW,SAAiB;EAC1B,GAAI,OAAO,KAAM;EACjB,GAAI,OAAO,IAAK;EAChB,GAAG,MAAM;EACV;;;;CAKD,WAAW,GAAW,GAAW,MAAc;EAC7C,OAAQ,KAAK,KAAO,KAAK,IAAK;;;;;CAMhC,QAAQ,QAAgB,QAAgB,WAAmB;EACzD,MAAM,OAAO,WAAW,SAAS,OAAO;EACxC,MAAM,OAAO,WAAW,SAAS,OAAO;EAExC,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;EACzD,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;EACzD,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,OAAO;EAEzD,OAAO,WAAW,SAAS,GAAG,GAAG,EAAE;;CAEtC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"designSystem.js","names":[],"sources":["../../../src/types/constants/designSystem.ts"],"sourcesContent":["/**\n * Design System for Black Trigram HUD Components\n * \n * Provides a unified visual language for cyberpunk Korean-themed interfaces\n * All values based on KOREAN_COLORS and FONT_FAMILY constants\n * \n * Key Principles:\n * - 4px base spacing scale for consistent rhythm\n * - Typography scale optimized for Korean text readability\n * - WCAG AA compliant color hierarchies\n * - Consistent HUD styling with cyberpunk aesthetic\n * \n * @korean 흑괘 HUD 디자인 시스템\n * @module DesignSystem\n */\n\nimport { KOREAN_COLORS } from './colors';\nimport { FONT_FAMILY } from './typography';\n\n/**\n * Convert hex color to RGB string\n * @param hex - Hex color value (e.g., 0x00e6e6)\n * @returns RGB string (e.g., \"0, 230, 230\")\n */\nfunction hexToRgbString(hex: number): string {\n const r = (hex >> 16) & 255;\n const g = (hex >> 8) & 255;\n const b = hex & 255;\n return `${r}, ${g}, ${b}`;\n}\n\n/**\n * Convert hex color to RGB color string\n * @param hex - Hex color value (e.g., 0x00e6e6)\n * @returns RGB color string (e.g., \"rgb(0, 230, 230)\")\n */\nfunction hexToRgb(hex: number): string {\n return `rgb(${hexToRgbString(hex)})`;\n}\n\n/**\n * Typography Scale\n * \n * Optimized for Korean text with proper line-heights and font weights.\n * All sizes include fontFamily to ensure consistent Korean rendering.\n * \n * @korean 타이포그래피 척도\n */\nexport const TYPOGRAPHY = {\n /** Heading 1 - Main titles (24px) */\n heading1: {\n fontSize: '24px',\n fontWeight: 700,\n lineHeight: 1.2,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Heading 2 - Section titles (20px) */\n heading2: {\n fontSize: '20px',\n fontWeight: 600,\n lineHeight: 1.3,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Heading 3 - Subsection titles (16px) */\n heading3: {\n fontSize: '16px',\n fontWeight: 600,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Body - Regular content (14px) */\n body: {\n fontSize: '14px',\n fontWeight: 400,\n lineHeight: 1.5,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Body Small - Secondary content (12px) */\n bodySmall: {\n fontSize: '12px',\n fontWeight: 400,\n lineHeight: 1.5,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Button - Button text (14px, semibold) */\n button: {\n fontSize: '14px',\n fontWeight: 600,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Caption - Labels and hints (10px) */\n caption: {\n fontSize: '10px',\n fontWeight: 400,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Micro - Very small text (9px) - for dense information */\n micro: {\n fontSize: '9px',\n fontWeight: 400,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Nano - Smallest text (8px) - for status indicators */\n nano: {\n fontSize: '8px',\n fontWeight: 400,\n lineHeight: 1.3,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n} as const;\n\n/**\n * Pre-parsed Numeric Typography Values\n * \n * Performance optimization: Numeric font sizes parsed once at module load\n * instead of repeated parseInt calls in component useMemo hooks.\n * \n * @korean 사전 파싱된 타이포그래피 숫자 값\n */\nexport const TYPOGRAPHY_NUMERIC = {\n heading1: 24,\n heading2: 20,\n heading3: 16,\n body: 14,\n bodySmall: 12,\n button: 14,\n caption: 10,\n micro: 9,\n nano: 8,\n} as const;\n\n/**\n * Spacing Scale (4px base)\n * \n * Consistent spacing system for margins, padding, and gaps.\n * Based on 4px increments for visual rhythm.\n * \n * @korean 간격 척도\n */\nexport const SPACING = {\n /** Extra Extra Small - 4px */\n xxs: '4px',\n /** Extra Small - 8px */\n xs: '8px',\n /** Small - 12px */\n sm: '12px',\n /** Medium - 16px */\n md: '16px',\n /** Large - 24px */\n lg: '24px',\n /** Extra Large - 32px */\n xl: '32px',\n /** Extra Extra Large - 48px */\n xxl: '48px',\n} as const;\n\n/**\n * Spacing Adjustments\n * \n * Fine-tuned spacing values for specific layout requirements.\n * Use when standard SPACING scale doesn't provide exact needed value.\n * \n * @korean 간격 조정\n */\nexport const SPACING_ADJUSTMENTS = {\n /** Extra small with minor adjustment - 10px (xs + 2px) */\n xsPlus: '10px',\n /** Small with minor adjustment - 14px (sm + 2px) */\n smPlus: '14px',\n /** Medium with minor adjustment - 18px (md + 2px) */\n mdPlus: '18px',\n /** Small gap for compact layouts - 6px */\n compact: '6px',\n /** \n * Horizontal emphasis - 24px\n * Aliases SPACING.lg for semantic use in wider horizontal padding\n * Defined as 1.5x SPACING.md to emphasize horizontal breathing room\n */\n horizontalEmphasis: '24px',\n /** Micro gap - 3px (for very tight layouts) */\n micro: '3px',\n /** Tiny margin - 2px (for subtle spacing) */\n tiny: '2px',\n} as const;\n\n/**\n * Pre-parsed Numeric Spacing Values\n * \n * Performance optimization: Numeric spacing values parsed once at module load.\n * Eliminates repeated parseInt calls in component calculations.\n * \n * @korean 사전 파싱된 간격 숫자 값\n */\nexport const SPACING_NUMERIC = {\n xxs: 4,\n xs: 8,\n sm: 12,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n // Adjustments\n xsPlus: 10,\n smPlus: 14,\n mdPlus: 18,\n compact: 6,\n horizontalEmphasis: 24,\n micro: 3,\n tiny: 2,\n} as const;\n\n/**\n * Font Size Multipliers\n * \n * Scaling factors for responsive font size calculations.\n * Used to maintain consistent proportions across different screen sizes.\n * \n * @korean 글꼴 크기 배율\n */\nexport const FONT_SIZE_MULTIPLIERS = {\n /** Small title scaling - 60% of base */\n titleSmall: 0.6,\n /** Small message scaling - 75% of base */\n messageSmall: 0.75,\n /** Body small scaling - 87.5% of base */\n bodySmall: 0.875,\n /** Title large scaling - 112.5% of base */\n titleLarge: 1.125,\n} as const;\n\n/**\n * Layout Multipliers\n * \n * Scaling factors for layout calculations.\n * Used to maintain consistent spacing relationships.\n * \n * @korean 레이아웃 배율\n */\nexport const LAYOUT_MULTIPLIERS = {\n /** Gap to padding ratio - 120% */\n gapToPadding: 1.2,\n} as const;\n\n\n\n/**\n * Border Radius Scale\n * \n * Consistent border radius values for UI elements.\n * Provides semantic naming for rounded corners.\n * \n * @korean 테두리 반경 척도\n */\nexport const BORDER_RADIUS = {\n /** None - 0px (sharp corners) */\n none: '0px',\n /** Small - 4px */\n sm: '4px',\n /** Medium - 6px */\n md: '6px',\n /** Large - 8px */\n lg: '8px',\n /** Extra Large - 12px */\n xl: '12px',\n /** Full - 9999px (pill shape) */\n full: '9999px',\n} as const;\n\n/**\n * HUD Style Constants\n * \n * Unified styling for all HUD panels with cyberpunk Korean aesthetic.\n * Includes backgrounds, borders, shadows, and interactive states.\n * \n * @korean HUD 스타일 상수\n */\nexport const HUD_STYLE = {\n /** Background - Dark with 85% opacity */\n background: `rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, 0.85)`,\n /** Background RGB for gradient stops */\n backgroundRgb: hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK),\n /** Border - 2px solid cyan */\n border: `2px solid ${hexToRgb(KOREAN_COLORS.PRIMARY_CYAN)}`,\n /** Border radius - 8px for smooth corners (from BORDER_RADIUS.lg) */\n borderRadius: BORDER_RADIUS.lg,\n /** Box shadow - Subtle depth */\n shadow: `0 4px 12px rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, 0.6)`,\n /** Hover shadow - Increased depth on interaction */\n shadowHover: `0 6px 20px rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.3)`,\n /** Backdrop filter - Blur for glassmorphism */\n backdropFilter: 'blur(8px)',\n /** Accent glow - For important elements */\n accentGlow: `0 0 10px rgba(${hexToRgbString(KOREAN_COLORS.ACCENT_GOLD)}, 0.5)`,\n /** Cyan glow - For primary highlights */\n cyanGlow: `0 0 10px rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.5)`,\n} as const;\n\n/**\n * Color Hierarchy for Text and UI Elements\n * \n * WCAG AA compliant color system for different levels of visual emphasis.\n * All colors formatted as RGB strings for easy opacity manipulation.\n * \n * @korean 색상 계층\n */\nexport const HIERARCHY = {\n /** Primary - Main content (White - highest contrast) */\n primary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_PRIMARY),\n hex: KOREAN_COLORS.TEXT_PRIMARY,\n },\n /** Secondary - Supporting content (Light gray) */\n secondary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_SECONDARY),\n hex: KOREAN_COLORS.TEXT_SECONDARY,\n },\n /** Tertiary - Subtle content (Medium gray) */\n tertiary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_TERTIARY),\n hex: KOREAN_COLORS.TEXT_TERTIARY,\n },\n /** Muted - Disabled or inactive (Dark gray) */\n muted: {\n color: hexToRgb(KOREAN_COLORS.UI_DISABLED_TEXT),\n hex: KOREAN_COLORS.UI_DISABLED_TEXT,\n },\n /** Accent - Emphasis and highlights (Cyan) */\n accent: {\n color: hexToRgb(KOREAN_COLORS.PRIMARY_CYAN),\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Gold - Special emphasis (Gold) */\n gold: {\n color: hexToRgb(KOREAN_COLORS.ACCENT_GOLD),\n hex: KOREAN_COLORS.ACCENT_GOLD,\n },\n /** Accent with 70% opacity - For subtle emphasis */\n accent70: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.7)`,\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Accent with 50% opacity - For backgrounds */\n accent50: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.5)`,\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Primary with 80% opacity - For hover states */\n primary80: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.TEXT_PRIMARY)}, 0.8)`,\n hex: KOREAN_COLORS.TEXT_PRIMARY,\n },\n} as const;\n\n/**\n * Border Styles for Different UI States\n * \n * @korean 테두리 스타일\n */\nexport const BORDERS = {\n /** Default border - Cyan 40% opacity */\n default: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.4)`,\n /** Accent border - Gold for emphasis */\n accent: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.ACCENT_GOLD)}, 0.6)`,\n /** Muted border - Gray for subtle separation */\n muted: `1px solid rgba(${hexToRgbString(KOREAN_COLORS.UI_STEEL_GRAY)}, 0.3)`,\n /** Active border - Full cyan for interaction */\n active: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 1.0)`,\n} as const;\n\n/**\n * Gradient Backgrounds\n * \n * Cyberpunk-inspired gradients for panels and overlays.\n * \n * @korean 그라디언트 배경\n */\nexport const GRADIENTS = {\n /** Vertical fade - Top to bottom */\n vertical: (opacity: number = 0.85) =>\n `linear-gradient(180deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.7}) 100%)`,\n /** Vertical fade (reverse) - Bottom to top */\n verticalReverse: (opacity: number = 0.85) =>\n `linear-gradient(0deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.7}) 100%)`,\n /** Horizontal fade - Left to right */\n horizontal: (opacity: number = 0.85) =>\n `linear-gradient(90deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.4}) 100%)`,\n /** Horizontal fade (reverse) - Right to left */\n horizontalReverse: (opacity: number = 0.85) =>\n `linear-gradient(270deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.4}) 100%)`,\n /** Radial fade - Center outward */\n radial: (opacity: number = 0.85) =>\n `radial-gradient(circle, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.5}) 100%)`,\n} as const;\n\n/**\n * Transition Timings\n * \n * Consistent animation durations for smooth interactions.\n * \n * @korean 전환 타이밍\n */\nexport const TRANSITIONS = {\n /** Fast - Quick interactions (150ms) */\n fast: '150ms ease-in-out',\n /** Normal - Standard interactions (250ms) */\n normal: '250ms ease-in-out',\n /** Slow - Emphasis animations (400ms) */\n slow: '400ms ease-in-out',\n} as const;\n\n/**\n * Opacity Constants\n * \n * Standard opacity values for consistent transparency effects.\n * \n * @korean 투명도 상수\n */\nexport const OPACITY = {\n /** Base opacity for layered elements */\n base: 0.7,\n /** Opacity increment for stacking */\n increment: 0.1,\n /** High transparency */\n light: 0.3,\n /** Medium transparency */\n medium: 0.5,\n /** Low transparency */\n heavy: 0.8,\n} as const;\n\n/**\n * Combat UI Dimensions\n * \n * Common width and size constraints for combat UI elements.\n * \n * @korean 전투 UI 크기\n */\nexport const COMBAT_UI_DIMENSIONS = {\n /** Combat log minimum width - mobile */\n combatLogMinMobile: '200px',\n /** Combat log minimum width - desktop */\n combatLogMinDesktop: '280px',\n /** Combat log maximum width - mobile (percentage) */\n combatLogMaxMobile: '90%',\n /** Combat log maximum width - desktop */\n combatLogMaxDesktop: '500px',\n /** Combat log maximum width percentage (mobile) - 90% as decimal */\n combatLogMaxWidthPercentMobile: 0.9,\n /** Technique bar width - mobile (full width) */\n techniqueBarWidthMobile: '100%',\n /** Technique bar width - desktop (70% width) */\n techniqueBarWidthDesktop: '70%',\n} as const;\n\n/**\n * Pre-parsed Numeric Combat UI Dimensions\n * \n * Performance optimization: Numeric dimension values parsed once at module load.\n * Eliminates repeated parseInt calls for combat UI dimensions.\n * \n * @korean 사전 파싱된 전투 UI 크기 숫자 값\n */\nexport const COMBAT_UI_DIMENSIONS_NUMERIC = {\n combatLogMinMobile: 200,\n combatLogMinDesktop: 280,\n combatLogMaxDesktop: 500,\n} as const;\n\n/**\n * Text Effects\n * \n * Reusable text shadow effects for emphasis and readability.\n * \n * @korean 텍스트 효과\n */\nexport const TEXT_EFFECTS = {\n /** Dark shadow for contrast on bright backgrounds */\n darkShadow: '0 0 4px rgba(0,0,0,0.8)',\n /** Light glow for emphasis */\n lightGlow: '0 0 8px rgba(255,255,255,0.5)',\n} as const;\n\n/**\n * Get responsive spacing based on screen size\n * \n * Note: This helper function uses parseInt internally for flexibility\n * in returning pixel-suffixed strings. For performance-critical useMemo\n * calculations, prefer using SPACING_NUMERIC constants directly.\n * \n * @param baseSpacing - Base spacing value from SPACING scale\n * @param isMobile - Whether mobile layout is active\n * @param positionScale - Position scale multiplier (for 4K displays)\n * @returns Calculated spacing in pixels\n */\nexport function getResponsiveSpacing(\n baseSpacing: keyof typeof SPACING,\n isMobile: boolean,\n positionScale: number = 1.0\n): string {\n const baseValue = parseInt(SPACING[baseSpacing], 10);\n const scaledValue = isMobile ? baseValue : baseValue * positionScale;\n return `${scaledValue}px`;\n}\n\n/**\n * Get responsive font size based on typography scale\n * \n * Note: This helper function uses parseInt internally for flexibility\n * in returning pixel-suffixed strings. For performance-critical useMemo\n * calculations, prefer using TYPOGRAPHY_NUMERIC constants directly.\n * \n * @param typographyLevel - Typography level from TYPOGRAPHY\n * @param isMobile - Whether mobile layout is active\n * @param positionScale - Position scale multiplier (for 4K displays)\n * @returns Calculated font size in pixels\n */\nexport function getResponsiveFontSize(\n typographyLevel: keyof typeof TYPOGRAPHY,\n isMobile: boolean,\n positionScale: number = 1.0\n): string {\n const baseSize = parseInt(TYPOGRAPHY[typographyLevel].fontSize, 10);\n const scaledSize = isMobile ? baseSize : baseSize * positionScale;\n return `${scaledSize}px`;\n}\n\n/**\n * Type definitions for design system usage\n */\nexport type TypographyLevel = keyof typeof TYPOGRAPHY;\nexport type SpacingLevel = keyof typeof SPACING;\nexport type BorderRadiusLevel = keyof typeof BORDER_RADIUS;\nexport type HierarchyLevel = keyof typeof HIERARCHY;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"designSystem.js","names":[],"sources":["../../../src/types/constants/designSystem.ts"],"sourcesContent":["/**\n * Design System for Black Trigram HUD Components\n * \n * Provides a unified visual language for cyberpunk Korean-themed interfaces\n * All values based on KOREAN_COLORS and FONT_FAMILY constants\n * \n * Key Principles:\n * - 4px base spacing scale for consistent rhythm\n * - Typography scale optimized for Korean text readability\n * - WCAG AA compliant color hierarchies\n * - Consistent HUD styling with cyberpunk aesthetic\n * \n * @korean 흑괘 HUD 디자인 시스템\n * @module DesignSystem\n */\n\nimport { KOREAN_COLORS } from './colors';\nimport { FONT_FAMILY } from './typography';\n\n/**\n * Convert hex color to RGB string\n * @param hex - Hex color value (e.g., 0x00e6e6)\n * @returns RGB string (e.g., \"0, 230, 230\")\n */\nfunction hexToRgbString(hex: number): string {\n const r = (hex >> 16) & 255;\n const g = (hex >> 8) & 255;\n const b = hex & 255;\n return `${r}, ${g}, ${b}`;\n}\n\n/**\n * Convert hex color to RGB color string\n * @param hex - Hex color value (e.g., 0x00e6e6)\n * @returns RGB color string (e.g., \"rgb(0, 230, 230)\")\n */\nfunction hexToRgb(hex: number): string {\n return `rgb(${hexToRgbString(hex)})`;\n}\n\n/**\n * Typography Scale\n * \n * Optimized for Korean text with proper line-heights and font weights.\n * All sizes include fontFamily to ensure consistent Korean rendering.\n * \n * @korean 타이포그래피 척도\n */\nexport const TYPOGRAPHY = {\n /** Heading 1 - Main titles (24px) */\n heading1: {\n fontSize: '24px',\n fontWeight: 700,\n lineHeight: 1.2,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Heading 2 - Section titles (20px) */\n heading2: {\n fontSize: '20px',\n fontWeight: 600,\n lineHeight: 1.3,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Heading 3 - Subsection titles (16px) */\n heading3: {\n fontSize: '16px',\n fontWeight: 600,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Body - Regular content (14px) */\n body: {\n fontSize: '14px',\n fontWeight: 400,\n lineHeight: 1.5,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Body Small - Secondary content (12px) */\n bodySmall: {\n fontSize: '12px',\n fontWeight: 400,\n lineHeight: 1.5,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Button - Button text (14px, semibold) */\n button: {\n fontSize: '14px',\n fontWeight: 600,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Caption - Labels and hints (10px) */\n caption: {\n fontSize: '10px',\n fontWeight: 400,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Micro - Very small text (9px) - for dense information */\n micro: {\n fontSize: '9px',\n fontWeight: 400,\n lineHeight: 1.4,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n /** Nano - Smallest text (8px) - for status indicators */\n nano: {\n fontSize: '8px',\n fontWeight: 400,\n lineHeight: 1.3,\n fontFamily: FONT_FAMILY.KOREAN,\n },\n} as const;\n\n/**\n * Pre-parsed Numeric Typography Values\n * \n * Performance optimization: Numeric font sizes parsed once at module load\n * instead of repeated parseInt calls in component useMemo hooks.\n * \n * @korean 사전 파싱된 타이포그래피 숫자 값\n */\nexport const TYPOGRAPHY_NUMERIC = {\n heading1: 24,\n heading2: 20,\n heading3: 16,\n body: 14,\n bodySmall: 12,\n button: 14,\n caption: 10,\n micro: 9,\n nano: 8,\n} as const;\n\n/**\n * Spacing Scale (4px base)\n * \n * Consistent spacing system for margins, padding, and gaps.\n * Based on 4px increments for visual rhythm.\n * \n * @korean 간격 척도\n */\nexport const SPACING = {\n /** Extra Extra Small - 4px */\n xxs: '4px',\n /** Extra Small - 8px */\n xs: '8px',\n /** Small - 12px */\n sm: '12px',\n /** Medium - 16px */\n md: '16px',\n /** Large - 24px */\n lg: '24px',\n /** Extra Large - 32px */\n xl: '32px',\n /** Extra Extra Large - 48px */\n xxl: '48px',\n} as const;\n\n/**\n * Spacing Adjustments\n * \n * Fine-tuned spacing values for specific layout requirements.\n * Use when standard SPACING scale doesn't provide exact needed value.\n * \n * @korean 간격 조정\n */\nexport const SPACING_ADJUSTMENTS = {\n /** Extra small with minor adjustment - 10px (xs + 2px) */\n xsPlus: '10px',\n /** Small with minor adjustment - 14px (sm + 2px) */\n smPlus: '14px',\n /** Medium with minor adjustment - 18px (md + 2px) */\n mdPlus: '18px',\n /** Small gap for compact layouts - 6px */\n compact: '6px',\n /** \n * Horizontal emphasis - 24px\n * Aliases SPACING.lg for semantic use in wider horizontal padding\n * Defined as 1.5x SPACING.md to emphasize horizontal breathing room\n */\n horizontalEmphasis: '24px',\n /** Micro gap - 3px (for very tight layouts) */\n micro: '3px',\n /** Tiny margin - 2px (for subtle spacing) */\n tiny: '2px',\n} as const;\n\n/**\n * Pre-parsed Numeric Spacing Values\n * \n * Performance optimization: Numeric spacing values parsed once at module load.\n * Eliminates repeated parseInt calls in component calculations.\n * \n * @korean 사전 파싱된 간격 숫자 값\n */\nexport const SPACING_NUMERIC = {\n xxs: 4,\n xs: 8,\n sm: 12,\n md: 16,\n lg: 24,\n xl: 32,\n xxl: 48,\n // Adjustments\n xsPlus: 10,\n smPlus: 14,\n mdPlus: 18,\n compact: 6,\n horizontalEmphasis: 24,\n micro: 3,\n tiny: 2,\n} as const;\n\n/**\n * Font Size Multipliers\n * \n * Scaling factors for responsive font size calculations.\n * Used to maintain consistent proportions across different screen sizes.\n * \n * @korean 글꼴 크기 배율\n */\nexport const FONT_SIZE_MULTIPLIERS = {\n /** Small title scaling - 60% of base */\n titleSmall: 0.6,\n /** Small message scaling - 75% of base */\n messageSmall: 0.75,\n /** Body small scaling - 87.5% of base */\n bodySmall: 0.875,\n /** Title large scaling - 112.5% of base */\n titleLarge: 1.125,\n} as const;\n\n/**\n * Layout Multipliers\n * \n * Scaling factors for layout calculations.\n * Used to maintain consistent spacing relationships.\n * \n * @korean 레이아웃 배율\n */\nexport const LAYOUT_MULTIPLIERS = {\n /** Gap to padding ratio - 120% */\n gapToPadding: 1.2,\n} as const;\n\n\n\n/**\n * Border Radius Scale\n * \n * Consistent border radius values for UI elements.\n * Provides semantic naming for rounded corners.\n * \n * @korean 테두리 반경 척도\n */\nexport const BORDER_RADIUS = {\n /** None - 0px (sharp corners) */\n none: '0px',\n /** Small - 4px */\n sm: '4px',\n /** Medium - 6px */\n md: '6px',\n /** Large - 8px */\n lg: '8px',\n /** Extra Large - 12px */\n xl: '12px',\n /** Full - 9999px (pill shape) */\n full: '9999px',\n} as const;\n\n/**\n * HUD Style Constants\n * \n * Unified styling for all HUD panels with cyberpunk Korean aesthetic.\n * Includes backgrounds, borders, shadows, and interactive states.\n * \n * @korean HUD 스타일 상수\n */\nexport const HUD_STYLE = {\n /** Background - Dark with 85% opacity */\n background: `rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, 0.85)`,\n /** Background RGB for gradient stops */\n backgroundRgb: hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK),\n /** Border - 2px solid cyan */\n border: `2px solid ${hexToRgb(KOREAN_COLORS.PRIMARY_CYAN)}`,\n /** Border radius - 8px for smooth corners (from BORDER_RADIUS.lg) */\n borderRadius: BORDER_RADIUS.lg,\n /** Box shadow - Subtle depth */\n shadow: `0 4px 12px rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, 0.6)`,\n /** Hover shadow - Increased depth on interaction */\n shadowHover: `0 6px 20px rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.3)`,\n /** Backdrop filter - Blur for glassmorphism */\n backdropFilter: 'blur(8px)',\n /** Accent glow - For important elements */\n accentGlow: `0 0 10px rgba(${hexToRgbString(KOREAN_COLORS.ACCENT_GOLD)}, 0.5)`,\n /** Cyan glow - For primary highlights */\n cyanGlow: `0 0 10px rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.5)`,\n} as const;\n\n/**\n * Color Hierarchy for Text and UI Elements\n * \n * WCAG AA compliant color system for different levels of visual emphasis.\n * All colors formatted as RGB strings for easy opacity manipulation.\n * \n * @korean 색상 계층\n */\nexport const HIERARCHY = {\n /** Primary - Main content (White - highest contrast) */\n primary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_PRIMARY),\n hex: KOREAN_COLORS.TEXT_PRIMARY,\n },\n /** Secondary - Supporting content (Light gray) */\n secondary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_SECONDARY),\n hex: KOREAN_COLORS.TEXT_SECONDARY,\n },\n /** Tertiary - Subtle content (Medium gray) */\n tertiary: {\n color: hexToRgb(KOREAN_COLORS.TEXT_TERTIARY),\n hex: KOREAN_COLORS.TEXT_TERTIARY,\n },\n /** Muted - Disabled or inactive (Dark gray) */\n muted: {\n color: hexToRgb(KOREAN_COLORS.UI_DISABLED_TEXT),\n hex: KOREAN_COLORS.UI_DISABLED_TEXT,\n },\n /** Accent - Emphasis and highlights (Cyan) */\n accent: {\n color: hexToRgb(KOREAN_COLORS.PRIMARY_CYAN),\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Gold - Special emphasis (Gold) */\n gold: {\n color: hexToRgb(KOREAN_COLORS.ACCENT_GOLD),\n hex: KOREAN_COLORS.ACCENT_GOLD,\n },\n /** Accent with 70% opacity - For subtle emphasis */\n accent70: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.7)`,\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Accent with 50% opacity - For backgrounds */\n accent50: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.5)`,\n hex: KOREAN_COLORS.PRIMARY_CYAN,\n },\n /** Primary with 80% opacity - For hover states */\n primary80: {\n color: `rgba(${hexToRgbString(KOREAN_COLORS.TEXT_PRIMARY)}, 0.8)`,\n hex: KOREAN_COLORS.TEXT_PRIMARY,\n },\n} as const;\n\n/**\n * Border Styles for Different UI States\n * \n * @korean 테두리 스타일\n */\nexport const BORDERS = {\n /** Default border - Cyan 40% opacity */\n default: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 0.4)`,\n /** Accent border - Gold for emphasis */\n accent: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.ACCENT_GOLD)}, 0.6)`,\n /** Muted border - Gray for subtle separation */\n muted: `1px solid rgba(${hexToRgbString(KOREAN_COLORS.UI_STEEL_GRAY)}, 0.3)`,\n /** Active border - Full cyan for interaction */\n active: `2px solid rgba(${hexToRgbString(KOREAN_COLORS.PRIMARY_CYAN)}, 1.0)`,\n} as const;\n\n/**\n * Gradient Backgrounds\n * \n * Cyberpunk-inspired gradients for panels and overlays.\n * \n * @korean 그라디언트 배경\n */\nexport const GRADIENTS = {\n /** Vertical fade - Top to bottom */\n vertical: (opacity: number = 0.85) =>\n `linear-gradient(180deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.7}) 100%)`,\n /** Vertical fade (reverse) - Bottom to top */\n verticalReverse: (opacity: number = 0.85) =>\n `linear-gradient(0deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.7}) 100%)`,\n /** Horizontal fade - Left to right */\n horizontal: (opacity: number = 0.85) =>\n `linear-gradient(90deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.4}) 100%)`,\n /** Horizontal fade (reverse) - Right to left */\n horizontalReverse: (opacity: number = 0.85) =>\n `linear-gradient(270deg, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.4}) 100%)`,\n /** Radial fade - Center outward */\n radial: (opacity: number = 0.85) =>\n `radial-gradient(circle, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity}) 0%, rgba(${hexToRgbString(KOREAN_COLORS.UI_BACKGROUND_DARK)}, ${opacity * 0.5}) 100%)`,\n} as const;\n\n/**\n * Transition Timings\n * \n * Consistent animation durations for smooth interactions.\n * \n * @korean 전환 타이밍\n */\nexport const TRANSITIONS = {\n /** Fast - Quick interactions (150ms) */\n fast: '150ms ease-in-out',\n /** Normal - Standard interactions (250ms) */\n normal: '250ms ease-in-out',\n /** Slow - Emphasis animations (400ms) */\n slow: '400ms ease-in-out',\n} as const;\n\n/**\n * Opacity Constants\n * \n * Standard opacity values for consistent transparency effects.\n * \n * @korean 투명도 상수\n */\nexport const OPACITY = {\n /** Base opacity for layered elements */\n base: 0.7,\n /** Opacity increment for stacking */\n increment: 0.1,\n /** High transparency */\n light: 0.3,\n /** Medium transparency */\n medium: 0.5,\n /** Low transparency */\n heavy: 0.8,\n} as const;\n\n/**\n * Combat UI Dimensions\n * \n * Common width and size constraints for combat UI elements.\n * \n * @korean 전투 UI 크기\n */\nexport const COMBAT_UI_DIMENSIONS = {\n /** Combat log minimum width - mobile */\n combatLogMinMobile: '200px',\n /** Combat log minimum width - desktop */\n combatLogMinDesktop: '280px',\n /** Combat log maximum width - mobile (percentage) */\n combatLogMaxMobile: '90%',\n /** Combat log maximum width - desktop */\n combatLogMaxDesktop: '500px',\n /** Combat log maximum width percentage (mobile) - 90% as decimal */\n combatLogMaxWidthPercentMobile: 0.9,\n /** Technique bar width - mobile (full width) */\n techniqueBarWidthMobile: '100%',\n /** Technique bar width - desktop (70% width) */\n techniqueBarWidthDesktop: '70%',\n} as const;\n\n/**\n * Pre-parsed Numeric Combat UI Dimensions\n * \n * Performance optimization: Numeric dimension values parsed once at module load.\n * Eliminates repeated parseInt calls for combat UI dimensions.\n * \n * @korean 사전 파싱된 전투 UI 크기 숫자 값\n */\nexport const COMBAT_UI_DIMENSIONS_NUMERIC = {\n combatLogMinMobile: 200,\n combatLogMinDesktop: 280,\n combatLogMaxDesktop: 500,\n} as const;\n\n/**\n * Text Effects\n * \n * Reusable text shadow effects for emphasis and readability.\n * \n * @korean 텍스트 효과\n */\nexport const TEXT_EFFECTS = {\n /** Dark shadow for contrast on bright backgrounds */\n darkShadow: '0 0 4px rgba(0,0,0,0.8)',\n /** Light glow for emphasis */\n lightGlow: '0 0 8px rgba(255,255,255,0.5)',\n} as const;\n\n/**\n * Get responsive spacing based on screen size\n * \n * Note: This helper function uses parseInt internally for flexibility\n * in returning pixel-suffixed strings. For performance-critical useMemo\n * calculations, prefer using SPACING_NUMERIC constants directly.\n * \n * @param baseSpacing - Base spacing value from SPACING scale\n * @param isMobile - Whether mobile layout is active\n * @param positionScale - Position scale multiplier (for 4K displays)\n * @returns Calculated spacing in pixels\n */\nexport function getResponsiveSpacing(\n baseSpacing: keyof typeof SPACING,\n isMobile: boolean,\n positionScale: number = 1.0\n): string {\n const baseValue = parseInt(SPACING[baseSpacing], 10);\n const scaledValue = isMobile ? baseValue : baseValue * positionScale;\n return `${scaledValue}px`;\n}\n\n/**\n * Get responsive font size based on typography scale\n * \n * Note: This helper function uses parseInt internally for flexibility\n * in returning pixel-suffixed strings. For performance-critical useMemo\n * calculations, prefer using TYPOGRAPHY_NUMERIC constants directly.\n * \n * @param typographyLevel - Typography level from TYPOGRAPHY\n * @param isMobile - Whether mobile layout is active\n * @param positionScale - Position scale multiplier (for 4K displays)\n * @returns Calculated font size in pixels\n */\nexport function getResponsiveFontSize(\n typographyLevel: keyof typeof TYPOGRAPHY,\n isMobile: boolean,\n positionScale: number = 1.0\n): string {\n const baseSize = parseInt(TYPOGRAPHY[typographyLevel].fontSize, 10);\n const scaledSize = isMobile ? baseSize : baseSize * positionScale;\n return `${scaledSize}px`;\n}\n\n/**\n * Type definitions for design system usage\n */\nexport type TypographyLevel = keyof typeof TYPOGRAPHY;\nexport type SpacingLevel = keyof typeof SPACING;\nexport type BorderRadiusLevel = keyof typeof BORDER_RADIUS;\nexport type HierarchyLevel = keyof typeof HIERARCHY;\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout.js","names":[],"sources":["../../../src/types/constants/layout.ts"],"sourcesContent":["/**\n * Layout positioning constants for combat and training screens\n * Centralized to prevent magic numbers and ensure consistency\n * \n * @category UI Constants\n * @korean 레이아웃위치상수\n */\n\n/**\n * Bottom positioning for UI elements (in pixels)\n * Values designed to prevent overlap and prioritize gameplay visibility:\n * - Mobile controls at 200px for ergonomic touch access\n * - TechniqueBar lowered to 20px (mobile) / 30px (desktop) to minimize arena obstruction\n * - Back button moved to top-right corner (off-center) for accessibility\n * \n * PRIORITY: Combat arena visibility > TechniqueBar > Mobile controls > Back button\n */\nexport const LAYOUT_BOTTOM_POSITIONS = {\n /** Mobile controls (VirtualDPad, ActionButtons) - must stay at 200px for accessibility */\n MOBILE_CONTROLS: 200,\n \n /** TechniqueBar container - lowered to bottom to prioritize arena visibility */\n TECHNIQUE_BAR: {\n MOBILE: 20, // Near bottom of screen to minimize arena obstruction\n DESKTOP: 30, // Slightly higher on desktop for better visibility\n },\n \n /** TechniqueBar container height (for overlap calculations) */\n TECHNIQUE_BAR_HEIGHT: 180,\n} as const;\n\n/**\n * Mobile touch controls placement ratios:\n * - 24% on short landscape viewports, clamped to 96–120 px, keeps controls\n * below the arena center while preserving thumb reach.\n * - 17% on tall portrait viewports, clamped to 128–200 px, lowers controls\n * toward the nav/home area without colliding with the bottom HUD or browser\n * safe area.\n */\nexport const MOBILE_CONTROLS_PLACEMENT = {\n SHORT_VIEWPORT_RATIO: 0.24,\n TALL_VIEWPORT_RATIO: 0.17,\n SHORT_MIN: 96,\n SHORT_MAX: 120,\n TALL_MIN: 128,\n /** 200 px upper bound intentionally matches LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS. */\n TALL_MAX: LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS,\n} as const;\n\n/**\n * Shared horizontal reservations for HUD side controls.\n *\n * These values keep centered technique cards readable while preserving space\n * for absolutely positioned controls such as the compact volume control and\n * mobile archetype selector.\n */\nexport const HUD_SIDE_CONTROL_RESERVES = {\n /** Compact volume control width (162px) plus interaction margin. */\n VOLUME_CONTROL: 180,\n\n /** Mobile archetype selector reserve in the training bottom HUD. */\n ARCHETYPE_SELECTOR: 180,\n\n /** Embedded mobile technique bar side reserve for compact controls. */\n TECHNIQUE_BAR_MOBILE: 96,\n\n /** Embedded desktop technique bar side reserve for side HUD controls. */\n TECHNIQUE_BAR_DESKTOP: 190,\n} as const;\n\n/**\n * Minimum visual scale before technique cards become unreadable.\n *\n * The 70% threshold preserves readable Korean/English labels and keyboard\n * hints on compact HUDs. Below this value, embedded bars switch to horizontal\n * scrolling instead of shrinking so touch targets and text remain usable.\n *\n * Used by TechniqueBar when calculating whether embedded cards should scale\n * down or remain full size with horizontal scroll.\n */\nexport const TECHNIQUE_BAR_MIN_READABLE_SCALE = 0.7;\n\n/**\n * Training top HUD height ratio.\n *\n * Must match the training context top offset used by useHUDLayout so the\n * top HUD and side HUDs align without overlap across responsive breakpoints.\n */\nexport const TRAINING_TOP_HUD_HEIGHT_PERCENT = 0.06;\n\n/**\n * Top positioning for UI elements (in pixels)\n * Used for elements positioned from the top of the screen\n */\nexport const LAYOUT_TOP_POSITIONS = {\n /** Back to Menu button positioned at top-right */\n BACK_BUTTON: {\n MOBILE: 10, // 10px from top on mobile\n DESKTOP: 20, // 20px from top on desktop\n },\n \n /** Safe area offset for notched devices */\n SAFE_AREA_TOP: 44, // iPhone notch height\n} as const;\n\n/**\n * Helper function to get technique bar bottom position\n * NOTE: positionScale NOT applied to prevent layout bugs on 4K displays\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @returns Bottom position in pixels\n */\nexport function getTechniqueBarBottom(isMobile: boolean): number {\n return isMobile \n ? LAYOUT_BOTTOM_POSITIONS.TECHNIQUE_BAR.MOBILE\n : LAYOUT_BOTTOM_POSITIONS.TECHNIQUE_BAR.DESKTOP;\n}\n\n/**\n * Get mobile controls bottom position.\n *\n * Returns a viewport-responsive band for comfortable D-Pad / ActionButton\n * reach without pushing controls into the arena center. Short landscape\n * viewports use a 96–120 px clamped band, while tall numeric viewports use a\n * 128–200 px clamped band.\n *\n * @param viewportHeight - Optional current viewport height in pixels.\n * When omitted or NaN, returns the 200 px default.\n * Numeric heights >= 500 use the tall viewport ratio\n * clamped to 128–200 px.\n * @returns Bottom position in pixels\n */\nexport function getMobileControlsBottom(viewportHeight?: number): number {\n if (typeof viewportHeight !== \"number\" || Number.isNaN(viewportHeight)) {\n return LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS;\n }\n\n if (viewportHeight < 500) {\n return Math.round(\n Math.max(\n MOBILE_CONTROLS_PLACEMENT.SHORT_MIN,\n Math.min(\n MOBILE_CONTROLS_PLACEMENT.SHORT_MAX,\n viewportHeight * MOBILE_CONTROLS_PLACEMENT.SHORT_VIEWPORT_RATIO,\n ),\n ),\n );\n }\n\n return Math.round(\n Math.max(\n MOBILE_CONTROLS_PLACEMENT.TALL_MIN,\n Math.min(\n MOBILE_CONTROLS_PLACEMENT.TALL_MAX,\n viewportHeight * MOBILE_CONTROLS_PLACEMENT.TALL_VIEWPORT_RATIO,\n ),\n ),\n );\n}\n\n/**\n * Get back button top position for top-right corner placement\n * Includes safe area offset for notched devices\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @param hasSafeArea - Whether device has notch/safe area (default: false)\n * @returns Top position in pixels\n */\nexport function getBackButtonTop(isMobile: boolean, hasSafeArea = false): number {\n const baseTop = isMobile \n ? LAYOUT_TOP_POSITIONS.BACK_BUTTON.MOBILE\n : LAYOUT_TOP_POSITIONS.BACK_BUTTON.DESKTOP;\n \n return hasSafeArea \n ? baseTop + LAYOUT_TOP_POSITIONS.SAFE_AREA_TOP\n : baseTop;\n}\n\n/**\n * Get back button right position for top-right corner placement\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @returns Right position in pixels\n */\nexport function getBackButtonRight(isMobile: boolean): number {\n return isMobile ? 10 : 20;\n}\n\n/**\n * Type for layout position values\n */\nexport type LayoutBottomPosition = number;\nexport type LayoutTopPosition = number;\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,0BAA0B;;CAErC,iBAAiB;;CAGjB,eAAe;EACb,QAAQ;EACR,SAAS;EACV;;CAGD,sBAAsB;CACvB;;;;;;;;;AAUD,IAAa,4BAA4B;CACvC,sBAAsB;CACtB,qBAAqB;CACrB,WAAW;CACX,WAAW;CACX,UAAU;;CAEV,UAAU,wBAAwB;CACnC;;;;;;;;AASD,IAAa,4BAA4B;;CAEvC,gBAAgB;;CAGhB,oBAAoB;;CAGpB,sBAAsB;;CAGtB,uBAAuB;CACxB;;;;;;;;;;;AAYD,IAAa,mCAAmC;;;;;;;AAQhD,IAAa,kCAAkC;;;;;;;;;;;;;;;AA4C/C,SAAgB,wBAAwB,gBAAiC;
|
|
1
|
+
{"version":3,"file":"layout.js","names":[],"sources":["../../../src/types/constants/layout.ts"],"sourcesContent":["/**\n * Layout positioning constants for combat and training screens\n * Centralized to prevent magic numbers and ensure consistency\n * \n * @category UI Constants\n * @korean 레이아웃위치상수\n */\n\n/**\n * Bottom positioning for UI elements (in pixels)\n * Values designed to prevent overlap and prioritize gameplay visibility:\n * - Mobile controls at 200px for ergonomic touch access\n * - TechniqueBar lowered to 20px (mobile) / 30px (desktop) to minimize arena obstruction\n * - Back button moved to top-right corner (off-center) for accessibility\n * \n * PRIORITY: Combat arena visibility > TechniqueBar > Mobile controls > Back button\n */\nexport const LAYOUT_BOTTOM_POSITIONS = {\n /** Mobile controls (VirtualDPad, ActionButtons) - must stay at 200px for accessibility */\n MOBILE_CONTROLS: 200,\n \n /** TechniqueBar container - lowered to bottom to prioritize arena visibility */\n TECHNIQUE_BAR: {\n MOBILE: 20, // Near bottom of screen to minimize arena obstruction\n DESKTOP: 30, // Slightly higher on desktop for better visibility\n },\n \n /** TechniqueBar container height (for overlap calculations) */\n TECHNIQUE_BAR_HEIGHT: 180,\n} as const;\n\n/**\n * Mobile touch controls placement ratios:\n * - 24% on short landscape viewports, clamped to 96–120 px, keeps controls\n * below the arena center while preserving thumb reach.\n * - 17% on tall portrait viewports, clamped to 128–200 px, lowers controls\n * toward the nav/home area without colliding with the bottom HUD or browser\n * safe area.\n */\nexport const MOBILE_CONTROLS_PLACEMENT = {\n SHORT_VIEWPORT_RATIO: 0.24,\n TALL_VIEWPORT_RATIO: 0.17,\n SHORT_MIN: 96,\n SHORT_MAX: 120,\n TALL_MIN: 128,\n /** 200 px upper bound intentionally matches LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS. */\n TALL_MAX: LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS,\n} as const;\n\n/**\n * Shared horizontal reservations for HUD side controls.\n *\n * These values keep centered technique cards readable while preserving space\n * for absolutely positioned controls such as the compact volume control and\n * mobile archetype selector.\n */\nexport const HUD_SIDE_CONTROL_RESERVES = {\n /** Compact volume control width (162px) plus interaction margin. */\n VOLUME_CONTROL: 180,\n\n /** Mobile archetype selector reserve in the training bottom HUD. */\n ARCHETYPE_SELECTOR: 180,\n\n /** Embedded mobile technique bar side reserve for compact controls. */\n TECHNIQUE_BAR_MOBILE: 96,\n\n /** Embedded desktop technique bar side reserve for side HUD controls. */\n TECHNIQUE_BAR_DESKTOP: 190,\n} as const;\n\n/**\n * Minimum visual scale before technique cards become unreadable.\n *\n * The 70% threshold preserves readable Korean/English labels and keyboard\n * hints on compact HUDs. Below this value, embedded bars switch to horizontal\n * scrolling instead of shrinking so touch targets and text remain usable.\n *\n * Used by TechniqueBar when calculating whether embedded cards should scale\n * down or remain full size with horizontal scroll.\n */\nexport const TECHNIQUE_BAR_MIN_READABLE_SCALE = 0.7;\n\n/**\n * Training top HUD height ratio.\n *\n * Must match the training context top offset used by useHUDLayout so the\n * top HUD and side HUDs align without overlap across responsive breakpoints.\n */\nexport const TRAINING_TOP_HUD_HEIGHT_PERCENT = 0.06;\n\n/**\n * Top positioning for UI elements (in pixels)\n * Used for elements positioned from the top of the screen\n */\nexport const LAYOUT_TOP_POSITIONS = {\n /** Back to Menu button positioned at top-right */\n BACK_BUTTON: {\n MOBILE: 10, // 10px from top on mobile\n DESKTOP: 20, // 20px from top on desktop\n },\n \n /** Safe area offset for notched devices */\n SAFE_AREA_TOP: 44, // iPhone notch height\n} as const;\n\n/**\n * Helper function to get technique bar bottom position\n * NOTE: positionScale NOT applied to prevent layout bugs on 4K displays\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @returns Bottom position in pixels\n */\nexport function getTechniqueBarBottom(isMobile: boolean): number {\n return isMobile \n ? LAYOUT_BOTTOM_POSITIONS.TECHNIQUE_BAR.MOBILE\n : LAYOUT_BOTTOM_POSITIONS.TECHNIQUE_BAR.DESKTOP;\n}\n\n/**\n * Get mobile controls bottom position.\n *\n * Returns a viewport-responsive band for comfortable D-Pad / ActionButton\n * reach without pushing controls into the arena center. Short landscape\n * viewports use a 96–120 px clamped band, while tall numeric viewports use a\n * 128–200 px clamped band.\n *\n * @param viewportHeight - Optional current viewport height in pixels.\n * When omitted or NaN, returns the 200 px default.\n * Numeric heights >= 500 use the tall viewport ratio\n * clamped to 128–200 px.\n * @returns Bottom position in pixels\n */\nexport function getMobileControlsBottom(viewportHeight?: number): number {\n if (typeof viewportHeight !== \"number\" || Number.isNaN(viewportHeight)) {\n return LAYOUT_BOTTOM_POSITIONS.MOBILE_CONTROLS;\n }\n\n if (viewportHeight < 500) {\n return Math.round(\n Math.max(\n MOBILE_CONTROLS_PLACEMENT.SHORT_MIN,\n Math.min(\n MOBILE_CONTROLS_PLACEMENT.SHORT_MAX,\n viewportHeight * MOBILE_CONTROLS_PLACEMENT.SHORT_VIEWPORT_RATIO,\n ),\n ),\n );\n }\n\n return Math.round(\n Math.max(\n MOBILE_CONTROLS_PLACEMENT.TALL_MIN,\n Math.min(\n MOBILE_CONTROLS_PLACEMENT.TALL_MAX,\n viewportHeight * MOBILE_CONTROLS_PLACEMENT.TALL_VIEWPORT_RATIO,\n ),\n ),\n );\n}\n\n/**\n * Get back button top position for top-right corner placement\n * Includes safe area offset for notched devices\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @param hasSafeArea - Whether device has notch/safe area (default: false)\n * @returns Top position in pixels\n */\nexport function getBackButtonTop(isMobile: boolean, hasSafeArea = false): number {\n const baseTop = isMobile \n ? LAYOUT_TOP_POSITIONS.BACK_BUTTON.MOBILE\n : LAYOUT_TOP_POSITIONS.BACK_BUTTON.DESKTOP;\n \n return hasSafeArea \n ? baseTop + LAYOUT_TOP_POSITIONS.SAFE_AREA_TOP\n : baseTop;\n}\n\n/**\n * Get back button right position for top-right corner placement\n * \n * @param isMobile - Whether device is mobile (<768px)\n * @returns Right position in pixels\n */\nexport function getBackButtonRight(isMobile: boolean): number {\n return isMobile ? 10 : 20;\n}\n\n/**\n * Type for layout position values\n */\nexport type LayoutBottomPosition = number;\nexport type LayoutTopPosition = number;\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,0BAA0B;;CAErC,iBAAiB;;CAGjB,eAAe;EACb,QAAQ;EACR,SAAS;EACV;;CAGD,sBAAsB;CACvB;;;;;;;;;AAUD,IAAa,4BAA4B;CACvC,sBAAsB;CACtB,qBAAqB;CACrB,WAAW;CACX,WAAW;CACX,UAAU;;CAEV,UAAU,wBAAwB;CACnC;;;;;;;;AASD,IAAa,4BAA4B;;CAEvC,gBAAgB;;CAGhB,oBAAoB;;CAGpB,sBAAsB;;CAGtB,uBAAuB;CACxB;;;;;;;;;;;AAYD,IAAa,mCAAmC;;;;;;;AAQhD,IAAa,kCAAkC;;;;;;;;;;;;;;;AA4C/C,SAAgB,wBAAwB,gBAAiC;CACvE,IAAI,OAAO,mBAAmB,YAAY,OAAO,MAAM,eAAe,EACpE,OAAO,wBAAwB;CAGjC,IAAI,iBAAiB,KACnB,OAAO,KAAK,MACV,KAAK,IACH,0BAA0B,WAC1B,KAAK,IACH,0BAA0B,WAC1B,iBAAiB,0BAA0B,qBAC5C,CACF,CACF;CAGH,OAAO,KAAK,MACV,KAAK,IACH,0BAA0B,UAC1B,KAAK,IACH,0BAA0B,UAC1B,iBAAiB,0BAA0B,oBAC5C,CACF,CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"performance.js","names":[],"sources":["../../../src/types/constants/performance.ts"],"sourcesContent":["/**\n * Performance constants and optimization settings for Black Trigram\n * \n * Optimized settings for different device categories to maintain 60fps target\n * Special attention to low-end mobile devices (<380px, older hardware)\n * \n * @module types/constants/performance\n * @category Performance\n * @korean 성능설정상수\n */\n\n/**\n * Performance tier levels based on device capabilities\n * \n * @category Performance\n * @korean 성능등급\n */\nexport type PerformanceTier = 'low' | 'medium' | 'high' | 'mobile-high';\n\n/**\n * Performance settings for different device tiers\n * Balances visual quality with frame rate targets\n * \n * @category Performance\n * @korean 성능설정\n */\nexport interface PerformanceSettings {\n /** Maximum particle count for effects */\n readonly maxParticles: number;\n /** Shadow map resolution (512, 1024, 2048) */\n readonly shadowMapSize: number;\n /** Enable antialiasing */\n readonly antialias: boolean;\n /** Device pixel ratio limit ([min, max] or single value) */\n readonly dpr: number | [number, number];\n /** Enable post-processing effects */\n readonly postProcessing: boolean;\n /** Target frame rate (fps) */\n readonly targetFPS: number;\n}\n\n/**\n * Performance settings by tier\n * \n * Low tier: Extra-small mobile (<380px), older devices, budget hardware\n * Medium tier: Standard mobile (380-768px), tablets\n * Mobile-high tier: High-resolution mobile devices (≥768px, 2K+, Motorola Edge, etc.)\n * High tier: Desktop, large displays, modern hardware\n * \n * @constant\n * @category Performance\n * @korean 성능등급별설정\n */\nexport const PERFORMANCE_SETTINGS_BY_TIER: Record<PerformanceTier, PerformanceSettings> = {\n low: {\n maxParticles: 20,\n shadowMapSize: 512,\n antialias: false, // Disable AA for performance\n dpr: 1, // Cap at 1x for low-end devices\n postProcessing: false,\n targetFPS: 50, // Realistic target for low-end\n },\n medium: {\n maxParticles: 40,\n shadowMapSize: 1024,\n antialias: true,\n dpr: [1, 2], // Allow up to 2x\n postProcessing: false, // Keep disabled for mobile\n targetFPS: 55,\n },\n 'mobile-high': {\n maxParticles: 50, // Between medium and high\n shadowMapSize: 1536, // Between 1024 and 2048\n antialias: true,\n dpr: [1, 2], // Cap at 2x to keep 2K-4K mobile WebGL buffers sustainable\n postProcessing: false, // Keep disabled for mobile battery life\n targetFPS: 55, // Realistic for high-end mobile\n },\n high: {\n maxParticles: 100,\n shadowMapSize: 2048,\n antialias: true,\n dpr: [1, 2],\n postProcessing: true,\n targetFPS: 60,\n },\n} as const;\n\n/**\n * Determine performance tier based on device characteristics\n * \n * Now properly handles high-resolution mobile devices (Motorola Edge 60 Pro, etc.)\n * by checking isMobile flag before using screen width to determine tier.\n * \n * @param screenWidth - Screen width in pixels\n * @param isMobile - Whether device is mobile (from user-agent detection)\n * @returns Performance tier\n * \n * @example\n * ```typescript\n * getPerformanceTier(320, true); // 'low' (extra-small mobile)\n * getPerformanceTier(768, true); // 'medium' (standard mobile)\n * getPerformanceTier(2712, true); // 'mobile-high' (Motorola Edge 60 Pro, 2K+ mobile)\n * getPerformanceTier(768, false); // 'medium' (tablet)\n * getPerformanceTier(1920, false); // 'high' (desktop)\n * ```\n * \n * @public\n * @korean 성능등급결정\n */\nexport function getPerformanceTier(\n screenWidth: number,\n isMobile: boolean\n): PerformanceTier {\n // Mobile device tiers (user-agent detection takes priority)\n if (isMobile) {\n // Extra-small mobile devices (<380px) are always low tier\n if (screenWidth < 380) {\n return 'low';\n }\n \n // High-resolution mobile devices (≥768px, 2K+ displays like Motorola Edge 60 Pro)\n // Get optimized settings for Super HD mobile displays\n if (screenWidth >= 768) {\n return 'mobile-high';\n }\n \n // Standard mobile devices (380-768px)\n return 'medium';\n }\n \n // Non-mobile devices (tablets and desktop)\n if (screenWidth < 1024) {\n return 'medium'; // Tablet tier\n }\n \n // Desktop and large displays are high tier\n return 'high';\n}\n\n/**\n * Get performance settings for current device\n * \n * Properly handles high-resolution mobile devices (2K+, Super HD) by using\n * the isMobile flag from user-agent detection before screen width classification.\n * \n * This ensures devices like Motorola Edge 60 Pro (2712x1220) get mobile-optimized\n * settings with proper dpr support up to 3.5x for their Super HD displays.\n * \n * @param screenWidth - Screen width in pixels\n * @param isMobile - Whether device is mobile (from user-agent detection)\n * @returns Performance settings object\n * \n * @example\n * ```typescript\n * // Standard mobile (iPhone SE)\n * const settings = getPerformanceSettings(375, true);\n * // { maxParticles: 40, shadowMapSize: 1024, dpr: [1, 2], ... }\n * \n * // High-res mobile (Motorola Edge 60 Pro)\n * const settingsHD = getPerformanceSettings(2712, true);\n * // { maxParticles: 50, shadowMapSize: 1536, dpr: [1, 3.5], ... }\n * \n * // Desktop\n * const settingsDesktop = getPerformanceSettings(1920, false);\n * // { maxParticles: 100, shadowMapSize: 2048, dpr: [1, 2], ... }\n * \n * <Canvas\n * dpr={settings.dpr}\n * gl={{ antialias: settings.antialias }}\n * />\n * ```\n * \n * @public\n * @korean 성능설정얻기\n */\nexport function getPerformanceSettings(\n screenWidth: number,\n isMobile: boolean\n): PerformanceSettings {\n const tier = getPerformanceTier(screenWidth, isMobile);\n return PERFORMANCE_SETTINGS_BY_TIER[tier];\n}\n\n/**\n * Frame time budget in milliseconds for target FPS\n * \n * @constant\n * @category Performance\n * @korean 프레임시간예산\n */\nexport const FRAME_TIME_BUDGET = {\n /** 60fps = 16.67ms per frame */\n FPS_60: 16.67,\n /** 55fps = 18.18ms per frame */\n FPS_55: 18.18,\n /** 50fps = 20ms per frame */\n FPS_50: 20,\n /** 30fps = 33.33ms per frame (minimum acceptable) */\n FPS_30: 33.33,\n} as const;\n\n/**\n * Performance optimization thresholds for mobile\n * \n * Target values for mobile performance optimization:\n * - FPS: 55+ sustained during combat\n * - Draw calls: <100 per frame\n * - Memory: <200MB heap usage\n * - Particle count: 50% of desktop\n * \n * Note: shadowMapSize (512) represents the baseline/minimum for mobile.\n * The adaptive quality system can dynamically adjust above this baseline\n * (512 → 1024 → 1536) when performance allows, providing better visuals\n * on higher-end mobile devices while maintaining the 512 minimum for\n * low-end devices.\n * \n * @constant\n * @category Performance\n * @korean 모바일성능임계값\n */\nexport const MOBILE_PERFORMANCE_THRESHOLDS = {\n /** Target FPS for mobile devices */\n targetFPS: 55,\n /** Minimum acceptable FPS before quality downgrade */\n minAcceptableFPS: 45,\n /** Maximum draw calls per frame */\n maxDrawCalls: 100,\n /** Maximum memory usage in MB */\n maxMemoryMB: 200,\n /** Particle count reduction factor (0.5 = 50% of desktop) */\n particleReduction: 0.5,\n /** Shadow map size for mobile (baseline - adaptive quality can increase) */\n shadowMapSize: 512,\n} as const;\n\n/**\n * Desktop performance thresholds\n * \n * @constant\n * @category Performance\n * @korean 데스크톱성능임계값\n */\nexport const DESKTOP_PERFORMANCE_THRESHOLDS = {\n /** Target FPS for desktop */\n targetFPS: 60,\n /** Minimum acceptable FPS before quality downgrade */\n minAcceptableFPS: 55,\n /** Maximum draw calls per frame */\n maxDrawCalls: 150,\n /** Maximum memory usage in MB */\n maxMemoryMB: 300,\n /** Particle count reduction factor (1.0 = full desktop quality) */\n particleReduction: 1.0,\n /** Shadow map size for desktop */\n shadowMapSize: 2048,\n} as const;\n"],"mappings":";;;;;;;;;;;;;AAqDA,IAAa,+BAA6E;CACxF,KAAK;EACH,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK;EACL,gBAAgB;EAChB,WAAW;EACZ;CACD,QAAQ;EACN,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACD,eAAe;EACb,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACD,MAAM;EACJ,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACF;;;;;;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,mBACd,aACA,UACiB;
|
|
1
|
+
{"version":3,"file":"performance.js","names":[],"sources":["../../../src/types/constants/performance.ts"],"sourcesContent":["/**\n * Performance constants and optimization settings for Black Trigram\n * \n * Optimized settings for different device categories to maintain 60fps target\n * Special attention to low-end mobile devices (<380px, older hardware)\n * \n * @module types/constants/performance\n * @category Performance\n * @korean 성능설정상수\n */\n\n/**\n * Performance tier levels based on device capabilities\n * \n * @category Performance\n * @korean 성능등급\n */\nexport type PerformanceTier = 'low' | 'medium' | 'high' | 'mobile-high';\n\n/**\n * Performance settings for different device tiers\n * Balances visual quality with frame rate targets\n * \n * @category Performance\n * @korean 성능설정\n */\nexport interface PerformanceSettings {\n /** Maximum particle count for effects */\n readonly maxParticles: number;\n /** Shadow map resolution (512, 1024, 2048) */\n readonly shadowMapSize: number;\n /** Enable antialiasing */\n readonly antialias: boolean;\n /** Device pixel ratio limit ([min, max] or single value) */\n readonly dpr: number | [number, number];\n /** Enable post-processing effects */\n readonly postProcessing: boolean;\n /** Target frame rate (fps) */\n readonly targetFPS: number;\n}\n\n/**\n * Performance settings by tier\n * \n * Low tier: Extra-small mobile (<380px), older devices, budget hardware\n * Medium tier: Standard mobile (380-768px), tablets\n * Mobile-high tier: High-resolution mobile devices (≥768px, 2K+, Motorola Edge, etc.)\n * High tier: Desktop, large displays, modern hardware\n * \n * @constant\n * @category Performance\n * @korean 성능등급별설정\n */\nexport const PERFORMANCE_SETTINGS_BY_TIER: Record<PerformanceTier, PerformanceSettings> = {\n low: {\n maxParticles: 20,\n shadowMapSize: 512,\n antialias: false, // Disable AA for performance\n dpr: 1, // Cap at 1x for low-end devices\n postProcessing: false,\n targetFPS: 50, // Realistic target for low-end\n },\n medium: {\n maxParticles: 40,\n shadowMapSize: 1024,\n antialias: true,\n dpr: [1, 2], // Allow up to 2x\n postProcessing: false, // Keep disabled for mobile\n targetFPS: 55,\n },\n 'mobile-high': {\n maxParticles: 50, // Between medium and high\n shadowMapSize: 1536, // Between 1024 and 2048\n antialias: true,\n dpr: [1, 2], // Cap at 2x to keep 2K-4K mobile WebGL buffers sustainable\n postProcessing: false, // Keep disabled for mobile battery life\n targetFPS: 55, // Realistic for high-end mobile\n },\n high: {\n maxParticles: 100,\n shadowMapSize: 2048,\n antialias: true,\n dpr: [1, 2],\n postProcessing: true,\n targetFPS: 60,\n },\n} as const;\n\n/**\n * Determine performance tier based on device characteristics\n * \n * Now properly handles high-resolution mobile devices (Motorola Edge 60 Pro, etc.)\n * by checking isMobile flag before using screen width to determine tier.\n * \n * @param screenWidth - Screen width in pixels\n * @param isMobile - Whether device is mobile (from user-agent detection)\n * @returns Performance tier\n * \n * @example\n * ```typescript\n * getPerformanceTier(320, true); // 'low' (extra-small mobile)\n * getPerformanceTier(768, true); // 'medium' (standard mobile)\n * getPerformanceTier(2712, true); // 'mobile-high' (Motorola Edge 60 Pro, 2K+ mobile)\n * getPerformanceTier(768, false); // 'medium' (tablet)\n * getPerformanceTier(1920, false); // 'high' (desktop)\n * ```\n * \n * @public\n * @korean 성능등급결정\n */\nexport function getPerformanceTier(\n screenWidth: number,\n isMobile: boolean\n): PerformanceTier {\n // Mobile device tiers (user-agent detection takes priority)\n if (isMobile) {\n // Extra-small mobile devices (<380px) are always low tier\n if (screenWidth < 380) {\n return 'low';\n }\n \n // High-resolution mobile devices (≥768px, 2K+ displays like Motorola Edge 60 Pro)\n // Get optimized settings for Super HD mobile displays\n if (screenWidth >= 768) {\n return 'mobile-high';\n }\n \n // Standard mobile devices (380-768px)\n return 'medium';\n }\n \n // Non-mobile devices (tablets and desktop)\n if (screenWidth < 1024) {\n return 'medium'; // Tablet tier\n }\n \n // Desktop and large displays are high tier\n return 'high';\n}\n\n/**\n * Get performance settings for current device\n * \n * Properly handles high-resolution mobile devices (2K+, Super HD) by using\n * the isMobile flag from user-agent detection before screen width classification.\n * \n * This ensures devices like Motorola Edge 60 Pro (2712x1220) get mobile-optimized\n * settings with proper dpr support up to 3.5x for their Super HD displays.\n * \n * @param screenWidth - Screen width in pixels\n * @param isMobile - Whether device is mobile (from user-agent detection)\n * @returns Performance settings object\n * \n * @example\n * ```typescript\n * // Standard mobile (iPhone SE)\n * const settings = getPerformanceSettings(375, true);\n * // { maxParticles: 40, shadowMapSize: 1024, dpr: [1, 2], ... }\n * \n * // High-res mobile (Motorola Edge 60 Pro)\n * const settingsHD = getPerformanceSettings(2712, true);\n * // { maxParticles: 50, shadowMapSize: 1536, dpr: [1, 3.5], ... }\n * \n * // Desktop\n * const settingsDesktop = getPerformanceSettings(1920, false);\n * // { maxParticles: 100, shadowMapSize: 2048, dpr: [1, 2], ... }\n * \n * <Canvas\n * dpr={settings.dpr}\n * gl={{ antialias: settings.antialias }}\n * />\n * ```\n * \n * @public\n * @korean 성능설정얻기\n */\nexport function getPerformanceSettings(\n screenWidth: number,\n isMobile: boolean\n): PerformanceSettings {\n const tier = getPerformanceTier(screenWidth, isMobile);\n return PERFORMANCE_SETTINGS_BY_TIER[tier];\n}\n\n/**\n * Frame time budget in milliseconds for target FPS\n * \n * @constant\n * @category Performance\n * @korean 프레임시간예산\n */\nexport const FRAME_TIME_BUDGET = {\n /** 60fps = 16.67ms per frame */\n FPS_60: 16.67,\n /** 55fps = 18.18ms per frame */\n FPS_55: 18.18,\n /** 50fps = 20ms per frame */\n FPS_50: 20,\n /** 30fps = 33.33ms per frame (minimum acceptable) */\n FPS_30: 33.33,\n} as const;\n\n/**\n * Performance optimization thresholds for mobile\n * \n * Target values for mobile performance optimization:\n * - FPS: 55+ sustained during combat\n * - Draw calls: <100 per frame\n * - Memory: <200MB heap usage\n * - Particle count: 50% of desktop\n * \n * Note: shadowMapSize (512) represents the baseline/minimum for mobile.\n * The adaptive quality system can dynamically adjust above this baseline\n * (512 → 1024 → 1536) when performance allows, providing better visuals\n * on higher-end mobile devices while maintaining the 512 minimum for\n * low-end devices.\n * \n * @constant\n * @category Performance\n * @korean 모바일성능임계값\n */\nexport const MOBILE_PERFORMANCE_THRESHOLDS = {\n /** Target FPS for mobile devices */\n targetFPS: 55,\n /** Minimum acceptable FPS before quality downgrade */\n minAcceptableFPS: 45,\n /** Maximum draw calls per frame */\n maxDrawCalls: 100,\n /** Maximum memory usage in MB */\n maxMemoryMB: 200,\n /** Particle count reduction factor (0.5 = 50% of desktop) */\n particleReduction: 0.5,\n /** Shadow map size for mobile (baseline - adaptive quality can increase) */\n shadowMapSize: 512,\n} as const;\n\n/**\n * Desktop performance thresholds\n * \n * @constant\n * @category Performance\n * @korean 데스크톱성능임계값\n */\nexport const DESKTOP_PERFORMANCE_THRESHOLDS = {\n /** Target FPS for desktop */\n targetFPS: 60,\n /** Minimum acceptable FPS before quality downgrade */\n minAcceptableFPS: 55,\n /** Maximum draw calls per frame */\n maxDrawCalls: 150,\n /** Maximum memory usage in MB */\n maxMemoryMB: 300,\n /** Particle count reduction factor (1.0 = full desktop quality) */\n particleReduction: 1.0,\n /** Shadow map size for desktop */\n shadowMapSize: 2048,\n} as const;\n"],"mappings":";;;;;;;;;;;;;AAqDA,IAAa,+BAA6E;CACxF,KAAK;EACH,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK;EACL,gBAAgB;EAChB,WAAW;EACZ;CACD,QAAQ;EACN,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACD,eAAe;EACb,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACD,MAAM;EACJ,cAAc;EACd,eAAe;EACf,WAAW;EACX,KAAK,CAAC,GAAG,EAAE;EACX,gBAAgB;EAChB,WAAW;EACZ;CACF;;;;;;;;;;;;;;;;;;;;;;;AAwBD,SAAgB,mBACd,aACA,UACiB;CAEjB,IAAI,UAAU;EAEZ,IAAI,cAAc,KAChB,OAAO;EAKT,IAAI,eAAe,KACjB,OAAO;EAIT,OAAO;;CAIT,IAAI,cAAc,MAChB,OAAO;CAIT,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCT,SAAgB,uBACd,aACA,UACqB;CAErB,OAAO,6BADM,mBAAmB,aAAa,SACT;;;;;;;;;AAUtC,IAAa,oBAAoB;;CAE/B,QAAQ;;CAER,QAAQ;;CAER,QAAQ;;CAER,QAAQ;CACT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typography.js","names":[],"sources":["../../../src/types/constants/typography.ts"],"sourcesContent":["/**\n * Typography constants for Black Trigram\n */\n\n// Font Families\nexport const FONT_FAMILY = {\n PRIMARY: '\"Noto Sans KR\", \"Malgun Gothic\", Arial, sans-serif',\n SECONDARY: '\"Nanum Gothic\", Arial, sans-serif',\n MONO: '\"Nanum Gothic Coding\", monospace',\n KOREAN_BATTLE: '\"Noto Sans KR\", Impact, sans-serif',\n CYBER: '\"Orbitron\", \"Noto Sans KR\", monospace',\n SYMBOL: '\"Arial Unicode MS\", Arial, sans-serif',\n KOREAN: '\"Noto Sans KR\", \"Malgun Gothic\", Arial, sans-serif',\n} as const;\n\n// Font sizes\nexport const FONT_SIZES = {\n xsmall: 8,\n tiny: 10,\n small: 12,\n medium: 16,\n large: 20,\n xlarge: 24,\n xxlarge: 28,\n huge: 32,\n title: 36,\n subtitle: 28,\n} as const;\n\n// Font weights\nexport const FONT_WEIGHTS = {\n light: 300,\n normal: 400,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n heavy: 900,\n} as const;\n\n// Korean text sizes\nexport const KOREAN_TEXT_SIZES: Record<string, number> = {\n tiny: 10,\n small: 12,\n medium: 16,\n large: 20,\n xlarge: 24,\n huge: 32,\n title: 36,\n};\n\n/**\n * Korean font sizes optimized for mobile devices\n * Korean characters need ~10-15% larger size than Latin for equal readability\n * \n * UPDATED: Minimum mobile size increased from 14px to 16px for better readability\n * \n * Extra-small: <380px width (iPhone SE, old Android, budget phones)\n * Small: 380-450px width (standard mobile phones)\n * Regular: 450+ width (large phones, tablets, desktop)\n * \n * @category Typography\n * @korean 한글모바일글꼴크기\n */\nexport const KOREAN_MOBILE_FONT_SIZES = {\n SMALL: {\n extraSmall: 15, // 320-380px width (was 13)\n small: 16, // 380-450px width (was 14)\n regular: 17, // 450+ width (was 16)\n },\n MEDIUM: {\n extraSmall: 17, // 320-380px width (was 15)\n small: 18, // 380-450px width (was 17)\n regular: 20, // 450+ width (was 19)\n },\n LARGE: {\n extraSmall: 20, // 320-380px width (was 18)\n small: 22, // 380-450px width (was 20)\n regular: 24, // 450+ width (was 22)\n },\n} as const;\n\n/**\n * Get Korean font size based on screen width\n * Automatically scales Korean text for readability on small screens\n * \n * @param baseSize - Base font size category ('SMALL', 'MEDIUM', 'LARGE')\n * @param screenWidth - Screen width in pixels\n * @returns Optimized font size in pixels\n * \n * @example\n * ```typescript\n * getKoreanFontSize('MEDIUM', 375); // 15 (extra-small)\n * getKoreanFontSize('MEDIUM', 410); // 17 (small)\n * getKoreanFontSize('MEDIUM', 768); // 19 (regular)\n * ```\n * \n * @public\n * @korean 한글글꼴크기얻기\n */\nexport function getKoreanFontSize(\n baseSize: keyof typeof KOREAN_MOBILE_FONT_SIZES,\n screenWidth: number\n): number {\n const sizeMap = KOREAN_MOBILE_FONT_SIZES[baseSize];\n \n if (screenWidth < 380) {\n return sizeMap.extraSmall;\n } else if (screenWidth < 450) {\n return sizeMap.small;\n } else {\n return sizeMap.regular;\n }\n}\n\n// Korean font weights\nexport const KOREAN_FONT_WEIGHTS: Record<string, number> = {\n light: 300,\n normal: 400,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n heavy: 900,\n} as const;\n"],"mappings":";;;;AAKA,IAAa,cAAc;CACzB,SAAS;CACT,WAAW;CACX,MAAM;CACN,eAAe;CACf,OAAO;CACP,QAAQ;CACR,QAAQ;CACT;AAGD,IAAa,aAAa;CACxB,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS;CACT,MAAM;CACN,OAAO;CACP,UAAU;CACX;AAGD,IAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,MAAM;CACN,OAAO;CACR;AAGD,IAAa,oBAA4C;CACvD,MAAM;CACN,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACR;;;;;;;;;;;;;;AAeD,IAAa,2BAA2B;CACtC,OAAO;EACL,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACD,QAAQ;EACN,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACD,OAAO;EACL,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACF;;;;;;;;;;;;;;;;;;;AAoBD,SAAgB,kBACd,UACA,aACQ;CACR,MAAM,UAAU,yBAAyB;
|
|
1
|
+
{"version":3,"file":"typography.js","names":[],"sources":["../../../src/types/constants/typography.ts"],"sourcesContent":["/**\n * Typography constants for Black Trigram\n */\n\n// Font Families\nexport const FONT_FAMILY = {\n PRIMARY: '\"Noto Sans KR\", \"Malgun Gothic\", Arial, sans-serif',\n SECONDARY: '\"Nanum Gothic\", Arial, sans-serif',\n MONO: '\"Nanum Gothic Coding\", monospace',\n KOREAN_BATTLE: '\"Noto Sans KR\", Impact, sans-serif',\n CYBER: '\"Orbitron\", \"Noto Sans KR\", monospace',\n SYMBOL: '\"Arial Unicode MS\", Arial, sans-serif',\n KOREAN: '\"Noto Sans KR\", \"Malgun Gothic\", Arial, sans-serif',\n} as const;\n\n// Font sizes\nexport const FONT_SIZES = {\n xsmall: 8,\n tiny: 10,\n small: 12,\n medium: 16,\n large: 20,\n xlarge: 24,\n xxlarge: 28,\n huge: 32,\n title: 36,\n subtitle: 28,\n} as const;\n\n// Font weights\nexport const FONT_WEIGHTS = {\n light: 300,\n normal: 400,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n heavy: 900,\n} as const;\n\n// Korean text sizes\nexport const KOREAN_TEXT_SIZES: Record<string, number> = {\n tiny: 10,\n small: 12,\n medium: 16,\n large: 20,\n xlarge: 24,\n huge: 32,\n title: 36,\n};\n\n/**\n * Korean font sizes optimized for mobile devices\n * Korean characters need ~10-15% larger size than Latin for equal readability\n * \n * UPDATED: Minimum mobile size increased from 14px to 16px for better readability\n * \n * Extra-small: <380px width (iPhone SE, old Android, budget phones)\n * Small: 380-450px width (standard mobile phones)\n * Regular: 450+ width (large phones, tablets, desktop)\n * \n * @category Typography\n * @korean 한글모바일글꼴크기\n */\nexport const KOREAN_MOBILE_FONT_SIZES = {\n SMALL: {\n extraSmall: 15, // 320-380px width (was 13)\n small: 16, // 380-450px width (was 14)\n regular: 17, // 450+ width (was 16)\n },\n MEDIUM: {\n extraSmall: 17, // 320-380px width (was 15)\n small: 18, // 380-450px width (was 17)\n regular: 20, // 450+ width (was 19)\n },\n LARGE: {\n extraSmall: 20, // 320-380px width (was 18)\n small: 22, // 380-450px width (was 20)\n regular: 24, // 450+ width (was 22)\n },\n} as const;\n\n/**\n * Get Korean font size based on screen width\n * Automatically scales Korean text for readability on small screens\n * \n * @param baseSize - Base font size category ('SMALL', 'MEDIUM', 'LARGE')\n * @param screenWidth - Screen width in pixels\n * @returns Optimized font size in pixels\n * \n * @example\n * ```typescript\n * getKoreanFontSize('MEDIUM', 375); // 15 (extra-small)\n * getKoreanFontSize('MEDIUM', 410); // 17 (small)\n * getKoreanFontSize('MEDIUM', 768); // 19 (regular)\n * ```\n * \n * @public\n * @korean 한글글꼴크기얻기\n */\nexport function getKoreanFontSize(\n baseSize: keyof typeof KOREAN_MOBILE_FONT_SIZES,\n screenWidth: number\n): number {\n const sizeMap = KOREAN_MOBILE_FONT_SIZES[baseSize];\n \n if (screenWidth < 380) {\n return sizeMap.extraSmall;\n } else if (screenWidth < 450) {\n return sizeMap.small;\n } else {\n return sizeMap.regular;\n }\n}\n\n// Korean font weights\nexport const KOREAN_FONT_WEIGHTS: Record<string, number> = {\n light: 300,\n normal: 400,\n regular: 400,\n medium: 500,\n semibold: 600,\n bold: 700,\n heavy: 900,\n} as const;\n"],"mappings":";;;;AAKA,IAAa,cAAc;CACzB,SAAS;CACT,WAAW;CACX,MAAM;CACN,eAAe;CACf,OAAO;CACP,QAAQ;CACR,QAAQ;CACT;AAGD,IAAa,aAAa;CACxB,QAAQ;CACR,MAAM;CACN,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,SAAS;CACT,MAAM;CACN,OAAO;CACP,UAAU;CACX;AAGD,IAAa,eAAe;CAC1B,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,MAAM;CACN,OAAO;CACR;AAGD,IAAa,oBAA4C;CACvD,MAAM;CACN,OAAO;CACP,QAAQ;CACR,OAAO;CACP,QAAQ;CACR,MAAM;CACN,OAAO;CACR;;;;;;;;;;;;;;AAeD,IAAa,2BAA2B;CACtC,OAAO;EACL,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACD,QAAQ;EACN,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACD,OAAO;EACL,YAAY;EACZ,OAAO;EACP,SAAS;EACV;CACF;;;;;;;;;;;;;;;;;;;AAoBD,SAAgB,kBACd,UACA,aACQ;CACR,MAAM,UAAU,yBAAyB;CAEzC,IAAI,cAAc,KAChB,OAAO,QAAQ;MACV,IAAI,cAAc,KACvB,OAAO,QAAQ;MAEf,OAAO,QAAQ;;AAKnB,IAAa,sBAA8C;CACzD,OAAO;CACP,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,MAAM;CACN,OAAO;CACR"}
|