openfree commited on
Commit
3454e01
·
verified ·
1 Parent(s): a3f5c3b

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +1072 -0
app.py ADDED
@@ -0,0 +1,1072 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Ultimate Brand Theory Generator
3
+ ===============================
4
+ 2025-05-28 | 15개 이론을 통합한 종합 브랜드 생성기
5
+ -----------------------------------------------------
6
+
7
+ 통합된 이론들:
8
+ 1. Square Theory - 의미적 사각형 구조
9
+ 2. Conceptual Blending - 개념 혼합
10
+ 3. Sound Symbolism - 음향 상징주의
11
+ 4. Linguistic Relativity - 언어 상대성
12
+ 5. Archetype Theory - 원형 이론
13
+ 6. Jobs-to-be-Done - 할 일 이론
14
+ 7. SCAMPER Method - 창의적 변형
15
+ 8. Design Thinking - 디자인 사고
16
+ 9. Biomimicry - 생체모방
17
+ 10. Cognitive Load - 인지 부하
18
+ 11. Von Restorff Effect - 고립 효과
19
+ 12. Network Effects - 네트워크 효과
20
+ 13. Memetics - 밈 이론
21
+ 14. Color Psychology - 색상 심리학
22
+ 15. Gestalt Principles - 게슈탈트 원칙
23
+ """
24
+
25
+ import os
26
+ import json
27
+ import gradio as gr
28
+ import openai
29
+ from openai import OpenAI
30
+ from datetime import datetime
31
+ from typing import List, Dict, Tuple, Optional
32
+ import random
33
+
34
+ # OpenAI 클라이언트
35
+ if not os.getenv("OPENAI_API_KEY"):
36
+ raise EnvironmentError("OPENAI_API_KEY 환경 변수를 설정하세요.")
37
+
38
+ client = OpenAI()
39
+
40
+ # 이론별 설명
41
+ THEORY_DESCRIPTIONS = {
42
+ "square": "4개의 단어가 의미적 관계로 연결되어 사각형을 이루는 구조입니다. 대변의 숨겨진 연결이 '아하!' 모먼트를 만듭니다.",
43
+ "blending": "두 개 이상의 개념을 혼합하여 새로운 의미를 창출합니다. Netflix(Net+Flix)처럼 혁신적인 개념을 탄생시킵니다.",
44
+ "sound": "음소와 의미 간의 연관성을 활용합니다. 'i,e'는 가볍고 빠른 느낌, 'o,u'는 무겁고 느린 느낌을 전달합니다.",
45
+ "linguistic": "언어별 사고방식 차이를 고려한 글로벌 브랜드를 만듭니다. 문화적 뉘앙스와 현지화 전략을 반영합니다.",
46
+ "archetype": "Jung의 12가지 보편적 원형을 활용합니다. Hero(Nike), Creator(Apple)처럼 무의식적 감정 연결을 만듭니다.",
47
+ "jobs": "고객이 해결하려는 '일'에 초점을 맞춥니다. 기능적, 감정적, 사회적 차원의 니즈를 통합적으로 해결합니다.",
48
+ "scamper": "7가지 창의적 기법(대체, 결합, 적응, 수정, 용도변경, 제거, 역전)으로 혁신적인 브랜드를 만듭니다.",
49
+ "design": "인간 중심 혁신을 추구합니다. 바람직함(인간), 실현가능성(기술), 생존가능성(비즈니스)의 교집합을 찾습니다.",
50
+ "biomimicry": "자연에서 영감을 받은 브랜드를 만듭니다. 38억년 진화의 지혜를 브랜딩에 적용합니다.",
51
+ "cognitive": "인지 처리를 최소화하는 브랜드를 만듭니다. 1-3음절의 쉬운 발음으로 즉각적 인식과 기억을 돕습니다.",
52
+ "vonrestorff": "독특하고 기억에 남는 브랜드를 만듭니다. 카테고리 관습을 의도적으로 위반하여 30배 더 잘 기억되게 합니다.",
53
+ "network": "네트워크 가치를 극대화하는 브랜드를 만듭니다. 사용자가 많을수록 가치가 증가하는 구조를 설계합니다.",
54
+ "memetics": "문화적으로 복제되고 진화하는 브랜드를 만듭니다. 밈처럼 자연스럽게 퍼져나가는 바이럴 요소를 내재화합니다.",
55
+ "color": "색상 연상과 감정을 활용한 브랜드를 만듭니다. 빨강(열정), 파랑(신뢰), 초록(자연) 등 색상 심리를 적용합니다.",
56
+ "gestalt": "지각 원리를 활용한 브랜드를 만듭니다. 전체가 부분의 합보다 크다는 원칙으로 통합적 브랜드 경험을 설계합니다."
57
+ }
58
+
59
+ # ===== 1. SQUARE THEORY =====
60
+ SQUARE_THEORY_PROMPT = """
61
+ 당신은 Square Theory 전문가입니다. Square Theory는 4개의 단어가 의미적 관계로 연결되어 사각형을 이루는 구조입니다.
62
+ 브랜드명이 Square를 완성하며 "아하!" 모먼트를 만들어야 합니다.
63
+
64
+ 사용자 입력(업종/키워드)을 받아 다음 JSON 형식의 배열을 생성하세요:
65
+ {
66
+ "brand_name": "브랜드명",
67
+ "tl": "왼쪽상단", "tr": "오른쪽상단", "bl": "왼쪽하단", "br": "오른쪽하단",
68
+ "top_edge": "상단 관계", "bottom_edge": "하단 관계",
69
+ "left_edge": "왼쪽 관계", "right_edge": "오른쪽 관계",
70
+ "slogan": "슬로건",
71
+ "explanation": "왜 효과적인지"
72
+ }
73
+
74
+ 반드시 유효한 JSON 형식으로 응답하세요.
75
+ """
76
+
77
+ # ===== 2. CONCEPTUAL BLENDING =====
78
+ CONCEPTUAL_BLENDING_PROMPT = """
79
+ 당신은 Conceptual Blending Theory 전문가입니다. 두 개 이상의 개념을 혼합하여 새로운 의미를 창출합니다.
80
+
81
+ 다음 JSON 형식으로 브랜드를 생성하세요:
82
+ {
83
+ "brand_name": "브랜드명",
84
+ "input_space1": "첫 번째 개념",
85
+ "input_space2": "두 번째 개념",
86
+ "generic_space": "공통 구조",
87
+ "blended_space": "혼합된 새로운 의미",
88
+ "emergent_properties": "창발적 속성들",
89
+ "slogan": "슬로건",
90
+ "explanation": "혼합이 효과적인 이유"
91
+ }
92
+
93
+ 예시: Netflix = Net(인터넷) + Flix(영화) → 온라인 스��리밍의 새로운 개념
94
+ 반드시 유효한 JSON 형식으로 응답하세요.
95
+ """
96
+
97
+ # ===== 3. SOUND SYMBOLISM =====
98
+ SOUND_SYMBOLISM_PROMPT = """
99
+ 당신은 Sound Symbolism 전문가입니다. 음소와 의미 간의 연관성을 활용합니다.
100
+
101
+ 음향 원칙:
102
+ - 전설모음(i,e): 작고, 빠르고, 가벼움
103
+ - 후설모음(o,u): 크고, 느리고, 무거움
104
+ - 유음(l,r,m,n): 부드럽고 유연함
105
+ - 파열음(p,t,k,b,d,g): 강하고 역동적
106
+
107
+ 다음 JSON 형식으로 브랜드를 생성하세요:
108
+ {
109
+ "brand_name": "브랜드명",
110
+ "phonetic_analysis": "음성 분석",
111
+ "sound_meaning": "음향이 전달하는 의미",
112
+ "target_emotion": "목표 감정",
113
+ "industry_fit": "업종 적합성",
114
+ "pronunciation_guide": "발음 가이드",
115
+ "slogan": "슬로건"
116
+ }
117
+
118
+ 반드시 유효한 JSON 형식으로 응답하세요.
119
+ """
120
+
121
+ # ===== 4. LINGUISTIC RELATIVITY =====
122
+ LINGUISTIC_RELATIVITY_PROMPT = """
123
+ 당신은 Linguistic Relativity 전문가입니다. 언어별 사고방식 차이를 고려합니다.
124
+
125
+ 다음 JSON 형식으로 다언어 브랜드를 생성하세요:
126
+ {
127
+ "brand_name": "글로벌 브랜드명",
128
+ "korean_adaptation": "한국어 적응",
129
+ "english_meaning": "영어 의미",
130
+ "cultural_considerations": "문화적 고려사항",
131
+ "avoid_meanings": "피해야 할 의미들",
132
+ "localization_strategy": "현지화 전략",
133
+ "slogan": "슬로건"
134
+ }
135
+
136
+ 반드시 유효한 JSON 형식으로 응답하세요.
137
+ """
138
+
139
+ # ===== 5. ARCHETYPE THEORY =====
140
+ ARCHETYPE_THEORY_PROMPT = """
141
+ 당신은 Jung의 Archetype Theory 전문가입니다. 12가지 원형 중 하나를 선택하여 브랜드를 만듭니다.
142
+
143
+ 12 원형: Innocent, Hero, Outlaw, Explorer, Creator, Ruler, Magician, Lover, Caregiver, Jester, Sage, Regular Guy
144
+
145
+ 다음 JSON 형식으로 브랜드를 생성하세요:
146
+ {
147
+ "brand_name": "브랜드명",
148
+ "archetype": "선택된 원형",
149
+ "archetype_traits": "원형의 특징들",
150
+ "brand_personality": "브랜드 성격",
151
+ "visual_direction": "시각적 방향",
152
+ "voice_tone": "목소리 톤",
153
+ "slogan": "슬로건",
154
+ "mythology_reference": "신화적 참조"
155
+ }
156
+
157
+ 반드시 유효한 JSON 형식으로 응답하세요.
158
+ """
159
+
160
+ # ===== 6. JOBS-TO-BE-DONE =====
161
+ JOBS_TO_BE_DONE_PROMPT = """
162
+ 당신은 Jobs-to-be-Done Theory 전문가입니다. 고객이 해결하려는 '일'에 초점을 맞춥니다.
163
+
164
+ 다음 JSON 형식으로 브랜드를 생성하세요:
165
+ {
166
+ "brand_name": "브랜드명",
167
+ "functional_job": "기능적 일",
168
+ "emotional_job": "감정적 일",
169
+ "social_job": "사회적 일",
170
+ "job_statement": "핵심 Job 문장",
171
+ "outcome_metrics": "성과 지표",
172
+ "slogan": "슬로건",
173
+ "value_proposition": "가치 제안"
174
+ }
175
+
176
+ 반드시 유효한 JSON 형식으로 응답하세요.
177
+ """
178
+
179
+ # ===== 7. SCAMPER METHOD =====
180
+ SCAMPER_PROMPT = """
181
+ 당신은 SCAMPER Method 전문가입니다. 7가지 창의적 기법을 적용합니다.
182
+
183
+ S - Substitute (대체)
184
+ C - Combine (결합)
185
+ A - Adapt (적응)
186
+ M - Modify/Magnify (수정/확대)
187
+ P - Put to another use (다른 용도)
188
+ E - Eliminate (제거)
189
+ R - Reverse (역전)
190
+
191
+ 다음 JSON 형식으로 브랜드를 생성하세요:
192
+ {
193
+ "brand_name": "브랜드명",
194
+ "scamper_technique": "사용된 기법",
195
+ "original_concept": "원래 개념",
196
+ "transformation": "변형 과정",
197
+ "innovative_aspect": "혁신적 측면",
198
+ "slogan": "슬로건"
199
+ }
200
+
201
+ 반드시 유효한 JSON 형식으로 응답하세요.
202
+ """
203
+
204
+ # ===== 8. DESIGN THINKING =====
205
+ DESIGN_THINKING_PROMPT = """
206
+ 당신은 IDEO의 Design Thinking 전문가입니다. 인간 중심 혁신을 추구합니다.
207
+
208
+ 다음 JSON 형식으로 브랜드를 생성하세요:
209
+ {
210
+ "brand_name": "브랜드명",
211
+ "user_insight": "사용자 통찰",
212
+ "pain_point": "해결하는 문제점",
213
+ "desirability": "바람직함 (인간)",
214
+ "feasibility": "실현가능성 (기술)",
215
+ "viability": "생존가능성 (비즈니스)",
216
+ "prototype_concept": "프로토타입 컨셉",
217
+ "slogan": "슬로건"
218
+ }
219
+
220
+ 반드시 유효한 JSON 형식으로 응답하세요.
221
+ """
222
+
223
+ # ===== 9. BIOMIMICRY =====
224
+ BIOMIMICRY_PROMPT = """
225
+ 당신은 Biomimicry 전문가입니다. 자연에서 영감을 받은 브랜드를 만듭니다.
226
+
227
+ 다음 JSON 형식으로 브랜드를 생성하세요:
228
+ {
229
+ "brand_name": "브랜드명",
230
+ "natural_inspiration": "자연적 영감원",
231
+ "biomimetic_principle": "생체모방 원리",
232
+ "form_function": "형태와 기능",
233
+ "sustainability_aspect": "지속가능성 측면",
234
+ "adaptation_strategy": "적응 전략",
235
+ "slogan": "슬로건"
236
+ }
237
+
238
+ 반드시 유효한 JSON 형식으로 응답하세요.
239
+ """
240
+
241
+ # ===== 10. COGNITIVE LOAD =====
242
+ COGNITIVE_LOAD_PROMPT = """
243
+ 당신은 Cognitive Load Theory 전문가입니다. 인지 처리를 최소화하는 브랜드를 만듭니다.
244
+
245
+ 다음 JSON 형식으로 브랜드를 생성하세요:
246
+ {
247
+ "brand_name": "브랜드명",
248
+ "syllable_count": "음절 수",
249
+ "processing_ease": "처리 용이성 점수",
250
+ "memory_hooks": "기억 고리",
251
+ "pronunciation_simplicity": "발음 단순성",
252
+ "cognitive_fluency": "인지적 유창성",
253
+ "slogan": "슬로건"
254
+ }
255
+
256
+ 반드시 유효한 JSON 형식으로 응답하세요.
257
+ """
258
+
259
+ # ===== 11. VON RESTORFF EFFECT =====
260
+ VON_RESTORFF_PROMPT = """
261
+ 당신은 Von Restorff Effect 전문가입니다. 독특하고 기억에 남는 브랜드를 만듭니다.
262
+
263
+ 다음 JSON 형식으로 브랜드를 생성하세요:
264
+ {
265
+ "brand_name": "브랜드명",
266
+ "category_norm": "카테고리 표준",
267
+ "deviation_strategy": "일탈 전략",
268
+ "uniqueness_factors": "독특성 요소들",
269
+ "memorability_score": "기억성 점수",
270
+ "attention_triggers": "주의 트리거",
271
+ "slogan": "슬로건"
272
+ }
273
+
274
+ 반드시 유효한 JSON 형식으로 응답하세요.
275
+ """
276
+
277
+ # ===== 12. NETWORK EFFECTS =====
278
+ NETWORK_EFFECTS_PROMPT = """
279
+ 당신은 Network Effects 전문가입니다. 네트워크 가치를 극대화하는 브랜드를 만듭니다.
280
+
281
+ 다음 JSON 형식으로 브랜드를 생성하세요:
282
+ {
283
+ "brand_name": "브랜드명",
284
+ "network_type": "네트워크 유형",
285
+ "viral_coefficient": "바이럴 계수",
286
+ "sharing_ease": "공유 용이성",
287
+ "community_aspect": "커뮤니티 측면",
288
+ "network_value": "네트워크 가치",
289
+ "slogan": "슬로건"
290
+ }
291
+
292
+ 반드시 유효한 JSON 형식으로 응답하세요.
293
+ """
294
+
295
+ # ===== 13. MEMETICS =====
296
+ MEMETICS_PROMPT = """
297
+ 당신은 Memetics 전문가입니다. 문화적으로 복제되고 진화하는 브랜드를 만듭니다.
298
+
299
+ 다음 JSON 형식으로 브랜드를 생성하세요:
300
+ {
301
+ "brand_name": "브랜드명",
302
+ "meme_structure": "밈 구조",
303
+ "replication_ease": "복제 용이성",
304
+ "mutation_potential": "변이 잠재력",
305
+ "cultural_fitness": "문화적 적합도",
306
+ "transmission_channels": "전달 채널",
307
+ "slogan": "슬로건"
308
+ }
309
+
310
+ 반드시 유효한 JSON 형식으로 응답하세요.
311
+ """
312
+
313
+ # ===== 14. COLOR PSYCHOLOGY =====
314
+ COLOR_PSYCHOLOGY_PROMPT = """
315
+ 당신은 Color Psychology 전문가입니다. 색상 연상과 감정을 활용한 브랜드를 만듭니다.
316
+
317
+ 다음 JSON 형식으로 브랜드를 생성하세요:
318
+ {
319
+ "brand_name": "브랜드명",
320
+ "primary_color": "주 색상",
321
+ "color_meaning": "색상 의미",
322
+ "emotional_response": "감정적 반응",
323
+ "cultural_associations": "문화적 연상",
324
+ "industry_alignment": "업종 정렬",
325
+ "slogan": "슬로건"
326
+ }
327
+
328
+ 반드시 유효한 JSON 형식으로 응답하세요.
329
+ """
330
+
331
+ # ===== 15. GESTALT PRINCIPLES =====
332
+ GESTALT_PROMPT = """
333
+ 당신은 Gestalt Theory 전문가입니다. 지각 원리를 활용한 브랜드를 만듭니다.
334
+
335
+ 다음 JSON 형식으로 브랜드를 생성하세요:
336
+ {
337
+ "brand_name": "브랜드명",
338
+ "gestalt_principle": "활용 원칙",
339
+ "visual_structure": "시각적 구조",
340
+ "perceptual_grouping": "지각적 그룹화",
341
+ "figure_ground": "전경-배경 관계",
342
+ "closure_effect": "폐쇄 효과",
343
+ "slogan": "슬로건"
344
+ }
345
+
346
+ 반드시 유효한 JSON 형식으로 응답하세요.
347
+ """
348
+
349
+ # 이론별 프롬프트 매핑
350
+ THEORY_PROMPTS = {
351
+ "square": SQUARE_THEORY_PROMPT,
352
+ "blending": CONCEPTUAL_BLENDING_PROMPT,
353
+ "sound": SOUND_SYMBOLISM_PROMPT,
354
+ "linguistic": LINGUISTIC_RELATIVITY_PROMPT,
355
+ "archetype": ARCHETYPE_THEORY_PROMPT,
356
+ "jobs": JOBS_TO_BE_DONE_PROMPT,
357
+ "scamper": SCAMPER_PROMPT,
358
+ "design": DESIGN_THINKING_PROMPT,
359
+ "biomimicry": BIOMIMICRY_PROMPT,
360
+ "cognitive": COGNITIVE_LOAD_PROMPT,
361
+ "vonrestorff": VON_RESTORFF_PROMPT,
362
+ "network": NETWORK_EFFECTS_PROMPT,
363
+ "memetics": MEMETICS_PROMPT,
364
+ "color": COLOR_PSYCHOLOGY_PROMPT,
365
+ "gestalt": GESTALT_PROMPT
366
+ }
367
+
368
+ def generate_by_theory(industry: str, keywords: str, theory: str, count: int = 3) -> Tuple[str, str]:
369
+ """특정 이론으로 브랜드 생성"""
370
+
371
+ if not industry or not keywords:
372
+ return "⚠️ 업종과 키워드를 입력해주세요.", ""
373
+
374
+ prompt = THEORY_PROMPTS.get(theory, SQUARE_THEORY_PROMPT)
375
+ user_input = f"""업종: {industry}
376
+ 키워드: {keywords}
377
+
378
+ 위 정보로 {count}개의 브랜드를 생성하세요.
379
+ 반드시 JSON 형식으로 응답하세요.
380
+ 결과는 브랜드 객체들의 JSON 배열이어야 합니다."""
381
+
382
+ try:
383
+ response = client.chat.completions.create(
384
+ model="gpt-4o-mini", # 경제적인 모델
385
+ messages=[
386
+ {"role": "system", "content": prompt},
387
+ {"role": "user", "content": user_input}
388
+ ],
389
+ temperature=0.8,
390
+ max_tokens=2000,
391
+ response_format={"type": "json_object"}
392
+ )
393
+
394
+ content = response.choices[0].message.content
395
+ data = json.loads(content)
396
+
397
+ # 응답 정규화
398
+ if isinstance(data, dict):
399
+ if "results" in data:
400
+ results = data["results"]
401
+ elif "brands" in data:
402
+ results = data["brands"]
403
+ elif "brand_name" in data:
404
+ # 단일 브랜드를 배열로 변환
405
+ results = [data]
406
+ else:
407
+ # 래핑된 응답 처리
408
+ results = []
409
+ for key, value in data.items():
410
+ if isinstance(value, list):
411
+ results = value
412
+ break
413
+ elif isinstance(value, dict) and "brand_name" in value:
414
+ results = [value]
415
+ break
416
+ else:
417
+ results = data
418
+
419
+ if not isinstance(results, list):
420
+ results = [results]
421
+
422
+ # 마크다운 생성
423
+ markdown = generate_theory_markdown(theory, results, industry, keywords)
424
+
425
+ # HTML 시각화 생성
426
+ html = generate_theory_visualization(theory, results)
427
+
428
+ return markdown, html
429
+
430
+ except Exception as e:
431
+ error_msg = f"❌ {theory} 이론 오류: {str(e)}"
432
+ print(error_msg) # 디버깅용
433
+ return error_msg, ""
434
+
435
+ def generate_theory_markdown(theory: str, results: List[Dict], industry: str, keywords: str) -> str:
436
+ """이론별 맞춤 마크다운 생성"""
437
+
438
+ theory_names = {
439
+ "square": "Square Theory",
440
+ "blending": "Conceptual Blending",
441
+ "sound": "Sound Symbolism",
442
+ "linguistic": "Linguistic Relativity",
443
+ "archetype": "Archetype Theory",
444
+ "jobs": "Jobs-to-be-Done",
445
+ "scamper": "SCAMPER Method",
446
+ "design": "Design Thinking",
447
+ "biomimicry": "Biomimicry",
448
+ "cognitive": "Cognitive Load Theory",
449
+ "vonrestorff": "Von Restorff Effect",
450
+ "network": "Network Effects",
451
+ "memetics": "Memetics",
452
+ "color": "Color Psychology",
453
+ "gestalt": "Gestalt Principles"
454
+ }
455
+
456
+ theory_icons = {
457
+ "square": "🟦",
458
+ "blending": "🔀",
459
+ "sound": "🔊",
460
+ "linguistic": "🌐",
461
+ "archetype": "🎭",
462
+ "jobs": "✅",
463
+ "scamper": "🔧",
464
+ "design": "💭",
465
+ "biomimicry": "🌿",
466
+ "cognitive": "🧠",
467
+ "vonrestorff": "⚡",
468
+ "network": "🌍",
469
+ "memetics": "🧬",
470
+ "color": "🎨",
471
+ "gestalt": "👁️"
472
+ }
473
+
474
+ markdown = f"""# {theory_icons[theory]} {theory_names[theory]}
475
+
476
+ <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
477
+ <h3 style="margin: 0 0 10px 0;">이론 개요</h3>
478
+ <p style="margin: 0; line-height: 1.6;">{THEORY_DESCRIPTIONS[theory]}</p>
479
+ </div>
480
+
481
+ **업종**: {industry} | **키워드**: {keywords}
482
+ *생성 시각: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
483
+
484
+ ---
485
+ """
486
+
487
+ for idx, result in enumerate(results, 1):
488
+ brand_name = result.get('brand_name', 'N/A')
489
+ slogan = result.get('slogan', 'N/A')
490
+
491
+ markdown += f"\n## {idx}. {brand_name}\n"
492
+ markdown += f"**슬로건**: *\"{slogan}\"*\n\n"
493
+
494
+ # 이론별 특수 필드 표시
495
+ if theory == "square":
496
+ markdown += f"""
497
+ ### Square 구조
498
+ ```
499
+ [{result.get('tl')}] ─({result.get('top_edge')})─ [{result.get('tr')}]
500
+ │ │
501
+ ({result.get('left_edge')}) ({result.get('right_edge')})
502
+ │ │
503
+ [{result.get('bl')}] ─({result.get('bottom_edge')})─ [{result.get('br')}]
504
+ ```
505
+ """
506
+ elif theory == "blending":
507
+ markdown += f"""
508
+ ### 개념 혼합
509
+ - **입력 공간 1**: {result.get('input_space1')}
510
+ - **입력 공간 2**: {result.get('input_space2')}
511
+ - **일반 공간**: {result.get('generic_space')}
512
+ - **혼합 공간**: {result.get('blended_space')}
513
+ - **창발적 속성**: {result.get('emergent_properties')}
514
+ """
515
+ elif theory == "sound":
516
+ markdown += f"""
517
+ ### 음향 분석
518
+ - **음성 분석**: {result.get('phonetic_analysis')}
519
+ - **음향 의미**: {result.get('sound_meaning')}
520
+ - **목표 감정**: {result.get('target_emotion')}
521
+ - **발음 가이드**: {result.get('pronunciation_guide')}
522
+ """
523
+ elif theory == "archetype":
524
+ markdown += f"""
525
+ ### 원형 분석
526
+ - **원형**: {result.get('archetype')}
527
+ - **원형 특징**: {result.get('archetype_traits')}
528
+ - **브랜드 성격**: {result.get('brand_personality')}
529
+ - **목소리 톤**: {result.get('voice_tone')}
530
+ """
531
+
532
+ # 설명 추가
533
+ explanation = result.get('explanation', result.get('value_proposition', ''))
534
+ if explanation:
535
+ markdown += f"\n💡 **핵심 가치**: {explanation}\n"
536
+
537
+ markdown += "\n---\n"
538
+
539
+ return markdown
540
+
541
+ def generate_theory_visualization(theory: str, results: List[Dict]) -> str:
542
+ """이론별 맞춤 시각화 생성"""
543
+
544
+ html_parts = []
545
+
546
+ for idx, result in enumerate(results, 1):
547
+ if theory == "square":
548
+ html_parts.append(visualize_square_brand(result))
549
+ elif theory == "blending":
550
+ html_parts.append(visualize_conceptual_blend(result))
551
+ elif theory == "sound":
552
+ html_parts.append(visualize_sound_symbolism(result))
553
+ elif theory == "archetype":
554
+ html_parts.append(visualize_archetype(result))
555
+ elif theory == "color":
556
+ html_parts.append(visualize_color_psychology(result))
557
+ else:
558
+ html_parts.append(visualize_generic_brand(result, theory))
559
+
560
+ return "\n".join(html_parts)
561
+
562
+ # 시각화 함수들 (일부만 예시)
563
+ def visualize_square_brand(brand: Dict) -> str:
564
+ """Square Theory 시각화"""
565
+ return f"""
566
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
567
+ <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 30px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
568
+ <h2 style="text-align: center; color: white; margin-bottom: 10px;">{brand.get('brand_name', 'Brand')}</h2>
569
+ <p style="text-align: center; font-style: italic; color: rgba(255,255,255,0.9);">"{brand.get('slogan', '')}"</p>
570
+
571
+ <div style="position: relative; width: 100%; height: 300px; background: rgba(255,255,255,0.1); border-radius: 12px; padding: 30px; margin-top: 20px;">
572
+ <!-- Square 구조 시각화 -->
573
+ <div style="position: absolute; top: 30px; left: 30px; background: rgba(255,255,255,0.9); color: #667eea; padding: 15px 20px; border-radius: 8px; font-weight: bold; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
574
+ {brand.get('tl', '?')}
575
+ </div>
576
+ <div style="position: absolute; top: 30px; right: 30px; background: rgba(255,255,255,0.9); color: #e74c3c; padding: 15px 20px; border-radius: 8px; font-weight: bold; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
577
+ {brand.get('tr', '?')}
578
+ </div>
579
+ <div style="position: absolute; bottom: 30px; left: 30px; background: rgba(255,255,255,0.9); color: #f39c12; padding: 15px 20px; border-radius: 8px; font-weight: bold; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
580
+ {brand.get('bl', '?')}
581
+ </div>
582
+ <div style="position: absolute; bottom: 30px; right: 30px; background: rgba(255,255,255,0.9); color: #27ae60; padding: 15px 20px; border-radius: 8px; font-weight: bold; box-shadow: 0 4px 15px rgba(0,0,0,0.1);">
583
+ {brand.get('br', '?')}
584
+ </div>
585
+
586
+ <!-- 브랜드명 중앙 -->
587
+ <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; padding: 20px 40px; border-radius: 12px; box-shadow: 0 8px 25px rgba(0,0,0,0.15);">
588
+ <div style="font-size: 1.8em; font-weight: bold; color: #2c3e50; text-align: center;">{brand.get('brand_name', 'Brand')}</div>
589
+ </div>
590
+ </div>
591
+ </div>
592
+ </div>
593
+ """
594
+
595
+ def visualize_conceptual_blend(brand: Dict) -> str:
596
+ """Conceptual Blending 시각화"""
597
+ brand_name = brand.get('brand_name', 'Brand')
598
+ input1 = brand.get('input_space1', 'Concept 1')
599
+ input2 = brand.get('input_space2', 'Concept 2')
600
+ blended = brand.get('blended_space', 'Blended Concept')
601
+ slogan = brand.get('slogan', '')
602
+
603
+ return f"""
604
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
605
+ <div style="background: linear-gradient(135deg, #ff6b6b 0%, #4ecdc4 100%); padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
606
+ <h2 style="text-align: center; color: white; margin-bottom: 20px;">{brand_name}</h2>
607
+
608
+ <div style="display: flex; justify-content: space-around; align-items: center; margin: 30px 0;">
609
+ <div style="text-align: center; padding: 30px; background: rgba(255,255,255,0.9); color: #ff6b6b; border-radius: 50%; width: 140px; height: 140px; display: flex; align-items: center; justify-content: center; box-shadow: 0 5px 20px rgba(0,0,0,0.2);">
610
+ <div>
611
+ <strong>Input 1</strong><br>
612
+ <span style="font-size: 0.9em;">{input1}</span>
613
+ </div>
614
+ </div>
615
+
616
+ <div style="font-size: 3em; color: white;">+</div>
617
+
618
+ <div style="text-align: center; padding: 30px; background: rgba(255,255,255,0.9); color: #4ecdc4; border-radius: 50%; width: 140px; height: 140px; display: flex; align-items: center; justify-content: center; box-shadow: 0 5px 20px rgba(0,0,0,0.2);">
619
+ <div>
620
+ <strong>Input 2</strong><br>
621
+ <span style="font-size: 0.9em;">{input2}</span>
622
+ </div>
623
+ </div>
624
+
625
+ <div style="font-size: 3em; color: white;">=</div>
626
+
627
+ <div style="text-align: center; padding: 30px; background: white; color: #2c3e50; border-radius: 20px; width: 180px; height: 180px; display: flex; align-items: center; justify-content: center; box-shadow: 0 8px 25px rgba(0,0,0,0.3);">
628
+ <div>
629
+ <strong style="font-size: 1.2em;">Blend</strong><br>
630
+ <span style="font-size: 0.95em;">{blended}</span>
631
+ </div>
632
+ </div>
633
+ </div>
634
+
635
+ <p style="text-align: center; font-style: italic; color: white; font-size: 1.1em; margin-top: 20px;">"{slogan}"</p>
636
+ </div>
637
+ </div>
638
+ """
639
+
640
+ def visualize_sound_symbolism(brand: Dict) -> str:
641
+ """Sound Symbolism 시각화"""
642
+ return f"""
643
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
644
+ <div style="background: linear-gradient(135deg, #fa709a 0%, #fee140 100%); padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
645
+ <h2 style="text-align: center; color: white; margin-bottom: 20px;">{brand.get('brand_name', 'Brand')}</h2>
646
+
647
+ <div style="text-align: center; margin: 30px 0;">
648
+ <div style="font-size: 4em; letter-spacing: 0.3em; color: white; text-shadow: 2px 2px 4px rgba(0,0,0,0.2); font-weight: bold;">
649
+ {brand.get('brand_name', 'BRAND')}
650
+ </div>
651
+ </div>
652
+
653
+ <div style="background: rgba(255,255,255,0.9); padding: 25px; border-radius: 15px; margin: 20px 0;">
654
+ <div style="text-align: center; margin-bottom: 15px;">
655
+ <strong style="color: #fa709a; font-size: 1.2em;">음성 분석</strong><br>
656
+ <span style="color: #555;">{brand.get('phonetic_analysis', '')}</span>
657
+ </div>
658
+
659
+ <div style="text-align: center;">
660
+ <strong style="color: #fee140; font-size: 1.2em;">음향이 전달하는 감정</strong><br>
661
+ <span style="color: #555;">{brand.get('sound_meaning', '')}</span>
662
+ </div>
663
+ </div>
664
+
665
+ <div style="text-align: center; color: white; font-style: italic;">
666
+ 발음: {brand.get('pronunciation_guide', '')}
667
+ </div>
668
+ </div>
669
+ </div>
670
+ """
671
+
672
+ def visualize_archetype(brand: Dict) -> str:
673
+ """Archetype Theory 시각화"""
674
+ archetype_colors = {
675
+ "Hero": "#e74c3c",
676
+ "Creator": "#9b59b6",
677
+ "Sage": "#3498db",
678
+ "Explorer": "#1abc9c",
679
+ "Innocent": "#f1c40f",
680
+ "Jester": "#e67e22",
681
+ "Lover": "#e91e63",
682
+ "Caregiver": "#00bcd4",
683
+ "Ruler": "#795548",
684
+ "Magician": "#673ab7",
685
+ "Outlaw": "#212121",
686
+ "Regular Guy": "#607d8b"
687
+ }
688
+
689
+ archetype = brand.get('archetype', 'Hero')
690
+ color = archetype_colors.get(archetype, "#3498db")
691
+
692
+ return f"""
693
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
694
+ <div style="background: linear-gradient(135deg, {color} 0%, #2c3e50 100%); padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
695
+ <h2 style="text-align: center; color: white; margin-bottom: 30px;">{brand.get('brand_name', 'Brand')}</h2>
696
+
697
+ <div style="text-align: center; margin: 30px 0;">
698
+ <div style="display: inline-block; padding: 50px; background: rgba(255,255,255,0.15); color: white; border-radius: 50%; width: 250px; height: 250px; border: 3px solid rgba(255,255,255,0.3);">
699
+ <h3 style="margin: 0 0 15px 0; font-size: 2em;">{archetype}</h3>
700
+ <p style="margin: 0; font-size: 1em; line-height: 1.5;">{brand.get('archetype_traits', '')}</p>
701
+ </div>
702
+ </div>
703
+
704
+ <div style="background: rgba(255,255,255,0.9); padding: 25px; border-radius: 15px; margin: 20px 0;">
705
+ <p style="margin: 10px 0;"><strong style="color: {color};">브랜드 성격</strong>: {brand.get('brand_personality', '')}</p>
706
+ <p style="margin: 10px 0;"><strong style="color: {color};">목소리 톤</strong>: {brand.get('voice_tone', '')}</p>
707
+ </div>
708
+
709
+ <p style="text-align: center; font-style: italic; font-size: 1.3em; color: white; margin-top: 30px;">"{brand.get('slogan', '')}"</p>
710
+ </div>
711
+ </div>
712
+ """
713
+
714
+ def visualize_color_psychology(brand: Dict) -> str:
715
+ """Color Psychology 시각화"""
716
+ color = brand.get('primary_color', '#3498db')
717
+
718
+ return f"""
719
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
720
+ <div style="background: #f8f9fa; padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.1);">
721
+ <h2 style="text-align: center; color: #2c3e50; margin-bottom: 30px;">{brand.get('brand_name', 'Brand')}</h2>
722
+
723
+ <div style="text-align: center; margin: 30px 0;">
724
+ <div style="display: inline-block; width: 300px; height: 300px; background: {color}; border-radius: 20px; box-shadow: 0 15px 40px rgba(0,0,0,0.3); position: relative; overflow: hidden;">
725
+ <div style="position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); color: white; font-size: 1.5em; font-weight: bold; text-shadow: 2px 2px 4px rgba(0,0,0,0.5);">
726
+ {brand.get('primary_color', '')}
727
+ </div>
728
+ </div>
729
+ </div>
730
+
731
+ <div style="background: white; padding: 25px; border-radius: 15px; box-shadow: 0 5px 15px rgba(0,0,0,0.1);">
732
+ <p style="margin: 10px 0;"><strong style="color: {color};">색상 의미</strong>: {brand.get('color_meaning', '')}</p>
733
+ <p style="margin: 10px 0;"><strong style="color: {color};">감정적 반응</strong>: {brand.get('emotional_response', '')}</p>
734
+ <p style="margin: 10px 0;"><strong style="color: {color};">문화적 연상</strong>: {brand.get('cultural_associations', '')}</p>
735
+ </div>
736
+
737
+ <p style="text-align: center; font-style: italic; margin-top: 30px; color: #7f8c8d; font-size: 1.2em;">"{brand.get('slogan', '')}"</p>
738
+ </div>
739
+ </div>
740
+ """
741
+
742
+ def visualize_generic_brand(brand: Dict, theory: str) -> str:
743
+ """일반적인 브랜드 시각화"""
744
+ # JSON을 HTML로 변환 (f-string 밖에서 처리)
745
+ json_str = json.dumps(brand, ensure_ascii=False, indent=2)
746
+
747
+ theory_gradients = {
748
+ "jobs": "linear-gradient(135deg, #a8edea 0%, #fed6e3 100%)",
749
+ "scamper": "linear-gradient(135deg, #ffecd2 0%, #fcb69f 100%)",
750
+ "design": "linear-gradient(135deg, #a1c4fd 0%, #c2e9fb 100%)",
751
+ "biomimicry": "linear-gradient(135deg, #d4fc79 0%, #96e6a1 100%)",
752
+ "cognitive": "linear-gradient(135deg, #fa709a 0%, #fee140 100%)",
753
+ "vonrestorff": "linear-gradient(135deg, #f093fb 0%, #f5576c 100%)",
754
+ "network": "linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)",
755
+ "memetics": "linear-gradient(135deg, #43e97b 0%, #38f9d7 100%)",
756
+ "gestalt": "linear-gradient(135deg, #fd6585 0%, #0d25b9 100%)"
757
+ }
758
+
759
+ gradient = theory_gradients.get(theory, "linear-gradient(135deg, #667eea 0%, #764ba2 100%)")
760
+
761
+ html = f"""
762
+ <div style="max-width: 700px; margin: 20px auto; font-family: -apple-system, sans-serif;">
763
+ <div style="background: {gradient}; padding: 40px; border-radius: 20px; box-shadow: 0 10px 30px rgba(0,0,0,0.2);">
764
+ <h2 style="text-align: center; color: white; margin-bottom: 10px;">{brand.get('brand_name', 'Brand')}</h2>
765
+ <p style="text-align: center; font-style: italic; color: rgba(255,255,255,0.9); margin-bottom: 30px; font-size: 1.2em;">"{brand.get('slogan', '')}"</p>
766
+
767
+ <div style="background: rgba(255,255,255,0.95); padding: 25px; border-radius: 15px; font-family: 'Courier New', monospace; font-size: 0.9em;">
768
+ <pre style="margin: 0; white-space: pre-wrap; color: #2c3e50;">{json_str}</pre>
769
+ </div>
770
+ </div>
771
+ </div>
772
+ """
773
+ return html
774
+
775
+ # Gradio UI
776
+ with gr.Blocks(
777
+ title="Ultimate Brand Theory Generator",
778
+ theme=gr.themes.Soft(),
779
+ css="""
780
+ .gradio-container {
781
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
782
+ }
783
+ .tab-nav button {
784
+ font-size: 0.9em !important;
785
+ padding: 10px 15px !important;
786
+ }
787
+ """
788
+ ) as demo:
789
+ gr.Markdown("""
790
+ <div style="text-align: center; padding: 30px 0;">
791
+ <h1 style="font-size: 2.5em; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 10px;">
792
+ 🌟 Ultimate Brand Theory Generator
793
+ </h1>
794
+ <p style="font-size: 1.2em; color: #7f8c8d;">15개 이론을 활용한 종합 브랜드 생성기</p>
795
+ </div>
796
+ """)
797
+
798
+ with gr.Row():
799
+ with gr.Column(scale=1, min_width=300):
800
+ gr.Markdown("""
801
+ <div style="background: #f8f9fa; padding: 20px; border-radius: 10px; margin-bottom: 20px;">
802
+ <h3 style="margin-top: 0;">📝 브랜드 정보 입력</h3>
803
+ </div>
804
+ """)
805
+
806
+ industry_input = gr.Textbox(
807
+ label="🏭 업종",
808
+ placeholder="예: 카페, 피트니스, 교육, 뷰티...",
809
+ value="카페/커피숍"
810
+ )
811
+
812
+ keywords_input = gr.Textbox(
813
+ label="🔑 핵심 키워드",
814
+ placeholder="프리미엄, 편안한, 도시적인, 친환경...",
815
+ info="브랜드가 담아야 할 핵심 가치나 특징들",
816
+ lines=2
817
+ )
818
+
819
+ gr.Markdown("""
820
+ <div style="background: #e3f2fd; padding: 15px; border-radius: 8px; margin-top: 20px;">
821
+ <h4 style="margin-top: 0; color: #1976d2;">💡 사용 방법</h4>
822
+ <ol style="margin: 10px 0; padding-left: 20px;">
823
+ <li>업종과 키워드를 입력하세요</li>
824
+ <li>원하는 이론 탭을 선택하세요</li>
825
+ <li>각 탭의 생성 버튼을 클릭하세요</li>
826
+ </ol>
827
+ <p style="margin: 0; font-size: 0.9em; color: #555;">
828
+ 각 이론은 독립적으로 작동하므로 원하는 것만 선택해서 생성할 수 있습니다.
829
+ </p>
830
+ </div>
831
+ """)
832
+
833
+ with gr.Column(scale=3):
834
+ # 15개 탭 생성
835
+ with gr.Tabs():
836
+ # 1. Square Theory
837
+ with gr.Tab("🟦 Square Theory"):
838
+ with gr.Row():
839
+ square_btn = gr.Button("Square Theory로 생성", variant="primary", size="sm")
840
+ square_output = gr.Markdown()
841
+ square_visual = gr.HTML()
842
+ square_btn.click(
843
+ lambda i, k: generate_by_theory(i, k, "square"),
844
+ inputs=[industry_input, keywords_input],
845
+ outputs=[square_output, square_visual]
846
+ )
847
+
848
+ # 2. Conceptual Blending
849
+ with gr.Tab("🔀 Conceptual Blending"):
850
+ with gr.Row():
851
+ blending_btn = gr.Button("Conceptual Blending으로 생성", variant="primary", size="sm")
852
+ blending_output = gr.Markdown()
853
+ blending_visual = gr.HTML()
854
+ blending_btn.click(
855
+ lambda i, k: generate_by_theory(i, k, "blending"),
856
+ inputs=[industry_input, keywords_input],
857
+ outputs=[blending_output, blending_visual]
858
+ )
859
+
860
+ # 3. Sound Symbolism
861
+ with gr.Tab("🔊 Sound Symbolism"):
862
+ with gr.Row():
863
+ sound_btn = gr.Button("Sound Symbolism으로 생성", variant="primary", size="sm")
864
+ sound_output = gr.Markdown()
865
+ sound_visual = gr.HTML()
866
+ sound_btn.click(
867
+ lambda i, k: generate_by_theory(i, k, "sound"),
868
+ inputs=[industry_input, keywords_input],
869
+ outputs=[sound_output, sound_visual]
870
+ )
871
+
872
+ # 4. Linguistic Relativity
873
+ with gr.Tab("🌐 Linguistic Relativity"):
874
+ with gr.Row():
875
+ linguistic_btn = gr.Button("Linguistic Relativity로 생성", variant="primary", size="sm")
876
+ linguistic_output = gr.Markdown()
877
+ linguistic_visual = gr.HTML()
878
+ linguistic_btn.click(
879
+ lambda i, k: generate_by_theory(i, k, "linguistic"),
880
+ inputs=[industry_input, keywords_input],
881
+ outputs=[linguistic_output, linguistic_visual]
882
+ )
883
+
884
+ # 5. Archetype Theory
885
+ with gr.Tab("🎭 Archetype Theory"):
886
+ with gr.Row():
887
+ archetype_btn = gr.Button("Archetype Theory로 생성", variant="primary", size="sm")
888
+ archetype_output = gr.Markdown()
889
+ archetype_visual = gr.HTML()
890
+ archetype_btn.click(
891
+ lambda i, k: generate_by_theory(i, k, "archetype"),
892
+ inputs=[industry_input, keywords_input],
893
+ outputs=[archetype_output, archetype_visual]
894
+ )
895
+
896
+ # 6. Jobs-to-be-Done
897
+ with gr.Tab("✅ Jobs-to-be-Done"):
898
+ with gr.Row():
899
+ jobs_btn = gr.Button("Jobs-to-be-Done으로 생성", variant="primary", size="sm")
900
+ jobs_output = gr.Markdown()
901
+ jobs_visual = gr.HTML()
902
+ jobs_btn.click(
903
+ lambda i, k: generate_by_theory(i, k, "jobs"),
904
+ inputs=[industry_input, keywords_input],
905
+ outputs=[jobs_output, jobs_visual]
906
+ )
907
+
908
+ # 7. SCAMPER
909
+ with gr.Tab("🔧 SCAMPER Method"):
910
+ with gr.Row():
911
+ scamper_btn = gr.Button("SCAMPER Method로 생성", variant="primary", size="sm")
912
+ scamper_output = gr.Markdown()
913
+ scamper_visual = gr.HTML()
914
+ scamper_btn.click(
915
+ lambda i, k: generate_by_theory(i, k, "scamper"),
916
+ inputs=[industry_input, keywords_input],
917
+ outputs=[scamper_output, scamper_visual]
918
+ )
919
+
920
+ # 8. Design Thinking
921
+ with gr.Tab("💭 Design Thinking"):
922
+ with gr.Row():
923
+ design_btn = gr.Button("Design Thinking으로 생성", variant="primary", size="sm")
924
+ design_output = gr.Markdown()
925
+ design_visual = gr.HTML()
926
+ design_btn.click(
927
+ lambda i, k: generate_by_theory(i, k, "design"),
928
+ inputs=[industry_input, keywords_input],
929
+ outputs=[design_output, design_visual]
930
+ )
931
+
932
+ # 9. Biomimicry
933
+ with gr.Tab("🌿 Biomimicry"):
934
+ with gr.Row():
935
+ biomimicry_btn = gr.Button("Biomimicry로 생성", variant="primary", size="sm")
936
+ biomimicry_output = gr.Markdown()
937
+ biomimicry_visual = gr.HTML()
938
+ biomimicry_btn.click(
939
+ lambda i, k: generate_by_theory(i, k, "biomimicry"),
940
+ inputs=[industry_input, keywords_input],
941
+ outputs=[biomimicry_output, biomimicry_visual]
942
+ )
943
+
944
+ # 10. Cognitive Load
945
+ with gr.Tab("🧠 Cognitive Load"):
946
+ with gr.Row():
947
+ cognitive_btn = gr.Button("Cognitive Load로 생성", variant="primary", size="sm")
948
+ cognitive_output = gr.Markdown()
949
+ cognitive_visual = gr.HTML()
950
+ cognitive_btn.click(
951
+ lambda i, k: generate_by_theory(i, k, "cognitive"),
952
+ inputs=[industry_input, keywords_input],
953
+ outputs=[cognitive_output, cognitive_visual]
954
+ )
955
+
956
+ # 11. Von Restorff
957
+ with gr.Tab("⚡ Von Restorff Effect"):
958
+ with gr.Row():
959
+ vonrestorff_btn = gr.Button("Von Restorff Effect로 생성", variant="primary", size="sm")
960
+ vonrestorff_output = gr.Markdown()
961
+ vonrestorff_visual = gr.HTML()
962
+ vonrestorff_btn.click(
963
+ lambda i, k: generate_by_theory(i, k, "vonrestorff"),
964
+ inputs=[industry_input, keywords_input],
965
+ outputs=[vonrestorff_output, vonrestorff_visual]
966
+ )
967
+
968
+ # 12. Network Effects
969
+ with gr.Tab("🌍 Network Effects"):
970
+ with gr.Row():
971
+ network_btn = gr.Button("Network Effects로 생성", variant="primary", size="sm")
972
+ network_output = gr.Markdown()
973
+ network_visual = gr.HTML()
974
+ network_btn.click(
975
+ lambda i, k: generate_by_theory(i, k, "network"),
976
+ inputs=[industry_input, keywords_input],
977
+ outputs=[network_output, network_visual]
978
+ )
979
+
980
+ # 13. Memetics
981
+ with gr.Tab("🧬 Memetics"):
982
+ with gr.Row():
983
+ memetics_btn = gr.Button("Memetics로 생성", variant="primary", size="sm")
984
+ memetics_output = gr.Markdown()
985
+ memetics_visual = gr.HTML()
986
+ memetics_btn.click(
987
+ lambda i, k: generate_by_theory(i, k, "memetics"),
988
+ inputs=[industry_input, keywords_input],
989
+ outputs=[memetics_output, memetics_visual]
990
+ )
991
+
992
+ # 14. Color Psychology
993
+ with gr.Tab("🎨 Color Psychology"):
994
+ with gr.Row():
995
+ color_btn = gr.Button("Color Psychology로 생성", variant="primary", size="sm")
996
+ color_output = gr.Markdown()
997
+ color_visual = gr.HTML()
998
+ color_btn.click(
999
+ lambda i, k: generate_by_theory(i, k, "color"),
1000
+ inputs=[industry_input, keywords_input],
1001
+ outputs=[color_output, color_visual]
1002
+ )
1003
+
1004
+ # 15. Gestalt Principles
1005
+ with gr.Tab("👁️ Gestalt Principles"):
1006
+ with gr.Row():
1007
+ gestalt_btn = gr.Button("Gestalt Principles로 생성", variant="primary", size="sm")
1008
+ gestalt_output = gr.Markdown()
1009
+ gestalt_visual = gr.HTML()
1010
+ gestalt_btn.click(
1011
+ lambda i, k: generate_by_theory(i, k, "gestalt"),
1012
+ inputs=[industry_input, keywords_input],
1013
+ outputs=[gestalt_output, gestalt_visual]
1014
+ )
1015
+
1016
+ gr.Markdown("""
1017
+ <div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 15px; margin-top: 40px;">
1018
+ <h3 style="margin-top: 0;">🎯 활용 가이드</h3>
1019
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-top: 20px;">
1020
+ <div>
1021
+ <h4>1. 비교 분석</h4>
1022
+ <p style="margin: 5px 0;">각 이론의 결과를 비교하여 가장 적합한 브랜드 선택</p>
1023
+ </div>
1024
+ <div>
1025
+ <h4>2. 하이브리드 접근</h4>
1026
+ <p style="margin: 5px 0;">여러 이론의 장점을 결합한 새로운 브랜드 창조</p>
1027
+ </div>
1028
+ <div>
1029
+ <h4>3. 타겟별 선택</h4>
1030
+ <p style="margin: 5px 0;">목표 고객층에 따라 가장 효과적인 이론 선택</p>
1031
+ </div>
1032
+ <div>
1033
+ <h4>4. A/B 테스트</h4>
1034
+ <p style="margin: 5px 0;">다양한 이론 기반 브랜드로 시장 테스트</p>
1035
+ </div>
1036
+ </div>
1037
+ </div>
1038
+
1039
+ <div style="margin-top: 30px; padding: 20px; background: #f8f9fa; border-radius: 10px;">
1040
+ <h3 style="margin-top: 0;">📚 각 이론의 강점</h3>
1041
+ <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; margin-top: 15px;">
1042
+ <div>
1043
+ <strong style="color: #3498db;">즉각적 이해</strong>: Cognitive Load, Sound Symbolism
1044
+ </div>
1045
+ <div>
1046
+ <strong style="color: #e74c3c;">감정적 연결</strong>: Archetype, Color Psychology
1047
+ </div>
1048
+ <div>
1049
+ <strong style="color: #f39c12;">차별화</strong>: Von Restorff, SCAMPER
1050
+ </div>
1051
+ <div>
1052
+ <strong style="color: #27ae60;">바이럴 잠재력</strong>: Memetics, Network Effects
1053
+ </div>
1054
+ <div>
1055
+ <strong style="color: #9b59b6;">문제 해결</strong>: Jobs-to-be-Done, Design Thinking
1056
+ </div>
1057
+ <div>
1058
+ <strong style="color: #1abc9c;">혁신성</strong>: Biomimicry, Conceptual Blending
1059
+ </div>
1060
+ <div>
1061
+ <strong style="color: #34495e;">구조적 완성도</strong>: Square Theory, Gestalt
1062
+ </div>
1063
+ </div>
1064
+ </div>
1065
+ """)
1066
+
1067
+ if __name__ == "__main__":
1068
+ demo.launch(
1069
+ server_name="0.0.0.0",
1070
+ server_port=7860,
1071
+ share=False
1072
+ )