openfree commited on
Commit
3599d8e
ยท
verified ยท
1 Parent(s): 3ebe514

Update app-backup.py

Browse files
Files changed (1) hide show
  1. app-backup.py +362 -187
app-backup.py CHANGED
@@ -12,7 +12,7 @@ from transformers import pipeline as hf_pipeline
12
  import re
13
 
14
  ##############################################################################
15
- # 1) ZeroGPU ํ™˜๊ฒฝ ์ฒ˜๋ฆฌ + device, dtype ์„ค์ •
16
  ##############################################################################
17
  try:
18
  import zerogpu
@@ -34,7 +34,7 @@ dtype = torch.bfloat16 if device == "cuda" else torch.float32
34
  print(f"Using device: {device}, dtype: {dtype}")
35
 
36
  ##############################################################################
37
- # 2) ๋ชจ๋ธ ๋กœ๋“œ: ๋ฒˆ์—ญ ๋ชจ๋ธ, DiffusionPipeline
38
  ##############################################################################
39
  try:
40
  translator = hf_pipeline(
@@ -71,7 +71,7 @@ MAX_SEED = np.iinfo(np.int32).max
71
  MAX_IMAGE_SIZE = 2048
72
 
73
  ##############################################################################
74
- # ํ•œ๊ตญ์–ด ๊ฐ์ง€ ํ•จ์ˆ˜
75
  ##############################################################################
76
  def contains_korean(text):
77
  for char in text:
@@ -79,45 +79,39 @@ def contains_korean(text):
79
  return True
80
  return False
81
 
82
- ##############################################################################
83
- # ์ž…๋ ฅ ํ…์ŠคํŠธ ํด๋ฆฐ์ง• ํ•จ์ˆ˜: ํ•œ๊ธ€, ์˜๋ฌธ, ์ˆซ์ž, ๊ณต๋ฐฑ ๋ฐ ์ผ๋ฐ˜์ ์ธ ๋ฌธ์žฅ ๋ถ€ํ˜ธ๋งŒ ํ—ˆ์šฉ
84
- ##############################################################################
85
  def clean_input_text(text):
86
  """
87
- ํ•œ๊ธ€, ์˜๋ฌธ, ์ˆซ์ž, ๊ณต๋ฐฑ ๋ฐ . , ! ? - : ; ' " ๋“ฑ์˜ ๋ฌธ์žฅ ๋ถ€ํ˜ธ๋งŒ ๋‚จ๊ธฐ๊ณ  ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.
88
- ํ•„์š”์— ๋”ฐ๋ผ ํ—ˆ์šฉํ•  ๋ฌธ์ž๋ฅผ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
89
  """
90
  allowed = re.compile(r'[^ใ„ฑ-ใ…Ž๊ฐ€-ํžฃa-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
91
  cleaned_text = allowed.sub('', text)
92
  return cleaned_text
93
 
94
- ##############################################################################
95
- # ์ž…๋ ฅ ํ…์ŠคํŠธ์˜ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ž ๋กœ๊ทธ ํ•จ์ˆ˜ (๋””๋ฒ„๊น…์šฉ)
96
- ##############################################################################
97
  def log_unexpected_characters(text):
98
  allowed = re.compile(r'[ใ„ฑ-ใ…Ž๊ฐ€-ํžฃa-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
99
  unexpected_chars = [char for char in text if not allowed.match(char)]
100
  if unexpected_chars:
101
- print("์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ž ๋ฐœ๊ฒฌ:", set(unexpected_chars))
102
  else:
103
- print("์ž…๋ ฅ ํ…์ŠคํŠธ์— ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋ฌธ์ž๋Š” ์—†์Šต๋‹ˆ๋‹ค.")
104
 
105
  ##############################################################################
106
- # ์ด๋ฏธ์ง€ ์ƒ์„ฑ ํ•จ์ˆ˜
107
  ##############################################################################
108
  def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4):
109
  original_prompt = prompt
110
  translated = False
111
 
112
- # ์ž…๋ ฅ ํ…์ŠคํŠธ ํด๋ฆฐ์ง• ์ ์šฉ
113
  prompt = clean_input_text(prompt)
114
 
115
- # ์‚ฌ์ „ ์ฒ˜๋ฆฌ: ์ž…๋ ฅ ํ…์ŠคํŠธ๊ฐ€ ๋„ˆ๋ฌด ๊ธธ๋ฉด ๋ฏธ๋ฆฌ ์ž๋ฅด๊ธฐ (์˜ˆ: 1000์ž ์ด์ƒ์ด๋ฉด 1000์ž๋กœ ์ž˜๋ผ๋ƒ„)
116
  if len(prompt) > 1000:
117
  prompt = prompt[:1000]
118
 
119
  if contains_korean(prompt):
120
- # ๋ฒˆ์—ญ ํ˜ธ์ถœ ์‹œ max_length์™€ truncation ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ธธ์ด ์ดˆ๊ณผ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€
121
  translation = translator(prompt, max_length=400, truncation=True)
122
  prompt = translation[0]['translation_text']
123
  translated = True
@@ -138,9 +132,8 @@ def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, heig
138
 
139
  return image
140
 
141
-
142
  ##############################################################################
143
- # ๋กœ๊น… ์„ค์ •
144
  ##############################################################################
145
  logging.basicConfig(
146
  level=logging.INFO,
@@ -153,13 +146,13 @@ logging.basicConfig(
153
  logger = logging.getLogger("idea_generator")
154
 
155
  ##############################################################################
156
- # Gemini API ํ‚ค
157
  ##############################################################################
158
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
159
  genai.configure(api_key=GEMINI_API_KEY)
160
 
161
  ##############################################################################
162
- # ์„ ํƒ์  ๋ณ€ํ˜• ์„ ํƒ ํ•จ์ˆ˜
163
  ##############################################################################
164
  def choose_alternative(transformation):
165
  if "/" not in transformation:
@@ -183,8 +176,9 @@ def choose_alternative(transformation):
183
  return random.choice([left, right])
184
 
185
  ##############################################################################
186
- # ๋ฌผ๋ฆฌ์  ๋ณ€ํ™” ์นดํ…Œ๊ณ ๋ฆฌ ์‚ฌ์ „ (์ด 15๊ฐœ)
187
  ##############################################################################
 
188
  physical_transformation_categories = {
189
  "์„ผ์„œ ๊ธฐ๋Šฅ": [
190
  "์‹œ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "์ฒญ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "์ด‰๊ฐ ์„ผ์„œ/๊ฐ์ง€", "๋ฏธ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "ํ›„๊ฐ ์„ผ์„œ/๊ฐ์ง€",
@@ -214,10 +208,7 @@ physical_transformation_categories = {
214
  "๊ด‘ํƒ/์œค๊ธฐ ๋ณ€ํ™”", "์ƒ‰์กฐ/์ฑ„๋„ ๋ณ€ํ™”", "๋ฐœ๊ด‘/ํ˜•๊ด‘", "๋น› ์‚ฐ๋ž€ ํšจ๊ณผ",
215
  "๋น› ํก์ˆ˜ ๋ณ€ํ™”", "๋ฐ˜ํˆฌ๋ช… ํšจ๊ณผ", "๊ทธ๋ฆผ์ž ํšจ๊ณผ ๋ณ€ํ™”", "์ž์™ธ์„  ๋ฐ˜์‘ ๋ณ€ํ™”",
216
  "์•ผ๊ด‘ ํšจ๊ณผ"
217
- ],
218
-
219
-
220
-
221
  "๋ฌผ์งˆ์˜ ์ƒํƒœ ๋ณ€ํ™”": [
222
  "๊ณ ์ฒด/์•ก์ฒด/๊ธฐ์ฒด ์ „ํ™˜", "๊ฒฐ์ •ํ™”/์šฉํ•ด", "์‚ฐํ™”/๋ถ€์‹", "๋”ฑ๋”ฑํ•ด์ง/๋ถ€๋“œ๋Ÿฌ์›Œ์ง",
223
  "ํŠน์ˆ˜ ์ƒํƒœ ์ „ํ™˜", "๋ฌด์ •ํ˜•/๊ฒฐ์ •ํ˜• ์ „ํ™˜", "์„ฑ๋ถ„ ๋ถ„๋ฆฌ", "๋ฏธ์„ธ ์ž…์ž ํ˜•์„ฑ/๋ถ„ํ•ด",
@@ -226,7 +217,6 @@ physical_transformation_categories = {
226
  "๊ฑด์กฐ/์Šต์œค", "ํŒฝ์œค/์ˆ˜์ถ•", "๋™๊ฒฐ/ํ•ด๋™", "ํ’ํ™”/์นจ์‹", "์ถฉ์ „/๋ฐฉ์ „",
227
  "๊ฒฐํ•ฉ/๋ถ„๋ฆฌ", "๋ฐœํšจ/๋ถ€ํŒจ"
228
  ],
229
-
230
  "์›€์ง์ž„ ํŠน์„ฑ ๋ณ€ํ™”": [
231
  "๊ฐ€์†/๊ฐ์†", "์ผ์ • ์†๋„ ์œ ์ง€", "์ง„๋™/์ง„๋™ ๊ฐ์†Œ", "๋ถ€๋”ชํž˜/ํŠ•๊น€",
232
  "ํšŒ์ „ ์†๋„ ์ฆ๊ฐ€/๊ฐ์†Œ", "ํšŒ์ „ ๋ฐฉํ–ฅ ๋ณ€ํ™”", "๋ถˆ๊ทœ์น™ ์›€์ง์ž„", "๋ฉˆ์ท„๋‹ค ๋ฏธ๋„๋Ÿฌ์ง€๋Š” ํ˜„์ƒ",
@@ -273,53 +263,138 @@ physical_transformation_categories = {
273
  "์ง„๋™ ํŒจํ„ด ๋ณ€ํ™”", "ํƒ€์•… ํšจ๊ณผ", "์Œํ–ฅ ํ”ผ๋“œ๋ฐฑ", "์Œํ–ฅ ์ฐจํ/์ฆํญ",
274
  "์†Œ๋ฆฌ ์ง€ํ–ฅ์„ฑ", "์Œํ–ฅ ์™œ๊ณก", "๋น„ํŠธ ์ƒ์„ฑ", "ํ•˜๋ชจ๋‹‰์Šค ์ƒ์„ฑ", "์ฃผํŒŒ์ˆ˜ ๋ณ€์กฐ",
275
  "์Œํ–ฅ ์ถฉ๊ฒฉํŒŒ", "์Œํ–ฅ ํ•„ํ„ฐ๋ง"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  ],
277
- "์—ด ๊ด€๋ จ ๋ณ€ํ™”": [
278
- "์˜จ๋„ ์ƒ์Šน/ํ•˜๊ฐ•", "์—ด์— ์˜ํ•œ ํŒฝ์ฐฝ/์ˆ˜์ถ•", "์—ด ์ „๋‹ฌ/์ฐจ๋‹จ", "์••๋ ฅ ์ƒ์Šน/ํ•˜๊ฐ•",
279
- "์—ด ๋ณ€ํ™”์— ๋”ฐ๋ฅธ ์žํ™”", "๋ฌด์งˆ์„œ๋„ ๋ณ€ํ™”", "์—ด์ „๊ธฐ ํ˜„์ƒ", "์ž๊ธฐ์žฅ์— ์˜ํ•œ ์—ด ๋ณ€ํ™”",
280
- "์ƒํƒœ๋ณ€ํ™” ์ค‘ ์—ด ์ €์žฅ/๋ฐฉ์ถœ", "์—ด ์ŠคํŠธ๋ ˆ์Šค ๋ฐœ์ƒ/ํ•ด์†Œ", "๊ธ‰๊ฒฉํ•œ ์˜จ๋„ ๋ณ€ํ™” ์˜ํ–ฅ",
281
- "๋ณต์‚ฌ์—ด์— ์˜ํ•œ ๋ƒ‰๊ฐ/๊ฐ€์—ด", "๋ฐœ์—ด/ํก์—ด", "์—ด ๋ถ„ํฌ ๋ณ€ํ™”", "์—ด ๋ฐ˜์‚ฌ/ํก์ˆ˜",
282
- "๋ƒ‰๊ฐ ์‘์ถ•", "์—ด ํ™œ์„ฑํ™”", "์—ด ๋ณ€์ƒ‰", "์—ด ํŒฝ์ฐฝ ๊ณ„์ˆ˜ ๋ณ€ํ™”", "์—ด ์•ˆ์ •์„ฑ ๋ณ€ํ™”",
283
- "๋‚ด์—ด์„ฑ/๋‚ดํ•œ์„ฑ", "์ž๊ธฐ๋ฐœ์—ด", "์—ด์  ํ‰ํ˜•/๋ถˆ๊ท ํ˜•", "์—ด์  ๋ณ€ํ˜•", "์—ด ๋ถ„์‚ฐ/์ง‘์ค‘"
284
  ],
285
- "์ „๊ธฐ ๋ฐ ์ž๊ธฐ ๋ณ€ํ™”": [
286
- "์ž์„ฑ ์ƒ์„ฑ/์†Œ๋ฉธ", "์ „ํ•˜๋Ÿ‰ ์ฆ๊ฐ€/๊ฐ์†Œ", "์ „๊ธฐ์žฅ ์ƒ์„ฑ/์†Œ๋ฉธ", "์ž๊ธฐ์žฅ ์ƒ์„ฑ/์†Œ๋ฉธ",
287
- "์ดˆ์ „๋„ ์ƒํƒœ ์ „ํ™˜", "๊ฐ•์œ ์ „์ฒด ํŠน์„ฑ ๋ณ€ํ™”", "์–‘์ž ์ƒํƒœ ๋ณ€ํ™”", "ํ”Œ๋ผ์ฆˆ๋งˆ ์ƒํƒœ ํ˜•์„ฑ/์†Œ๋ฉธ",
288
- "์Šคํ•€ํŒŒ ์ „๋‹ฌ", "๋น›์— ์˜ํ•œ ์ „๊ธฐ ๋ฐœ์ƒ", "์••๋ ฅ์— ์˜ํ•œ ์ „๊ธฐ ๋ฐœ์ƒ", "์ž๊ธฐ์žฅ ์† ์ „๋ฅ˜ ๋ณ€ํ™”",
289
- "์ „๊ธฐ ์ €ํ•ญ ๋ณ€ํ™”", "์ „๊ธฐ ์ „๋„์„ฑ ๋ณ€ํ™”", "์ •์ „๊ธฐ ๋ฐœ์ƒ/๋ฐฉ์ „", "์ „์ž๊ธฐ ์œ ๋„",
290
- "์ „์ž๊ธฐํŒŒ ๋ฐฉ์ถœ/ํก์ˆ˜", "์ „๊ธฐ ์šฉ๋Ÿ‰ ๋ณ€ํ™”", "์ž๊ธฐ ์ด๋ ฅ ํ˜„์ƒ", "์ „๊ธฐ์  ๋ถ„๊ทน",
291
- "์ „์ž ํ๋ฆ„ ๋ฐฉํ–ฅ ๋ณ€ํ™”", "์ „๊ธฐ์  ๊ณต๋ช…", "์ „๊ธฐ์  ์ฐจํ/๋…ธ์ถœ", "์ž๊ธฐ ์ฐจํ/๋…ธ์ถœ",
292
- "์ž๊ธฐ์žฅ ๋ฐฉํ–ฅ ์ •๋ ฌ"
293
  ],
294
- "ํ™”ํ•™์  ๋ณ€ํ™”": [
295
- "ํ‘œ๋ฉด ์ฝ”ํŒ… ๋ณ€ํ™”", "๋ฌผ์งˆ ์„ฑ๋ถ„ ๋ณ€ํ™”", "ํ™”ํ•™ ๋ฐ˜์‘ ๋ณ€ํ™”", "์ด‰๋งค ์ž‘์šฉ ์‹œ์ž‘/์ค‘๋‹จ",
296
- "๋น›์— ์˜ํ•œ ํ™”ํ•™ ๋ฐ˜์‘", "์ „๊ธฐ์— ์˜ํ•œ ํ™”ํ•™ ๋ฐ˜์‘", "๋‹จ๋ถ„์ž๋ง‰ ํ˜•์„ฑ", "๋ถ„์ž ์ˆ˜์ค€ ๊ณ„์‚ฐ ๋ณ€ํ™”",
297
- "์ž์—ฐ ๋ชจ๋ฐฉ ํ‘œ๋ฉด ๋ณ€ํ™”", "ํ™˜๊ฒฝ ๋ฐ˜์‘ํ˜• ๋ฌผ์งˆ ๋ณ€ํ™”", "์ฃผ๊ธฐ์  ํ™”ํ•™ ๋ฐ˜์‘", "์‚ฐํ™”", "ํ™˜์›",
298
- "๊ณ ๋ถ„์žํ™”", "๋ฌผ ๋ถ„ํ•ด", "ํ™”ํ•ฉ", "๋ฐฉ์‚ฌ์„  ์˜ํ–ฅ", "์‚ฐ-์—ผ๊ธฐ ๋ฐ˜์‘", "์ค‘ํ™” ๋ฐ˜์‘",
299
- "์ด์˜จํ™”", "ํ™”ํ•™์  ํก์ฐฉ/ํƒˆ์ฐฉ", "์ด‰๋งค ํšจ์œจ ๋ณ€ํ™”", "ํšจ์†Œ ํ™œ์„ฑ ๋ณ€ํ™”", "๋ฐœ์ƒ‰ ๋ฐ˜์‘",
300
- "pH ๋ณ€ํ™”", "ํ™”ํ•™์  ํ‰ํ˜• ์ด๋™", "๊ฒฐํ•ฉ ํ˜•์„ฑ/๋ถ„ํ•ด", "์šฉํ•ด๋„ ๋ณ€ํ™”"
301
  ],
302
-
303
- "์ƒ๋ฌผํ•™์  ๋ณ€ํ™”": [
304
- "์ƒ์žฅ/์œ„์ถ•", "์„ธํฌ ๋ถ„์—ด/์‚ฌ๋ฉธ", "์ƒ๋ฌผ ๋ฐœ๊ด‘", "์‹ ์ง„๋Œ€์‚ฌ ๋ณ€ํ™”", "๋ฉด์—ญ ๋ฐ˜์‘",
305
- "ํ˜ธ๋ฅด๋ชฌ ๋ถ„๋น„", "์‹ ๊ฒฝ ๋ฐ˜์‘", "์œ ์ „์  ๋ฐœํ˜„", "์ ์‘/์ง„ํ™”", "์ƒ์ฒด๋ฆฌ๋“ฌ ๋ณ€ํ™”",
306
- "์žฌ์ƒ/์น˜์œ ", "๋…ธํ™”/์„ฑ์ˆ™", "์ƒ์ฒด ๋ชจ๋ฐฉ ๋ณ€ํ™”", "๋ฐ”์ด์˜คํ•„๋ฆ„ ํ˜•์„ฑ", "์ƒ๋ฌผํ•™์  ๋ถ„ํ•ด",
307
- "ํšจ์†Œ ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”", "์ƒ๋ฌผํ•™์  ์‹ ํ˜ธ ์ „๋‹ฌ", "์ŠคํŠธ๋ ˆ์Šค ๋ฐ˜์‘", "์ฒด์˜จ ์กฐ์ ˆ",
308
- "์ƒ๋ฌผํ•™์  ์‹œ๊ณ„ ๋ณ€ํ™”", "์„ธํฌ์™ธ ๊ธฐ์งˆ ๋ณ€ํ™”", "์ƒ์ฒด ์—ญํ•™์  ๋ฐ˜์‘", "์„ธํฌ ์šด๋™์„ฑ",
309
- "์„ธํฌ ๊ทน์„ฑ ๋ณ€ํ™”", "์˜์–‘ ์ƒํƒœ ๋ณ€ํ™”"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
310
  ],
311
- "ํ™˜๊ฒฝ ์ƒํ˜ธ์ž‘์šฉ": [
312
- "์˜จ๋„ ๋ฐ˜์‘", "์Šต๋„ ๋ฐ˜์‘", "๊ธฐ์•• ๋ฐ˜์‘", "์ค‘๋ ฅ ๋ฐ˜์‘", "์ž๊ธฐ์žฅ ๋ฐ˜์‘",
313
- "๋น› ๋ฐ˜์‘", "์†Œ๋ฆฌ ๋ฐ˜์‘", "ํ™”ํ•™ ๋ฌผ์งˆ ๊ฐ์ง€", "๊ธฐ๊ณ„์  ์ž๊ทน ๊ฐ์ง€", "์ „๊ธฐ ์ž๊ทน ๋ฐ˜์‘",
314
- "๋ฐฉ์‚ฌ์„  ๋ฐ˜์‘", "์ง„๋™ ๊ฐ์ง€", "pH ๋ฐ˜์‘", "์šฉ๋งค ๋ฐ˜์‘", "๊ธฐ์ฒด ๊ตํ™˜",
315
- "ํ™˜๊ฒฝ ์˜ค์—ผ ๋ฐ˜์‘", "๋‚ ์”จ ๋ฐ˜์‘", "๊ณ„์ ˆ ๋ณ€ํ™” ๋ฐ˜์‘", "์ผ์ฃผ๊ธฐ ๋ฐ˜์‘", "์ƒํƒœ๊ณ„ ์ƒํ˜ธ์ž‘์šฉ",
316
- "๊ณต์ƒ/๊ฒฝ์Ÿ ๋ฐ˜์‘", "ํฌ์‹/ํ”ผ์‹ ๊ด€๊ณ„", "๊ตฐ์ง‘ ํ˜•์„ฑ", "์˜์—ญ ์„ค์ •", "์ด์ฃผ/์ •์ฐฉ ํŒจํ„ด"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  ]
318
-
319
  }
320
 
321
  ##############################################################################
322
- # Gemini API ํ˜ธ์ถœ ํ•จ์ˆ˜
323
  ##############################################################################
324
  def query_gemini_api(prompt):
325
  try:
@@ -349,7 +424,7 @@ def query_gemini_api(prompt):
349
  return f"An error occurred while calling the API: {str(e)}"
350
 
351
  ##############################################################################
352
- # ์„ค๋ช… ํ™•์žฅ ํ•จ์ˆ˜ (LLM ์ด์šฉ)
353
  ##############################################################################
354
  def enhance_with_llm(base_description, obj_name, category):
355
  prompt = f"""
@@ -362,101 +437,129 @@ def enhance_with_llm(base_description, obj_name, category):
362
  """
363
  return query_gemini_api(prompt)
364
 
 
 
 
 
 
 
 
 
 
 
 
365
  ##############################################################################
366
- # ๊ฐ ๊ฐ์ฒด์ˆ˜(1, 2, 3)์— ๋”ฐ๋ฅธ ๋ณ€ํ˜• ์•„์ด๋””์–ด ์ƒ์„ฑ
367
  ##############################################################################
368
- def generate_single_object_transformation_for_category(obj, selected_category):
369
- transformations = physical_transformation_categories.get(selected_category)
370
  if not transformations:
371
  return {}
372
  transformation = choose_alternative(random.choice(transformations))
373
- base_description = f"{obj}์ด(๊ฐ€) {transformation} ํ˜„์ƒ์„ ๋ณด์ธ๋‹ค"
 
 
 
374
  return {selected_category: {"base": base_description, "enhanced": None}}
375
 
376
- def generate_two_objects_interaction_for_category(obj1, obj2, selected_category):
377
- transformations = physical_transformation_categories.get(selected_category)
378
  if not transformations:
379
  return {}
380
  transformation = choose_alternative(random.choice(transformations))
381
- template = random.choice([
382
- "{obj1}์ด(๊ฐ€) {obj2}์— ๊ฒฐํ•ฉํ•˜์—ฌ {change}๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค",
383
- "{obj1}๊ณผ(์™€) {obj2}์ด(๊ฐ€) ์ถฉ๋Œํ•˜๋ฉด์„œ {change}๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค"
384
- ])
 
 
 
 
 
 
385
  base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
386
  return {selected_category: {"base": base_description, "enhanced": None}}
387
 
388
- def generate_three_objects_interaction_for_category(obj1, obj2, obj3, selected_category):
389
- transformations = physical_transformation_categories.get(selected_category)
390
  if not transformations:
391
  return {}
392
  transformation = choose_alternative(random.choice(transformations))
393
- template = random.choice([
394
- "{obj1}, {obj2}, {obj3}์ด(๊ฐ€) ์‚ผ๊ฐํ˜• ๊ตฌ์กฐ๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ {change}๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค",
395
- "{obj1}์ด(๊ฐ€) {obj2}์™€(๊ณผ) {obj3} ์‚ฌ์ด์—์„œ ๋งค๊ฐœ์ฒด ์—ญํ• ์„ ํ•˜๋ฉฐ {change}๋ฅผ ์ด‰์ง„ํ–ˆ๋‹ค"
396
- ])
 
 
 
 
 
 
397
  base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
398
  return {selected_category: {"base": base_description, "enhanced": None}}
399
 
400
- ##############################################################################
401
- # ์ƒ์„ฑ๋œ ๊ธฐ๋ณธ ์„ค๋ช…์„ LLM์„ ํ†ตํ•ด ํ™•์žฅ (๊ฐ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„)
402
- ##############################################################################
403
- def enhance_descriptions(results, objects):
404
- obj_name = " ๋ฐ ".join([obj for obj in objects if obj])
405
  for category, result in results.items():
406
- result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
 
 
 
407
  return results
408
 
409
- ##############################################################################
410
- # ์‚ฌ์šฉ์ž ์ž…๋ ฅ(์ตœ๋Œ€ 3๊ฐœ ํ‚ค์›Œ๋“œ) + ์„ ํƒ ์นดํ…Œ๊ณ ๋ฆฌ โ†’ ๋ณ€ํ™” ์•„์ด๋””์–ด ์ƒ์„ฑ
411
- ##############################################################################
412
- def generate_transformations(text1, text2, text3, selected_category):
413
  if text2 and text3:
414
- results = generate_three_objects_interaction_for_category(text1, text2, text3, selected_category)
415
  objects = [text1, text2, text3]
416
  elif text2:
417
- results = generate_two_objects_interaction_for_category(text1, text2, selected_category)
418
  objects = [text1, text2]
419
  else:
420
- results = generate_single_object_transformation_for_category(text1, selected_category)
421
  objects = [text1]
422
- return enhance_descriptions(results, objects)
423
 
424
- ##############################################################################
425
- # ๊ฒฐ๊ณผ ํฌ๋งทํŒ…
426
- ##############################################################################
427
- def format_results(results):
428
  formatted = ""
429
- for category, result in results.items():
430
- formatted += f"## {category}\n**๊ธฐ๋ณธ ์•„์ด๋””์–ด**: {result['base']}\n\n**ํ™•์žฅ๋œ ์•„์ด๋””์–ด**: {result['enhanced']}\n\n---\n\n"
 
 
 
 
431
  return formatted
432
 
433
- ##############################################################################
434
- # Gradio UI์—์„œ ํ˜ธ์ถœ๋  ํ•จ์ˆ˜ (ํ…์ŠคํŠธ ์•„์ด๋””์–ด๋งŒ ์ƒ์„ฑ)
435
- ##############################################################################
436
- def process_inputs(text1, text2, text3, selected_category, progress=gr.Progress()):
437
  text1 = text1.strip() if text1 else None
438
  text2 = text2.strip() if text2 else None
439
  text3 = text3.strip() if text3 else None
440
 
441
  if not text1:
442
- return "์˜ค๋ฅ˜: ์ตœ์†Œ ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”."
443
 
444
- progress(0.05, desc="์•„์ด๋””์–ด ์ƒ์„ฑ ์ค€๋น„ ์ค‘...")
445
- time.sleep(0.3)
446
- progress(0.1, desc="์ฐฝ์˜์ ์ธ ์•„์ด๋””์–ด ์ƒ์„ฑ ์‹œ์ž‘...")
 
 
 
 
 
447
 
448
- results = generate_transformations(text1, text2, text3, selected_category)
449
 
450
- progress(0.8, desc="๊ฒฐ๊ณผ ํฌ๋งทํŒ… ์ค‘...")
451
- formatted = format_results(results)
452
- progress(1.0, desc="์™„๋ฃŒ!")
 
 
 
 
 
453
  return formatted
454
 
455
- ##############################################################################
456
- # ์•„์ด๋””์–ด์™€ ์ด๋ฏธ์ง€๋ฅผ ํ•จ๊ป˜ ์ƒ์„ฑํ•˜๋Š” ์ตœ์ข… ํ•จ์ˆ˜
457
- ##############################################################################
458
- def process_all(text1, text2, text3, selected_category, progress=gr.Progress()):
459
- idea_result = process_inputs(text1, text2, text3, selected_category, progress)
460
  image_result = generate_design_image(
461
  idea_result,
462
  seed=42,
@@ -468,18 +571,19 @@ def process_all(text1, text2, text3, selected_category, progress=gr.Progress()):
468
  return idea_result, image_result
469
 
470
  ##############################################################################
471
- # API ํ‚ค ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€
472
  ##############################################################################
473
- def get_warning_message():
474
  if not GEMINI_API_KEY:
475
- return "โš ๏ธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GEMINI_API_KEY๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Gemini API ํ‚ค๋ฅผ ์„ค์ •ํ•˜์„ธ์š”."
476
  return ""
477
 
 
478
  ##############################################################################
479
- # Gradio UI
480
  ##############################################################################
481
  with gr.Blocks(
482
- title="ํ‚ค์›Œ๋“œ ๊ธฐ๋ฐ˜ ์ฐฝ์˜์  ๋ณ€ํ™” ์•„์ด๋””์–ด ๋ฐ ๋””์ž์ธ ์ƒ์„ฑ๊ธฐ",
483
  theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")
484
  ) as demo:
485
 
@@ -521,73 +625,144 @@ with gr.Blocks(
521
  </style>
522
  """)
523
 
524
- gr.Markdown("# ๐Ÿš€ ์•„์ด๋””์–ด ํŠธ๋žœ์Šคํฌ๋จธ")
525
- gr.Markdown("์ž…๋ ฅํ•œ **ํ‚ค์›Œ๋“œ**(์ตœ๋Œ€ 3๊ฐœ)์™€ **์นดํ…Œ๊ณ ๋ฆฌ**๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ, ์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™” ์•„์ด๋””์–ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•ด๋‹น ํ™•์žฅ ์•„์ด๋””์–ด๋ฅผ ํ”„๋กฌํ”„ํŠธ๋กœ ํ•˜์—ฌ ๋””์ž์ธ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.")
526
-
527
- warning = gr.Markdown(get_warning_message())
528
-
529
- with gr.Row():
530
- with gr.Column(scale=1):
531
- text_input1 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 1 (ํ•„์ˆ˜)", placeholder="์˜ˆ: ์Šค๋งˆํŠธํฐ")
532
- text_input2 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 2 (์„ ํƒ)", placeholder="์˜ˆ: ์ธ๊ณต์ง€๋Šฅ")
533
- text_input3 = gr.Textbox(label="ํ‚ค์›Œ๋“œ 3 (์„ ํƒ)", placeholder="์˜ˆ: ํ—ฌ์Šค์ผ€์–ด")
534
- category_radio = gr.Radio(
535
- label="์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ",
536
- choices=list(physical_transformation_categories.keys()),
537
- value=list(physical_transformation_categories.keys())[0],
538
- info="์ถœ๋ ฅํ•  ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์„ ํƒํ•˜์„ธ์š”."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
539
  )
540
- status_msg = gr.Markdown("๐Ÿ’ก '์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์„ ํƒํ•œ ์นดํ…Œ๊ณ ๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” ์•„์ด๋””์–ด์™€ ๋””์ž์ธ ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.")
541
 
542
- processing_indicator = gr.HTML("""
543
- <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
544
- <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
545
- <p style="margin-left: 10px; font-weight: bold; color: #3498db;">์ฒ˜๋ฆฌ ์ค‘์ž…๋‹ˆ๋‹ค...</p>
546
- </div>
547
- <style>
548
- @keyframes spin {
549
- 0% { transform: rotate(0deg); }
550
- 100% { transform: rotate(360deg); }
551
- }
552
- </style>
553
- """, visible=False)
554
 
555
- submit_button = gr.Button("์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
556
 
557
- with gr.Column(scale=2):
558
- idea_output = gr.Markdown(label="์•„์ด๋””์–ด ๊ฒฐ๊ณผ")
559
- generated_image = gr.Image(label="์ƒ์„ฑ๋œ ๋””์ž์ธ ์ด๋ฏธ์ง€", type="pil")
560
-
561
- gr.Examples(
562
- examples=[
563
- ["์Šค๋งˆํŠธํฐ", "", "", "์„ผ์„œ ๊ธฐ๋Šฅ"],
564
- ["์ž๋™์ฐจ", "", "", "ํฌ๊ธฐ์™€ ํ˜•ํƒœ ๋ณ€ํ™”"],
565
- ["์ž๋™์ฐจ", "์ธ๊ณต์ง€๋Šฅ", "", "ํ‘œ๋ฉด ๋ฐ ์™ธ๊ด€ ๋ณ€ํ™”"],
566
- ["๋“œ๋ก ", "์ธ๊ณต์ง€๋Šฅ", "", "๋ฌผ์งˆ์˜ ์ƒํƒœ ๋ณ€ํ™”"],
567
- ["์šด๋™ํ™”", "์›จ์–ด๋Ÿฌ๋ธ”", "๊ฑด๊ฐ•", "๊ตฌ์กฐ์  ๋ณ€ํ™”"],
568
- ],
569
- inputs=[text_input1, text_input2, text_input3, category_radio],
570
- )
571
-
572
- def show_processing_indicator():
573
- return gr.update(visible=True)
574
-
575
- def hide_processing_indicator():
576
- return gr.update(visible=False)
577
-
578
- submit_button.click(
579
- fn=show_processing_indicator,
580
- inputs=None,
581
- outputs=processing_indicator
582
- ).then(
583
- fn=process_all,
584
- inputs=[text_input1, text_input2, text_input3, category_radio],
585
- outputs=[idea_output, generated_image]
586
- ).then(
587
- fn=hide_processing_indicator,
588
- inputs=None,
589
- outputs=processing_indicator
590
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
591
 
592
  if __name__ == "__main__":
593
  demo.launch(debug=True)
 
12
  import re
13
 
14
  ##############################################################################
15
+ # 1) ZeroGPU Environment Setup + Device and Dtype Configuration
16
  ##############################################################################
17
  try:
18
  import zerogpu
 
34
  print(f"Using device: {device}, dtype: {dtype}")
35
 
36
  ##############################################################################
37
+ # 2) Load Models: Translation Model, Diffusion Pipeline
38
  ##############################################################################
39
  try:
40
  translator = hf_pipeline(
 
71
  MAX_IMAGE_SIZE = 2048
72
 
73
  ##############################################################################
74
+ # Korean detection and input text cleaning functions
75
  ##############################################################################
76
  def contains_korean(text):
77
  for char in text:
 
79
  return True
80
  return False
81
 
 
 
 
82
  def clean_input_text(text):
83
  """
84
+ Allows only Korean, English, numbers, whitespace and common punctuation marks.
85
+ Adjust allowed characters as needed.
86
  """
87
  allowed = re.compile(r'[^ใ„ฑ-ใ…Ž๊ฐ€-ํžฃa-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
88
  cleaned_text = allowed.sub('', text)
89
  return cleaned_text
90
 
 
 
 
91
  def log_unexpected_characters(text):
92
  allowed = re.compile(r'[ใ„ฑ-ใ…Ž๊ฐ€-ํžฃa-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
93
  unexpected_chars = [char for char in text if not allowed.match(char)]
94
  if unexpected_chars:
95
+ print("Unexpected characters found:", set(unexpected_chars))
96
  else:
97
+ print("No unexpected characters in the input text.")
98
 
99
  ##############################################################################
100
+ # Image Generation Function
101
  ##############################################################################
102
  def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4):
103
  original_prompt = prompt
104
  translated = False
105
 
106
+ # Clean the input text
107
  prompt = clean_input_text(prompt)
108
 
109
+ # Pre-process: if input is too long, trim to 1000 characters
110
  if len(prompt) > 1000:
111
  prompt = prompt[:1000]
112
 
113
  if contains_korean(prompt):
114
+ # When calling translation, add max_length and truncation options to avoid length issues
115
  translation = translator(prompt, max_length=400, truncation=True)
116
  prompt = translation[0]['translation_text']
117
  translated = True
 
132
 
133
  return image
134
 
 
135
  ##############################################################################
136
+ # Logging Setup
137
  ##############################################################################
138
  logging.basicConfig(
139
  level=logging.INFO,
 
146
  logger = logging.getLogger("idea_generator")
147
 
148
  ##############################################################################
149
+ # Gemini API Key
150
  ##############################################################################
151
  GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
152
  genai.configure(api_key=GEMINI_API_KEY)
153
 
154
  ##############################################################################
155
+ # Optional Transformation Choice Function
156
  ##############################################################################
157
  def choose_alternative(transformation):
158
  if "/" not in transformation:
 
176
  return random.choice([left, right])
177
 
178
  ##############################################################################
179
+ # Transformation Categories Dictionaries
180
  ##############################################################################
181
+ # Korean version
182
  physical_transformation_categories = {
183
  "์„ผ์„œ ๊ธฐ๋Šฅ": [
184
  "์‹œ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "์ฒญ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "์ด‰๊ฐ ์„ผ์„œ/๊ฐ์ง€", "๋ฏธ๊ฐ ์„ผ์„œ/๊ฐ์ง€", "ํ›„๊ฐ ์„ผ์„œ/๊ฐ์ง€",
 
208
  "๊ด‘ํƒ/์œค๊ธฐ ๋ณ€ํ™”", "์ƒ‰์กฐ/์ฑ„๋„ ๋ณ€ํ™”", "๋ฐœ๊ด‘/ํ˜•๊ด‘", "๋น› ์‚ฐ๋ž€ ํšจ๊ณผ",
209
  "๋น› ํก์ˆ˜ ๋ณ€ํ™”", "๋ฐ˜ํˆฌ๋ช… ํšจ๊ณผ", "๊ทธ๋ฆผ์ž ํšจ๊ณผ ๋ณ€ํ™”", "์ž์™ธ์„  ๋ฐ˜์‘ ๋ณ€ํ™”",
210
  "์•ผ๊ด‘ ํšจ๊ณผ"
211
+ ],
 
 
 
212
  "๋ฌผ์งˆ์˜ ์ƒํƒœ ๋ณ€ํ™”": [
213
  "๊ณ ์ฒด/์•ก์ฒด/๊ธฐ์ฒด ์ „ํ™˜", "๊ฒฐ์ •ํ™”/์šฉํ•ด", "์‚ฐํ™”/๋ถ€์‹", "๋”ฑ๋”ฑํ•ด์ง/๋ถ€๋“œ๋Ÿฌ์›Œ์ง",
214
  "ํŠน์ˆ˜ ์ƒํƒœ ์ „ํ™˜", "๋ฌด์ •ํ˜•/๊ฒฐ์ •ํ˜• ์ „ํ™˜", "์„ฑ๋ถ„ ๋ถ„๋ฆฌ", "๋ฏธ์„ธ ์ž…์ž ํ˜•์„ฑ/๋ถ„ํ•ด",
 
217
  "๊ฑด์กฐ/์Šต์œค", "ํŒฝ์œค/์ˆ˜์ถ•", "๋™๊ฒฐ/ํ•ด๋™", "ํ’ํ™”/์นจ์‹", "์ถฉ์ „/๋ฐฉ์ „",
218
  "๊ฒฐํ•ฉ/๋ถ„๋ฆฌ", "๋ฐœํšจ/๋ถ€ํŒจ"
219
  ],
 
220
  "์›€์ง์ž„ ํŠน์„ฑ ๋ณ€ํ™”": [
221
  "๊ฐ€์†/๊ฐ์†", "์ผ์ • ์†๋„ ์œ ์ง€", "์ง„๋™/์ง„๋™ ๊ฐ์†Œ", "๋ถ€๋”ชํž˜/ํŠ•๊น€",
222
  "ํšŒ์ „ ์†๋„ ์ฆ๊ฐ€/๊ฐ์†Œ", "ํšŒ์ „ ๋ฐฉํ–ฅ ๋ณ€ํ™”", "๋ถˆ๊ทœ์น™ ์›€์ง์ž„", "๋ฉˆ์ท„๋‹ค ๋ฏธ๋„๋Ÿฌ์ง€๋Š” ํ˜„์ƒ",
 
263
  "์ง„๋™ ํŒจํ„ด ๋ณ€ํ™”", "ํƒ€์•… ํšจ๊ณผ", "์Œํ–ฅ ํ”ผ๋“œ๋ฐฑ", "์Œํ–ฅ ์ฐจํ/์ฆํญ",
264
  "์†Œ๋ฆฌ ์ง€ํ–ฅ์„ฑ", "์Œํ–ฅ ์™œ๊ณก", "๋น„ํŠธ ์ƒ์„ฑ", "ํ•˜๋ชจ๋‹‰์Šค ์ƒ์„ฑ", "์ฃผํŒŒ์ˆ˜ ๋ณ€์กฐ",
265
  "์Œํ–ฅ ์ถฉ๊ฒฉํŒŒ", "์Œํ–ฅ ํ•„ํ„ฐ๋ง"
266
+ ]
267
+ }
268
+
269
+ # English version
270
+ physical_transformation_categories_en = {
271
+ "Sensor Functions": [
272
+ "Visual sensor/detection", "Auditory sensor/detection", "Tactile sensor/detection", "Taste sensor/detection", "Olfactory sensor/detection",
273
+ "Temperature sensor/detection", "Humidity sensor/detection", "Pressure sensor/detection", "Acceleration sensor/detection", "Rotational sensor/detection",
274
+ "Proximity sensor/detection", "Position sensor/detection", "Motion sensor/detection", "Gas sensor/detection", "Infrared sensor/detection",
275
+ "Ultraviolet sensor/detection", "Radiation sensor/detection", "Magnetic sensor/detection", "Electric field sensor/detection", "Chemical sensor/detection",
276
+ "Biosignal sensor/detection", "Vibration sensor/detection", "Noise sensor/detection", "Light intensity sensor/detection", "Light wavelength sensor/detection",
277
+ "Tilt sensor/detection", "pH sensor/detection", "Current sensor/detection", "Voltage sensor/detection", "Image sensor/detection",
278
+ "Distance sensor/detection", "Depth sensor/detection", "Gravity sensor/detection", "Speed sensor/detection", "Flow sensor/detection",
279
+ "Water level sensor/detection", "Turbidity sensor/detection", "Salinity sensor/detection", "Metal detection", "Piezoelectric sensor/detection",
280
+ "Photovoltaic sensor/detection", "Thermocouple sensor/detection", "Hall effect sensor/detection", "Ultrasonic sensor/detection", "Radar sensor/detection",
281
+ "Lidar sensor/detection", "Touch sensor/detection", "Gesture sensor/detection", "Heart rate sensor/detection", "Blood pressure sensor/detection"
282
  ],
283
+ "Size and Shape Change": [
284
+ "Volume increase/decrease", "Length increase/decrease", "Width increase/decrease", "Height increase/decrease",
285
+ "Density change", "Weight increase/decrease", "Shape deformation", "State change", "Uneven deformation",
286
+ "Complex shape deformation", "Twisting/entwining", "Non-uniform expansion/contraction", "Rounded/sharpened edges",
287
+ "Cracking/splitting", "Fragmentation", "Water resistance", "Dust resistance", "Denting/recovery",
288
+ "Folding/unfolding", "Compression/expansion", "Stretching/contraction", "Wrinkling/flattening", "Crushing/hardening",
289
+ "Rolling/unrolling", "Bending/curving"
290
  ],
291
+ "Surface and Appearance Change": [
292
+ "Color change", "Texture change", "Transparency change", "Glossy/matte change",
293
+ "Light reflection variation", "Pattern change", "Angle-dependent color change", "Light-induced color change",
294
+ "Temperature-dependent color change", "Holographic effect", "Angle-specific light reflection", "Surface shape alteration",
295
+ "Nano-scale surface structure change", "Self-cleaning effect", "Stain/pattern formation", "Blurriness/clarity change",
296
+ "Luster/shine change", "Hue/saturation change", "Luminescence/fluorescence", "Light scattering effect",
297
+ "Light absorption change", "Translucency effect", "Shadow effect change", "UV response change",
298
+ "Glow effect"
299
  ],
300
+ "Material State Change": [
301
+ "Solid/liquid/gas transition", "Crystallization/dissolution", "Oxidation/corrosion", "Hardening/softening",
302
+ "Special state transition", "Amorphous/crystalline transition", "Component separation", "Particle formation/disintegration",
303
+ "Gel formation/dissolution", "Metastable state change", "Molecular self-assembly/disintegration", "Delayed state change",
304
+ "Melting", "Solidification", "Evaporation/condensation", "Sublimation/deposition", "Precipitation/suspension", "Dispersion/aggregation",
305
+ "Drying/moistening", "Swelling/shrinkage", "Freezing/thawing", "Weathering/erosion", "Charging/discharging",
306
+ "Bonding/separation", "Fermentation/decay"
307
  ],
308
+ "Movement Characteristics Change": [
309
+ "Acceleration/deceleration", "Maintaining constant speed", "Vibration/vibration reduction", "Collision/bouncing",
310
+ "Increase/decrease in rotational speed", "Change in rotational direction", "Irregular movement", "Stop-and-slide phenomenon",
311
+ "Resonance/anti-resonance", "Resistance/lift change in fluid", "Change in movement resistance", "Complex vibrational movement",
312
+ "Movement in special fluid", "Rotational-translational movement", "Inertial stoppage", "Shock absorption",
313
+ "Shock transfer", "Conservation of momentum", "Friction change", "Overcoming inertia", "Unstable equilibrium",
314
+ "Dynamic stability", "Damping of oscillation", "Path predictability", "Evasive movement"
315
+ ],
316
+ "Structural Change": [
317
+ "Addition/removal of components", "Assembly/disassembly", "Folding/unfolding", "Deformation/recovery", "Optimal structural change",
318
+ "Self-rearrangement", "Natural pattern formation/disappearance", "Regular pattern change", "Modular transformation",
319
+ "Increased structural complexity", "Memory of original shape effect", "Shape change over time", "Partial removal",
320
+ "Partial replacement", "Bonding", "Separation", "Division/integration", "Overlaying", "Internal structure change",
321
+ "External structure change", "Shift of center axis", "Balance point change", "Hierarchical structure change", "Support structure change",
322
+ "Stress distribution structure", "Shock absorption structure", "Grid/matrix structure change", "Interconnectivity change"
323
+ ],
324
+ "Spatial Movement": [
325
+ "Forward/backward movement", "Left/right movement", "Up/down movement", "Vertical axis rotation (nodding)",
326
+ "Horizontal axis rotation (shaking head)", "Longitudinal axis rotation (tilting sideways)", "Circular motion", "Spiral movement",
327
+ "Slipping due to inertia", "Change of rotation axis", "Irregular rotation", "Shaking movement", "Parabolic motion",
328
+ "Zero-gravity floating", "Floating on water surface", "Jump/leap", "Sliding", "Rolling", "Free fall",
329
+ "Reciprocating motion", "Elastic bouncing", "Penetration", "Evasive movement", "Zigzag movement", "Swinging movement"
330
+ ],
331
+ "Time-Related Change": [
332
+ "Aging/weathering", "Wear/corrosion", "Fading/discoloration", "Damage/recovery", "Lifecycle change",
333
+ "Adaptation through user interaction", "Learning-based shape optimization", "Property change over time",
334
+ "Collective memory effect", "Cultural significance change", "Delayed response", "History-dependent change",
335
+ "Gradual time change", "Evolutionary change", "Periodic regeneration", "Seasonal adaptation",
336
+ "Circadian rhythm change", "Lifecycle stage", "Growth/decline", "Self-repair/regeneration",
337
+ "Natural cycle adaptation", "Persistence/transience", "Memory effect", "Delayed effect", "Cumulative effect"
338
+ ],
339
+ "Light and Visual Effects": [
340
+ "Illumination/shutdown", "Light transmission/blocking", "Light scattering/concentration", "Color spectrum change", "Light diffraction",
341
+ "Light interference", "Hologram creation", "Laser effect", "Light polarization", "Fluorescence/phosphorescence",
342
+ "UV/IR emission", "Optical illusion", "Light refraction", "Shadow creation/removal",
343
+ "Chromatic aberration", "Rainbow effect", "Glow effect", "Flash effect", "Lighting pattern",
344
+ "Beam effect", "Light filter effect", "Change in light direction", "Projection effect", "Light detection/response",
345
+ "Luminance change"
346
  ],
347
+ "Sound and Vibration Effects": [
348
+ "Sound generation/cessation", "Pitch change", "Volume change", "Timbre change",
349
+ "Resonance/antiresonance", "Acoustic vibration", "Ultrasonic/infrasonic emission", "Sound concentration/distribution",
350
+ "Sound reflection/absorption", "Acoustic Doppler effect", "Sound wave interference", "Acoustic resonance",
351
+ "Vibration pattern change", "Percussive effect", "Audio feedback", "Sound shielding/amplification",
352
+ "Directional sound", "Sound distortion", "Beat generation", "Harmonics generation", "Frequency modulation",
353
+ "Acoustic shockwave", "Sound filtering"
354
+ ],
355
+ "Thermal Changes": [
356
+ "Temperature rise/fall", "Thermal expansion/contraction", "Heat transfer/blocking", "Pressure increase/decrease",
357
+ "Magnetization due to heat change", "Entropy change", "Thermoelectric effect", "Magnetic-induced thermal change",
358
+ "Heat storage/release during phase change", "Thermal stress buildup/release", "Impact of rapid temperature change",
359
+ "Radiative cooling/heating", "Exothermic/endothermic", "Heat distribution change", "Heat reflection/absorption",
360
+ "Cooling condensation", "Thermal activation", "Thermal discoloration", "Coefficient of thermal expansion change", "Thermal stability change",
361
+ "Heat resistance/cold resistance", "Self-heating", "Thermal equilibrium/imbalance", "Thermal deformation", "Heat dispersion/concentration"
362
+ ],
363
+ "Electrical and Magnetic Changes": [
364
+ "Magnetism creation/cessation", "Charge increase/decrease", "Electric field creation/cessation", "Magnetic field creation/cessation",
365
+ "Superconducting transition", "Ferroelectric property change", "Quantum state change", "Plasma formation/cessation",
366
+ "Spin wave transmission", "Electricity generation by light", "Electricity generation by pressure", "Current change in magnetic field",
367
+ "Electrical resistance change", "Electrical conductivity change", "Static electricity generation/discharge", "Electromagnetic induction",
368
+ "Electromagnetic wave emission/absorption", "Capacitance change", "Magnetic hysteresis", "Electrical polarization",
369
+ "Electron flow direction change", "Electrical resonance", "Electrical shielding/exposure", "Magnetic shielding/exposure",
370
+ "Magnetic field alignment"
371
+ ],
372
+ "Chemical Change": [
373
+ "Surface coating change", "Material composition change", "Chemical reaction change", "Catalytic action start/stop",
374
+ "Light-induced chemical reaction", "Electricity-induced chemical reaction", "Monolayer formation", "Molecular-level structural change",
375
+ "Biomimetic surface change", "Environmentally responsive material change", "Periodic chemical reaction", "Oxidation", "Reduction",
376
+ "Polymerization", "Water splitting", "Compound formation", "Radiation effects", "Acid-base reaction", "Neutralization reaction",
377
+ "Ionization", "Chemical adsorption/desorption", "Catalytic efficiency change", "Enzyme activity change", "Colorimetric reaction",
378
+ "pH change", "Chemical equilibrium shift", "Bond formation/breakage", "Solubility change"
379
+ ],
380
+ "Biological Change": [
381
+ "Growth/shrinkage", "Cell division/death", "Bioluminescence", "Metabolic change", "Immune response",
382
+ "Hormone secretion", "Neural response", "Genetic expression", "Adaptation/evolution", "Circadian rhythm change",
383
+ "Regeneration/healing", "Aging/maturation", "Biomimetic change", "Biofilm formation", "Biological degradation",
384
+ "Enzyme activation/inactivation", "Biological signaling", "Stress response", "Thermoregulation", "Biological clock change",
385
+ "Extracellular matrix change", "Biomechanical response", "Cell motility", "Cell polarity change", "Nutritional status change"
386
+ ],
387
+ "Environmental Interaction": [
388
+ "Temperature response", "Humidity response", "Pressure response", "Gravity response", "Magnetic field response",
389
+ "Light response", "Sound response", "Chemical detection", "Mechanical stimulus detection", "Electrical stimulus response",
390
+ "Radiation response", "Vibration detection", "pH response", "Solvent response", "Gas exchange",
391
+ "Pollution response", "Weather response", "Seasonal response", "Circadian response", "Ecosystem interaction",
392
+ "Symbiotic/competitive interaction", "Predator/prey relationship", "Swarm formation", "Territorial behavior", "Migration/settlement pattern"
393
  ]
 
394
  }
395
 
396
  ##############################################################################
397
+ # Gemini API Call Function (Language Independent)
398
  ##############################################################################
399
  def query_gemini_api(prompt):
400
  try:
 
424
  return f"An error occurred while calling the API: {str(e)}"
425
 
426
  ##############################################################################
427
+ # Description Expansion Functions (LLM) - Korean and English Versions
428
  ##############################################################################
429
  def enhance_with_llm(base_description, obj_name, category):
430
  prompt = f"""
 
437
  """
438
  return query_gemini_api(prompt)
439
 
440
+ def enhance_with_llm_en(base_description, obj_name, category):
441
+ prompt = f"""
442
+ Below is a brief description related to '{category}' for '{obj_name}':
443
+ "{base_description}"
444
+ Please expand the above content into a more detailed explanation, focusing on:
445
+ 1) Creative transformation of the model/concept/shape,
446
+ 2) Innovative aspects and functionality,
447
+ in 3-4 sentences.
448
+ """
449
+ return query_gemini_api(prompt)
450
+
451
  ##############################################################################
452
+ # Transformation Idea Generation Functions for Both Languages
453
  ##############################################################################
454
+ def generate_single_object_transformation_for_category_lang(obj, selected_category, categories_dict, lang="ko"):
455
+ transformations = categories_dict.get(selected_category)
456
  if not transformations:
457
  return {}
458
  transformation = choose_alternative(random.choice(transformations))
459
+ if lang == "ko":
460
+ base_description = f"{obj}์ด(๊ฐ€) {transformation} ํ˜„์ƒ์„ ๋ณด์ธ๋‹ค"
461
+ else:
462
+ base_description = f"{obj} exhibits {transformation}"
463
  return {selected_category: {"base": base_description, "enhanced": None}}
464
 
465
+ def generate_two_objects_interaction_for_category_lang(obj1, obj2, selected_category, categories_dict, lang="ko"):
466
+ transformations = categories_dict.get(selected_category)
467
  if not transformations:
468
  return {}
469
  transformation = choose_alternative(random.choice(transformations))
470
+ if lang == "ko":
471
+ template = random.choice([
472
+ "{obj1}์ด(๊ฐ€) {obj2}์— ๊ฒฐํ•ฉํ•˜์—ฌ {change}๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค",
473
+ "{obj1}๊ณผ(์™€) {obj2}์ด(๊ฐ€) ์ถฉ๋Œํ•˜๋ฉด์„œ {change}๊ฐ€ ์ผ์–ด๋‚ฌ๋‹ค"
474
+ ])
475
+ else:
476
+ template = random.choice([
477
+ "{obj1} combined with {obj2} resulted in {change}",
478
+ "A collision between {obj1} and {obj2} led to {change}"
479
+ ])
480
  base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
481
  return {selected_category: {"base": base_description, "enhanced": None}}
482
 
483
+ def generate_three_objects_interaction_for_category_lang(obj1, obj2, obj3, selected_category, categories_dict, lang="ko"):
484
+ transformations = categories_dict.get(selected_category)
485
  if not transformations:
486
  return {}
487
  transformation = choose_alternative(random.choice(transformations))
488
+ if lang == "ko":
489
+ template = random.choice([
490
+ "{obj1}, {obj2}, {obj3}์ด(๊ฐ€) ์‚ผ๊ฐํ˜• ๊ตฌ์กฐ๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ {change}๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค",
491
+ "{obj1}์ด(๊ฐ€) {obj2}์™€(๊ณผ) {obj3} ์‚ฌ์ด์—์„œ ๋งค๊ฐœ์ฒด ์—ญํ• ์„ ํ•˜๋ฉฐ {change}๋ฅผ ์ด‰์ง„ํ–ˆ๋‹ค"
492
+ ])
493
+ else:
494
+ template = random.choice([
495
+ "{obj1}, {obj2}, and {obj3} formed a triangular structure resulting in {change}",
496
+ "{obj1} acted as an intermediary between {obj2} and {obj3}, facilitating {change}"
497
+ ])
498
  base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
499
  return {selected_category: {"base": base_description, "enhanced": None}}
500
 
501
+ def enhance_descriptions_lang(results, objects, lang="ko"):
502
+ obj_name = " ๋ฐ ".join([obj for obj in objects if obj]) if lang=="ko" else " and ".join([obj for obj in objects if obj])
 
 
 
503
  for category, result in results.items():
504
+ if lang == "ko":
505
+ result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
506
+ else:
507
+ result["enhanced"] = enhance_with_llm_en(result["base"], obj_name, category)
508
  return results
509
 
510
+ def generate_transformations_lang(text1, text2, text3, selected_category, categories_dict, lang="ko"):
 
 
 
511
  if text2 and text3:
512
+ results = generate_three_objects_interaction_for_category_lang(text1, text2, text3, selected_category, categories_dict, lang)
513
  objects = [text1, text2, text3]
514
  elif text2:
515
+ results = generate_two_objects_interaction_for_category_lang(text1, text2, selected_category, categories_dict, lang)
516
  objects = [text1, text2]
517
  else:
518
+ results = generate_single_object_transformation_for_category_lang(text1, selected_category, categories_dict, lang)
519
  objects = [text1]
520
+ return enhance_descriptions_lang(results, objects, lang)
521
 
522
+ def format_results_lang(results, lang="ko"):
 
 
 
523
  formatted = ""
524
+ if lang == "ko":
525
+ for category, result in results.items():
526
+ formatted += f"## {category}\n**๊ธฐ๋ณธ ์•„์ด๋””์–ด**: {result['base']}\n\n**ํ™•์žฅ๋œ ์•„์ด๋””์–ด**: {result['enhanced']}\n\n---\n\n"
527
+ else:
528
+ for category, result in results.items():
529
+ formatted += f"## {category}\n**Base Idea**: {result['base']}\n\n**Expanded Idea**: {result['enhanced']}\n\n---\n\n"
530
  return formatted
531
 
532
+ def process_inputs_lang(text1, text2, text3, selected_category, categories_dict, lang="ko", progress=gr.Progress()):
 
 
 
533
  text1 = text1.strip() if text1 else None
534
  text2 = text2.strip() if text2 else None
535
  text3 = text3.strip() if text3 else None
536
 
537
  if not text1:
538
+ return "์˜ค๋ฅ˜: ์ตœ์†Œ ํ•˜๋‚˜์˜ ํ‚ค์›Œ๋“œ๋ฅผ ์ž…๋ ฅํ•ด์ฃผ์„ธ์š”." if lang=="ko" else "Error: Please enter at least one keyword."
539
 
540
+ if lang == "ko":
541
+ progress(0.05, desc="์•„์ด๋””์–ด ์ƒ์„ฑ ์ค€๋น„ ์ค‘...")
542
+ time.sleep(0.3)
543
+ progress(0.1, desc="์ฐฝ์˜์ ์ธ ์•„์ด๋””์–ด ์ƒ์„ฑ ์‹œ์ž‘...")
544
+ else:
545
+ progress(0.05, desc="Preparing idea generation...")
546
+ time.sleep(0.3)
547
+ progress(0.1, desc="Generating creative idea...")
548
 
549
+ results = generate_transformations_lang(text1, text2, text3, selected_category, categories_dict, lang)
550
 
551
+ if lang == "ko":
552
+ progress(0.8, desc="๊ฒฐ๊ณผ ํฌ๋งทํŒ… ์ค‘...")
553
+ formatted = format_results_lang(results, lang)
554
+ progress(1.0, desc="์™„๋ฃŒ!")
555
+ else:
556
+ progress(0.8, desc="Formatting results...")
557
+ formatted = format_results_lang(results, lang)
558
+ progress(1.0, desc="Done!")
559
  return formatted
560
 
561
+ def process_all_lang(text1, text2, text3, selected_category, categories_dict, lang="ko", progress=gr.Progress()):
562
+ idea_result = process_inputs_lang(text1, text2, text3, selected_category, categories_dict, lang, progress)
 
 
 
563
  image_result = generate_design_image(
564
  idea_result,
565
  seed=42,
 
571
  return idea_result, image_result
572
 
573
  ##############################################################################
574
+ # Warning Message Function for API Key (Language Specific)
575
  ##############################################################################
576
+ def get_warning_message_lang(lang="ko"):
577
  if not GEMINI_API_KEY:
578
+ return "โš ๏ธ ํ™˜๊ฒฝ ๋ณ€์ˆ˜ GEMINI_API_KEY๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. Gemini API ํ‚ค๋ฅผ ์„ค์ •ํ•˜์„ธ์š”." if lang=="ko" else "โš ๏ธ The GEMINI_API_KEY environment variable is not set. Please set your Gemini API key."
579
  return ""
580
 
581
+
582
  ##############################################################################
583
+ # Gradio UI with Two Tabs: English (Main Home) and Korean
584
  ##############################################################################
585
  with gr.Blocks(
586
+ title="Idea Transformer",
587
  theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")
588
  ) as demo:
589
 
 
625
  </style>
626
  """)
627
 
628
+ with gr.Tabs():
629
+ with gr.Tab(label="English"):
630
+ gr.Markdown("# ๐Ÿš€ Idea Transformer")
631
+ gr.Markdown("Based on up to **three keywords** and a **selected category**, this tool generates a creative transformation idea and a design image using the expanded idea as a prompt.")
632
+
633
+ warning_en = gr.Markdown(get_warning_message_lang("en"))
634
+
635
+ with gr.Row():
636
+ with gr.Column(scale=1):
637
+ text_input1_en = gr.Textbox(label="Keyword 1 (required)", placeholder="e.g., Smartphone")
638
+ text_input2_en = gr.Textbox(label="Keyword 2 (optional)", placeholder="e.g., Artificial Intelligence")
639
+ text_input3_en = gr.Textbox(label="Keyword 3 (optional)", placeholder="e.g., Healthcare")
640
+ category_radio_en = gr.Radio(
641
+ label="Select Category",
642
+ choices=list(physical_transformation_categories_en.keys()),
643
+ value=list(physical_transformation_categories_en.keys())[0],
644
+ info="Select a category."
645
+ )
646
+ status_msg_en = gr.Markdown("๐Ÿ’ก Click the 'Generate Idea' button to create an idea and design image based on the selected category.")
647
+
648
+ processing_indicator_en = gr.HTML("""
649
+ <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
650
+ <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
651
+ <p style="margin-left: 10px; font-weight: bold; color: #3498db;">Processing...</p>
652
+ </div>
653
+ <style>
654
+ @keyframes spin {
655
+ 0% { transform: rotate(0deg); }
656
+ 100% { transform: rotate(360deg); }
657
+ }
658
+ </style>
659
+ """, visible=False)
660
+
661
+ submit_button_en = gr.Button("Generate Idea", variant="primary")
662
+
663
+ with gr.Column(scale=2):
664
+ idea_output_en = gr.Markdown(label="Idea Output")
665
+ generated_image_en = gr.Image(label="Generated Design Image", type="pil")
666
+
667
+ gr.Examples(
668
+ examples=[
669
+ ["Smartphone", "", "", "Sensor Functions"],
670
+ ["Car", "", "", "Size and Shape Change"],
671
+ ["Car", "Artificial Intelligence", "", "Surface and Appearance Change"],
672
+ ["Drone", "Artificial Intelligence", "", "Material State Change"],
673
+ ["Sneakers", "Wearable", "Health", "Structural Change"],
674
+ ],
675
+ inputs=[text_input1_en, text_input2_en, text_input3_en, category_radio_en],
676
  )
 
677
 
678
+ def show_processing_indicator_en():
679
+ return gr.update(visible=True)
680
+
681
+ def hide_processing_indicator_en():
682
+ return gr.update(visible=False)
 
 
 
 
 
 
 
683
 
684
+ submit_button_en.click(
685
+ fn=show_processing_indicator_en,
686
+ inputs=None,
687
+ outputs=processing_indicator_en
688
+ ).then(
689
+ fn=process_all_lang,
690
+ inputs=[text_input1_en, text_input2_en, text_input3_en, category_radio_en, gr.State(physical_transformation_categories_en), gr.State("en")],
691
+ outputs=[idea_output_en, generated_image_en]
692
+ ).then(
693
+ fn=hide_processing_indicator_en,
694
+ inputs=None,
695
+ outputs=processing_indicator_en
696
+ )
697
 
698
+ with gr.Tab(label="ํ•œ๊ตญ์–ด"):
699
+ gr.Markdown("# ๐Ÿš€ ์•„์ด๋””์–ด ํŠธ๋žœ์Šคํฌ๋จธ")
700
+ gr.Markdown("์ž…๋ ฅํ•œ **ํ‚ค์›Œ๋“œ**(์ตœ๋Œ€ 3๊ฐœ)์™€ **์นดํ…Œ๊ณ ๋ฆฌ**๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ, ์ฐฝ์˜์ ์ธ ๋ชจ๋ธ/์ปจ์…‰/ํ˜•์ƒ ๋ณ€ํ™” ์•„์ด๋””์–ด๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ํ•ด๋‹น ํ™•์žฅ ์•„์ด๋””์–ด๋ฅผ ํ”„๋กฌํ”„ํŠธ๋กœ ํ•˜์—ฌ ๋””์ž์ธ ์ด๋ฏธ์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.")
701
+
702
+ warning_ko = gr.Markdown(get_warning_message_lang("ko"))
703
+
704
+ with gr.Row():
705
+ with gr.Column(scale=1):
706
+ text_input1_ko = gr.Textbox(label="ํ‚ค์›Œ๋“œ 1 (ํ•„์ˆ˜)", placeholder="์˜ˆ: ์Šค๋งˆํŠธํฐ")
707
+ text_input2_ko = gr.Textbox(label="ํ‚ค์›Œ๋“œ 2 (์„ ํƒ)", placeholder="์˜ˆ: ์ธ๊ณต์ง€๋Šฅ")
708
+ text_input3_ko = gr.Textbox(label="ํ‚ค์›Œ๋“œ 3 (์„ ํƒ)", placeholder="์˜ˆ: ํ—ฌ์Šค์ผ€์–ด")
709
+ category_radio_ko = gr.Radio(
710
+ label="์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ",
711
+ choices=list(physical_transformation_categories.keys()),
712
+ value=list(physical_transformation_categories.keys())[0],
713
+ info="์ถœ๋ ฅํ•  ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์„ ํƒํ•˜์„ธ์š”."
714
+ )
715
+ status_msg_ko = gr.Markdown("๐Ÿ’ก '์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ' ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ์„ ํƒํ•œ ์นดํ…Œ๊ณ ๋ฆฌ์— ํ•ด๋‹นํ•˜๋Š” ์•„์ด๋””์–ด์™€ ๋””์ž์ธ ์ด๋ฏธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.")
716
+
717
+ processing_indicator_ko = gr.HTML("""
718
+ <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
719
+ <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
720
+ <p style="margin-left: 10px; font-weight: bold; color: #3498db;">์ฒ˜๋ฆฌ ์ค‘์ž…๋‹ˆ๋‹ค...</p>
721
+ </div>
722
+ <style>
723
+ @keyframes spin {
724
+ 0% { transform: rotate(0deg); }
725
+ 100% { transform: rotate(360deg); }
726
+ }
727
+ </style>
728
+ """, visible=False)
729
+
730
+ submit_button_ko = gr.Button("์•„์ด๋””์–ด ์ƒ์„ฑํ•˜๊ธฐ", variant="primary")
731
+
732
+ with gr.Column(scale=2):
733
+ idea_output_ko = gr.Markdown(label="์•„์ด๋””์–ด ๊ฒฐ๊ณผ")
734
+ generated_image_ko = gr.Image(label="์ƒ์„ฑ๋œ ๋””์ž์ธ ์ด๋ฏธ์ง€", type="pil")
735
+
736
+ gr.Examples(
737
+ examples=[
738
+ ["์Šค๋งˆํŠธํฐ", "", "", "์„ผ์„œ ๊ธฐ๋Šฅ"],
739
+ ["์ž๋™์ฐจ", "", "", "ํฌ๊ธฐ์™€ ํ˜•ํƒœ ๋ณ€ํ™”"],
740
+ ["์ž๋™์ฐจ", "์ธ๊ณต์ง€๋Šฅ", "", "ํ‘œ๋ฉด ๋ฐ ์™ธ๊ด€ ๋ณ€ํ™”"],
741
+ ["๋“œ๋ก ", "์ธ๊ณต์ง€๋Šฅ", "", "๋ฌผ์งˆ์˜ ์ƒํƒœ ๋ณ€ํ™”"],
742
+ ["์šด๋™ํ™”", "์›จ์–ด๋Ÿฌ๋ธ”", "๊ฑด๊ฐ•", "๊ตฌ์กฐ์  ๋ณ€ํ™”"],
743
+ ],
744
+ inputs=[text_input1_ko, text_input2_ko, text_input3_ko, category_radio_ko],
745
+ )
746
+
747
+ def show_processing_indicator_ko():
748
+ return gr.update(visible=True)
749
+
750
+ def hide_processing_indicator_ko():
751
+ return gr.update(visible=False)
752
+
753
+ submit_button_ko.click(
754
+ fn=show_processing_indicator_ko,
755
+ inputs=None,
756
+ outputs=processing_indicator_ko
757
+ ).then(
758
+ fn=process_all_lang,
759
+ inputs=[text_input1_ko, text_input2_ko, text_input3_ko, category_radio_ko, gr.State(physical_transformation_categories), gr.State("ko")],
760
+ outputs=[idea_output_ko, generated_image_ko]
761
+ ).then(
762
+ fn=hide_processing_indicator_ko,
763
+ inputs=None,
764
+ outputs=processing_indicator_ko
765
+ )
766
 
767
  if __name__ == "__main__":
768
  demo.launch(debug=True)