SJLee-0525
commited on
Commit
Β·
ab1ab06
1
Parent(s):
f0f41bc
[TEST] test45
Browse files- README.md +1 -1
- client/frontend/app_ui.py +1 -1
- client/frontend/components/floating_chatbot.py +7 -7
- client/frontend/components/header.py +10 -10
- client/frontend/components/welcome_modal.py +2 -2
- client/frontend/styles/__init__.py +1 -1
- client/frontend/styles/buttons_style.py +3 -3
- client/frontend/styles/chatbot_style.py +4 -4
- client/frontend/styles/custom_css.py +1 -1
- client/frontend/styles/failure_modal_style.py +3 -3
- client/frontend/styles/falling_elements_style.py +1 -1
- client/frontend/styles/history_style.py +3 -3
- client/frontend/styles/result_screen_style.py +3 -3
- client/frontend/styles/theme_style.py +3 -3
- client/utils/elevenlabs_tts.py +2 -2
- voice_app.py +1 -1
README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
---
|
| 2 |
-
title: VOICE
|
| 3 |
emoji: ποΈ
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: pink
|
|
|
|
| 1 |
---
|
| 2 |
+
title: VOICE SEMENTLE
|
| 3 |
emoji: ποΈ
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: pink
|
client/frontend/app_ui.py
CHANGED
|
@@ -75,7 +75,7 @@ class AppUI:
|
|
| 75 |
import json
|
| 76 |
stats_json = json.dumps(stats)
|
| 77 |
|
| 78 |
-
with gr.Blocks(title="VOICE
|
| 79 |
|
| 80 |
# ============== Dashboard Stats (JSμμ μ κ·Ό κ°λ₯) ==============
|
| 81 |
gr.HTML(
|
|
|
|
| 75 |
import json
|
| 76 |
stats_json = json.dumps(stats)
|
| 77 |
|
| 78 |
+
with gr.Blocks(title="VOICE SEMENTLE") as demo:
|
| 79 |
|
| 80 |
# ============== Dashboard Stats (JSμμ μ κ·Ό κ°λ₯) ==============
|
| 81 |
gr.HTML(
|
client/frontend/components/floating_chatbot.py
CHANGED
|
@@ -70,7 +70,7 @@ def build_system_prompt_from_game_state(game_state: Optional[Dict], include_audi
|
|
| 70 |
str: 컨ν
μ€νΈκ° ν¬ν¨λ μμ€ν
ν둬ννΈ
|
| 71 |
"""
|
| 72 |
# κΈ°λ³Έ ν둬ννΈ (Phase 3: Enhanced)
|
| 73 |
-
base_prompt = """You are the help assistant for "
|
| 74 |
|
| 75 |
## Game Mechanics
|
| 76 |
This is a BLIND pronunciation game where:
|
|
@@ -90,7 +90,7 @@ This is a BLIND pronunciation game where:
|
|
| 90 |
## Your Role as Help Assistant
|
| 91 |
You are a friendly, encouraging coach who helps users discover the answer through strategic hints:
|
| 92 |
|
| 93 |
-
1. **Explain the game** - When users are confused, explain
|
| 94 |
2. **Give progressive hints** - Start vague, gradually get more specific with each request
|
| 95 |
3. **Interpret scores intelligently** - Explain what their scores mean and what to try next
|
| 96 |
4. **Build on previous hints** - NEVER repeat hints, always add new information
|
|
@@ -183,7 +183,7 @@ Greet them warmly and help them understand the game:
|
|
| 183 |
**Goal**: Get them to make their first attempt without fear
|
| 184 |
|
| 185 |
**Key Points to Convey**:
|
| 186 |
-
1. This is
|
| 187 |
2. They start COMPLETELY BLIND - no clues about what to say
|
| 188 |
3. First step: Just say ANY word or phrase that comes to mind
|
| 189 |
4. The game will analyze their voice and give similarity scores
|
|
@@ -192,12 +192,12 @@ Greet them warmly and help them understand the game:
|
|
| 192 |
7. First attempts are always wild guesses - that's the fun part!
|
| 193 |
|
| 194 |
**Example Welcome**:
|
| 195 |
-
"Welcome! π Ready to play
|
| 196 |
|
| 197 |
**When they ask questions**:
|
| 198 |
- "How do I play?" β Explain the blind start and score-based discovery
|
| 199 |
- "Give me a hint" β Encourage them to try first: "Take a guess first! Any word works. Then I can help based on your scores."
|
| 200 |
-
- "What should I say?" β "Anything! That's the beauty of
|
| 201 |
- "I'm confused" β Walk them through: speak β get scores β get hints β figure it out"""
|
| 202 |
|
| 203 |
# guesses μΆμΆ
|
|
@@ -309,7 +309,7 @@ Greet them warmly and help them understand the game:
|
|
| 309 |
context_parts.append("Based on their attempts and scores, provide intelligent responses:")
|
| 310 |
context_parts.append("")
|
| 311 |
context_parts.append("**Common Questions**:")
|
| 312 |
-
context_parts.append("- \"How do I play?\" β Explain
|
| 313 |
context_parts.append("- \"Give me a hint\" β Follow the attempt-based progression strategy (see above)")
|
| 314 |
context_parts.append("- \"What should I try next?\" β Analyze their score pattern and suggest strategic next steps")
|
| 315 |
context_parts.append("- \"Why are my scores low?\" β Interpret scores specifically and suggest what to change")
|
|
@@ -506,7 +506,7 @@ class FloatingChatbotComponent:
|
|
| 506 |
game_state: μΈλΆμμ μ λ¬λ°μ gr.BrowserState (UUID ν¬ν¨)
|
| 507 |
"""
|
| 508 |
# μ΄κΈ° νμ λ©μμ§ μ μ
|
| 509 |
-
welcome_message = """Welcome to
|
| 510 |
|
| 511 |
Here's how it works:
|
| 512 |
|
|
|
|
| 70 |
str: 컨ν
μ€νΈκ° ν¬ν¨λ μμ€ν
ν둬ννΈ
|
| 71 |
"""
|
| 72 |
# κΈ°λ³Έ ν둬ννΈ (Phase 3: Enhanced)
|
| 73 |
+
base_prompt = """You are the help assistant for "Audio Sementle" - an innovative pronunciation puzzle game that combines voice recognition with progressive hint discovery.
|
| 74 |
|
| 75 |
## Game Mechanics
|
| 76 |
This is a BLIND pronunciation game where:
|
|
|
|
| 90 |
## Your Role as Help Assistant
|
| 91 |
You are a friendly, encouraging coach who helps users discover the answer through strategic hints:
|
| 92 |
|
| 93 |
+
1. **Explain the game** - When users are confused, explain Audio Sementle mechanics clearly
|
| 94 |
2. **Give progressive hints** - Start vague, gradually get more specific with each request
|
| 95 |
3. **Interpret scores intelligently** - Explain what their scores mean and what to try next
|
| 96 |
4. **Build on previous hints** - NEVER repeat hints, always add new information
|
|
|
|
| 183 |
**Goal**: Get them to make their first attempt without fear
|
| 184 |
|
| 185 |
**Key Points to Convey**:
|
| 186 |
+
1. This is Audio Sementle - a voice-based puzzle game (not just pronunciation practice!)
|
| 187 |
2. They start COMPLETELY BLIND - no clues about what to say
|
| 188 |
3. First step: Just say ANY word or phrase that comes to mind
|
| 189 |
4. The game will analyze their voice and give similarity scores
|
|
|
|
| 192 |
7. First attempts are always wild guesses - that's the fun part!
|
| 193 |
|
| 194 |
**Example Welcome**:
|
| 195 |
+
"Welcome! π Ready to play Audio Sementle? Here's the fun part: you start completely blind - you have NO idea what word or phrase to say! Just speak anything that comes to mind, and the game will tell you how close you are. Based on the scores and hints, you'll figure it out. Don't overthink your first attempt - it's supposed to be a shot in the dark! Need help? Just ask!"
|
| 196 |
|
| 197 |
**When they ask questions**:
|
| 198 |
- "How do I play?" β Explain the blind start and score-based discovery
|
| 199 |
- "Give me a hint" β Encourage them to try first: "Take a guess first! Any word works. Then I can help based on your scores."
|
| 200 |
+
- "What should I say?" β "Anything! That's the beauty of Audio Sementle - you discover what to say through playing."
|
| 201 |
- "I'm confused" β Walk them through: speak β get scores β get hints β figure it out"""
|
| 202 |
|
| 203 |
# guesses μΆμΆ
|
|
|
|
| 309 |
context_parts.append("Based on their attempts and scores, provide intelligent responses:")
|
| 310 |
context_parts.append("")
|
| 311 |
context_parts.append("**Common Questions**:")
|
| 312 |
+
context_parts.append("- \"How do I play?\" β Explain Audio Sementle mechanics with enthusiasm")
|
| 313 |
context_parts.append("- \"Give me a hint\" β Follow the attempt-based progression strategy (see above)")
|
| 314 |
context_parts.append("- \"What should I try next?\" β Analyze their score pattern and suggest strategic next steps")
|
| 315 |
context_parts.append("- \"Why are my scores low?\" β Interpret scores specifically and suggest what to change")
|
|
|
|
| 506 |
game_state: μΈλΆμμ μ λ¬λ°μ gr.BrowserState (UUID ν¬ν¨)
|
| 507 |
"""
|
| 508 |
# μ΄κΈ° νμ λ©μμ§ μ μ
|
| 509 |
+
welcome_message = """Welcome to Audio Sementle! π Get ready for a unique and super fun pronunciation puzzle game where your voice is the key!
|
| 510 |
|
| 511 |
Here's how it works:
|
| 512 |
|
client/frontend/components/header.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
"""
|
| 2 |
-
ν€λ μ»΄ν¬λνΈ - Voice
|
| 3 |
μ λλ©μ΄μ
ν κ·μ¬μ΄ λ‘κ³ λμμΈ
|
| 4 |
|
| 5 |
π¨βπ» λ΄λΉ: κ°λ°μ A
|
|
@@ -9,9 +9,9 @@ import gradio as gr
|
|
| 9 |
|
| 10 |
|
| 11 |
class HeaderComponent:
|
| 12 |
-
"""Voice
|
| 13 |
|
| 14 |
-
# Voice
|
| 15 |
HEADER_HTML_TEMPLATE = """
|
| 16 |
<link href="https://fonts.googleapis.com/css2?family=Lilita+One&family=Bangers&display=swap" rel="stylesheet">
|
| 17 |
<div class="vs-header">
|
|
@@ -21,7 +21,7 @@ class HeaderComponent:
|
|
| 21 |
<span class="title-voice">VOICE</span>
|
| 22 |
</span>
|
| 23 |
<span class="title-line">
|
| 24 |
-
<span class="title-
|
| 25 |
</span>
|
| 26 |
</h1>
|
| 27 |
</div>
|
|
@@ -69,7 +69,7 @@ class HeaderComponent:
|
|
| 69 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 70 |
paint-order: stroke fill;
|
| 71 |
}
|
| 72 |
-
.title-
|
| 73 |
font-size: 90px;
|
| 74 |
font-weight: 500;
|
| 75 |
color: #e8a054;
|
|
@@ -96,7 +96,7 @@ class HeaderComponent:
|
|
| 96 |
8px 8px 0 #082a35,
|
| 97 |
0 0 25px rgba(90, 200, 250, 0.6);
|
| 98 |
}
|
| 99 |
-
.dark .title-
|
| 100 |
color: #e8a054;
|
| 101 |
-webkit-text-stroke: 4px #5c3d1e;
|
| 102 |
text-shadow:
|
|
@@ -118,7 +118,7 @@ class HeaderComponent:
|
|
| 118 |
7px 7px 0 #0d4a5f,
|
| 119 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 120 |
}
|
| 121 |
-
.title-
|
| 122 |
font-size: 72px;
|
| 123 |
letter-spacing: 4px;
|
| 124 |
-webkit-text-stroke: 4px #8b5a2b;
|
|
@@ -136,7 +136,7 @@ class HeaderComponent:
|
|
| 136 |
7px 7px 0 #0d4a5f,
|
| 137 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 138 |
}
|
| 139 |
-
.dark .title-
|
| 140 |
-webkit-text-stroke: 4px #8b5a2b;
|
| 141 |
text-shadow:
|
| 142 |
5px 5px 0 #8b5a2b,
|
|
@@ -157,7 +157,7 @@ class HeaderComponent:
|
|
| 157 |
5px 5px 0 #0d4a5f,
|
| 158 |
0 0 15px rgba(90, 200, 250, 0.5);
|
| 159 |
}
|
| 160 |
-
.title-
|
| 161 |
font-size: 52px;
|
| 162 |
letter-spacing: 3px;
|
| 163 |
-webkit-text-stroke: 3px #8b5a2b;
|
|
@@ -173,7 +173,7 @@ class HeaderComponent:
|
|
| 173 |
5px 5px 0 #082a35,
|
| 174 |
0 0 20px rgba(90, 200, 250, 0.6);
|
| 175 |
}
|
| 176 |
-
.dark .title-
|
| 177 |
-webkit-text-stroke: 3px #5c3d1e;
|
| 178 |
text-shadow:
|
| 179 |
4px 4px 0 #5c3d1e,
|
|
|
|
| 1 |
"""
|
| 2 |
+
ν€λ μ»΄ν¬λνΈ - Voice Sementle μ€νμΌ
|
| 3 |
μ λλ©μ΄μ
ν κ·μ¬μ΄ λ‘κ³ λμμΈ
|
| 4 |
|
| 5 |
π¨βπ» λ΄λΉ: κ°λ°μ A
|
|
|
|
| 9 |
|
| 10 |
|
| 11 |
class HeaderComponent:
|
| 12 |
+
"""Voice Sementle μ€νμΌ ν€λ μ»΄ν¬λνΈ"""
|
| 13 |
|
| 14 |
+
# Voice Sementle μ€νμΌ ν€λ HTML ν
νλ¦Ώ
|
| 15 |
HEADER_HTML_TEMPLATE = """
|
| 16 |
<link href="https://fonts.googleapis.com/css2?family=Lilita+One&family=Bangers&display=swap" rel="stylesheet">
|
| 17 |
<div class="vs-header">
|
|
|
|
| 21 |
<span class="title-voice">VOICE</span>
|
| 22 |
</span>
|
| 23 |
<span class="title-line">
|
| 24 |
+
<span class="title-sementle">SEMENTLE</span>
|
| 25 |
</span>
|
| 26 |
</h1>
|
| 27 |
</div>
|
|
|
|
| 69 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 70 |
paint-order: stroke fill;
|
| 71 |
}
|
| 72 |
+
.title-sementle {
|
| 73 |
font-size: 90px;
|
| 74 |
font-weight: 500;
|
| 75 |
color: #e8a054;
|
|
|
|
| 96 |
8px 8px 0 #082a35,
|
| 97 |
0 0 25px rgba(90, 200, 250, 0.6);
|
| 98 |
}
|
| 99 |
+
.dark .title-sementle {
|
| 100 |
color: #e8a054;
|
| 101 |
-webkit-text-stroke: 4px #5c3d1e;
|
| 102 |
text-shadow:
|
|
|
|
| 118 |
7px 7px 0 #0d4a5f,
|
| 119 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 120 |
}
|
| 121 |
+
.title-sementle {
|
| 122 |
font-size: 72px;
|
| 123 |
letter-spacing: 4px;
|
| 124 |
-webkit-text-stroke: 4px #8b5a2b;
|
|
|
|
| 136 |
7px 7px 0 #0d4a5f,
|
| 137 |
0 0 20px rgba(90, 200, 250, 0.5);
|
| 138 |
}
|
| 139 |
+
.dark .title-sementle {
|
| 140 |
-webkit-text-stroke: 4px #8b5a2b;
|
| 141 |
text-shadow:
|
| 142 |
5px 5px 0 #8b5a2b,
|
|
|
|
| 157 |
5px 5px 0 #0d4a5f,
|
| 158 |
0 0 15px rgba(90, 200, 250, 0.5);
|
| 159 |
}
|
| 160 |
+
.title-sementle {
|
| 161 |
font-size: 52px;
|
| 162 |
letter-spacing: 3px;
|
| 163 |
-webkit-text-stroke: 3px #8b5a2b;
|
|
|
|
| 173 |
5px 5px 0 #082a35,
|
| 174 |
0 0 20px rgba(90, 200, 250, 0.6);
|
| 175 |
}
|
| 176 |
+
.dark .title-sementle {
|
| 177 |
-webkit-text-stroke: 3px #5c3d1e;
|
| 178 |
text-shadow:
|
| 179 |
4px 4px 0 #5c3d1e,
|
client/frontend/components/welcome_modal.py
CHANGED
|
@@ -28,12 +28,12 @@ class WelcomeModal:
|
|
| 28 |
<div class="welcome-modal-overlay" data-welcome-overlay="true">
|
| 29 |
<div class="welcome-modal-container">
|
| 30 |
<div class="welcome-modal-content">
|
| 31 |
-
<h2 class="welcome-modal-title">Welcome to Voice
|
| 32 |
|
| 33 |
<div class="welcome-modal-video">
|
| 34 |
<iframe
|
| 35 |
src="https://www.youtube.com/embed/${value.videoId || 'YbCf6x0B3fU'}?rel=0&modestbranding=1"
|
| 36 |
-
title="Voice
|
| 37 |
frameborder="0"
|
| 38 |
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
| 39 |
referrerpolicy="strict-origin-when-cross-origin"
|
|
|
|
| 28 |
<div class="welcome-modal-overlay" data-welcome-overlay="true">
|
| 29 |
<div class="welcome-modal-container">
|
| 30 |
<div class="welcome-modal-content">
|
| 31 |
+
<h2 class="welcome-modal-title">Welcome to Voice Sementle!</h2>
|
| 32 |
|
| 33 |
<div class="welcome-modal-video">
|
| 34 |
<iframe
|
| 35 |
src="https://www.youtube.com/embed/${value.videoId || 'YbCf6x0B3fU'}?rel=0&modestbranding=1"
|
| 36 |
+
title="Voice Sementle Tutorial"
|
| 37 |
frameborder="0"
|
| 38 |
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
| 39 |
referrerpolicy="strict-origin-when-cross-origin"
|
client/frontend/styles/__init__.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
"""
|
| 2 |
-
Voice
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ 체 μ ν리μΌμ΄μ
CSS
|
| 4 |
"""
|
| 5 |
|
|
|
|
| 1 |
"""
|
| 2 |
+
Voice Sementle μ€νμΌ λͺ¨λ
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ 체 μ ν리μΌμ΄μ
CSS
|
| 4 |
"""
|
| 5 |
|
client/frontend/styles/buttons_style.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
λ²νΌ λ° μ€λμ€ μ
λ ₯ CSS - Voice
|
| 3 |
λ²νΌ μ€νμΌ λ° μ€λμ€ μ»΄ν¬λνΈ μ€νμΌλ§
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# Voice
|
| 7 |
BUTTON_CSS = """
|
| 8 |
-
/* Voice
|
| 9 |
#verify-btn,
|
| 10 |
#restart-btn {
|
| 11 |
font-family: 'Lilita One' !important;
|
|
|
|
| 1 |
"""
|
| 2 |
+
λ²νΌ λ° μ€λμ€ μ
λ ₯ CSS - Voice Sementle ν
λ§
|
| 3 |
λ²νΌ μ€νμΌ λ° μ€λμ€ μ»΄ν¬λνΈ μ€νμΌλ§
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# Voice Sementle μ€νμΌ λ²νΌ CSS - μ λλ©μ΄μ
ν νλμ
|
| 7 |
BUTTON_CSS = """
|
| 8 |
+
/* Voice Sementle μ€νμΌ λ²νΌ - νλμ ν
λ§ */
|
| 9 |
#verify-btn,
|
| 10 |
#restart-btn {
|
| 11 |
font-family: 'Lilita One' !important;
|
client/frontend/styles/chatbot_style.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
| 1 |
"""
|
| 2 |
-
νλ‘ν
AI μ±λ΄ CSS - Voice
|
| 3 |
νλ‘ν
ν κΈ λ²νΌ, μ±λ΄ 컨ν
μ΄λ, μ
λ ₯ μμ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# νλ‘ν
AI μ±λ΄ CSS - Voice
|
| 7 |
FLOATING_CHATBOT_CSS = """
|
| 8 |
/* νλ‘ν
ν κΈ λ²νΌ 컨ν
μ΄λ */
|
| 9 |
#floating-toggle {
|
| 10 |
position: fixed;
|
| 11 |
-
|
| 12 |
right: 20px;
|
| 13 |
z-index: 1001;
|
| 14 |
width: 64px;
|
|
@@ -86,7 +86,7 @@ FLOATING_CHATBOT_CSS = """
|
|
| 86 |
/* μ±λ΄ 컨ν
μ΄λ - λ λ₯κΈκ² */
|
| 87 |
#chat-container {
|
| 88 |
position: fixed;
|
| 89 |
-
|
| 90 |
right: 20px;
|
| 91 |
width: 636px;
|
| 92 |
height: 840px;
|
|
|
|
| 1 |
"""
|
| 2 |
+
νλ‘ν
AI μ±λ΄ CSS - Voice Sementle ν
λ§
|
| 3 |
νλ‘ν
ν κΈ λ²νΌ, μ±λ΄ 컨ν
μ΄λ, μ
λ ₯ μμ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# νλ‘ν
AI μ±λ΄ CSS - Voice Sementle νλμ ν
λ§
|
| 7 |
FLOATING_CHATBOT_CSS = """
|
| 8 |
/* νλ‘ν
ν κΈ λ²νΌ 컨ν
μ΄λ */
|
| 9 |
#floating-toggle {
|
| 10 |
position: fixed;
|
| 11 |
+
bottom: 20px;
|
| 12 |
right: 20px;
|
| 13 |
z-index: 1001;
|
| 14 |
width: 64px;
|
|
|
|
| 86 |
/* μ±λ΄ 컨ν
μ΄λ - λ λ₯κΈκ² */
|
| 87 |
#chat-container {
|
| 88 |
position: fixed;
|
| 89 |
+
bottom: 104px;
|
| 90 |
right: 20px;
|
| 91 |
width: 636px;
|
| 92 |
height: 840px;
|
client/frontend/styles/custom_css.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
"""
|
| 2 |
-
컀μ€ν
CSS μ€νμΌ - Voice
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ 체 μ ν리μΌμ΄μ
CSS
|
| 4 |
|
| 5 |
μ΄ νμΌμ νμ νΈνμ±μ μν΄ μ μ§λ©λλ€.
|
|
|
|
| 1 |
"""
|
| 2 |
+
컀μ€ν
CSS μ€νμΌ - Voice Sementle ν
λ§
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ 체 μ ν리μΌμ΄μ
CSS
|
| 4 |
|
| 5 |
μ΄ νμΌμ νμ νΈνμ±μ μν΄ μ μ§λ©λλ€.
|
client/frontend/styles/failure_modal_style.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
μ€ν¨ λͺ¨λ¬ CSS - Voice
|
| 3 |
μ€ν¨ λͺ¨λ¬ λ° κ²°κ³Ό νμΌ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# μ€ν¨ λͺ¨λ¬ CSS - Voice
|
| 7 |
FAILURE_MODAL_CSS = """
|
| 8 |
-
/* μ€ν¨ λͺ¨λ¬ - Voice
|
| 9 |
.modal-content {
|
| 10 |
text-align: center;
|
| 11 |
padding: 20px;
|
|
|
|
| 1 |
"""
|
| 2 |
+
μ€ν¨ λͺ¨λ¬ CSS - Voice Sementle ν
λ§
|
| 3 |
μ€ν¨ λͺ¨λ¬ λ° κ²°κ³Ό νμΌ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# μ€ν¨ λͺ¨λ¬ CSS - Voice Sementle νλμ ν
λ§
|
| 7 |
FAILURE_MODAL_CSS = """
|
| 8 |
+
/* μ€ν¨ λͺ¨λ¬ - Voice Sementle νλμ ν
λ§ */
|
| 9 |
.modal-content {
|
| 10 |
text-align: center;
|
| 11 |
padding: 20px;
|
client/frontend/styles/falling_elements_style.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
"""
|
| 2 |
-
λ°°κ²½ κ½/μν λ¨μ΄μ§λ μ λλ©μ΄μ
- Voice
|
| 3 |
λ°°κ²½ μ λλ©μ΄μ
CSS λ° JavaScript
|
| 4 |
"""
|
| 5 |
|
|
|
|
| 1 |
"""
|
| 2 |
+
λ°°κ²½ κ½/μν λ¨μ΄μ§λ μ λλ©μ΄μ
- Voice Sementle ν
λ§
|
| 3 |
λ°°κ²½ μ λλ©μ΄μ
CSS λ° JavaScript
|
| 4 |
"""
|
| 5 |
|
client/frontend/styles/history_style.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
νμ€ν 리 λμ€νλ μ΄ CSS - Voice
|
| 3 |
μλ κΈ°λ‘ λ° νμ€ν 리 νμ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# νμ€ν 리 λμ€νλ μ΄ CSS - Voice
|
| 7 |
HISTORY_CSS = """
|
| 8 |
-
/* μλ κΈ°λ‘ - Voice
|
| 9 |
.attempt-history {
|
| 10 |
margin-top: 20px;
|
| 11 |
padding: 16px;
|
|
|
|
| 1 |
"""
|
| 2 |
+
νμ€ν 리 λμ€νλ μ΄ CSS - Voice Sementle ν
λ§
|
| 3 |
μλ κΈ°λ‘ λ° νμ€ν 리 νμ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# νμ€ν 리 λμ€νλ μ΄ CSS - Voice Sementle νλμ ν
λ§
|
| 7 |
HISTORY_CSS = """
|
| 8 |
+
/* μλ κΈ°λ‘ - Voice Sementle νλμ ν
λ§ */
|
| 9 |
.attempt-history {
|
| 10 |
margin-top: 20px;
|
| 11 |
padding: 16px;
|
client/frontend/styles/result_screen_style.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
μ±κ³΅ νλ©΄ CSS λ° Celebration JavaScript - Voice
|
| 3 |
μ±κ³΅ νλ©΄ μ€νμΌ, ν΅κ³ μΉ΄λ, Confetti ν¨κ³Ό
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# μ±κ³΅ νλ©΄ CSS - Voice
|
| 7 |
RESULT_SCREEN_CSS = """
|
| 8 |
-
/* μ±κ³΅ νλ©΄ - Voice
|
| 9 |
#success-screen,
|
| 10 |
#giveup-screen {
|
| 11 |
position: fixed !important;
|
|
|
|
| 1 |
"""
|
| 2 |
+
μ±κ³΅ νλ©΄ CSS λ° Celebration JavaScript - Voice Sementle ν
λ§
|
| 3 |
μ±κ³΅ νλ©΄ μ€νμΌ, ν΅κ³ μΉ΄λ, Confetti ν¨κ³Ό
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# μ±κ³΅ νλ©΄ CSS - Voice Sementle μ λλ©μ΄μ
ν
λ§ + Confetti ν¨κ³Ό
|
| 7 |
RESULT_SCREEN_CSS = """
|
| 8 |
+
/* μ±κ³΅ νλ©΄ - Voice Sementle νλμ ν
λ§ */
|
| 9 |
#success-screen,
|
| 10 |
#giveup-screen {
|
| 11 |
position: fixed !important;
|
client/frontend/styles/theme_style.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
| 1 |
"""
|
| 2 |
-
κΈ°λ³Έ ν
λ§ CSS - Voice
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ μ λ³μ λ° κΈ°λ³Έ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
-
# Voice
|
| 7 |
BASE_THEME_CSS = """
|
| 8 |
-
/* Voice
|
| 9 |
:root {
|
| 10 |
/* λ©μΈ ν
λ§ μμ - νλμ κ³μ΄ */
|
| 11 |
--theme-primary: #4db8ff;
|
|
|
|
| 1 |
"""
|
| 2 |
+
κΈ°λ³Έ ν
λ§ CSS - Voice Sementle ν
λ§
|
| 3 |
μ λλ©μ΄μ
ν νλμ ν
λ§ κΈ°λ°μ μ μ λ³μ λ° κΈ°λ³Έ μ€νμΌ
|
| 4 |
"""
|
| 5 |
|
| 6 |
+
# Voice Sementle ν
λ§ CSS - μ λλ©μ΄μ
ν νλμ ν
λ§
|
| 7 |
BASE_THEME_CSS = """
|
| 8 |
+
/* Voice Sementle μ€νμΌ κΈ°λ³Έ ν
λ§ - μ λλ©μ΄μ
ν νλμ */
|
| 9 |
:root {
|
| 10 |
/* λ©μΈ ν
λ§ μμ - νλμ κ³μ΄ */
|
| 11 |
--theme-primary: #4db8ff;
|
client/utils/elevenlabs_tts.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
| 2 |
ElevenLabs TTS Integration for Audio Hints
|
| 3 |
|
| 4 |
This module provides text-to-speech functionality for generating partial
|
| 5 |
-
audio hints in the Audio
|
| 6 |
"""
|
| 7 |
|
| 8 |
import os
|
|
@@ -87,7 +87,7 @@ def clone_voice_from_reference(reference_audio_path: str) -> Optional[str]:
|
|
| 87 |
voice = client.voices.ivc.create(
|
| 88 |
name=voice_name,
|
| 89 |
files=[BytesIO(open(full_path, "rb").read())],
|
| 90 |
-
description="Cloned voice for Audio
|
| 91 |
remove_background_noise=False
|
| 92 |
)
|
| 93 |
|
|
|
|
| 2 |
ElevenLabs TTS Integration for Audio Hints
|
| 3 |
|
| 4 |
This module provides text-to-speech functionality for generating partial
|
| 5 |
+
audio hints in the Audio Sementle game.
|
| 6 |
"""
|
| 7 |
|
| 8 |
import os
|
|
|
|
| 87 |
voice = client.voices.ivc.create(
|
| 88 |
name=voice_name,
|
| 89 |
files=[BytesIO(open(full_path, "rb").read())],
|
| 90 |
+
description="Cloned voice for Audio Sementle hints",
|
| 91 |
remove_background_noise=False
|
| 92 |
)
|
| 93 |
|
voice_app.py
CHANGED
|
@@ -9,7 +9,7 @@ from datetime import datetime
|
|
| 9 |
import os
|
| 10 |
|
| 11 |
# Backend API URL (νκ²½λ³μλ‘ κ΄λ¦¬ κ°λ₯)
|
| 12 |
-
BACKEND_URL = os.getenv("BACKEND_URL"
|
| 13 |
|
| 14 |
def process_voice(audio):
|
| 15 |
"""
|
|
|
|
| 9 |
import os
|
| 10 |
|
| 11 |
# Backend API URL (νκ²½λ³μλ‘ κ΄λ¦¬ κ°λ₯)
|
| 12 |
+
BACKEND_URL = os.getenv("BACKEND_URL")
|
| 13 |
|
| 14 |
def process_voice(audio):
|
| 15 |
"""
|