openfree commited on
Commit
bfecec5
ยท
verified ยท
1 Parent(s): 6315685

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +25 -1220
app.py CHANGED
@@ -1,1230 +1,35 @@
1
  import os
2
- import json
3
- import gradio as gr
4
- import openai
5
- from openai import OpenAI
6
- from datetime import datetime
7
- from typing import List, Dict, Tuple, Optional
8
- import random
9
- import time
10
 
11
- # OpenAI ํด๋ผ์ด์–ธํŠธ
12
- if not os.getenv("OPENAI_API_KEY"):
13
- raise EnvironmentError("OPENAI_API_KEY ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•˜์„ธ์š”.")
14
-
15
- client = OpenAI()
16
-
17
- # ์–ธ์–ด๋ณ„ ํ…์ŠคํŠธ ์ •์˜
18
- TEXTS = {
19
- "en": {
20
- "title": "THEORIAโ„ข",
21
- "subtitle": "Theory-driven Naming AI with 15 Specialized Theories",
22
- "description": "Generate innovative brand names using 15 cognitive and creative theories",
23
- "industry_label": "๐Ÿญ Industry",
24
- "industry_placeholder": "e.g., cafe, fitness, education, beauty...",
25
- "keywords_label": "๐Ÿ”‘ Keywords",
26
- "keywords_placeholder": "premium, comfortable, urban, eco-friendly...",
27
- "keywords_info": "Core values or characteristics the brand should embody",
28
- "generate_button": "Generate with {theory}",
29
- "language_label": "๐ŸŒ Language",
30
- "progress_message": "Generating innovative names using {theory}...",
31
- "error_message": "โŒ Error in {theory}: {error}",
32
- "input_required": "โš ๏ธ Please enter both industry and keywords.",
33
- "evaluation_labels": {
34
- "creativity": "Creativity",
35
- "memorability": "Memorability",
36
- "relevance": "Relevance"
37
- }
38
- },
39
- "ko": {
40
- "title": "THEORIAโ„ข",
41
- "subtitle": "ํŠน๋ณ„ํ•œ 15๊ฐœ์˜ ์ด๋ก ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๋„ค์ด๋ฐ AI",
42
- "description": "15๊ฐ€์ง€ ์ธ์ง€ ๋ฐ ์ฐฝ์˜ ์ด๋ก ์„ ํ™œ์šฉํ•œ ํ˜์‹ ์ ์ธ ๋ธŒ๋žœ๋“œ๋ช… ์ƒ์„ฑ",
43
- "industry_label": "๐Ÿญ ์—…์ข…",
44
- "industry_placeholder": "์˜ˆ: ์นดํŽ˜, ํ”ผํŠธ๋‹ˆ์Šค, ๊ต์œก, ๋ทฐํ‹ฐ...",
45
- "keywords_label": "๐Ÿ”‘ ํ•ต์‹ฌ ํ‚ค์›Œ๋“œ",
46
- "keywords_placeholder": "ํ”„๋ฆฌ๋ฏธ์—„, ํŽธ์•ˆํ•œ, ๋„์‹œ์ ์ธ, ์นœํ™˜๊ฒฝ...",
47
- "keywords_info": "๋ธŒ๋žœ๋“œ๊ฐ€ ๋‹ด์•„์•ผ ํ•  ํ•ต์‹ฌ ๊ฐ€์น˜๋‚˜ ํŠน์ง•๋“ค",
48
- "generate_button": "{theory}๋กœ ์ƒ์„ฑ",
49
- "language_label": "๐ŸŒ ์–ธ์–ด",
50
- "progress_message": "{theory}๋ฅผ ํ™œ์šฉํ•ด ํ˜์‹ ์ ์ธ ์ด๋ฆ„์„ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค...",
51
- "error_message": "โŒ {theory} ์˜ค๋ฅ˜: {error}",
52
- "input_required": "โš ๏ธ ์—…์ข…๊ณผ ํ‚ค์›Œ๋“œ๋ฅผ ๋ชจ๋‘ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”.",
53
- "evaluation_labels": {
54
- "creativity": "์ฐฝ์˜์„ฑ",
55
- "memorability": "๊ธฐ์–ต์„ฑ",
56
- "relevance": "๊ด€๋ จ์„ฑ"
57
- }
58
- }
59
- }
60
-
61
- # ์ด๋ก ๋ณ„ ์„ค๋ช… (์˜์–ด/ํ•œ๊ตญ์–ด)
62
- THEORY_DESCRIPTIONS = {
63
- "en": {
64
- "square": "Creates a semantic square structure where 4 words are connected by meaningful relationships. Hidden diagonal connections create 'aha!' moments.",
65
- "blending": "Blends two or more concepts to create new meaning. Like Netflix (Net+Flix), it births innovative concepts.",
66
- "sound": "Utilizes associations between phonemes and meaning. 'i,e' convey lightness and speed, 'o,u' convey weight and slowness.",
67
- "linguistic": "Creates global brands considering linguistic thought differences. Reflects cultural nuances and localization strategies.",
68
- "archetype": "Leverages Jung's 12 universal archetypes. Creates unconscious emotional connections like Hero (Nike) or Creator (Apple).",
69
- "jobs": "Focuses on the 'job' customers are trying to get done. Integrates functional, emotional, and social needs.",
70
- "scamper": "Uses 7 creative techniques (Substitute, Combine, Adapt, Modify, Put to other use, Eliminate, Reverse) for innovation.",
71
- "design": "Pursues human-centered innovation. Finds the intersection of desirability (human), feasibility (technical), and viability (business).",
72
- "biomimicry": "Creates nature-inspired brands. Applies 3.8 billion years of evolutionary wisdom to branding.",
73
- "cognitive": "Creates brands that minimize cognitive processing. Uses 1-3 syllables for instant recognition and recall.",
74
- "vonrestorff": "Creates unique, memorable brands. Intentionally violates category conventions for 30x better recall.",
75
- "network": "Creates brands that maximize network value. Designs structures where value increases with more users.",
76
- "memetics": "Creates culturally replicable and evolving brands. Embeds viral elements that spread naturally like memes.",
77
- "color": "Creates brands using color associations and emotions. Applies color psychology: red (passion), blue (trust), green (nature).",
78
- "gestalt": "Creates brands using perception principles. Designs holistic brand experiences where the whole exceeds the sum of parts."
79
- },
80
- "ko": {
81
- "square": "4๊ฐœ์˜ ๋‹จ์–ด๊ฐ€ ์˜๋ฏธ์  ๊ด€๊ณ„๋กœ ์—ฐ๊ฒฐ๋˜์–ด ์‚ฌ๊ฐํ˜•์„ ์ด๋ฃจ๋Š” ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ๋Œ€๋ณ€์˜ ์ˆจ๊ฒจ์ง„ ์—ฐ๊ฒฐ์ด '์•„ํ•˜!' ๋ชจ๋จผํŠธ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.",
82
- "blending": "๋‘ ๊ฐœ ์ด์ƒ์˜ ๊ฐœ๋…์„ ํ˜ผํ•ฉํ•˜์—ฌ ์ƒˆ๋กœ์šด ์˜๋ฏธ๋ฅผ ์ฐฝ์ถœํ•ฉ๋‹ˆ๋‹ค. Netflix(Net+Flix)์ฒ˜๏ฟฝ๏ฟฝ ํ˜์‹ ์ ์ธ ๊ฐœ๋…์„ ํƒ„์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.",
83
- "sound": "์Œ์†Œ์™€ ์˜๋ฏธ ๊ฐ„์˜ ์—ฐ๊ด€์„ฑ์„ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. 'i,e'๋Š” ๊ฐ€๋ณ๊ณ  ๋น ๋ฅธ ๋А๋‚Œ, 'o,u'๋Š” ๋ฌด๊ฒ๊ณ  ๋А๋ฆฐ ๋А๋‚Œ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.",
84
- "linguistic": "์–ธ์–ด๋ณ„ ์‚ฌ๊ณ ๋ฐฉ์‹ ์ฐจ์ด๋ฅผ ๊ณ ๋ คํ•œ ๊ธ€๋กœ๋ฒŒ ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ฌธํ™”์  ๋‰˜์•™์Šค์™€ ํ˜„์ง€ํ™” ์ „๋žต์„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค.",
85
- "archetype": "Jung์˜ 12๊ฐ€์ง€ ๋ณดํŽธ์  ์›ํ˜•์„ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค. Hero(Nike), Creator(Apple)์ฒ˜๋Ÿผ ๋ฌด์˜์‹์  ๊ฐ์ • ์—ฐ๊ฒฐ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.",
86
- "jobs": "๊ณ ๊ฐ์ด ํ•ด๊ฒฐํ•˜๋ ค๋Š” '์ผ'์— ์ดˆ์ ์„ ๋งž์ถฅ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์ , ๊ฐ์ •์ , ์‚ฌํšŒ์  ์ฐจ์›์˜ ๋‹ˆ์ฆˆ๋ฅผ ํ†ตํ•ฉ์ ์œผ๋กœ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.",
87
- "scamper": "7๊ฐ€์ง€ ์ฐฝ์˜์  ๊ธฐ๋ฒ•(๋Œ€์ฒด, ๊ฒฐํ•ฉ, ์ ์‘, ์ˆ˜์ •, ์šฉ๋„๋ณ€๊ฒฝ, ์ œ๊ฑฐ, ์—ญ์ „)์œผ๋กœ ํ˜์‹ ์ ์ธ ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค.",
88
- "design": "์ธ๊ฐ„ ์ค‘์‹ฌ ํ˜์‹ ์„ ์ถ”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”๋žŒ์งํ•จ(์ธ๊ฐ„), ์‹คํ˜„๊ฐ€๋Šฅ์„ฑ(๊ธฐ์ˆ ), ์ƒ์กด๊ฐ€๋Šฅ์„ฑ(๋น„์ฆˆ๋‹ˆ์Šค)์˜ ๊ต์ง‘ํ•ฉ์„ ์ฐพ์Šต๋‹ˆ๋‹ค.",
89
- "biomimicry": "์ž์—ฐ์—์„œ ์˜๊ฐ์„ ๋ฐ›์€ ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 38์–ต๋…„ ์ง„ํ™”์˜ ์ง€ํ˜œ๋ฅผ ๋ธŒ๋žœ๋”ฉ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.",
90
- "cognitive": "์ธ์ง€ ์ฒ˜๋ฆฌ๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. 1-3์Œ์ ˆ์˜ ์‰ฌ์šด ๋ฐœ์Œ์œผ๋กœ ์ฆ‰๊ฐ์  ์ธ์‹๊ณผ ๊ธฐ์–ต์„ ๋•์Šต๋‹ˆ๋‹ค.",
91
- "vonrestorff": "๋…ํŠนํ•˜๊ณ  ๊ธฐ์–ต์— ๋‚จ๋Š” ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์นดํ…Œ๊ณ ๋ฆฌ ๊ด€์Šต์„ ์˜๋„์ ์œผ๋กœ ์œ„๋ฐ˜ํ•˜์—ฌ 30๋ฐฐ ๋” ์ž˜ ๊ธฐ์–ต๋˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.",
92
- "network": "๋„คํŠธ์›Œํฌ ๊ฐ€์น˜๋ฅผ ๊ทน๋Œ€ํ™”ํ•˜๋Š” ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋งŽ์„์ˆ˜๋ก ๊ฐ€์น˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค.",
93
- "memetics": "๋ฌธํ™”์ ์œผ๋กœ ๋ณต์ œ๋˜๊ณ  ์ง„ํ™”ํ•˜๋Š” ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋ฐˆ์ฒ˜๋Ÿผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํผ์ ธ๋‚˜๊ฐ€๋Š” ๋ฐ”์ด๋Ÿด ์š”์†Œ๋ฅผ ๋‚ด์žฌํ™”ํ•ฉ๋‹ˆ๋‹ค.",
94
- "color": "์ƒ‰์ƒ ์—ฐ์ƒ๊ณผ ๊ฐ์ •์„ ํ™œ์šฉํ•œ ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋นจ๊ฐ•(์—ด์ •), ํŒŒ๋ž‘(์‹ ๋ขฐ), ์ดˆ๋ก(์ž์—ฐ) ๋“ฑ ์ƒ‰์ƒ ์‹ฌ๋ฆฌ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.",
95
- "gestalt": "์ง€๊ฐ ์›๋ฆฌ๋ฅผ ํ™œ์šฉํ•œ ๋ธŒ๋žœ๋“œ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ „์ฒด๊ฐ€ ๋ถ€๋ถ„์˜ ํ•ฉ๋ณด๋‹ค ํฌ๋‹ค๋Š” ์›์น™์œผ๋กœ ํ†ตํ•ฉ์  ๋ธŒ๋žœ๋“œ ๊ฒฝํ—˜์„ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค."
96
- }
97
- }
98
-
99
- # ํ†ต์ผ๋œ ๊ธฐ๋ณธ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ (์˜์–ด)
100
- UNIFIED_BASE_PROMPT_EN = """
101
- You are a {theory_name} expert. {theory_description}
102
-
103
- Based on the user input (industry/keywords), generate an array in the following unified JSON format:
104
-
105
- {{
106
- "brands": [
107
- {{
108
- "core": {{
109
- "brand_name": "Brand Name",
110
- "slogan": "Slogan",
111
- "core_value": "Core Value",
112
- "target_emotion": "Target Emotion",
113
- "brand_personality": "Brand Personality"
114
- }},
115
- "visual": {{
116
- "primary_color": "#HEX",
117
- "color_meaning": "Color Meaning",
118
- "visual_concept": "Visual Concept",
119
- "typography_style": "Typography Style"
120
- }},
121
- "linguistic": {{
122
- "pronunciation": "Pronunciation Guide",
123
- "etymology": "Etymology/Structure",
124
- "global_adaptability": "Global Adaptability",
125
- "memorable_factor": "Memorability Factor"
126
- }},
127
- "strategic": {{
128
- "differentiation": "Differentiation Point",
129
- "market_positioning": "Market Positioning",
130
- "growth_potential": "Growth Potential",
131
- "implementation_ease": "Implementation Ease"
132
- }},
133
- "theory_specific": {{
134
- {theory_specific_fields}
135
- }},
136
- "evaluation": {{
137
- "creativity_score": 0-10,
138
- "memorability_score": 0-10,
139
- "relevance_score": 0-10,
140
- "overall_effectiveness": "Overall effectiveness description"
141
- }}
142
- }}
143
- ]
144
- }}
145
-
146
- Return valid JSON format and fill all fields.
147
- Include theory-specific characteristics in the theory_specific section while maintaining the unified structure.
148
- All content should be in English.
149
- """
150
-
151
- # ํ†ต์ผ๋œ ๊ธฐ๋ณธ ํ”„๋กฌํ”„ํŠธ ํ…œํ”Œ๋ฆฟ (ํ•œ๊ตญ์–ด)
152
- UNIFIED_BASE_PROMPT_KO = """
153
- ๋‹น์‹ ์€ {theory_name} ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค. {theory_description}
154
-
155
- ์‚ฌ์šฉ์ž ์ž…๋ ฅ(์—…์ข…/ํ‚ค์›Œ๋“œ)์„ ๋ฐ›์•„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ†ต์ผ๋œ JSON ํ˜•์‹์˜ ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•˜์„ธ์š”:
156
-
157
- {{
158
- "brands": [
159
- {{
160
- "core": {{
161
- "brand_name": "๋ธŒ๋žœ๋“œ๋ช…",
162
- "slogan": "์Šฌ๋กœ๊ฑด",
163
- "core_value": "ํ•ต์‹ฌ ๊ฐ€์น˜",
164
- "target_emotion": "๋ชฉํ‘œ ๊ฐ์ •",
165
- "brand_personality": "๋ธŒ๋žœ๋“œ ์„ฑ๊ฒฉ"
166
- }},
167
- "visual": {{
168
- "primary_color": "#HEX์ฝ”๋“œ",
169
- "color_meaning": "์ƒ‰์ƒ ์˜๋ฏธ",
170
- "visual_concept": "์‹œ๊ฐ์  ์ปจ์…‰",
171
- "typography_style": "ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ ์Šคํƒ€์ผ"
172
- }},
173
- "linguistic": {{
174
- "pronunciation": "๋ฐœ์Œ ๊ฐ€์ด๋“œ",
175
- "etymology": "์–ด์›/๊ตฌ์„ฑ",
176
- "global_adaptability": "๊ธ€๋กœ๋ฒŒ ์ ์‘์„ฑ",
177
- "memorable_factor": "๊ธฐ์–ต ์šฉ์ด์„ฑ ์š”์†Œ"
178
- }},
179
- "strategic": {{
180
- "differentiation": "์ฐจ๋ณ„ํ™” ํฌ์ธํŠธ",
181
- "market_positioning": "์‹œ์žฅ ํฌ์ง€์…”๋‹",
182
- "growth_potential": "์„ฑ์žฅ ์ž ์žฌ๋ ฅ",
183
- "implementation_ease": "์‹คํ–‰ ์šฉ์ด์„ฑ"
184
- }},
185
- "theory_specific": {{
186
- {theory_specific_fields}
187
- }},
188
- "evaluation": {{
189
- "creativity_score": 0-10,
190
- "memorability_score": 0-10,
191
- "relevance_score": 0-10,
192
- "overall_effectiveness": "์ „์ฒด์ ์ธ ํšจ๊ณผ์„ฑ ์„ค๋ช…"
193
- }}
194
- }}
195
- ]
196
- }}
197
-
198
- ๋ฐ˜๋“œ์‹œ ์œ ํšจํ•œ JSON ํ˜•์‹์œผ๋กœ ์‘๋‹ตํ•˜๊ณ , ๋ชจ๋“  ํ•„๋“œ๋ฅผ ์ฑ„์›Œ์ฃผ์„ธ์š”.
199
- ๊ฐ ์ด๋ก ์˜ ํŠน์„ฑ์„ theory_specific ์„น์…˜์— ๋‹ด๋˜, ๋‚˜๋จธ์ง€๋Š” ํ†ต์ผ๋œ ๊ตฌ์กฐ๋ฅผ ์œ ์ง€ํ•˜์„ธ์š”.
200
- ๋ชจ๋“  ๋‚ด์šฉ์€ ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑํ•˜์„ธ์š”.
201
- """
202
-
203
- # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ํ•„๋“œ ์ •์˜ (์˜์–ด)
204
- THEORY_SPECIFIC_FIELDS_EN = {
205
- "square": """
206
- "tl": "Top Left",
207
- "tr": "Top Right",
208
- "bl": "Bottom Left",
209
- "br": "Bottom Right",
210
- "top_edge": "Top Relationship",
211
- "bottom_edge": "Bottom Relationship",
212
- "left_edge": "Left Relationship",
213
- "right_edge": "Right Relationship",
214
- "diagonal_insight": "Diagonal Insight"
215
- """,
216
-
217
- "blending": """
218
- "input_space1": "First Concept",
219
- "input_space2": "Second Concept",
220
- "generic_space": "Common Structure",
221
- "blended_space": "Blended New Meaning",
222
- "emergent_properties": "Emergent Properties",
223
- "blend_ratio": "Blend Ratio"
224
- """,
225
-
226
- "sound": """
227
- "phonetic_analysis": "Phonetic Analysis",
228
- "sound_meaning": "Sound Meaning",
229
- "vowel_consonant_ratio": "Vowel/Consonant Ratio",
230
- "phoneme_emotion_map": "Phoneme-Emotion Mapping",
231
- "cross_linguistic_sound": "Cross-linguistic Sound Consistency"
232
- """,
233
-
234
- "linguistic": """
235
- "korean_adaptation": "Korean Adaptation",
236
- "english_meaning": "English Meaning",
237
- "cultural_considerations": "Cultural Considerations",
238
- "avoid_meanings": "Meanings to Avoid",
239
- "localization_strategy": "Localization Strategy"
240
- """,
241
-
242
- "archetype": """
243
- "archetype": "Selected Archetype",
244
- "archetype_traits": "Archetype Traits",
245
- "shadow_side": "Shadow Side",
246
- "mythology_reference": "Mythological Reference",
247
- "customer_journey": "Customer Journey Connection"
248
- """,
249
-
250
- "jobs": """
251
- "functional_job": "Functional Job",
252
- "emotional_job": "Emotional Job",
253
- "social_job": "Social Job",
254
- "job_statement": "Core Job Statement",
255
- "outcome_metrics": "Outcome Metrics"
256
- """,
257
-
258
- "scamper": """
259
- "scamper_technique": "Technique Used",
260
- "original_concept": "Original Concept",
261
- "transformation": "Transformation Process",
262
- "innovation_type": "Innovation Type",
263
- "disruption_level": "Disruption Level"
264
- """,
265
-
266
- "design": """
267
- "user_insight": "User Insight",
268
- "pain_point": "Pain Point Solved",
269
- "desirability": "Desirability (Human)",
270
- "feasibility": "Feasibility (Technical)",
271
- "viability": "Viability (Business)"
272
- """,
273
-
274
- "biomimicry": """
275
- "natural_inspiration": "Natural Inspiration",
276
- "biomimetic_principle": "Biomimetic Principle",
277
- "form_function": "Form and Function",
278
- "sustainability_aspect": "Sustainability Aspect",
279
- "adaptation_strategy": "Adaptation Strategy"
280
- """,
281
-
282
- "cognitive": """
283
- "syllable_count": "Syllable Count",
284
- "processing_ease": "Processing Ease Score",
285
- "memory_hooks": "Memory Hooks",
286
- "cognitive_fluency": "Cognitive Fluency",
287
- "attention_span_fit": "Attention Span Fit"
288
- """,
289
-
290
- "vonrestorff": """
291
- "category_norm": "Category Norm",
292
- "deviation_strategy": "Deviation Strategy",
293
- "uniqueness_factors": "Uniqueness Factors",
294
- "attention_triggers": "Attention Triggers",
295
- "isolation_effect": "Isolation Effect Usage"
296
- """,
297
-
298
- "network": """
299
- "network_type": "Network Type",
300
- "viral_coefficient": "Viral Coefficient",
301
- "sharing_ease": "Sharing Ease",
302
- "community_aspect": "Community Aspect",
303
- "network_value": "Network Value"
304
- """,
305
-
306
- "memetics": """
307
- "meme_structure": "Meme Structure",
308
- "replication_ease": "Replication Ease",
309
- "mutation_potential": "Mutation Potential",
310
- "cultural_fitness": "Cultural Fitness",
311
- "transmission_channels": "Transmission Channels"
312
- """,
313
-
314
- "color": """
315
- "color_palette": "Color Palette",
316
- "emotional_response": "Emotional Response",
317
- "cultural_associations": "Cultural Associations",
318
- "industry_alignment": "Industry Alignment",
319
- "color_accessibility": "Color Accessibility"
320
- """,
321
-
322
- "gestalt": """
323
- "gestalt_principle": "Principle Used",
324
- "visual_structure": "Visual Structure",
325
- "perceptual_grouping": "Perceptual Grouping",
326
- "figure_ground": "Figure-Ground Relationship",
327
- "closure_effect": "Closure Effect"
328
- """
329
- }
330
-
331
- # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ํ•„๋“œ ์ •์˜ (ํ•œ๊ตญ์–ด)
332
- THEORY_SPECIFIC_FIELDS_KO = {
333
- "square": """
334
- "tl": "์™ผ์ชฝ์ƒ๋‹จ",
335
- "tr": "์˜ค๋ฅธ์ชฝ์ƒ๋‹จ",
336
- "bl": "์™ผ์ชฝํ•˜๋‹จ",
337
- "br": "์˜ค๋ฅธ์ชฝํ•˜๋‹จ",
338
- "top_edge": "์ƒ๋‹จ ๊ด€๊ณ„",
339
- "bottom_edge": "ํ•˜๋‹จ ๊ด€๊ณ„",
340
- "left_edge": "์™ผ์ชฝ ๊ด€๊ณ„",
341
- "right_edge": "์˜ค๋ฅธ์ชฝ ๊ด€๊ณ„",
342
- "diagonal_insight": "๋Œ€๊ฐ์„  ํ†ต์ฐฐ"
343
- """,
344
-
345
- "blending": """
346
- "input_space1": "์ฒซ ๋ฒˆ์งธ ๊ฐœ๋…",
347
- "input_space2": "๋‘ ๋ฒˆ์งธ ๊ฐœ๋…",
348
- "generic_space": "๊ณตํ†ต ๊ตฌ์กฐ",
349
- "blended_space": "ํ˜ผํ•ฉ๋œ ์ƒˆ๋กœ์šด ์˜๋ฏธ",
350
- "emergent_properties": "์ฐฝ๋ฐœ์  ์†์„ฑ๋“ค",
351
- "blend_ratio": "ํ˜ผํ•ฉ ๋น„์œจ"
352
- """,
353
-
354
- "sound": """
355
- "phonetic_analysis": "์Œ์„ฑ ๋ถ„์„",
356
- "sound_meaning": "์Œํ–ฅ์ด ์ „๋‹ฌํ•˜๋Š” ์˜๋ฏธ",
357
- "vowel_consonant_ratio": "๋ชจ์Œ/์ž์Œ ๋น„์œจ",
358
- "phoneme_emotion_map": "์Œ์†Œ-๊ฐ์ • ๋งคํ•‘",
359
- "cross_linguistic_sound": "์–ธ์–ด๊ฐ„ ์Œํ–ฅ ์ผ๊ด€์„ฑ"
360
- """,
361
-
362
- "linguistic": """
363
- "korean_adaptation": "ํ•œ๊ตญ์–ด ์ ์‘",
364
- "english_meaning": "์˜์–ด ์˜๋ฏธ",
365
- "cultural_considerations": "๋ฌธํ™”์  ๊ณ ๋ ค์‚ฌํ•ญ",
366
- "avoid_meanings": "ํ”ผํ•ด์•ผ ํ•  ์˜๋ฏธ๋“ค",
367
- "localization_strategy": "ํ˜„์ง€ํ™” ์ „๋žต"
368
- """,
369
-
370
- "archetype": """
371
- "archetype": "์„ ํƒ๋œ ์›ํ˜•",
372
- "archetype_traits": "์›ํ˜•์˜ ํŠน์ง•๋“ค",
373
- "shadow_side": "๊ทธ๋ฆผ์ž ์ธก๋ฉด",
374
- "mythology_reference": "์‹ ํ™”์  ์ฐธ์กฐ",
375
- "customer_journey": "๊ณ ๊ฐ ์—ฌ์ • ์—ฐ๊ฒฐ"
376
- """,
377
-
378
- "jobs": """
379
- "functional_job": "๊ธฐ๋Šฅ์  ์ผ",
380
- "emotional_job": "๊ฐ์ •์  ์ผ",
381
- "social_job": "์‚ฌํšŒ์  ์ผ",
382
- "job_statement": "ํ•ต์‹ฌ Job ๋ฌธ์žฅ",
383
- "outcome_metrics": "์„ฑ๊ณผ ์ง€ํ‘œ"
384
- """,
385
-
386
- "scamper": """
387
- "scamper_technique": "์‚ฌ์šฉ๋œ ๊ธฐ๋ฒ•",
388
- "original_concept": "์›๋ž˜ ๊ฐœ๋…",
389
- "transformation": "๋ณ€ํ˜• ๊ณผ์ •",
390
- "innovation_type": "ํ˜์‹  ์œ ํ˜•",
391
- "disruption_level": "ํŒŒ๊ดด์  ํ˜์‹  ์ˆ˜์ค€"
392
- """,
393
-
394
- "design": """
395
- "user_insight": "์‚ฌ์šฉ์ž ํ†ต์ฐฐ",
396
- "pain_point": "ํ•ด๊ฒฐํ•˜๋Š” ๋ฌธ์ œ์ ",
397
- "desirability": "๋ฐ”๋žŒ์งํ•จ (์ธ๊ฐ„)",
398
- "feasibility": "์‹คํ˜„๊ฐ€๋Šฅ์„ฑ (๊ธฐ์ˆ )",
399
- "viability": "์ƒ์กด๊ฐ€๋Šฅ์„ฑ (๋น„์ฆˆ๋‹ˆ์Šค)"
400
- """,
401
-
402
- "biomimicry": """
403
- "natural_inspiration": "์ž์—ฐ์  ์˜๊ฐ์›",
404
- "biomimetic_principle": "์ƒ์ฒด๋ชจ๋ฐฉ ์›๋ฆฌ",
405
- "form_function": "ํ˜•ํƒœ์™€ ๊ธฐ๋Šฅ",
406
- "sustainability_aspect": "์ง€์†๊ฐ€๋Šฅ์„ฑ ์ธก๋ฉด",
407
- "adaptation_strategy": "์ ์‘ ์ „๋žต"
408
- """,
409
-
410
- "cognitive": """
411
- "syllable_count": "์Œ์ ˆ ์ˆ˜",
412
- "processing_ease": "์ฒ˜๋ฆฌ ์šฉ์ด์„ฑ ์ ์ˆ˜",
413
- "memory_hooks": "๊ธฐ์–ต ๊ณ ๋ฆฌ",
414
- "cognitive_fluency": "์ธ์ง€์  ์œ ์ฐฝ์„ฑ",
415
- "attention_span_fit": "์ฃผ์˜๋ ฅ ์ ํ•ฉ๋„"
416
- """,
417
-
418
- "vonrestorff": """
419
- "category_norm": "์นดํ…Œ๊ณ ๋ฆฌ ํ‘œ์ค€",
420
- "deviation_strategy": "์ผํƒˆ ์ „๋žต",
421
- "uniqueness_factors": "๋…ํŠน์„ฑ ์š”์†Œ๋“ค",
422
- "attention_triggers": "์ฃผ์˜ ํŠธ๋ฆฌ๊ฑฐ",
423
- "isolation_effect": "๊ณ ๋ฆฝ ํšจ๊ณผ ํ™œ์šฉ"
424
- """,
425
-
426
- "network": """
427
- "network_type": "๋„คํŠธ์›Œํฌ ์œ ํ˜•",
428
- "viral_coefficient": "๋ฐ”์ด๋Ÿด ๊ณ„์ˆ˜",
429
- "sharing_ease": "๊ณต์œ  ์šฉ์ด์„ฑ",
430
- "community_aspect": "์ปค๋ฎค๋‹ˆํ‹ฐ ์ธก๋ฉด",
431
- "network_value": "๋„คํŠธ์›Œํฌ ๊ฐ€์น˜"
432
- """,
433
-
434
- "memetics": """
435
- "meme_structure": "๋ฐˆ ๊ตฌ์กฐ",
436
- "replication_ease": "๋ณต์ œ ์šฉ์ด์„ฑ",
437
- "mutation_potential": "๋ณ€์ด ์ž ์žฌ๋ ฅ",
438
- "cultural_fitness": "๋ฌธํ™”์  ์ ํ•ฉ๋„",
439
- "transmission_channels": "์ „๋‹ฌ ์ฑ„๋„"
440
- """,
441
-
442
- "color": """
443
- "color_palette": "์ƒ‰์ƒ ํŒ”๋ ˆํŠธ",
444
- "emotional_response": "๊ฐ์ •์  ๋ฐ˜์‘",
445
- "cultural_associations": "๋ฌธํ™”์  ์—ฐ์ƒ",
446
- "industry_alignment": "์—…์ข… ์ •๋ ฌ",
447
- "color_accessibility": "์ƒ‰์ƒ ์ ‘๊ทผ์„ฑ"
448
- """,
449
-
450
- "gestalt": """
451
- "gestalt_principle": "ํ™œ์šฉ ์›์น™",
452
- "visual_structure": "์‹œ๊ฐ์  ๊ตฌ์กฐ",
453
- "perceptual_grouping": "์ง€๊ฐ์  ๊ทธ๋ฃนํ™”",
454
- "figure_ground": "์ „๊ฒฝ-๋ฐฐ๊ฒฝ ๊ด€๊ณ„",
455
- "closure_effect": "ํ์‡„ ํšจ๊ณผ"
456
- """
457
- }
458
-
459
- def create_theory_prompt(theory: str, language: str) -> str:
460
- """๊ฐ ์ด๋ก ๋ณ„ ํ†ต์ผ๋œ ํ”„๋กฌํ”„ํŠธ ์ƒ์„ฑ"""
461
- theory_names = {
462
- "en": {
463
- "square": "Square Theory",
464
- "blending": "Conceptual Blending Theory",
465
- "sound": "Sound Symbolism",
466
- "linguistic": "Linguistic Relativity",
467
- "archetype": "Jung's Archetype Theory",
468
- "jobs": "Jobs-to-be-Done Theory",
469
- "scamper": "SCAMPER Method",
470
- "design": "IDEO's Design Thinking",
471
- "biomimicry": "Biomimicry",
472
- "cognitive": "Cognitive Load Theory",
473
- "vonrestorff": "Von Restorff Effect",
474
- "network": "Network Effects",
475
- "memetics": "Memetics",
476
- "color": "Color Psychology",
477
- "gestalt": "Gestalt Theory"
478
- },
479
- "ko": {
480
- "square": "Square Theory",
481
- "blending": "Conceptual Blending Theory",
482
- "sound": "Sound Symbolism",
483
- "linguistic": "Linguistic Relativity",
484
- "archetype": "Jung์˜ Archetype Theory",
485
- "jobs": "Jobs-to-be-Done Theory",
486
- "scamper": "SCAMPER Method",
487
- "design": "IDEO์˜ Design Thinking",
488
- "biomimicry": "Biomimicry",
489
- "cognitive": "Cognitive Load Theory",
490
- "vonrestorff": "Von Restorff Effect",
491
- "network": "Network Effects",
492
- "memetics": "Memetics",
493
- "color": "Color Psychology",
494
- "gestalt": "Gestalt Theory"
495
- }
496
- }
497
-
498
- base_prompt = UNIFIED_BASE_PROMPT_EN if language == "en" else UNIFIED_BASE_PROMPT_KO
499
- theory_specific_fields = THEORY_SPECIFIC_FIELDS_EN if language == "en" else THEORY_SPECIFIC_FIELDS_KO
500
-
501
- return base_prompt.format(
502
- theory_name=theory_names[language][theory],
503
- theory_description=THEORY_DESCRIPTIONS[language][theory],
504
- theory_specific_fields=theory_specific_fields[theory]
505
- )
506
-
507
- def generate_by_theory(industry: str, keywords: str, theory: str, language: str, count: int = 3) -> Tuple[str, str, gr.update]:
508
- """ํŠน์ • ์ด๋ก ์œผ๋กœ ๋ธŒ๋žœ๋“œ ์ƒ์„ฑ"""
509
-
510
- texts = TEXTS[language]
511
-
512
- if not industry or not keywords:
513
- return texts["input_required"], "", gr.update(visible=False)
514
-
515
- prompt = create_theory_prompt(theory, language)
516
-
517
- if language == "en":
518
- user_input = f"""Industry: {industry}
519
- Keywords: {keywords}
520
-
521
- Generate {count} brands with the above information.
522
- Each brand should have a unified structure, with theory-specific characteristics in the theory_specific section."""
523
- else:
524
- user_input = f"""์—…์ข…: {industry}
525
- ํ‚ค์›Œ๋“œ: {keywords}
526
-
527
- ์œ„ ์ •๋ณด๋กœ {count}๊ฐœ์˜ ๋ธŒ๋žœ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.
528
- ๊ฐ ๋ธŒ๋žœ๋“œ๋Š” ํ†ต์ผ๋œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง€๋˜, theory_specific ์„น์…˜์—๋Š” {theory} ์ด๋ก ์˜ ํŠน์„ฑ์„ ๋ฐ˜์˜ํ•˜์„ธ์š”."""
529
-
530
  try:
531
- # ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ํ‘œ์‹œ
532
- theory_names = {
533
- "square": "Square Theory",
534
- "blending": "Conceptual Blending",
535
- "sound": "Sound Symbolism",
536
- "linguistic": "Linguistic Relativity",
537
- "archetype": "Archetype Theory",
538
- "jobs": "Jobs-to-be-Done",
539
- "scamper": "SCAMPER Method",
540
- "design": "Design Thinking",
541
- "biomimicry": "Biomimicry",
542
- "cognitive": "Cognitive Load Theory",
543
- "vonrestorff": "Von Restorff Effect",
544
- "network": "Network Effects",
545
- "memetics": "Memetics",
546
- "color": "Color Psychology",
547
- "gestalt": "Gestalt Principles"
548
- }
549
-
550
- response = client.chat.completions.create(
551
- model="gpt-4o-mini",
552
- messages=[
553
- {"role": "system", "content": prompt},
554
- {"role": "user", "content": user_input}
555
- ],
556
- temperature=0.8,
557
- max_tokens=2000,
558
- response_format={"type": "json_object"}
559
- )
560
 
561
- content = response.choices[0].message.content
562
- data = json.loads(content)
563
-
564
- # ์‘๋‹ต ์ •๊ทœํ™”
565
- if "brands" in data:
566
- results = data["brands"]
567
- else:
568
- results = [data]
569
-
570
- if not isinstance(results, list):
571
- results = [results]
572
 
573
- # ๋งˆํฌ๋‹ค์šด ์ƒ์„ฑ
574
- markdown = generate_unified_markdown(theory, results, industry, keywords, language)
 
 
575
 
576
- # HTML ์‹œ๊ฐํ™” ์ƒ์„ฑ
577
- html = generate_unified_visualization(theory, results, language)
578
 
579
- return markdown, html, gr.update(visible=False)
580
-
581
- except Exception as e:
582
- error_msg = texts["error_message"].format(theory=theory_names[theory], error=str(e))
583
- print(error_msg)
584
- return error_msg, "", gr.update(visible=False)
585
-
586
- def generate_unified_markdown(theory: str, results: List[Dict], industry: str, keywords: str, language: str) -> str:
587
- """ํ†ต์ผ๋œ ๋งˆํฌ๋‹ค์šด ์ƒ์„ฑ"""
588
-
589
- theory_names = {
590
- "square": "Square Theory",
591
- "blending": "Conceptual Blending",
592
- "sound": "Sound Symbolism",
593
- "linguistic": "Linguistic Relativity",
594
- "archetype": "Archetype Theory",
595
- "jobs": "Jobs-to-be-Done",
596
- "scamper": "SCAMPER Method",
597
- "design": "Design Thinking",
598
- "biomimicry": "Biomimicry",
599
- "cognitive": "Cognitive Load Theory",
600
- "vonrestorff": "Von Restorff Effect",
601
- "network": "Network Effects",
602
- "memetics": "Memetics",
603
- "color": "Color Psychology",
604
- "gestalt": "Gestalt Principles"
605
- }
606
-
607
- theory_icons = {
608
- "square": "๐ŸŸฆ", "blending": "๐Ÿ”€", "sound": "๐Ÿ”Š", "linguistic": "๐ŸŒ",
609
- "archetype": "๐ŸŽญ", "jobs": "โœ…", "scamper": "๐Ÿ”ง", "design": "๐Ÿ’ญ",
610
- "biomimicry": "๐ŸŒฟ", "cognitive": "๐Ÿง ", "vonrestorff": "โšก", "network": "๐ŸŒ",
611
- "memetics": "๐Ÿงฌ", "color": "๐ŸŽจ", "gestalt": "๐Ÿ‘๏ธ"
612
- }
613
-
614
- texts = TEXTS[language]
615
-
616
- if language == "en":
617
- markdown = f"""# {theory_icons[theory]} {theory_names[theory]}
618
-
619
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
620
- <h3 style="margin: 0 0 10px 0;">Theory Overview</h3>
621
- <p style="margin: 0; line-height: 1.6;">{THEORY_DESCRIPTIONS[language][theory]}</p>
622
- </div>
623
-
624
- **Industry**: {industry} | **Keywords**: {keywords}
625
- *Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
626
-
627
- ---
628
- """
629
- else:
630
- markdown = f"""# {theory_icons[theory]} {theory_names[theory]}
631
-
632
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
633
- <h3 style="margin: 0 0 10px 0;">์ด๋ก  ๊ฐœ์š”</h3>
634
- <p style="margin: 0; line-height: 1.6;">{THEORY_DESCRIPTIONS[language][theory]}</p>
635
- </div>
636
-
637
- **์—…์ข…**: {industry} | **ํ‚ค์›Œ๋“œ**: {keywords}
638
- *์ƒ์„ฑ ์‹œ๊ฐ: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
639
-
640
- ---
641
- """
642
-
643
- for idx, result in enumerate(results, 1):
644
- core = result.get('core', {})
645
- visual = result.get('visual', {})
646
- linguistic = result.get('linguistic', {})
647
- strategic = result.get('strategic', {})
648
- theory_specific = result.get('theory_specific', {})
649
- evaluation = result.get('evaluation', {})
650
-
651
- brand_name = core.get('brand_name', 'N/A')
652
- slogan = core.get('slogan', 'N/A')
653
-
654
- markdown += f"\n## {idx}. {brand_name}\n"
655
-
656
- if language == "en":
657
- markdown += f"""**Slogan**: *"{slogan}"*
658
-
659
- ### ๐Ÿ“ Core Information
660
- - **Core Value**: {core.get('core_value', 'N/A')}
661
- - **Target Emotion**: {core.get('target_emotion', 'N/A')}
662
- - **Brand Personality**: {core.get('brand_personality', 'N/A')}
663
-
664
- ### ๐ŸŽจ Visual Concept
665
- - **Primary Color**: {visual.get('primary_color', '#000000')} - {visual.get('color_meaning', 'N/A')}
666
- - **Visual Concept**: {visual.get('visual_concept', 'N/A')}
667
- - **Typography**: {visual.get('typography_style', 'N/A')}
668
-
669
- ### ๐Ÿ—ฃ๏ธ Linguistic Features
670
- - **Pronunciation**: {linguistic.get('pronunciation', 'N/A')}
671
- - **Etymology**: {linguistic.get('etymology', 'N/A')}
672
- - **Global Adaptability**: {linguistic.get('global_adaptability', 'N/A')}
673
-
674
- ### ๐ŸŽฏ Strategic Value
675
- - **Differentiation**: {strategic.get('differentiation', 'N/A')}
676
- - **Market Positioning**: {strategic.get('market_positioning', 'N/A')}
677
- - **Growth Potential**: {strategic.get('growth_potential', 'N/A')}
678
- """
679
- else:
680
- markdown += f"""**์Šฌ๋กœ๊ฑด**: *"{slogan}"*
681
-
682
- ### ๐Ÿ“ ํ•ต์‹ฌ ์ •๋ณด
683
- - **ํ•ต์‹ฌ ๊ฐ€์น˜**: {core.get('core_value', 'N/A')}
684
- - **๋ชฉํ‘œ ๊ฐ์ •**: {core.get('target_emotion', 'N/A')}
685
- - **๋ธŒ๋žœ๋“œ ์„ฑ๊ฒฉ**: {core.get('brand_personality', 'N/A')}
686
-
687
- ### ๐ŸŽจ ์‹œ๊ฐ์  ์ปจ์…‰
688
- - **์ฃผ์š” ์ƒ‰์ƒ**: {visual.get('primary_color', '#000000')} - {visual.get('color_meaning', 'N/A')}
689
- - **๋น„์ฃผ์–ผ ์ปจ์…‰**: {visual.get('visual_concept', 'N/A')}
690
- - **ํƒ€์ดํฌ๊ทธ๋ž˜ํ”ผ**: {visual.get('typography_style', 'N/A')}
691
-
692
- ### ๐Ÿ—ฃ๏ธ ์–ธ์–ด์  ํŠน์„ฑ
693
- - **๋ฐœ์Œ**: {linguistic.get('pronunciation', 'N/A')}
694
- - **์–ด์›/๊ตฌ์„ฑ**: {linguistic.get('etymology', 'N/A')}
695
- - **๊ธ€๋กœ๋ฒŒ ์ ์‘์„ฑ**: {linguistic.get('global_adaptability', 'N/A')}
696
-
697
- ### ๐ŸŽฏ ์ „๋žต์  ๊ฐ€์น˜
698
- - **์ฐจ๋ณ„ํ™” ํฌ์ธํŠธ**: {strategic.get('differentiation', 'N/A')}
699
- - **์‹œ์žฅ ํฌ์ง€์…”๋‹**: {strategic.get('market_positioning', 'N/A')}
700
- - **์„ฑ์žฅ ์ž ์žฌ๋ ฅ**: {strategic.get('growth_potential', 'N/A')}
701
- """
702
-
703
- # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ์ •๋ณด
704
- if theory_specific:
705
- theory_header = f"### ๐Ÿ’ก {theory_names[theory]} " + ("Features" if language == "en" else "ํŠน์„ฑ") + "\n"
706
- markdown += theory_header
707
- for key, value in theory_specific.items():
708
- display_key = key.replace('_', ' ').title()
709
- markdown += f"- **{display_key}**: {value}\n"
710
-
711
- # ํ‰๊ฐ€ ์ ์ˆ˜
712
- eval_labels = texts["evaluation_labels"]
713
-
714
- if language == "en":
715
- markdown += f"""
716
- ### ๐Ÿ“Š Evaluation
717
- - **{eval_labels['creativity']}**: {'โญ' * int(evaluation.get('creativity_score', 0))} ({evaluation.get('creativity_score', 0)}/10)
718
- - **{eval_labels['memorability']}**: {'โญ' * int(evaluation.get('memorability_score', 0))} ({evaluation.get('memorability_score', 0)}/10)
719
- - **{eval_labels['relevance']}**: {'โญ' * int(evaluation.get('relevance_score', 0))} ({evaluation.get('relevance_score', 0)}/10)
720
-
721
- ๐Ÿ’ฌ **Overall Assessment**: {evaluation.get('overall_effectiveness', 'N/A')}
722
- """
723
- else:
724
- markdown += f"""
725
- ### ๐Ÿ“Š ํ‰๊ฐ€
726
- - **{eval_labels['creativity']}**: {'โญ' * int(evaluation.get('creativity_score', 0))} ({evaluation.get('creativity_score', 0)}/10)
727
- - **{eval_labels['memorability']}**: {'โญ' * int(evaluation.get('memorability_score', 0))} ({evaluation.get('memorability_score', 0)}/10)
728
- - **{eval_labels['relevance']}**: {'โญ' * int(evaluation.get('relevance_score', 0))} ({evaluation.get('relevance_score', 0)}/10)
729
-
730
- ๐Ÿ’ฌ **์ „์ฒด ํ‰๊ฐ€**: {evaluation.get('overall_effectiveness', 'N/A')}
731
- """
732
-
733
- markdown += "\n---\n"
734
-
735
- return markdown
736
-
737
- def generate_unified_visualization(theory: str, results: List[Dict], language: str) -> str:
738
- """ํ†ต์ผ๋œ ์‹œ๊ฐํ™” ์ƒ์„ฑ"""
739
-
740
- texts = TEXTS[language]
741
- eval_labels = texts["evaluation_labels"]
742
-
743
- html_parts = []
744
-
745
- for idx, result in enumerate(results, 1):
746
- core = result.get('core', {})
747
- visual = result.get('visual', {})
748
- linguistic = result.get('linguistic', {})
749
- strategic = result.get('strategic', {})
750
- theory_specific = result.get('theory_specific', {})
751
- evaluation = result.get('evaluation', {})
752
-
753
- brand_name = core.get('brand_name', 'Brand')
754
- slogan = core.get('slogan', '')
755
- primary_color = visual.get('primary_color', '#667eea')
756
-
757
- # ์–ธ์–ด๋ณ„ ๋ผ๋ฒจ
758
- if language == "en":
759
- labels = {
760
- "core_value": "Core Value",
761
- "target_emotion": "Target Emotion",
762
- "differentiation": "Differentiation",
763
- "pronunciation": "Pronunciation"
764
- }
765
- else:
766
- labels = {
767
- "core_value": "ํ•ต์‹ฌ ๊ฐ€์น˜",
768
- "target_emotion": "๋ชฉํ‘œ ๊ฐ์ •",
769
- "differentiation": "์ฐจ๋ณ„ํ™” ํฌ์ธํŠธ",
770
- "pronunciation": "๋ฐœ์Œ ๊ฐ€์ด๋“œ"
771
- }
772
-
773
- # ํ†ต์ผ๋œ ์นด๋“œ ๋ ˆ์ด์•„์›ƒ
774
- html = f"""
775
- <div style="max-width: 800px; margin: 30px auto; font-family: -apple-system, sans-serif;">
776
- <div style="background: white; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); overflow: hidden;">
777
- <!-- ํ—ค๋” -->
778
- <div style="background: linear-gradient(135deg, {primary_color} 0%, #2c3e50 100%); padding: 40px; color: white;">
779
- <h2 style="margin: 0 0 10px 0; font-size: 2.5em;">{brand_name}</h2>
780
- <p style="margin: 0; font-style: italic; font-size: 1.2em; opacity: 0.9;">"{slogan}"</p>
781
- </div>
782
-
783
- <!-- ๋ณธ๋ฌธ -->
784
- <div style="padding: 40px;">
785
- <!-- ํ‰๊ฐ€ ์ ์ˆ˜ -->
786
- <div style="display: flex; justify-content: space-around; margin-bottom: 30px;">
787
- <div style="text-align: center;">
788
- <div style="font-size: 2em; color: {primary_color}; font-weight: bold;">
789
- {evaluation.get('creativity_score', 0)}/10
790
- </div>
791
- <div style="color: #7f8c8d; margin-top: 5px;">{eval_labels['creativity']}</div>
792
- </div>
793
- <div style="text-align: center;">
794
- <div style="font-size: 2em; color: {primary_color}; font-weight: bold;">
795
- {evaluation.get('memorability_score', 0)}/10
796
- </div>
797
- <div style="color: #7f8c8d; margin-top: 5px;">{eval_labels['memorability']}</div>
798
- </div>
799
- <div style="text-align: center;">
800
- <div style="font-size: 2em; color: {primary_color}; font-weight: bold;">
801
- {evaluation.get('relevance_score', 0)}/10
802
- </div>
803
- <div style="color: #7f8c8d; margin-top: 5px;">{eval_labels['relevance']}</div>
804
- </div>
805
- </div>
806
-
807
- <!-- ํ•ต์‹ฌ ์ •๋ณด ๊ทธ๋ฆฌ๋“œ -->
808
- <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom: 30px;">
809
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px;">
810
- <h4 style="margin: 0 0 10px 0; color: {primary_color};">{labels['core_value']}</h4>
811
- <p style="margin: 0; color: #555;">{core.get('core_value', 'N/A')}</p>
812
- </div>
813
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px;">
814
- <h4 style="margin: 0 0 10px 0; color: {primary_color};">{labels['target_emotion']}</h4>
815
- <p style="margin: 0; color: #555;">{core.get('target_emotion', 'N/A')}</p>
816
- </div>
817
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px;">
818
- <h4 style="margin: 0 0 10px 0; color: {primary_color};">{labels['differentiation']}</h4>
819
- <p style="margin: 0; color: #555;">{strategic.get('differentiation', 'N/A')}</p>
820
- </div>
821
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px;">
822
- <h4 style="margin: 0 0 10px 0; color: {primary_color};">{labels['pronunciation']}</h4>
823
- <p style="margin: 0; color: #555;">{linguistic.get('pronunciation', 'N/A')}</p>
824
- </div>
825
- </div>
826
- """
827
-
828
- # ์ด๋ก ๋ณ„ ํŠน์ˆ˜ ์‹œ๊ฐํ™” ์ถ”๊ฐ€
829
- if theory == "square" and all(k in theory_specific for k in ['tl', 'tr', 'bl', 'br']):
830
- html += visualize_square_specific(theory_specific, primary_color)
831
- elif theory == "blending" and 'input_space1' in theory_specific:
832
- html += visualize_blending_specific(theory_specific, primary_color)
833
- elif theory == "color" and 'color_palette' in theory_specific:
834
- html += visualize_color_specific(theory_specific, primary_color)
835
- else:
836
- # ๊ธฐ๋ณธ ์ด๋ก  ํŠน์„ฑ ํ‘œ์‹œ
837
- theory_header = "Theory Features" if language == "en" else "์ด๋ก  ํŠน์„ฑ"
838
- html += f"""
839
- <div style="background: linear-gradient(135deg, {primary_color}15 0%, {primary_color}05 100%); padding: 25px; border-radius: 15px; margin-top: 20px;">
840
- <h4 style="margin: 0 0 15px 0; color: {primary_color};">{theory_header}</h4>
841
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 15px;">
842
- """
843
- for key, value in theory_specific.items():
844
- display_key = key.replace('_', ' ').title()
845
- html += f"""
846
- <div>
847
- <strong style="color: #555;">{display_key}:</strong><br>
848
- <span style="color: #777;">{value}</span>
849
- </div>
850
- """
851
- html += """
852
- </div>
853
- </div>
854
- """
855
-
856
- # ์ „์ฒด ํ‰๊ฐ€
857
- overall_header = "Overall Assessment" if language == "en" else "์ „์ฒด ํ‰๊ฐ€"
858
- html += f"""
859
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-top: 20px;">
860
- <h4 style="margin: 0 0 10px 0; color: {primary_color};">{overall_header}</h4>
861
- <p style="margin: 0; color: #555; line-height: 1.6;">{evaluation.get('overall_effectiveness', 'N/A')}</p>
862
- </div>
863
- </div>
864
- </div>
865
- </div>
866
- """
867
-
868
- html_parts.append(html)
869
-
870
- return "\n".join(html_parts)
871
-
872
- def visualize_square_specific(theory_specific: Dict, primary_color: str) -> str:
873
- """Square Theory ํŠน์ˆ˜ ์‹œ๊ฐํ™”"""
874
- return f"""
875
- <div style="background: #f8f9fa; padding: 30px; border-radius: 15px; margin-top: 20px;">
876
- <h4 style="margin: 0 0 20px 0; color: {primary_color}; text-align: center;">Square Structure</h4>
877
- <div style="position: relative; width: 100%; max-width: 400px; height: 300px; margin: 0 auto;">
878
- <div style="position: absolute; top: 0; left: 0; background: white; color: {primary_color}; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-weight: bold;">
879
- {theory_specific.get('tl', '?')}
880
- </div>
881
- <div style="position: absolute; top: 0; right: 0; background: white; color: {primary_color}; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-weight: bold;">
882
- {theory_specific.get('tr', '?')}
883
- </div>
884
- <div style="position: absolute; bottom: 0; left: 0; background: white; color: {primary_color}; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-weight: bold;">
885
- {theory_specific.get('bl', '?')}
886
- </div>
887
- <div style="position: absolute; bottom: 0; right: 0; background: white; color: {primary_color}; padding: 15px 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); font-weight: bold;">
888
- {theory_specific.get('br', '?')}
889
- </div>
890
-
891
- <!-- ์—ฐ๊ฒฐ์„ ๊ณผ ๊ด€๊ณ„ ํ‘œ์‹œ -->
892
- <div style="position: absolute; top: 25px; left: 50%; transform: translateX(-50%); color: #7f8c8d; font-size: 0.9em;">
893
- {theory_specific.get('top_edge', '')}
894
- </div>
895
- <div style="position: absolute; bottom: 25px; left: 50%; transform: translateX(-50%); color: #7f8c8d; font-size: 0.9em;">
896
- {theory_specific.get('bottom_edge', '')}
897
- </div>
898
- <div style="position: absolute; top: 50%; left: 25px; transform: translateY(-50%) rotate(-90deg); color: #7f8c8d; font-size: 0.9em;">
899
- {theory_specific.get('left_edge', '')}
900
- </div>
901
- <div style="position: absolute; top: 50%; right: 25px; transform: translateY(-50%) rotate(90deg); color: #7f8c8d; font-size: 0.9em;">
902
- {theory_specific.get('right_edge', '')}
903
- </div>
904
- </div>
905
- </div>
906
- """
907
-
908
- def visualize_blending_specific(theory_specific: Dict, primary_color: str) -> str:
909
- """Conceptual Blending ํŠน์ˆ˜ ์‹œ๊ฐํ™”"""
910
- return f"""
911
- <div style="background: #f8f9fa; padding: 30px; border-radius: 15px; margin-top: 20px;">
912
- <h4 style="margin: 0 0 20px 0; color: {primary_color}; text-align: center;">Concept Blending</h4>
913
- <div style="display: flex; justify-content: center; align-items: center; gap: 20px; flex-wrap: wrap;">
914
- <div style="text-align: center; padding: 20px; background: white; color: {primary_color}; border-radius: 50%; width: 120px; height: 120px; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
915
- <div>
916
- <strong>Input 1</strong><br>
917
- <span style="font-size: 0.9em;">{theory_specific.get('input_space1', '')}</span>
918
- </div>
919
- </div>
920
 
921
- <div style="font-size: 2em; color: {primary_color};">+</div>
922
-
923
- <div style="text-align: center; padding: 20px; background: white; color: {primary_color}; border-radius: 50%; width: 120px; height: 120px; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
924
- <div>
925
- <strong>Input 2</strong><br>
926
- <span style="font-size: 0.9em;">{theory_specific.get('input_space2', '')}</span>
927
- </div>
928
- </div>
929
-
930
- <div style="font-size: 2em; color: {primary_color};">=</div>
931
-
932
- <div style="text-align: center; padding: 20px; background: {primary_color}; color: white; border-radius: 20px; min-width: 150px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);">
933
- <strong>Blend</strong><br>
934
- <span style="font-size: 0.95em;">{theory_specific.get('blended_space', '')}</span>
935
- </div>
936
- </div>
937
- </div>
938
- """
939
-
940
- def visualize_color_specific(theory_specific: Dict, primary_color: str) -> str:
941
- """Color Psychology ํŠน์ˆ˜ ์‹œ๊ฐํ™”"""
942
- palette = theory_specific.get('color_palette', primary_color)
943
- colors = palette.split(',') if ',' in palette else [primary_color]
944
-
945
- html = f"""
946
- <div style="background: #f8f9fa; padding: 30px; border-radius: 15px; margin-top: 20px;">
947
- <h4 style="margin: 0 0 20px 0; color: {primary_color}; text-align: center;">Color Palette</h4>
948
- <div style="display: flex; justify-content: center; gap: 10px; flex-wrap: wrap;">
949
- """
950
-
951
- for color in colors[:5]: # ์ตœ๋Œ€ 5๊ฐœ ์ƒ‰์ƒ๋งŒ ํ‘œ์‹œ
952
- color = color.strip()
953
- html += f"""
954
- <div style="width: 80px; height: 80px; background: {color}; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1);"></div>
955
- """
956
-
957
- html += """
958
- </div>
959
- </div>
960
- """
961
- return html
962
-
963
- # Gradio UI
964
- with gr.Blocks(
965
- title="THEORIAโ„ข - Theory-driven Naming AI",
966
- theme=gr.themes.Soft(),
967
- css="""
968
- .gradio-container {
969
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
970
- }
971
-
972
- /* โ‘  ํƒญ ๋„ค๋น„๊ฒŒ์ด์…˜: ๊ฐ€๋กœ ์Šคํฌ๋กค ๊ฐ€๋Šฅํ•˜๋„๋ก */
973
- .tab-nav {
974
- display: flex !important;
975
- flex-wrap: nowrap !important; /* ์ค„๋ฐ”๊ฟˆ ๋ฐฉ์ง€ */
976
- overflow-x: auto !important; /* ๊ฐ€๋กœ ์Šคํฌ๋กค */
977
- white-space: nowrap !important; /* ๋ฒ„ํŠผ ํ•œ ์ค„ ์œ ์ง€ */
978
- gap: 5px !important;
979
- scrollbar-width: none; /* Firefox */
980
- -ms-overflow-style: none; /* IE/Edge */
981
- }
982
- .tab-nav::-webkit-scrollbar { /* Chrome */
983
- display: none;
984
- }
985
-
986
- /* โ‘ก ํƒญ ๋ฒ„ํŠผ์€ ์ค„๋ฐ”๊ฟˆ ์—†์ด ๊ณ ์ •ํญ์œผ๋กœ */
987
- .tab-nav button {
988
- flex: 0 0 auto !important;
989
- font-size: 1.6em !important; /* ์ด๋ชจ์ง€๋ฅผ ํฌ๊ฒŒ */
990
- padding: 8px 12px !important;
991
- white-space: nowrap !important;
992
- }
993
- .tab-nav button {
994
- flex: 0 0 auto !important;
995
- font-size: 1.6em !important; /* ์ด๋ชจ์ง€๋ฅผ ํฌ๊ฒŒ */
996
- padding: 8px 12px !important;
997
- white-space: nowrap !important;
998
- }
999
- @keyframes pulse {
1000
- 0% { opacity: 0.6; }
1001
- 50% { opacity: 1; }
1002
- 100% { opacity: 0.6; }
1003
- }
1004
- .progress-bar {
1005
- animation: pulse 1.5s ease-in-out infinite;
1006
- }
1007
- """
1008
- ) as demo:
1009
-
1010
- # ์–ธ์–ด ์ƒํƒœ ๊ด€๋ฆฌ
1011
- current_language = gr.State(value="en")
1012
-
1013
- def update_ui_language(language):
1014
- """UI ์–ธ์–ด ์—…๋ฐ์ดํŠธ"""
1015
- texts = TEXTS[language]
1016
-
1017
- return (
1018
- language, # current_language state update
1019
- # Title section update
1020
- gr.update(value=f"""
1021
- <div style="text-align: center; padding: 30px 0;">
1022
- <h1 style="font-size: 3em; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 10px;">
1023
- {texts['title']}
1024
- </h1>
1025
- <p style="font-size: 1.4em; color: #7f8c8d; font-weight: 500;">{texts['subtitle']}</p>
1026
- <p style="font-size: 1.1em; color: #95a5a6; margin-top: 10px;">{texts['description']}</p>
1027
- </div>
1028
- """),
1029
- gr.update(label=texts['industry_label'], placeholder=texts['industry_placeholder']),
1030
- gr.update(label=texts['keywords_label'], placeholder=texts['keywords_placeholder'], info=texts['keywords_info']),
1031
- )
1032
-
1033
- # ํ—ค๋”
1034
- title_section = gr.Markdown("""
1035
- <div style="text-align: center; padding: 30px 0;">
1036
- <h1 style="font-size: 3em; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 10px;">
1037
- THEORIAโ„ข
1038
- </h1>
1039
- <p style="font-size: 1.4em; color: #7f8c8d; font-weight: 500;">Theory-driven Naming AI with 15 Specialized Theories</p>
1040
- <p style="font-size: 1.1em; color: #95a5a6; margin-top: 10px;">Generate innovative brand names using 15 cognitive and creative theories</p>
1041
- </div>
1042
- """)
1043
-
1044
- with gr.Row():
1045
- with gr.Column(scale=1, min_width=300):
1046
- gr.Markdown("""
1047
- <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
1048
- <h3 style="margin-top: 0; color: #2c3e50;">๐Ÿ“ Brand Information</h3>
1049
- </div>
1050
- """)
1051
-
1052
- # ์–ธ์–ด ์„ ํƒ
1053
- language_selector = gr.Radio(
1054
- choices=[("English", "en"), ("ํ•œ๊ตญ์–ด", "ko")],
1055
- value="en",
1056
- label="๐ŸŒ Language",
1057
- info="Select output language"
1058
- )
1059
-
1060
- industry_input = gr.Textbox(
1061
- label="๐Ÿญ Industry",
1062
- placeholder="e.g., cafe, fitness, education, beauty...",
1063
- value="์นดํŽ˜/์ปคํ”ผ์ˆ"
1064
- )
1065
-
1066
- keywords_input = gr.Textbox(
1067
- label="๐Ÿ”‘ Keywords",
1068
- placeholder="premium, comfortable, urban, eco-friendly...",
1069
- info="Core values or characteristics the brand should embody",
1070
- lines=2
1071
- )
1072
-
1073
- # ์–ธ์–ด ๋ณ€๊ฒฝ ์ด๋ฒคํŠธ
1074
- language_selector.change(
1075
- update_ui_language,
1076
- inputs=[language_selector],
1077
- outputs=[current_language, title_section, industry_input, keywords_input]
1078
- )
1079
-
1080
- gr.Markdown("""
1081
- <div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
1082
- <h4 style="margin-top: 0; color: #1976d2;">๐ŸŽฏ 15 Specialized Theories</h4>
1083
- <p style="margin: 10px 0; font-size: 0.9em;">Each theory offers a unique approach to brand naming:</p>
1084
- <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.85em;">
1085
- <li><strong>Cognitive</strong>: Square, Sound, Cognitive Load, Gestalt</li>
1086
- <li><strong>Creative</strong>: Blending, SCAMPER, Biomimicry</li>
1087
- <li><strong>Strategic</strong>: Jobs-to-be-Done, Design Thinking</li>
1088
- <li><strong>Cultural</strong>: Archetype, Linguistic, Memetics</li>
1089
- <li><strong>Distinctive</strong>: Von Restorff, Color, Network</li>
1090
- </ul>
1091
- </div>
1092
-
1093
- <div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-top: 15px;">
1094
- <h4 style="margin-top: 0; color: #856404;">๐Ÿ’ก Pro Tips</h4>
1095
- <ul style="margin: 5px 0; padding-left: 20px; font-size: 0.85em;">
1096
- <li>Try multiple theories to find the perfect fit</li>
1097
- <li>Compare results across different approaches</li>
1098
- <li>Combine insights from various theories</li>
1099
- </ul>
1100
- </div>
1101
- """)
1102
-
1103
- with gr.Column(scale=3):
1104
- # 15๊ฐœ ํƒญ์„ 3๊ฐœ ํ–‰์œผ๋กœ ๊ตฌ์„ฑ
1105
- gr.Markdown("""
1106
- <div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 20px;">
1107
- <h3 style="margin: 0; color: #2c3e50; text-align: center;">Select a Theory to Generate Names</h3>
1108
- </div>
1109
- """)
1110
-
1111
- # 15๊ฐœ ํƒญ ์ƒ์„ฑ
1112
- with gr.Tabs(elem_classes="tab-nav"):
1113
- theories = [
1114
- ("๐ŸŸฆ", "square"),
1115
- ("๐Ÿ”€", "blending"),
1116
- ("๐Ÿ”Š", "sound"),
1117
- ("๐ŸŒ", "linguistic"),
1118
- ("๐ŸŽญ", "archetype"),
1119
- ("โœ…", "jobs"),
1120
- ("๐Ÿ”ง", "scamper"),
1121
- ("๐Ÿ’ญ", "design"),
1122
- ("๐ŸŒฟ", "biomimicry"),
1123
- ("๐Ÿง ", "cognitive"),
1124
- ("โšก", "vonrestorff"),
1125
- ("๐ŸŒ", "network"),
1126
- ("๐Ÿงฌ", "memetics"),
1127
- ("๐ŸŽจ", "color"),
1128
- ("๐Ÿ‘๏ธ", "gestalt")
1129
- ]
1130
-
1131
- for tab_name, theory_key in theories:
1132
- with gr.Tab(tab_name):
1133
- with gr.Column():
1134
- # ํ”„๋กœ๊ทธ๋ ˆ์Šค ๋ฉ”์‹œ์ง€
1135
- progress_msg = gr.Markdown(
1136
- visible=False
1137
- )
1138
-
1139
- with gr.Row():
1140
- btn = gr.Button(
1141
- f"Generate with {tab_name}",
1142
- variant="primary",
1143
- size="lg",
1144
- elem_id=f"btn_{theory_key}"
1145
- )
1146
-
1147
- output = gr.Markdown()
1148
- visual = gr.HTML()
1149
-
1150
- def show_progress(industry, keywords, theory, language, tab_name):
1151
- """ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ํ‘œ์‹œ"""
1152
- if not industry or not keywords:
1153
- return "", "", gr.update(visible=False)
1154
-
1155
- texts = TEXTS[language]
1156
- progress_text = texts["progress_message"].format(theory=tab_name)
1157
-
1158
- progress_html = f"""
1159
- <div style="text-align: center; padding: 20px; background: #f0f8ff; border-radius: 10px; margin: 10px 0;">
1160
- <div class="progress-bar" style="font-size: 1.2em; color: #1976d2;">
1161
- {progress_text}
1162
- </div>
1163
- <div style="margin-top: 10px;">
1164
- <div style="width: 100%; background: #e0e0e0; border-radius: 5px; overflow: hidden;">
1165
- <div style="width: 100%; height: 4px; background: linear-gradient(90deg, #1976d2 0%, #42a5f5 50%, #1976d2 100%); animation: slide 1.5s linear infinite;"></div>
1166
- </div>
1167
- </div>
1168
- </div>
1169
- <style>
1170
- @keyframes slide {{
1171
- 0% {{ transform: translateX(-100%); }}
1172
- 100% {{ transform: translateX(100%); }}
1173
- }}
1174
- </style>
1175
- """
1176
- return "", "", gr.update(visible=True, value=progress_html)
1177
-
1178
- def generate_and_hide_progress(industry, keywords, theory, language):
1179
- """์ƒ์„ฑ ํ›„ ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ์ˆจ๊น€"""
1180
- result_md, result_html, _ = generate_by_theory(industry, keywords, theory, language)
1181
- return result_md, result_html, gr.update(visible=False)
1182
-
1183
- # ํ”„๋กœ๊ทธ๋ ˆ์Šค๋ฐ” ํ‘œ์‹œ
1184
- btn.click(
1185
- lambda i, k, l, t=theory_key, n=tab_name: show_progress(i, k, t, l, n),
1186
- inputs=[industry_input, keywords_input, current_language],
1187
- outputs=[output, visual, progress_msg]
1188
- ).then(
1189
- # ์‹ค์ œ ์ƒ์„ฑ ์ž‘์—…
1190
- lambda i, k, l, t=theory_key: generate_and_hide_progress(i, k, t, l),
1191
- inputs=[industry_input, keywords_input, current_language],
1192
- outputs=[output, visual, progress_msg]
1193
- )
1194
-
1195
- gr.Markdown("""
1196
- <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; border-radius: 15px; margin-top: 40px;">
1197
- <h3 style="margin-top: 0; text-align: center;">๐Ÿ† Why THEORIAโ„ข?</h3>
1198
- <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 25px; margin-top: 25px;">
1199
- <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px;">
1200
- <h4 style="margin: 0 0 10px 0;">๐Ÿงช Scientific Foundation</h4>
1201
- <p style="margin: 0; font-size: 0.95em;">Based on proven cognitive and creative theories from psychology, linguistics, and design</p>
1202
- </div>
1203
- <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px;">
1204
- <h4 style="margin: 0 0 10px 0;">๐ŸŽฏ Multi-dimensional Approach</h4>
1205
- <p style="margin: 0; font-size: 0.95em;">15 different perspectives ensure you find the perfect name for your brand</p>
1206
- </div>
1207
- <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px;">
1208
- <h4 style="margin: 0 0 10px 0;">๐Ÿ“Š Unified Evaluation</h4>
1209
- <p style="margin: 0; font-size: 0.95em;">Consistent scoring system allows easy comparison across all theories</p>
1210
- </div>
1211
- <div style="background: rgba(255,255,255,0.1); padding: 20px; border-radius: 10px;">
1212
- <h4 style="margin: 0 0 10px 0;">๐ŸŒ Global Ready</h4>
1213
- <p style="margin: 0; font-size: 0.95em;">Multilingual support and cultural considerations built into every theory</p>
1214
- </div>
1215
- </div>
1216
-
1217
- <div style="text-align: center; margin-top: 30px; padding-top: 20px; border-top: 1px solid rgba(255,255,255,0.2);">
1218
- <p style="margin: 0; font-size: 0.9em; opacity: 0.8;">
1219
- THEORIAโ„ข - Where Science Meets Creativity in Brand Naming
1220
- </p>
1221
- </div>
1222
- </div>
1223
- """)
1224
 
1225
  if __name__ == "__main__":
1226
- demo.launch(
1227
- server_name="0.0.0.0",
1228
- server_port=7860,
1229
- share=False
1230
- )
 
1
  import os
2
+ import sys
3
+ import streamlit as st
4
+ from tempfile import NamedTemporaryFile
 
 
 
 
 
5
 
6
+ def main():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  try:
8
+ # Get the code from secrets
9
+ code = os.environ.get("MAIN_CODE")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if not code:
12
+ st.error("โš ๏ธ The application code wasn't found in secrets. Please add the MAIN_CODE secret.")
13
+ return
 
 
 
 
 
 
 
 
14
 
15
+ # Create a temporary Python file
16
+ with NamedTemporaryFile(suffix='.py', delete=False, mode='w') as tmp:
17
+ tmp.write(code)
18
+ tmp_path = tmp.name
19
 
20
+ # Execute the code
21
+ exec(compile(code, tmp_path, 'exec'), globals())
22
 
23
+ # Clean up the temporary file
24
+ try:
25
+ os.unlink(tmp_path)
26
+ except:
27
+ pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ except Exception as e:
30
+ st.error(f"โš ๏ธ Error loading or executing the application: {str(e)}")
31
+ import traceback
32
+ st.code(traceback.format_exc())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
  if __name__ == "__main__":
35
+ main()