Update app.py
Browse files
app.py
CHANGED
@@ -166,7 +166,7 @@ UNIFIED_BASE_PROMPT_KO = """
|
|
166 |
"brands": [
|
167 |
{{
|
168 |
"core": {{
|
169 |
-
"brand_name": "๋ธ๋๋๋ช
",
|
170 |
"slogan": "์ฌ๋ก๊ฑด",
|
171 |
"core_value": "ํต์ฌ ๊ฐ์น",
|
172 |
"target_emotion": "๋ชฉํ ๊ฐ์ ",
|
@@ -179,9 +179,9 @@ UNIFIED_BASE_PROMPT_KO = """
|
|
179 |
"typography_style": "ํ์ดํฌ๊ทธ๋ํผ ์คํ์ผ"
|
180 |
}},
|
181 |
"linguistic": {{
|
182 |
-
"pronunciation": "๋ฐ์ ๊ฐ์ด๋",
|
183 |
-
"etymology": "์ด์/๊ตฌ์ฑ",
|
184 |
-
"global_adaptability": "
|
185 |
"memorable_factor": "๊ธฐ์ต ์ฉ์ด์ฑ ์์"
|
186 |
}},
|
187 |
"strategic": {{
|
@@ -203,9 +203,11 @@ UNIFIED_BASE_PROMPT_KO = """
|
|
203 |
]
|
204 |
}}
|
205 |
|
206 |
-
|
207 |
-
|
208 |
-
|
|
|
|
|
209 |
"""
|
210 |
|
211 |
# ์ด๋ก ๋ณ ํน์ ํ๋ ์ ์ (์์ด)
|
@@ -369,7 +371,7 @@ THEORY_SPECIFIC_FIELDS_KO = {
|
|
369 |
|
370 |
"linguistic": """
|
371 |
"korean_adaptation": "ํ๊ตญ์ด ์ ์",
|
372 |
-
"english_meaning": "์์ด
|
373 |
"cultural_considerations": "๋ฌธํ์ ๊ณ ๋ ค์ฌํญ",
|
374 |
"avoid_meanings": "ํผํด์ผ ํ ์๋ฏธ๋ค",
|
375 |
"localization_strategy": "ํ์งํ ์ ๋ต"
|
@@ -533,7 +535,8 @@ Each brand should have a unified structure, with theory-specific characteristics
|
|
533 |
ํค์๋: {keywords}
|
534 |
|
535 |
์ ์ ๋ณด๋ก {count}๊ฐ์ ๋ธ๋๋๋ฅผ ์์ฑํ์ธ์.
|
536 |
-
๊ฐ ๋ธ๋๋๋ ํต์ผ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋, theory_specific ์น์
์๋ {theory} ์ด๋ก ์ ํน์ฑ์ ๋ฐ์ํ์ธ์.
|
|
|
537 |
|
538 |
try:
|
539 |
# ํ๋ก๊ทธ๋ ์ค๋ฐ ํ์
|
@@ -659,7 +662,47 @@ def generate_unified_markdown(theory: str, results: List[Dict], industry: str, k
|
|
659 |
brand_name = core.get('brand_name', 'N/A')
|
660 |
slogan = core.get('slogan', 'N/A')
|
661 |
|
662 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
663 |
|
664 |
if language == "en":
|
665 |
markdown += f"""**Slogan**: *"{slogan}"*
|
@@ -762,6 +805,46 @@ def generate_unified_visualization(theory: str, results: List[Dict], language: s
|
|
762 |
slogan = core.get('slogan', '')
|
763 |
primary_color = visual.get('primary_color', '#667eea')
|
764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
765 |
# ์ธ์ด๋ณ ๋ผ๋ฒจ
|
766 |
if language == "en":
|
767 |
labels = {
|
@@ -784,7 +867,7 @@ def generate_unified_visualization(theory: str, results: List[Dict], language: s
|
|
784 |
<div style="background: white; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); overflow: hidden;">
|
785 |
<!-- ํค๋ -->
|
786 |
<div style="background: linear-gradient(135deg, {primary_color} 0%, #2c3e50 100%); padding: 40px; color: white;">
|
787 |
-
<h2 style="margin: 0 0 10px 0; font-size: 2.5em;">{
|
788 |
<p style="margin: 0; font-style: italic; font-size: 1.2em; opacity: 0.9;">"{slogan}"</p>
|
789 |
</div>
|
790 |
|
@@ -975,15 +1058,51 @@ with gr.Blocks(
|
|
975 |
css="""
|
976 |
.gradio-container {
|
977 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
978 |
}
|
979 |
.tab-nav button {
|
980 |
-
font-size: 0.
|
981 |
-
padding: 8px
|
982 |
-
white-space:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
}
|
984 |
-
.tab-nav {
|
985 |
-
|
986 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
987 |
}
|
988 |
@keyframes pulse {
|
989 |
0% { opacity: 0.6; }
|
@@ -1030,7 +1149,7 @@ with gr.Blocks(
|
|
1030 |
""")
|
1031 |
|
1032 |
with gr.Row():
|
1033 |
-
with gr.Column(scale=1, min_width=
|
1034 |
gr.Markdown("""
|
1035 |
<div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
|
1036 |
<h3 style="margin-top: 0; color: #2c3e50;">๐ Brand Information</h3>
|
@@ -1067,28 +1186,28 @@ with gr.Blocks(
|
|
1067 |
|
1068 |
gr.Markdown("""
|
1069 |
<div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
|
1070 |
-
<h4 style="margin-top: 0; color: #1976d2;">๐ฏ 15
|
1071 |
-
<p style="margin: 10px 0; font-size: 0.9em;">Each theory offers
|
1072 |
-
<ul style="margin: 5px 0; padding-left: 20px; font-size: 0.
|
1073 |
-
<li><strong>Cognitive</strong>: Square, Sound, Cognitive
|
1074 |
<li><strong>Creative</strong>: Blending, SCAMPER, Biomimicry</li>
|
1075 |
-
<li><strong>Strategic</strong>: Jobs-to-be-Done, Design
|
1076 |
<li><strong>Cultural</strong>: Archetype, Linguistic, Memetics</li>
|
1077 |
<li><strong>Distinctive</strong>: Von Restorff, Color, Network</li>
|
1078 |
</ul>
|
1079 |
</div>
|
1080 |
|
1081 |
<div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-top: 15px;">
|
1082 |
-
<h4 style="margin-top: 0; color: #856404;">๐ก
|
1083 |
-
<ul style="margin: 5px 0; padding-left: 20px; font-size: 0.
|
1084 |
-
<li>Try multiple theories
|
1085 |
-
<li>Compare results
|
1086 |
-
<li>Combine insights
|
1087 |
</ul>
|
1088 |
</div>
|
1089 |
""")
|
1090 |
|
1091 |
-
with gr.Column(scale=
|
1092 |
# 15๊ฐ ํญ์ 3๊ฐ ํ์ผ๋ก ๊ตฌ์ฑ
|
1093 |
gr.Markdown("""
|
1094 |
<div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 20px;">
|
|
|
166 |
"brands": [
|
167 |
{{
|
168 |
"core": {{
|
169 |
+
"brand_name": "ํ๊ธ ๋ธ๋๋๋ช
",
|
170 |
"slogan": "์ฌ๋ก๊ฑด",
|
171 |
"core_value": "ํต์ฌ ๊ฐ์น",
|
172 |
"target_emotion": "๋ชฉํ ๊ฐ์ ",
|
|
|
179 |
"typography_style": "ํ์ดํฌ๊ทธ๋ํผ ์คํ์ผ"
|
180 |
}},
|
181 |
"linguistic": {{
|
182 |
+
"pronunciation": "ํ๊ธ ๋ฐ์ ๊ฐ์ด๋",
|
183 |
+
"etymology": "์ด์/๊ตฌ์ฑ (์์ด๋ช
ํฌํจ)",
|
184 |
+
"global_adaptability": "์์ด ๋ธ๋๋๋ช
(์: Mother's Garden)",
|
185 |
"memorable_factor": "๊ธฐ์ต ์ฉ์ด์ฑ ์์"
|
186 |
}},
|
187 |
"strategic": {{
|
|
|
203 |
]
|
204 |
}}
|
205 |
|
206 |
+
์ค์:
|
207 |
+
1. brand_name์ ๋ฐ๋์ ํ๊ธ๋ก ์์ฑํ์ธ์.
|
208 |
+
2. linguistic > global_adaptability์๋ ๋ฐ๋์ ์์ด ๋ธ๋๋๋ช
์ ํฌํจํ์ธ์.
|
209 |
+
3. ์์ด๋ช
์ ํ๊ธ๋ช
์ ์๋ฏธ๋ฅผ ์ ์ ๋ฌํ๋, ๊ธ๋ก๋ฒํ๊ฒ ์ฌ์ฉ ๊ฐ๋ฅํ ์ด๋ฆ์ผ๋ก ๋ง๋์ธ์.
|
210 |
+
4. ๋ชจ๋ ํ๋๋ฅผ ํ๊ตญ์ด๋ก ์์ฑํ๋, ์์ด ๋ธ๋๋๋ช
๋ง ์์ด๋ก ํ๊ธฐํ์ธ์.
|
211 |
"""
|
212 |
|
213 |
# ์ด๋ก ๋ณ ํน์ ํ๋ ์ ์ (์์ด)
|
|
|
371 |
|
372 |
"linguistic": """
|
373 |
"korean_adaptation": "ํ๊ตญ์ด ์ ์",
|
374 |
+
"english_meaning": "์์ด ๋ธ๋๋๋ช
",
|
375 |
"cultural_considerations": "๋ฌธํ์ ๊ณ ๋ ค์ฌํญ",
|
376 |
"avoid_meanings": "ํผํด์ผ ํ ์๋ฏธ๋ค",
|
377 |
"localization_strategy": "ํ์งํ ์ ๋ต"
|
|
|
535 |
ํค์๋: {keywords}
|
536 |
|
537 |
์ ์ ๋ณด๋ก {count}๊ฐ์ ๋ธ๋๋๋ฅผ ์์ฑํ์ธ์.
|
538 |
+
๊ฐ ๋ธ๋๋๋ ํต์ผ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋, theory_specific ์น์
์๋ {theory} ์ด๋ก ์ ํน์ฑ์ ๋ฐ์ํ์ธ์.
|
539 |
+
์ค์: linguistic > global_adaptability ํ๋์ ๋ฐ๋์ ์์ด ๋ธ๋๋๋ช
์ ํฌํจํ์ธ์."""
|
540 |
|
541 |
try:
|
542 |
# ํ๋ก๊ทธ๋ ์ค๋ฐ ํ์
|
|
|
662 |
brand_name = core.get('brand_name', 'N/A')
|
663 |
slogan = core.get('slogan', 'N/A')
|
664 |
|
665 |
+
# ํ๊ธ์ผ ๊ฒฝ์ฐ ์์ด ํํ ์ถ๊ฐ
|
666 |
+
if language == "ko":
|
667 |
+
# ์ฐ์ ์์์ ๋ฐ๋ผ ์์ด๋ช
์ฐพ๊ธฐ
|
668 |
+
english_name = None
|
669 |
+
|
670 |
+
# 1. linguistic theory์ ๊ฒฝ์ฐ theory_specific์์ ์ฐพ๊ธฐ
|
671 |
+
if theory == "linguistic" and 'english_meaning' in theory_specific:
|
672 |
+
english_name = theory_specific.get('english_meaning', '')
|
673 |
+
|
674 |
+
# 2. global_adaptability์์ ์ฐพ๊ธฐ
|
675 |
+
if not english_name or english_name == 'N/A':
|
676 |
+
english_name = linguistic.get('global_adaptability', '')
|
677 |
+
|
678 |
+
# 3. etymology์์ ์์ด ์ถ์ถ
|
679 |
+
if not english_name or english_name == 'N/A':
|
680 |
+
etymology = linguistic.get('etymology', '')
|
681 |
+
if etymology and '์์ด' in etymology and ':' in etymology:
|
682 |
+
# "์์ด: Brand Name" ํ์์์ ์ถ์ถ
|
683 |
+
parts = etymology.split(':')
|
684 |
+
for i, part in enumerate(parts):
|
685 |
+
if '์์ด' in part and i + 1 < len(parts):
|
686 |
+
english_name = parts[i + 1].strip().split(',')[0].strip()
|
687 |
+
break
|
688 |
+
|
689 |
+
# ์์ด๋ช
์ด ์ ํจํ ๊ฒฝ์ฐ์๋ง ์ถ๊ฐ
|
690 |
+
if english_name and english_name != 'N/A' and english_name != brand_name:
|
691 |
+
# ๊ธธ์ด๊ฐ ๋๋ฌด ๊ธธ๊ฑฐ๋ ์ค๋ช
์ด ํฌํจ๋ ๊ฒฝ์ฐ ์ ๋ฆฌ
|
692 |
+
if len(english_name) > 50 or '(' in english_name or ',' in english_name:
|
693 |
+
english_name = english_name.split('(')[0].split(',')[0].strip()
|
694 |
+
|
695 |
+
# ์์ด๋ช
์ด ์ค์ ๋ก ์์ด์ธ์ง ๊ฐ๋จํ ํ์ธ (ํ๊ธ์ด ํฌํจ๋์ง ์์๋์ง)
|
696 |
+
if not any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in english_name):
|
697 |
+
brand_display = f"{brand_name} / {english_name}"
|
698 |
+
else:
|
699 |
+
brand_display = brand_name
|
700 |
+
else:
|
701 |
+
brand_display = brand_name
|
702 |
+
else:
|
703 |
+
brand_display = brand_name
|
704 |
+
|
705 |
+
markdown += f"\n## {idx}. {brand_display}\n"
|
706 |
|
707 |
if language == "en":
|
708 |
markdown += f"""**Slogan**: *"{slogan}"*
|
|
|
805 |
slogan = core.get('slogan', '')
|
806 |
primary_color = visual.get('primary_color', '#667eea')
|
807 |
|
808 |
+
# ํ๊ธ์ผ ๊ฒฝ์ฐ ์์ด ํํ ์ถ๊ฐ
|
809 |
+
if language == "ko":
|
810 |
+
# ์ฐ์ ์์์ ๋ฐ๋ผ ์์ด๋ช
์ฐพ๊ธฐ
|
811 |
+
english_name = None
|
812 |
+
|
813 |
+
# 1. linguistic theory์ ๊ฒฝ์ฐ theory_specific์์ ์ฐพ๊ธฐ
|
814 |
+
if theory == "linguistic" and 'english_meaning' in theory_specific:
|
815 |
+
english_name = theory_specific.get('english_meaning', '')
|
816 |
+
|
817 |
+
# 2. global_adaptability์์ ์ฐพ๊ธฐ
|
818 |
+
if not english_name or english_name == 'N/A':
|
819 |
+
english_name = linguistic.get('global_adaptability', '')
|
820 |
+
|
821 |
+
# 3. etymology์์ ์์ด ์ถ์ถ
|
822 |
+
if not english_name or english_name == 'N/A':
|
823 |
+
etymology = linguistic.get('etymology', '')
|
824 |
+
if etymology and '์์ด' in etymology and ':' in etymology:
|
825 |
+
# "์์ด: Brand Name" ํ์์์ ์ถ์ถ
|
826 |
+
parts = etymology.split(':')
|
827 |
+
for i, part in enumerate(parts):
|
828 |
+
if '์์ด' in part and i + 1 < len(parts):
|
829 |
+
english_name = parts[i + 1].strip().split(',')[0].strip()
|
830 |
+
break
|
831 |
+
|
832 |
+
# ์์ด๋ช
์ด ์ ํจํ ๊ฒฝ์ฐ์๋ง ์ถ๊ฐ
|
833 |
+
if english_name and english_name != 'N/A' and english_name != brand_name:
|
834 |
+
# ๊ธธ์ด๊ฐ ๋๋ฌด ๊ธธ๊ฑฐ๋ ์ค๋ช
์ด ํฌํจ๋ ๊ฒฝ์ฐ ์ ๋ฆฌ
|
835 |
+
if len(english_name) > 50 or '(' in english_name or ',' in english_name:
|
836 |
+
english_name = english_name.split('(')[0].split(',')[0].strip()
|
837 |
+
|
838 |
+
# ์์ด๋ช
์ด ์ค์ ๋ก ์์ด์ธ์ง ๊ฐ๋จํ ํ์ธ (ํ๊ธ์ด ํฌํจ๋์ง ์์๋์ง)
|
839 |
+
if not any(ord(char) >= 0xAC00 and ord(char) <= 0xD7A3 for char in english_name):
|
840 |
+
brand_display = f"{brand_name} / {english_name}"
|
841 |
+
else:
|
842 |
+
brand_display = brand_name
|
843 |
+
else:
|
844 |
+
brand_display = brand_name
|
845 |
+
else:
|
846 |
+
brand_display = brand_name
|
847 |
+
|
848 |
# ์ธ์ด๋ณ ๋ผ๋ฒจ
|
849 |
if language == "en":
|
850 |
labels = {
|
|
|
867 |
<div style="background: white; border-radius: 20px; box-shadow: 0 10px 40px rgba(0,0,0,0.1); overflow: hidden;">
|
868 |
<!-- ํค๋ -->
|
869 |
<div style="background: linear-gradient(135deg, {primary_color} 0%, #2c3e50 100%); padding: 40px; color: white;">
|
870 |
+
<h2 style="margin: 0 0 10px 0; font-size: 2.5em;">{brand_display}</h2>
|
871 |
<p style="margin: 0; font-style: italic; font-size: 1.2em; opacity: 0.9;">"{slogan}"</p>
|
872 |
</div>
|
873 |
|
|
|
1058 |
css="""
|
1059 |
.gradio-container {
|
1060 |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
1061 |
+
max-width: 1400px !important;
|
1062 |
+
}
|
1063 |
+
/* ํญ ๋ค๋น๊ฒ์ด์
์คํ์ผ ๊ฐ์ */
|
1064 |
+
.tab-nav {
|
1065 |
+
display: grid !important;
|
1066 |
+
grid-template-columns: repeat(5, 1fr) !important;
|
1067 |
+
gap: 8px !important;
|
1068 |
+
padding: 15px !important;
|
1069 |
+
background: #f8f9fa !important;
|
1070 |
+
border-radius: 10px !important;
|
1071 |
+
margin-bottom: 20px !important;
|
1072 |
}
|
1073 |
.tab-nav button {
|
1074 |
+
font-size: 0.8em !important;
|
1075 |
+
padding: 10px 8px !important;
|
1076 |
+
white-space: normal !important;
|
1077 |
+
line-height: 1.3 !important;
|
1078 |
+
height: auto !important;
|
1079 |
+
min-height: 50px !important;
|
1080 |
+
display: flex !important;
|
1081 |
+
align-items: center !important;
|
1082 |
+
justify-content: center !important;
|
1083 |
+
text-align: center !important;
|
1084 |
+
border-radius: 8px !important;
|
1085 |
+
transition: all 0.3s ease !important;
|
1086 |
}
|
1087 |
+
.tab-nav button:hover {
|
1088 |
+
transform: translateY(-2px) !important;
|
1089 |
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15) !important;
|
1090 |
+
}
|
1091 |
+
.tab-nav button.selected {
|
1092 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
1093 |
+
color: white !important;
|
1094 |
+
font-weight: 600 !important;
|
1095 |
+
}
|
1096 |
+
/* ๋ชจ๋ฐ์ผ ๋ฐ์ํ */
|
1097 |
+
@media (max-width: 768px) {
|
1098 |
+
.tab-nav {
|
1099 |
+
grid-template-columns: repeat(3, 1fr) !important;
|
1100 |
+
}
|
1101 |
+
}
|
1102 |
+
@media (max-width: 480px) {
|
1103 |
+
.tab-nav {
|
1104 |
+
grid-template-columns: repeat(2, 1fr) !important;
|
1105 |
+
}
|
1106 |
}
|
1107 |
@keyframes pulse {
|
1108 |
0% { opacity: 0.6; }
|
|
|
1149 |
""")
|
1150 |
|
1151 |
with gr.Row():
|
1152 |
+
with gr.Column(scale=1, min_width=250):
|
1153 |
gr.Markdown("""
|
1154 |
<div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
|
1155 |
<h3 style="margin-top: 0; color: #2c3e50;">๐ Brand Information</h3>
|
|
|
1186 |
|
1187 |
gr.Markdown("""
|
1188 |
<div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
|
1189 |
+
<h4 style="margin-top: 0; color: #1976d2;">๐ฏ 15 Theories</h4>
|
1190 |
+
<p style="margin: 10px 0; font-size: 0.9em;">Each theory offers unique approach:</p>
|
1191 |
+
<ul style="margin: 5px 0; padding-left: 20px; font-size: 0.8em; line-height: 1.4;">
|
1192 |
+
<li><strong>Cognitive</strong>: Square, Sound, Cognitive, Gestalt</li>
|
1193 |
<li><strong>Creative</strong>: Blending, SCAMPER, Biomimicry</li>
|
1194 |
+
<li><strong>Strategic</strong>: Jobs-to-be-Done, Design</li>
|
1195 |
<li><strong>Cultural</strong>: Archetype, Linguistic, Memetics</li>
|
1196 |
<li><strong>Distinctive</strong>: Von Restorff, Color, Network</li>
|
1197 |
</ul>
|
1198 |
</div>
|
1199 |
|
1200 |
<div style="background: #fff3cd; padding: 15px; border-radius: 8px; margin-top: 15px;">
|
1201 |
+
<h4 style="margin-top: 0; color: #856404;">๐ก Tips</h4>
|
1202 |
+
<ul style="margin: 5px 0; padding-left: 20px; font-size: 0.8em; line-height: 1.4;">
|
1203 |
+
<li>Try multiple theories</li>
|
1204 |
+
<li>Compare results</li>
|
1205 |
+
<li>Combine insights</li>
|
1206 |
</ul>
|
1207 |
</div>
|
1208 |
""")
|
1209 |
|
1210 |
+
with gr.Column(scale=4):
|
1211 |
# 15๊ฐ ํญ์ 3๊ฐ ํ์ผ๋ก ๊ตฌ์ฑ
|
1212 |
gr.Markdown("""
|
1213 |
<div style="background: #f8f9fa; padding: 15px; border-radius: 10px; margin-bottom: 20px;">
|