openfree commited on
Commit
20da2d9
โ€ข
1 Parent(s): d90d160

Upload 6 files

Browse files
Files changed (7) hide show
  1. .gitattributes +1 -0
  2. README (2).md +14 -0
  3. app (2).css +397 -0
  4. app (26).py +1091 -0
  5. config (2).py +48 -0
  6. mouse (2).gif +3 -0
  7. requirements (7).txt +23 -0
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ mouse[[:space:]](2).gif filter=lfs diff=lfs merge=lfs -text
README (2).md ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: MOUSE-Visual AI Chatbot
3
+ emoji: ๐Ÿ”ฅ
4
+ colorFrom: indigo
5
+ colorTo: yellow
6
+ sdk: gradio
7
+ sdk_version: 5.7.1
8
+ app_file: app.py
9
+ pinned: false
10
+ license: apache-2.0
11
+ short_description: A highly visual AI chatbot that transforms every response in
12
+ ---
13
+
14
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
app (2).css ADDED
@@ -0,0 +1,397 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Modern color scheme */
2
+ :root {
3
+ --primary: #0066cc;
4
+ --secondary: #3385ff;
5
+ --accent: #66a3ff;
6
+ --background: #f7f9fc;
7
+ --surface: #ffffff;
8
+ --text-primary: #2c3e50;
9
+ --text-secondary: #546e7a;
10
+ --text-tertiary: #78909c;
11
+ --success: #34c759;
12
+ --warning: #ff9500;
13
+ --error: #ff3b30;
14
+ --neutral-100: #f8f9fa;
15
+ --neutral-200: #e9ecef;
16
+ --neutral-300: #dee2e6;
17
+ --neutral-400: #ced4da;
18
+ }
19
+
20
+ body {
21
+ font-family: 'Inter', system-ui, sans-serif;
22
+ background: var(--background);
23
+ color: var(--text-primary);
24
+ line-height: 1.5;
25
+ }
26
+
27
+ /* ํƒญ ์Šคํƒ€์ผ ๊ฐ•ํ™” */
28
+ .main-tabs > div.tab-nav {
29
+ background: rgba(255, 255, 255, 0.95);
30
+ padding: 10px 10px 0 10px;
31
+ border-radius: 12px 12px 0 0;
32
+ box-shadow: 0 -4px 20px rgba(0,0,0,0.05);
33
+ }
34
+
35
+ .main-tabs > div.tab-nav > button {
36
+ font-size: 1.2em !important;
37
+ padding: 0.8em 1.5em !important;
38
+ background: rgba(255, 255, 255, 0.9) !important;
39
+ border: 1px solid #eef2f6 !important;
40
+ border-bottom: none !important;
41
+ border-radius: 12px 12px 0 0 !important;
42
+ margin-right: 8px !important;
43
+ color: #94a3b8 !important;
44
+ font-weight: 500 !important;
45
+ transition: all 0.3s ease !important;
46
+ position: relative !important;
47
+ top: 1px !important;
48
+ }
49
+
50
+ .main-tabs > div.tab-nav > button:hover {
51
+ background: linear-gradient(to bottom, #ffffff, #f8fafc) !important;
52
+ color: #64748b !important;
53
+ transform: translateY(-2px);
54
+ }
55
+
56
+ .main-tabs > div.tab-nav > button.selected {
57
+ background: linear-gradient(45deg, #0084ff, #00a3ff) !important;
58
+ color: white !important;
59
+ border: none !important;
60
+ box-shadow: 0 4px 15px rgba(0,132,255,0.3) !important;
61
+ transform: translateY(-2px);
62
+ }
63
+
64
+ .main-tabs {
65
+ margin-top: -20px !important;
66
+ border-radius: 0 0 15px 15px !important;
67
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08) !important;
68
+ border: 1px solid rgba(255,255,255,0.8) !important;
69
+ background: white !important;
70
+ }
71
+
72
+ /* ํƒญ ์ปจํ…์ธ  ์˜์—ญ */
73
+ .main-tabs > div[role="tabpanel"] {
74
+ background: white;
75
+ border-radius: 0 0 12px 12px;
76
+ padding: 20px;
77
+ box-shadow: inset 0 2px 10px rgba(0,0,0,0.03);
78
+ }
79
+
80
+ /* ํ”„๋กฌํ”„ํŠธ ์ž…๋ ฅ์ฐฝ ์Šคํƒ€์ผ - ๋” ๊ตฌ์ฒด์ ์ธ ์„ ํƒ์ž */
81
+ .mouse-tab .ant-input-textarea .ant-input,
82
+ .mouse-tab .ant-input-textarea-large .ant-input,
83
+ #mouse-tab .ant-input-textarea .ant-input,
84
+ #mouse-tab .ant-input-textarea-large .ant-input,
85
+ .ant-input-textarea .ant-input,
86
+ .ant-input-textarea-large .ant-input,
87
+ div[class*="ant-input"] textarea,
88
+ textarea.ant-input {
89
+ height: 300px !important;
90
+ min-height: 300px !important;
91
+ max-height: 300px !important;
92
+ resize: none !important;
93
+ border: 2px solid var(--neutral-200) !important;
94
+ border-radius: 12px !important;
95
+ padding: 1rem !important;
96
+ font-size: 14px !important;
97
+ line-height: 1.5 !important;
98
+ width: 100% !important;
99
+ box-sizing: border-box !important;
100
+ overflow-y: auto !important;
101
+ }
102
+
103
+ /* ์ปจํ…Œ์ด๋„ˆ ์Šคํƒ€์ผ๋„ ๊ฐ•์ œ ์ ์šฉ */
104
+ .mouse-tab .ant-input-textarea,
105
+ .mouse-tab .ant-input-textarea-large,
106
+ #mouse-tab .ant-input-textarea,
107
+ #mouse-tab .ant-input-textarea-large,
108
+ .ant-input-textarea,
109
+ .ant-input-textarea-large,
110
+ div[class*="ant-input-textarea"] {
111
+ height: 300px !important;
112
+ min-height: 300px !important;
113
+ max-height: 300px !important;
114
+ }
115
+
116
+
117
+ /* ์ถ”๊ฐ€์ ์ธ ์Šคํƒ€์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ */
118
+ .ant-input-textarea-large .ant-input {
119
+ height: 300px !important;
120
+ min-height: 300px !important;
121
+ max-height: 300px !important;
122
+ }
123
+
124
+ /* Gradio ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ์˜ค๋ฒ„๋ผ์ด๋“œ */
125
+ .gradio-container .gr-text-input,
126
+ .gradio-container textarea {
127
+ height: 300px !important;
128
+ min-height: 300px !important;
129
+ max-height: 300px !important;
130
+ }
131
+
132
+
133
+ /* ์ž…๋ ฅ์ฐฝ ๋ถ€๋ชจ ์š”์†Œ๋“ค์˜ ๋†’์ด ์ œํ•œ ํ•ด์ œ */
134
+ .ant-input-textarea-show-count::after,
135
+ .ant-input-textarea-large::after,
136
+ .ant-input-textarea::after {
137
+ height: auto !important;
138
+ min-height: auto !important;
139
+ max-height: none !important;
140
+ }
141
+
142
+ /* iframe ์ปจํ…Œ์ด๋„ˆ */
143
+ .html_content {
144
+ height: 800px !important;
145
+ max-height: 800px !important;
146
+ min-height: 800px !important;
147
+ border-radius: 12px;
148
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
149
+ background: var(--surface);
150
+ }
151
+
152
+ /* iframe ์ž์ฒด */
153
+ iframe {
154
+ height: 800px !important;
155
+ max-height: 800px !important;
156
+ min-height: 800px !important;
157
+ width: 100% !important;
158
+ border: none !important;
159
+ }
160
+
161
+ .left_header {
162
+ display: flex;
163
+ flex-direction: column;
164
+ justify-content: center;
165
+ align-items: center;
166
+ background: linear-gradient(135deg, var(--surface), var(--neutral-100));
167
+ backdrop-filter: blur(10px);
168
+ border-radius: 24px;
169
+ padding: 2rem;
170
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.08);
171
+ border: 1px solid var(--neutral-200);
172
+ text-align: center;
173
+ margin-bottom: 2rem;
174
+ }
175
+
176
+ .left_header img {
177
+ width: 180px;
178
+ margin-bottom: 1rem;
179
+ border-radius: 12px;
180
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
181
+ }
182
+
183
+ .left_header h1 {
184
+ margin: 0.5rem 0;
185
+ font-weight: 600;
186
+ color: var(--text-primary);
187
+ }
188
+
189
+ .render_header {
190
+ height: 30px;
191
+ width: 100%;
192
+ padding: 5px 16px;
193
+ background-color: var(--neutral-100);
194
+ margin-top: 50px;
195
+ border-radius: 8px 8px 0 0;
196
+ }
197
+
198
+ .header_btn {
199
+ display: inline-block;
200
+ height: 10px;
201
+ width: 10px;
202
+ border-radius: 50%;
203
+ margin-right: 4px;
204
+ }
205
+
206
+ .render_header > .header_btn:nth-child(1) {
207
+ background-color: var(--error);
208
+ }
209
+
210
+ .render_header > .header_btn:nth-child(2) {
211
+ background-color: var(--warning);
212
+ }
213
+
214
+ .render_header > .header_btn:nth-child(3) {
215
+ background-color: var(--success);
216
+ }
217
+
218
+ .setting-buttons {
219
+ position: sticky;
220
+ top: 1rem;
221
+ right: 0;
222
+ z-index: 1000;
223
+ display: flex;
224
+ gap: 8px;
225
+ padding: 12px;
226
+ background: rgba(255, 255, 255, 0.9);
227
+ backdrop-filter: blur(8px);
228
+ border-radius: 12px;
229
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
230
+ border: 1px solid var(--neutral-200);
231
+ }
232
+
233
+ .ant-btn {
234
+ flex: 1;
235
+ min-width: 80px;
236
+ border-radius: 8px;
237
+ font-weight: 500;
238
+ transition: all 0.3s;
239
+ height: 40px;
240
+ display: flex;
241
+ align-items: center;
242
+ justify-content: center;
243
+ }
244
+
245
+ .ant-btn-primary {
246
+ background: linear-gradient(to right, var(--primary), var(--secondary));
247
+ border: none;
248
+ color: white;
249
+ }
250
+
251
+ .ant-btn-primary:hover {
252
+ transform: translateY(-2px);
253
+ box-shadow: 0 4px 12px rgba(0, 102, 204, 0.3);
254
+ }
255
+
256
+ .ant-btn-default {
257
+ background: var(--surface);
258
+ border: 1px solid var(--primary);
259
+ color: var(--primary);
260
+ }
261
+
262
+ .ant-btn-default:hover {
263
+ color: var(--secondary);
264
+ border-color: var(--secondary);
265
+ transform: translateY(-2px);
266
+ box-shadow: 0 4px 12px rgba(0, 102, 204, 0.1);
267
+ }
268
+
269
+ .ant-btn-default[title="Code ์‹คํ–‰"] {
270
+ background-color: var(--success);
271
+ color: white;
272
+ border: none;
273
+ }
274
+
275
+ .ant-btn-default[title="Code ์‹คํ–‰"]:hover {
276
+ background-color: #40d869;
277
+ }
278
+
279
+ /* ์Šคํฌ๋กค๋ฐ” ์„ค์ • */
280
+ ::-webkit-scrollbar {
281
+ width: 8px;
282
+ height: 8px;
283
+ }
284
+
285
+ ::-webkit-scrollbar-track {
286
+ background: var(--neutral-100);
287
+ }
288
+
289
+ ::-webkit-scrollbar-thumb {
290
+ background: var(--neutral-300);
291
+ border-radius: 4px;
292
+ }
293
+
294
+ ::-webkit-scrollbar-thumb:hover {
295
+ background: var(--neutral-400);
296
+ }
297
+
298
+ /* Drawer customization */
299
+ .ant-drawer-content-wrapper {
300
+ border-radius: 16px 0 0 16px;
301
+ }
302
+
303
+ .ant-drawer-header {
304
+ background: var(--primary);
305
+ color: white;
306
+ border-radius: 16px 0 0 0;
307
+ }
308
+
309
+ .ant-drawer-title {
310
+ color: white;
311
+ font-weight: 500;
312
+ }
313
+
314
+ .ant-drawer-close {
315
+ color: white;
316
+ }
317
+
318
+ .ant-drawer-body {
319
+ background: var(--surface);
320
+ }
321
+
322
+ /* ์ž…๋ ฅ์ฐฝ ํฌ์ปค์Šค ์Šคํƒ€์ผ */
323
+ .ant-input-textarea textarea:focus {
324
+ border-color: var(--accent);
325
+ box-shadow: 0 0 0 3px rgba(102, 163, 255, 0.2);
326
+ }
327
+
328
+ /* Responsive adjustments */
329
+ @media (max-width: 768px), screen and (max-height: 900px) {
330
+ .left_header {
331
+ padding: 1rem;
332
+ }
333
+
334
+ .setting-buttons {
335
+ flex-wrap: wrap;
336
+ }
337
+
338
+ .ant-btn {
339
+ min-width: 60px;
340
+ font-size: 0.9rem;
341
+ }
342
+
343
+ /* ๋ชจ๋ฐ”์ผ์—์„œ๋„ ๋™์ผํ•œ ๋†’์ด ์œ ์ง€ */
344
+ div[class*="ant-input-textarea"],
345
+ div[class*="ant-input-textarea"] textarea,
346
+ .ant-input-textarea,
347
+ .ant-input-textarea textarea,
348
+ .ant-input-textarea-large,
349
+ .ant-input-textarea-large textarea,
350
+ .ant-input.ant-input-textarea-large,
351
+ .ant-input.ant-input-textarea-large textarea,
352
+ textarea.ant-input,
353
+ .ant-input-textarea .ant-input,
354
+ .ant-input-textarea-large .ant-input,
355
+ #mouse-tab textarea,
356
+ .mouse-tab textarea,
357
+ [class*="textbox"] textarea,
358
+ .gradio-container textarea,
359
+ .gr-text-input,
360
+ textarea.gr-text-input,
361
+ .gr-panel textarea {
362
+ height: 300px !important;
363
+ min-height: 300px !important;
364
+ max-height: 300px !important;
365
+ }
366
+
367
+ .html_content,
368
+ iframe {
369
+ height: 800px !important;
370
+ min-height: 800px !important;
371
+ max-height: 800px !important;
372
+ }
373
+
374
+ .right_panel {
375
+ height: calc(100vh - 80px);
376
+ min-height: 600px;
377
+ }
378
+
379
+ .html_content {
380
+ height: calc(100vh - 160px);
381
+ min-height: 500px;
382
+ }
383
+ }
384
+
385
+ footer, .footer, div[class*="footer"], #footer {
386
+ display: none !important;
387
+ }
388
+
389
+ /* ์šฐ์ธก ํŒจ๋„ ์Šคํƒ€์ผ */
390
+ .right_panel {
391
+ background: white;
392
+ border-radius: 15px;
393
+ padding: 20px;
394
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
395
+ height: calc(100vh - 100px);
396
+ min-height: 800px;
397
+ }
app (26).py ADDED
@@ -0,0 +1,1091 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import random
4
+ from http import HTTPStatus
5
+ from typing import Dict, List, Optional, Tuple
6
+ import base64
7
+ import anthropic
8
+ import openai
9
+ import asyncio
10
+ import time
11
+ from functools import partial
12
+ import json
13
+ import gradio as gr
14
+ import modelscope_studio.components.base as ms
15
+ import modelscope_studio.components.legacy as legacy
16
+ import modelscope_studio.components.antd as antd
17
+ import html
18
+ import urllib.parse
19
+ from huggingface_hub import HfApi, create_repo, hf_hub_download
20
+ import string
21
+ import requests
22
+ from selenium import webdriver
23
+ from selenium.webdriver.support.ui import WebDriverWait
24
+ from selenium.webdriver.support import expected_conditions as EC
25
+ from selenium.webdriver.common.by import By
26
+ from selenium.common.exceptions import WebDriverException, TimeoutException
27
+ from PIL import Image
28
+ from io import BytesIO
29
+ from datetime import datetime
30
+ import spaces
31
+ from safetensors.torch import load_file
32
+ from diffusers import FluxPipeline
33
+ import torch
34
+ from os import path # ์ด ์ค„์„ ์ถ”๊ฐ€
35
+
36
+ # ์บ์‹œ ๊ฒฝ๋กœ ์„ค์ •
37
+ cache_path = path.join(path.dirname(path.abspath(__file__)), "models")
38
+ os.environ["TRANSFORMERS_CACHE"] = cache_path
39
+ os.environ["HF_HUB_CACHE"] = cache_path
40
+ os.environ["HF_HOME"] = cache_path
41
+
42
+
43
+ # Hugging Face ํ† ํฐ ์„ค์ •
44
+ HF_TOKEN = os.getenv("HF_TOKEN")
45
+ if not HF_TOKEN:
46
+ print("Warning: HF_TOKEN not found in environment variables")
47
+
48
+ # FLUX ๋ชจ๋ธ ์ดˆ๊ธฐํ™”
49
+ if not path.exists(cache_path):
50
+ os.makedirs(cache_path, exist_ok=True)
51
+
52
+ try:
53
+ pipe = FluxPipeline.from_pretrained(
54
+ "black-forest-labs/FLUX.1-dev",
55
+ torch_dtype=torch.bfloat16,
56
+ use_auth_token=HF_TOKEN # Hugging Face ํ† ํฐ ์ถ”๊ฐ€
57
+ )
58
+ pipe.load_lora_weights(
59
+ hf_hub_download(
60
+ "ByteDance/Hyper-SD",
61
+ "Hyper-FLUX.1-dev-8steps-lora.safetensors",
62
+ token=HF_TOKEN # Hugging Face ํ† ํฐ ์ถ”๊ฐ€
63
+ )
64
+ )
65
+ pipe.fuse_lora(lora_scale=0.125)
66
+ pipe.to(device="cuda", dtype=torch.bfloat16)
67
+ print("Successfully initialized FLUX model with authentication")
68
+ except Exception as e:
69
+ print(f"Error initializing FLUX model: {str(e)}")
70
+ pipe = None
71
+
72
+
73
+
74
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ ํ•จ์ˆ˜ ์ถ”๊ฐ€
75
+ @spaces.GPU
76
+ def generate_image(prompt, height=512, width=512, steps=8, scales=3.5, seed=3413):
77
+ with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16):
78
+ return pipe(
79
+ prompt=[prompt],
80
+ generator=torch.Generator().manual_seed(int(seed)),
81
+ num_inference_steps=int(steps),
82
+ guidance_scale=float(scales),
83
+ height=int(height),
84
+ width=int(width),
85
+ max_sequence_length=256
86
+ ).images[0]
87
+
88
+ # SystemPrompt ๋ถ€๋ถ„์„ ์ง์ ‘ ์ •์˜
89
+ SystemPrompt = """You are 'MOUSE-I', an advanced AI visualization expert. Your mission is to transform every response into a visually stunning and highly informative presentation.
90
+
91
+ Core Capabilities:
92
+ - Transform text responses into rich visual experiences
93
+ - Create interactive data visualizations and charts
94
+ - Design beautiful and intuitive user interfaces
95
+ - Utilize engaging animations and transitions
96
+ - Present information in a clear, structured manner
97
+
98
+ Visual Elements to Include:
99
+ - Charts & Graphs (using Chart.js, D3.js)
100
+ - Interactive Data Visualizations
101
+ - Modern UI Components
102
+ - Engaging Animations
103
+ - Informative Icons & Emojis
104
+ - Color-coded Information Blocks
105
+ - Progress Indicators
106
+ - Timeline Visualizations
107
+ - Statistical Representations
108
+ - Comparison Tables
109
+
110
+ Technical Requirements:
111
+ - Modern HTML5/CSS3/JavaScript
112
+ - Responsive Design
113
+ - Interactive Elements
114
+ - Clean Typography
115
+ - Professional Color Schemes
116
+ - Smooth Animations
117
+ - Cross-browser Compatibility
118
+
119
+ Libraries Available:
120
+ - Chart.js for Data Visualization
121
+ - D3.js for Complex Graphics
122
+ - Bootstrap for Layout
123
+ - jQuery for Interactions
124
+ - Three.js for 3D Elements
125
+
126
+ Design Principles:
127
+ - Visual Hierarchy
128
+ - Clear Information Flow
129
+ - Consistent Styling
130
+ - Intuitive Navigation
131
+ - Engaging User Experience
132
+ - Accessibility Compliance
133
+
134
+ Remember to:
135
+ - Present data in the most visually appealing way
136
+ - Use appropriate charts for different data types
137
+ - Include interactive elements where relevant
138
+ - Maintain a professional and modern aesthetic
139
+ - Ensure responsive design for all devices
140
+
141
+ Return only HTML code wrapped in code blocks, focusing on creating visually stunning and informative presentations.
142
+ """
143
+
144
+ from config import DEMO_LIST
145
+
146
+ class Role:
147
+ SYSTEM = "system"
148
+ USER = "user"
149
+ ASSISTANT = "assistant"
150
+
151
+ History = List[Tuple[str, str]]
152
+ Messages = List[Dict[str, str]]
153
+
154
+ # ์ด๋ฏธ์ง€ ์บ์‹œ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ
155
+ IMAGE_CACHE = {}
156
+
157
+ # boost_prompt ํ•จ์ˆ˜์™€ handle_boost ํ•จ์ˆ˜๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค
158
+ def boost_prompt(prompt: str) -> str:
159
+ if not prompt:
160
+ return ""
161
+
162
+ # ์ฆ๊ฐ•์„ ์œ„ํ•œ ์‹œ์Šคํ…œ ํ”„๋กฌํ”„ํŠธ
163
+ boost_system_prompt = """
164
+ ๋‹น์‹ ์€ ์›น ๊ฐœ๋ฐœ ํ”„๋กฌํ”„ํŠธ ์ „๋ฌธ๊ฐ€์ž…๋‹ˆ๋‹ค.
165
+ ์ฃผ์–ด์ง„ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ„์„ํ•˜์—ฌ ๋” ์ƒ์„ธํ•˜๏ฟฝ๏ฟฝ ์ „๋ฌธ์ ์ธ ์š”๊ตฌ์‚ฌํ•ญ์œผ๋กœ ํ™•์žฅํ•˜๋˜,
166
+ ์›๋ž˜ ์˜๋„์™€ ๋ชฉ์ ์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ ๋‹ค์Œ ๊ด€์ ๋“ค์„ ๊ณ ๋ คํ•˜์—ฌ ์ฆ๊ฐ•ํ•˜์‹ญ์‹œ์˜ค:
167
+ 1. ๊ธฐ์ˆ ์  ๊ตฌํ˜„ ์ƒ์„ธ
168
+ 2. UI/UX ๋””์ž์ธ ์š”์†Œ
169
+ 3. ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ์ตœ์ ํ™”
170
+ 4. ์„ฑ๋Šฅ๊ณผ ๋ณด์•ˆ
171
+ 5. ์ ‘๊ทผ์„ฑ๊ณผ ํ˜ธํ™˜์„ฑ
172
+
173
+ ๊ธฐ์กด SystemPrompt์˜ ๋ชจ๋“  ๊ทœ์น™์„ ์ค€์ˆ˜ํ•˜๋ฉด์„œ ์ฆ๊ฐ•๋œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ์ƒ์„ฑํ•˜์‹ญ์‹œ์˜ค.
174
+ """
175
+
176
+ try:
177
+ # Claude API ์‹œ๋„
178
+ try:
179
+ response = claude_client.messages.create(
180
+ model="claude-3-5-sonnet-20241022",
181
+ max_tokens=2000,
182
+ messages=[{
183
+ "role": "user",
184
+ "content": f"๋‹ค์Œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ฆ๊ฐ•ํ•˜์‹œ์˜ค: {prompt}"
185
+ }]
186
+ )
187
+
188
+ if hasattr(response, 'content') and len(response.content) > 0:
189
+ return response.content[0].text
190
+ raise Exception("Claude API ์‘๋‹ต ํ˜•์‹ ์˜ค๋ฅ˜")
191
+
192
+ except Exception as claude_error:
193
+ print(f"Claude API ์—๋Ÿฌ, OpenAI๋กœ ์ „ํ™˜: {str(claude_error)}")
194
+
195
+ # OpenAI API ์‹œ๋„
196
+ completion = openai_client.chat.completions.create(
197
+ model="gpt-4",
198
+ messages=[
199
+ {"role": "system", "content": boost_system_prompt},
200
+ {"role": "user", "content": f"๋‹ค์Œ ํ”„๋กฌํ”„ํŠธ๋ฅผ ๋ถ„์„ํ•˜๊ณ  ์ฆ๊ฐ•ํ•˜์‹œ์˜ค: {prompt}"}
201
+ ],
202
+ max_tokens=2000,
203
+ temperature=0.7
204
+ )
205
+
206
+ if completion.choices and len(completion.choices) > 0:
207
+ return completion.choices[0].message.content
208
+ raise Exception("OpenAI API ์‘๋‹ต ํ˜•์‹ ์˜ค๋ฅ˜")
209
+
210
+ except Exception as e:
211
+ print(f"ํ”„๋กฌํ”„ํŠธ ์ฆ๊ฐ• ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
212
+ return prompt # ์˜ค๋ฅ˜ ๋ฐœ์ƒ์‹œ ์›๋ณธ ํ”„๋กฌํ”„ํŠธ ๋ฐ˜ํ™˜
213
+
214
+ # Boost ๋ฒ„ํŠผ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ
215
+ def handle_boost(prompt: str):
216
+ try:
217
+ boosted_prompt = boost_prompt(prompt)
218
+ return boosted_prompt, gr.update(active_key="empty")
219
+ except Exception as e:
220
+ print(f"Boost ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜: {str(e)}")
221
+ return prompt, gr.update(active_key="empty")
222
+
223
+ def get_image_base64(image_path):
224
+ if image_path in IMAGE_CACHE:
225
+ return IMAGE_CACHE[image_path]
226
+ try:
227
+ with open(image_path, "rb") as image_file:
228
+ encoded_string = base64.b64encode(image_file.read()).decode()
229
+ IMAGE_CACHE[image_path] = encoded_string
230
+ return encoded_string
231
+ except:
232
+ return IMAGE_CACHE.get('default.png', '')
233
+
234
+ def history_to_messages(history: History, system: str) -> Messages:
235
+ messages = [{'role': Role.SYSTEM, 'content': system}]
236
+ for h in history:
237
+ messages.append({'role': Role.USER, 'content': h[0]})
238
+ messages.append({'role': Role.ASSISTANT, 'content': h[1]})
239
+ return messages
240
+
241
+ def messages_to_history(messages: Messages) -> History:
242
+ assert messages[0]['role'] == Role.SYSTEM
243
+ history = []
244
+ for q, r in zip(messages[1::2], messages[2::2]):
245
+ history.append([q['content'], r['content']])
246
+ return history
247
+
248
+ # API ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™”
249
+ YOUR_ANTHROPIC_TOKEN = os.getenv('ANTHROPIC_API_KEY', '') # ๊ธฐ๋ณธ๊ฐ’ ์ถ”๊ฐ€
250
+ YOUR_OPENAI_TOKEN = os.getenv('OPENAI_API_KEY', '') # ๊ธฐ๋ณธ๊ฐ’ ์ถ”๊ฐ€
251
+
252
+ # API ํ‚ค ๊ฒ€์ฆ
253
+ if not YOUR_ANTHROPIC_TOKEN or not YOUR_OPENAI_TOKEN:
254
+ print("Warning: API keys not found in environment variables")
255
+
256
+ # API ํด๋ผ์ด์–ธํŠธ ์ดˆ๊ธฐํ™” ์‹œ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ์ถ”๊ฐ€
257
+ try:
258
+ claude_client = anthropic.Anthropic(api_key=YOUR_ANTHROPIC_TOKEN)
259
+ openai_client = openai.OpenAI(api_key=YOUR_OPENAI_TOKEN)
260
+ except Exception as e:
261
+ print(f"Error initializing API clients: {str(e)}")
262
+ claude_client = None
263
+ openai_client = None
264
+
265
+ # try_claude_api ํ•จ์ˆ˜ ์ˆ˜์ •
266
+ async def try_claude_api(system_message, claude_messages, timeout=15):
267
+ try:
268
+ start_time = time.time()
269
+ with claude_client.messages.stream(
270
+ model="claude-3-5-sonnet-20241022",
271
+ max_tokens=7860,
272
+ system=system_message,
273
+ messages=claude_messages
274
+ ) as stream:
275
+ collected_content = ""
276
+ for chunk in stream:
277
+ current_time = time.time()
278
+ if current_time - start_time > timeout:
279
+ print(f"Claude API response time: {current_time - start_time:.2f} seconds")
280
+ raise TimeoutError("Claude API timeout")
281
+ if chunk.type == "content_block_delta":
282
+ collected_content += chunk.delta.text
283
+ yield collected_content
284
+ await asyncio.sleep(0)
285
+
286
+ start_time = current_time
287
+
288
+ except Exception as e:
289
+ print(f"Claude API error: {str(e)}")
290
+ raise e
291
+
292
+ async def try_openai_api(openai_messages):
293
+ try:
294
+ stream = openai_client.chat.completions.create(
295
+ model="gpt-4o",
296
+ messages=openai_messages,
297
+ stream=True,
298
+ max_tokens=4096,
299
+ temperature=0.7
300
+ )
301
+
302
+ collected_content = ""
303
+ for chunk in stream:
304
+ if chunk.choices[0].delta.content is not None:
305
+ collected_content += chunk.choices[0].delta.content
306
+ yield collected_content
307
+
308
+ except Exception as e:
309
+ print(f"OpenAI API error: {str(e)}")
310
+ raise e
311
+
312
+ class Demo:
313
+ def __init__(self):
314
+ pass
315
+
316
+ async def generation_code(self, query: Optional[str], _setting: Dict[str, str]):
317
+ if not query or query.strip() == '':
318
+ query = get_random_placeholder()
319
+
320
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ์ด ํ•„์š”ํ•œ์ง€ ํ™•์ธ
321
+ needs_image = '์ด๋ฏธ์ง€' in query or '๊ทธ๋ฆผ' in query or 'image' in query.lower()
322
+ image_prompt = None
323
+
324
+ # ์ด๋ฏธ์ง€ ํ”„๋กฌํ”„ํŠธ ์ถ”์ถœ
325
+ if needs_image:
326
+ for keyword in ['์ด๋ฏธ์ง€:', '๊ทธ๋ฆผ:', 'image:']:
327
+ if keyword in query.lower():
328
+ image_prompt = query.split(keyword)[1].strip()
329
+ break
330
+ if not image_prompt:
331
+ image_prompt = query # ๋ช…์‹œ์  ํ”„๋กฌํ”„ํŠธ๊ฐ€ ์—†์œผ๋ฉด ์ „์ฒด ์ฟผ๋ฆฌ ์‚ฌ์šฉ
332
+
333
+ messages = [{'role': Role.SYSTEM, 'content': _setting['system']}]
334
+ messages.append({'role': Role.USER, 'content': query})
335
+
336
+ system_message = messages[0]['content']
337
+ claude_messages = [{"role": "user", "content": query}]
338
+ openai_messages = [
339
+ {"role": "system", "content": system_message},
340
+ {"role": "user", "content": query}
341
+ ]
342
+
343
+ try:
344
+ yield [
345
+ "",
346
+ None,
347
+ gr.update(active_key="loading"),
348
+ gr.update(open=True)
349
+ ]
350
+ await asyncio.sleep(0)
351
+
352
+ collected_content = None
353
+ try:
354
+ async for content in try_claude_api(system_message, claude_messages):
355
+ yield [
356
+ "",
357
+ None,
358
+ gr.update(active_key="loading"),
359
+ gr.update(open=True)
360
+ ]
361
+ await asyncio.sleep(0)
362
+ collected_content = content
363
+
364
+ except Exception as claude_error:
365
+ print(f"Falling back to OpenAI API due to Claude error: {str(claude_error)}")
366
+
367
+ async for content in try_openai_api(openai_messages):
368
+ yield [
369
+ "",
370
+ None,
371
+ gr.update(active_key="loading"),
372
+ gr.update(open=True)
373
+ ]
374
+ await asyncio.sleep(0)
375
+ collected_content = content
376
+
377
+ if collected_content:
378
+ # ์ด๋ฏธ์ง€ ์ƒ์„ฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ
379
+ if needs_image and image_prompt:
380
+ try:
381
+ print(f"Generating image for prompt: {image_prompt}")
382
+ # FLUX ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ์ƒ์„ฑ
383
+ if pipe is not None:
384
+ image = generate_image(
385
+ prompt=image_prompt,
386
+ height=512,
387
+ width=512,
388
+ steps=8,
389
+ scales=3.5,
390
+ seed=random.randint(1, 10000)
391
+ )
392
+
393
+ # ์ด๋ฏธ์ง€๋ฅผ Base64๋กœ ์ธ์ฝ”๋”ฉ
394
+ buffered = BytesIO()
395
+ image.save(buffered, format="PNG")
396
+ img_str = base64.b64encode(buffered.getvalue()).decode()
397
+
398
+ # HTML์— ์ด๋ฏธ์ง€ ์ถ”๊ฐ€
399
+ image_html = f'''
400
+ <div class="generated-image" style="margin: 20px 0; text-align: center;">
401
+ <h3 style="color: #333; margin-bottom: 10px;">Generated Image:</h3>
402
+ <img src="data:image/png;base64,{img_str}"
403
+ style="max-width: 100%;
404
+ border-radius: 10px;
405
+ box-shadow: 0 4px 8px rgba(0,0,0,0.1);">
406
+ <p style="color: #666; margin-top: 10px; font-style: italic;">
407
+ Prompt: {html.escape(image_prompt)}
408
+ </p>
409
+ </div>
410
+ '''
411
+
412
+ # HTML ์‘๋‹ต์— ์ด๋ฏธ์ง€ ์‚ฝ์ž…
413
+ if '```html' in collected_content:
414
+ # HTML ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด๋ถ€์— ์ด๋ฏธ์ง€ ์ถ”๊ฐ€
415
+ collected_content = collected_content.replace('```html\n', f'```html\n{image_html}')
416
+ else:
417
+ # HTML ์ฝ”๋“œ ๋ธ”๋ก์œผ๋กœ ๊ฐ์‹ธ์„œ ์ด๋ฏธ์ง€ ์ถ”๊ฐ€
418
+ collected_content = f'```html\n{image_html}\n```\n{collected_content}'
419
+
420
+ print("Image generation successful")
421
+ else:
422
+ raise Exception("FLUX model not initialized")
423
+
424
+ except Exception as e:
425
+ print(f"Image generation error: {str(e)}")
426
+ error_message = f'''
427
+ <div style="color: #ff4d4f; padding: 10px; margin: 10px 0;
428
+ border-left: 4px solid #ff4d4f; background: #fff2f0;">
429
+ <p>Failed to generate image: {str(e)}</p>
430
+ </div>
431
+ '''
432
+ if '```html' in collected_content:
433
+ collected_content = collected_content.replace('```html\n', f'```html\n{error_message}')
434
+ else:
435
+ collected_content = f'```html\n{error_message}\n```\n{collected_content}'
436
+
437
+ # ์ตœ์ข… ๊ฒฐ๊ณผ ํ‘œ์‹œ
438
+ yield [
439
+ collected_content,
440
+ send_to_sandbox(remove_code_block(collected_content)),
441
+ gr.update(active_key="render"),
442
+ gr.update(open=False)
443
+ ]
444
+ else:
445
+ raise ValueError("No content was generated from either API")
446
+
447
+ except Exception as e:
448
+ print(f"Error details: {str(e)}")
449
+ raise ValueError(f'Error calling APIs: {str(e)}')
450
+
451
+ def clear_history(self):
452
+ return []
453
+
454
+ def remove_code_block(text):
455
+ pattern = r'```html\n(.+?)\n```'
456
+ match = re.search(pattern, text, re.DOTALL)
457
+ if match:
458
+ return match.group(1).strip()
459
+ else:
460
+ return text.strip()
461
+
462
+ def history_render(history: History):
463
+ return gr.update(open=True), history
464
+
465
+ def send_to_sandbox(code):
466
+ encoded_html = base64.b64encode(code.encode('utf-8')).decode('utf-8')
467
+ data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
468
+ return f"""
469
+ <iframe
470
+ src="{data_uri}"
471
+ style="width:100%; height:800px; border:none;"
472
+ frameborder="0"
473
+ ></iframe>
474
+ """
475
+ # ๋ฐฐํฌ ๊ด€๋ จ ํ•จ์ˆ˜ ์ถ”๊ฐ€
476
+ def generate_space_name():
477
+ """6์ž๋ฆฌ ๋žœ๋ค ์˜๋ฌธ ์ด๋ฆ„ ์ƒ์„ฑ"""
478
+ letters = string.ascii_lowercase
479
+ return ''.join(random.choice(letters) for i in range(6))
480
+
481
+ def deploy_to_vercel(code: str):
482
+ try:
483
+ token = "A8IFZmgW2cqA4yUNlLPnci0N"
484
+ if not token:
485
+ return "Vercel ํ† ํฐ์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค."
486
+
487
+ # 6์ž๋ฆฌ ์˜๋ฌธ ํ”„๋กœ์ ํŠธ ์ด๋ฆ„ ์ƒ์„ฑ
488
+ project_name = ''.join(random.choice(string.ascii_lowercase) for i in range(6))
489
+
490
+
491
+ # Vercel API ์—”๋“œํฌ์ธํŠธ
492
+ deploy_url = "https://api.vercel.com/v13/deployments"
493
+
494
+ # ํ—ค๋” ์„ค์ •
495
+ headers = {
496
+ "Authorization": f"Bearer {token}",
497
+ "Content-Type": "application/json"
498
+ }
499
+
500
+ # package.json ํŒŒ์ผ ์ƒ์„ฑ
501
+ package_json = {
502
+ "name": project_name,
503
+ "version": "1.0.0",
504
+ "private": True, # true -> True๋กœ ์ˆ˜์ •
505
+ "dependencies": {
506
+ "vite": "^5.0.0"
507
+ },
508
+ "scripts": {
509
+ "dev": "vite",
510
+ "build": "echo 'No build needed' && mkdir -p dist && cp index.html dist/",
511
+ "preview": "vite preview"
512
+ }
513
+ }
514
+
515
+ # ๋ฐฐํฌํ•  ํŒŒ์ผ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ
516
+ files = [
517
+ {
518
+ "file": "index.html",
519
+ "data": code
520
+ },
521
+ {
522
+ "file": "package.json",
523
+ "data": json.dumps(package_json, indent=2) # indent ์ถ”๊ฐ€๋กœ ๊ฐ€๋…์„ฑ ํ–ฅ์ƒ
524
+ }
525
+ ]
526
+
527
+ # ํ”„๋กœ์ ํŠธ ์„ค์ •
528
+ project_settings = {
529
+ "buildCommand": "npm run build",
530
+ "outputDirectory": "dist",
531
+ "installCommand": "npm install",
532
+ "framework": None
533
+ }
534
+
535
+ # ๋ฐฐํฌ ์š”์ฒญ ๋ฐ์ดํ„ฐ
536
+ deploy_data = {
537
+ "name": project_name,
538
+ "files": files,
539
+ "target": "production",
540
+ "projectSettings": project_settings
541
+ }
542
+
543
+
544
+ deploy_response = requests.post(deploy_url, headers=headers, json=deploy_data)
545
+
546
+ if deploy_response.status_code != 200:
547
+ return f"๋ฐฐํฌ ์‹คํŒจ: {deploy_response.text}"
548
+
549
+ # URL ํ˜•์‹ ์ˆ˜์ • - 6์ž๋ฆฌ.vercel.app ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜
550
+ deployment_url = f"{project_name}.vercel.app"
551
+
552
+ time.sleep(5)
553
+
554
+ return f"""๋ฐฐํฌ ์™„๋ฃŒ! <a href="https://{deployment_url}" target="_blank" style="color: #1890ff; text-decoration: underline; cursor: pointer;">https://{deployment_url}</a>"""
555
+
556
+ except Exception as e:
557
+ return f"๋ฐฐํฌ ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}"
558
+
559
+ theme = gr.themes.Soft()
560
+
561
+ def get_random_placeholder():
562
+ return random.choice(DEMO_LIST)['description']
563
+
564
+ def update_placeholder():
565
+ return gr.update(placeholder=get_random_placeholder())
566
+
567
+ def create_main_interface():
568
+ """๋ฉ”์ธ ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ ํ•จ์ˆ˜"""
569
+
570
+ def execute_code(query: str):
571
+ if not query or query.strip() == '':
572
+ return None, gr.update(active_key="empty")
573
+
574
+ try:
575
+ if '```html' in query and '```' in query:
576
+ code = remove_code_block(query)
577
+ else:
578
+ code = query.strip()
579
+
580
+ return send_to_sandbox(code), gr.update(active_key="render")
581
+ except Exception as e:
582
+ print(f"Error executing code: {str(e)}")
583
+ return None, gr.update(active_key="empty")
584
+
585
+ # CSS ํŒŒ์ผ ๋‚ด์šฉ์„ ์ง์ ‘ ์ ์šฉ
586
+ with open('app.css', 'r', encoding='utf-8') as f:
587
+ custom_css = f.read()
588
+
589
+ demo = gr.Blocks(css=custom_css + """
590
+
591
+ .empty-content {
592
+ padding: 40px !important;
593
+ background: #f8f9fa !important;
594
+ border-radius: 10px !important;
595
+ margin: 20px !important;
596
+ }
597
+
598
+ .container {
599
+ background: #f0f0f0;
600
+ min-height: 100vh;
601
+ padding: 20px;
602
+ display: flex;
603
+ justify-content: center;
604
+ align-items: center;
605
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
606
+ }
607
+
608
+ .app-window {
609
+ background: white;
610
+ border-radius: 10px;
611
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
612
+ width: 100%;
613
+ max-width: 1400px;
614
+ overflow: hidden;
615
+ }
616
+
617
+ .window-header {
618
+ background: #f0f0f0;
619
+ padding: 12px 16px;
620
+ display: flex;
621
+ align-items: center;
622
+ border-bottom: 1px solid #e0e0e0;
623
+ }
624
+
625
+ .window-controls {
626
+ display: flex;
627
+ gap: 8px;
628
+ }
629
+
630
+ .control {
631
+ width: 12px;
632
+ height: 12px;
633
+ border-radius: 50%;
634
+ cursor: pointer;
635
+ }
636
+
637
+ .control.close { background: #ff5f57; }
638
+ .control.minimize { background: #febc2e; }
639
+ .control.maximize { background: #28c840; }
640
+
641
+ .window-title {
642
+ flex: 1;
643
+ text-align: center;
644
+ color: #333;
645
+ font-size: 14px;
646
+ font-weight: 500;
647
+ }
648
+
649
+ .main-content {
650
+ display: flex;
651
+ height: calc(100vh - 100px);
652
+ }
653
+
654
+ .left-panel {
655
+ width: 40%;
656
+ border-right: 1px solid #e0e0e0;
657
+ padding: 20px;
658
+ display: flex;
659
+ flex-direction: column;
660
+ }
661
+
662
+ .right-panel {
663
+ width: 60%;
664
+ background: #fff;
665
+ position: relative;
666
+ }
667
+
668
+ .input-area {
669
+ background: #f8f9fa;
670
+ border-radius: 10px;
671
+ padding: 20px;
672
+ margin-top: 20px;
673
+ }
674
+
675
+ .button-group {
676
+ display: flex;
677
+ gap: 10px;
678
+ margin-top: 20px;
679
+ }
680
+
681
+ .custom-button {
682
+ background: #007aff;
683
+ color: white;
684
+ border: none;
685
+ padding: 10px 20px;
686
+ border-radius: 6px;
687
+ cursor: pointer;
688
+ transition: all 0.2s;
689
+ }
690
+
691
+ .custom-button:hover {
692
+ background: #0056b3;
693
+ }
694
+ """, theme=theme)
695
+
696
+
697
+
698
+ with demo:
699
+ with gr.Tabs(elem_classes="main-tabs") as tabs:
700
+ with gr.Tab("Visual AI Assistant", elem_id="mouse-tab", elem_classes="mouse-tab"):
701
+ # SystemPrompt ์„ค์ •์„ ์œ„ํ•œ State ์ถ”๊ฐ€
702
+ setting = gr.State({
703
+ "system": SystemPrompt,
704
+ })
705
+
706
+ with ms.Application() as app:
707
+ with antd.ConfigProvider():
708
+
709
+ with antd.Drawer(open=False, title="AI is Creating...", placement="left", width="750px") as code_drawer:
710
+ gr.HTML("""
711
+ <div class="thinking-container">
712
+ <style>
713
+ .custom-textarea {
714
+ background: #f8f9fa !important;
715
+ border: 1px solid #e0e0e0 !important;
716
+ border-radius: 10px !important;
717
+ padding: 15px !important;
718
+ min-height: 150px !important;
719
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif !important;
720
+ }
721
+
722
+ .custom-textarea:focus {
723
+ border-color: #007aff !important;
724
+ box-shadow: 0 0 0 2px rgba(0,122,255,0.2) !important;
725
+ }
726
+
727
+ .thinking-container {
728
+ text-align: center;
729
+ padding: 20px;
730
+ background: #f8f9fa;
731
+ border-radius: 15px;
732
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
733
+ }
734
+
735
+ .progress-bar {
736
+ width: 100%;
737
+ height: 4px;
738
+ background: #e9ecef;
739
+ border-radius: 4px;
740
+ margin: 20px 0;
741
+ overflow: hidden;
742
+ }
743
+
744
+ .progress-bar-inner {
745
+ width: 30%;
746
+ height: 100%;
747
+ background: linear-gradient(90deg, #007aff, #28c840);
748
+ animation: progress 2s ease-in-out infinite;
749
+ }
750
+
751
+ .thinking-icon {
752
+ font-size: 48px;
753
+ margin: 20px 0;
754
+ animation: bounce 1s ease infinite;
755
+ }
756
+
757
+ .tip-box {
758
+ background: white;
759
+ padding: 20px;
760
+ border-radius: 10px;
761
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
762
+ margin: 20px 0;
763
+ transition: all 0.3s ease;
764
+ }
765
+
766
+ .status-text {
767
+ color: #007aff;
768
+ font-size: 18px;
769
+ margin: 15px 0;
770
+ animation: fade 1.5s ease infinite;
771
+ }
772
+
773
+ .icon-grid {
774
+ display: grid;
775
+ grid-template-columns: repeat(4, 1fr);
776
+ gap: 15px;
777
+ margin: 20px 0;
778
+ }
779
+
780
+ .icon-item {
781
+ padding: 10px;
782
+ background: rgba(0,122,255,0.1);
783
+ border-radius: 8px;
784
+ animation: pulse 2s ease infinite;
785
+ }
786
+
787
+ @keyframes progress {
788
+ 0% { transform: translateX(-100%); }
789
+ 100% { transform: translateX(400%); }
790
+ }
791
+
792
+ @keyframes bounce {
793
+ 0%, 100% { transform: translateY(0); }
794
+ 50% { transform: translateY(-10px); }
795
+ }
796
+
797
+ @keyframes fade {
798
+ 0%, 100% { opacity: 1; }
799
+ 50% { opacity: 0.6; }
800
+ }
801
+
802
+ @keyframes pulse {
803
+ 0% { transform: scale(1); }
804
+ 50% { transform: scale(1.05); }
805
+ 100% { transform: scale(1); }
806
+ }
807
+ </style>
808
+
809
+ <div class="thinking-icon">๐ŸŽจ</div>
810
+ <div class="status-text">Creating Your Visualization...</div>
811
+ <div class="progress-bar">
812
+ <div class="progress-bar-inner"></div>
813
+ </div>
814
+ <div class="icon-grid">
815
+ <div class="icon-item">๐Ÿ“Š</div>
816
+ <div class="icon-item">๐ŸŽฏ</div>
817
+ <div class="icon-item">๐Ÿ’ก</div>
818
+ <div class="icon-item">โœจ</div>
819
+ </div>
820
+ <div class="tip-box">
821
+ <h3 style="color: #007aff; margin-bottom: 10px;">Did You Know?</h3>
822
+ <div id="tip-content" style="font-size: 16px; line-height: 1.6;"></div>
823
+ </div>
824
+
825
+ <script>
826
+ const tips = [
827
+ "MOUSE-I is creating responsive and interactive visualizations! ๐Ÿ“Š",
828
+ "We're applying modern design principles for the best user experience! ๐ŸŽจ",
829
+ "Your content will be optimized for all devices! ๐Ÿ“ฑ",
830
+ "Adding engaging animations to bring your data to life! โœจ",
831
+ "Crafting a beautiful presentation just for you! ๐ŸŽฏ",
832
+ "Implementing interactive elements for better engagement! ๐ŸŽฎ",
833
+ "Optimizing colors and layout for visual appeal! ๐ŸŽช",
834
+ "Creating smooth transitions and animations! ๐ŸŒŸ"
835
+ ];
836
+
837
+ function updateTip() {
838
+ const tipElement = document.getElementById('tip-content');
839
+ if (tipElement) {
840
+ const randomTip = tips[Math.floor(Math.random() * tips.length)];
841
+ tipElement.innerHTML = randomTip;
842
+ tipElement.style.opacity = 0;
843
+ setTimeout(() => {
844
+ tipElement.style.transition = 'opacity 0.5s ease';
845
+ tipElement.style.opacity = 1;
846
+ }, 100);
847
+ }
848
+ }
849
+
850
+ updateTip();
851
+ setInterval(updateTip, 3000);
852
+ </script>
853
+ </div>
854
+ """)
855
+ code_output = legacy.Markdown(visible=False)
856
+
857
+
858
+ # ๋ฉ”์ธ ์ปจํ…์ธ ๋ฅผ ์œ„ํ•œ Row
859
+ with antd.Row(gutter=[32, 12]) as layout:
860
+ # ์ขŒ์ธก ํŒจ๋„
861
+ with antd.Col(span=24, md=8):
862
+ with antd.Flex(vertical=True, gap="middle", wrap=True):
863
+ # macOS ์Šคํƒ€์ผ ์œˆ๋„์šฐ ํ—ค๋”
864
+ header = gr.HTML("""
865
+ <div class="window-frame">
866
+ <div class="window-header">
867
+ <div class="window-controls">
868
+ <div class="control close"></div>
869
+ <div class="control minimize"></div>
870
+ <div class="control maximize"></div>
871
+ </div>
872
+ <div class="window-title">
873
+ <div class="window-address">
874
+ <div class="secure-icon">๐Ÿ”’</div>
875
+ <div class="url-bar">https://VIDraft-mouse-chat.hf.space</div>
876
+ </div>
877
+ </div>
878
+ </div>
879
+ <div class="app-content">
880
+ <img src="data:image/gif;base64,{}" width="360px" />
881
+ <h1 class="app-title">MOUSE-Chat Visual AI</h1>
882
+ <p class="app-description">Creates visualized web pages from text input, and when you include keywords like "image:", "๊ทธ๋ฆผ:", or "image:" in your input, it automatically generates AI images based on the description and incorporates them into the web page.
883
+ Use the "Generate" button for basic creation, "Enhance" button for prompt improvement, "Share" button to deploy results to the web, and input like "image: a dog playing in the park" to create results containing both text and generated images.</p>
884
+ </div>
885
+ </div>
886
+ """.format(get_image_base64('mouse.gif')))
887
+
888
+ # ์ž…๋ ฅ ์˜์—ญ
889
+ input = antd.InputTextarea(
890
+ size="large",
891
+ allow_clear=True,
892
+ placeholder=get_random_placeholder(),
893
+ elem_classes="custom-textarea" # style ๋Œ€์‹  class ์‚ฌ์šฉ
894
+
895
+ )
896
+
897
+ # ๋ฒ„ํŠผ ๊ทธ๋ฃน
898
+ with antd.Flex(gap="small", justify="flex-start"):
899
+ btn = antd.Button(
900
+ "Generate",
901
+ type="primary",
902
+ size="large",
903
+ elem_classes="generate-btn"
904
+ )
905
+ boost_btn = antd.Button(
906
+ "Enhance",
907
+ type="default",
908
+ size="large",
909
+ elem_classes="enhance-btn"
910
+ )
911
+ deploy_btn = antd.Button(
912
+ "Share",
913
+ type="default",
914
+ size="large",
915
+ elem_classes="share-btn"
916
+ )
917
+
918
+
919
+ deploy_result = gr.HTML(
920
+ label="Share Result",
921
+ elem_classes="deploy-result"
922
+ )
923
+
924
+ # ์šฐ์ธก ํŒจ๋„
925
+ with antd.Col(span=24, md=16):
926
+ with ms.Div(elem_classes="right_panel"):
927
+ # macOS ์Šคํƒ€์ผ ์œˆ๋„์šฐ ํ—ค๋”
928
+ gr.HTML("""
929
+ <div class="window-frame">
930
+ <div class="window-header">
931
+ <div class="window-controls">
932
+ <div class="control close"></div>
933
+ <div class="control minimize"></div>
934
+ <div class="control maximize"></div>
935
+ </div>
936
+ <div class="window-title">Preview</div>
937
+ </div>
938
+ </div>
939
+ """)
940
+
941
+ # ํƒญ ์ปจํ…์ธ 
942
+ with antd.Tabs(active_key="empty", render_tab_bar="() => null") as state_tab:
943
+ with antd.Tabs.Item(key="empty"):
944
+ empty = antd.Empty(
945
+ description="Enter your question to begin",
946
+
947
+ elem_classes="right_content empty-content" # style ๋Œ€์‹  class ์‚ฌ์šฉ
948
+
949
+ )
950
+
951
+ with antd.Tabs.Item(key="loading"):
952
+ loading = antd.Spin(
953
+ True,
954
+ tip="Creating visual presentation...",
955
+ size="large",
956
+ elem_classes="right_content"
957
+ )
958
+
959
+ with antd.Tabs.Item(key="render"):
960
+ sandbox = gr.HTML(elem_classes="html_content")
961
+
962
+
963
+ btn.click(
964
+ demo_instance.generation_code,
965
+ inputs=[input, setting], # setting์ด ์ด์ œ ์ •์˜๋จ
966
+ outputs=[code_output, sandbox, state_tab, code_drawer]
967
+ ).then(
968
+ fn=update_placeholder,
969
+ inputs=[],
970
+ outputs=[input]
971
+ )
972
+
973
+
974
+ boost_btn.click(
975
+ fn=handle_boost,
976
+ inputs=[input],
977
+ outputs=[input, state_tab]
978
+ )
979
+
980
+ deploy_btn.click(
981
+ fn=lambda code: deploy_to_vercel(remove_code_block(code)) if code else "No code to share.",
982
+ inputs=[code_output],
983
+ outputs=[deploy_result]
984
+ )
985
+
986
+ gr.HTML("""
987
+ <style>
988
+ .generate-btn {
989
+ background: #007aff !important;
990
+ border-radius: 8px !important;
991
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1) !important;
992
+ }
993
+
994
+ .enhance-btn {
995
+ border-radius: 8px !important;
996
+ border: 1px solid #007aff !important;
997
+ color: #007aff !important;
998
+ }
999
+
1000
+ .share-btn {
1001
+ border-radius: 8px !important;
1002
+ border: 1px solid #28c840 !important;
1003
+ color: #28c840 !important;
1004
+ }
1005
+
1006
+ /* hover ํšจ๊ณผ */
1007
+ .generate-btn:hover {
1008
+ background: #0056b3 !important;
1009
+ }
1010
+
1011
+ .enhance-btn:hover {
1012
+ background: rgba(0,122,255,0.1) !important;
1013
+ }
1014
+
1015
+ .share-btn:hover {
1016
+ background: rgba(40,200,64,0.1) !important;
1017
+ }
1018
+
1019
+ .app-content {
1020
+ padding: 20px;
1021
+ text-align: center;
1022
+ }
1023
+
1024
+ .app-title {
1025
+ font-size: 24px;
1026
+ color: #333;
1027
+ margin: 20px 0 10px;
1028
+ font-weight: 600;
1029
+ }
1030
+
1031
+ .app-description {
1032
+ color: #666;
1033
+ font-size: 14px;
1034
+ margin-bottom: 30px;
1035
+ }
1036
+
1037
+ .deploy-result {
1038
+ margin-top: 20px;
1039
+ padding: 15px;
1040
+ background: #f8f9fa;
1041
+ border-radius: 8px;
1042
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif;
1043
+ }
1044
+
1045
+ .deploy-result a {
1046
+ color: #007aff;
1047
+ text-decoration: none;
1048
+ font-weight: 500;
1049
+ }
1050
+
1051
+ .deploy-result a:hover {
1052
+ text-decoration: underline;
1053
+ }
1054
+
1055
+ /* ๋ฐ˜์‘ํ˜• ๋””์ž์ธ์„ ์œ„ํ•œ ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ */
1056
+ @media (max-width: 768px) {
1057
+ .window-frame {
1058
+ border-radius: 0;
1059
+ }
1060
+
1061
+ .left-panel, .right-panel {
1062
+ width: 100%;
1063
+ }
1064
+
1065
+ .main-content {
1066
+ flex-direction: column;
1067
+ }
1068
+ }
1069
+ </style>
1070
+ """)
1071
+
1072
+ return demo
1073
+
1074
+ # ๋ฉ”์ธ ์‹คํ–‰ ๋ถ€๋ถ„
1075
+ if __name__ == "__main__":
1076
+ try:
1077
+ demo_instance = Demo() # Demo ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
1078
+ demo = create_main_interface() # ์ธํ„ฐํŽ˜์ด์Šค ์ƒ์„ฑ
1079
+ demo.queue(
1080
+ default_concurrency_limit=20, # concurrency_count ๋Œ€์‹  default_concurrency_limit ์‚ฌ์šฉ
1081
+ status_update_rate=10,
1082
+ api_open=False
1083
+ ).launch(
1084
+ server_name="0.0.0.0",
1085
+ server_port=7860,
1086
+ share=False,
1087
+ debug=False
1088
+ )
1089
+ except Exception as e:
1090
+ print(f"Initialization error: {e}")
1091
+ raise
config (2).py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # DEMO_LIST ์ •์˜
2
+ DEMO_LIST = [
3
+ {
4
+ "description": "์ฃผ์‹ ์‹œ์žฅ์˜ ์ตœ๊ทผ 10๋…„๊ฐ„ ๋ณ€๋™์„ฑ์„ ์ฐจํŠธ์™€ ๊ทธ๋ž˜ํ”„๋กœ ์‹œ๊ฐํ™”ํ•˜์—ฌ ๋ถ„์„ํ•ด์ฃผ์„ธ์š”. Show stock market volatility analysis for the past 10 years using interactive charts and graphs."
5
+ },
6
+ {
7
+ "description": "์„ธ๊ณ„ ์ฃผ์š” ๋„์‹œ์˜ ๋Œ€๊ธฐ ์˜ค์—ผ๋„๋ฅผ ๋น„๊ตํ•˜๋Š” ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”. Create an air quality comparison dashboard for major global cities."
8
+ },
9
+ {
10
+ "description": "ํ•œ๊ตญ์˜ ์—ฐ๋ น๋ณ„ ์ธ๊ตฌ ๊ตฌ์กฐ ๋ณ€ํ™”๋ฅผ ํ”ผ๋ผ๋ฏธ๋“œ ์ฐจํŠธ๋กœ ์‹œ๊ฐํ™”ํ•ด์ฃผ์„ธ์š”. Visualize Korea's demographic changes using population pyramid charts."
11
+ },
12
+ {
13
+ "description": "๊ธ€๋กœ๋ฒŒ IT ๊ธฐ์—…๋“ค์˜ ์‹œ๊ฐ€์ด์•ก ๋ณ€ํ™”๋ฅผ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋ฐ” ์ฐจํŠธ๋กœ ๋ณด์—ฌ์ฃผ์„ธ์š”. Show market cap changes of global tech companies with animated bar charts."
14
+ },
15
+ {
16
+ "description": "์ „์„ธ๊ณ„ ์ฝ”๋กœ๋‚˜19 ํ™•์ง„์ž ์ถ”์ด๋ฅผ ํžˆํŠธ๋งต๊ณผ ๋ผ์ธ ์ฐจํŠธ๋กœ ๋ถ„์„ํ•ด์ฃผ์„ธ์š”. Analyze global COVID-19 trends using heatmaps and line charts."
17
+ },
18
+ {
19
+ "description": "์ฃผ์š” ์•”ํ˜ธํ™”ํ๋“ค์˜ ๊ฐ€๊ฒฉ ๋ณ€๋™์„ฑ์„ ์‹ค์‹œ๊ฐ„ ์ฐจํŠธ๋กœ ์‹œ๊ฐํ™”ํ•ด์ฃผ์„ธ์š”. Visualize cryptocurrency price volatility with real-time charts."
20
+ },
21
+ {
22
+ "description": "์„ธ๊ณ„ ๊ฐ๊ตญ์˜ ๊ต์œก ์ˆ˜์ค€๊ณผ GDP ๊ด€๊ณ„๋ฅผ ์‚ฐ์ ๋„๋กœ ๋ถ„์„ํ•ด์ฃผ์„ธ์š”. Analyze the relationship between education levels and GDP using scatter plots."
23
+ },
24
+ {
25
+ "description": "ํ•œ๊ตญ์˜ ๋ถ€๋™์‚ฐ ๊ฐ€๊ฒฉ ๋ณ€๋™ ์ถ”์ด๋ฅผ ์ง€์—ญ๋ณ„๋กœ ๋น„๊ต ๋ถ„์„ํ•ด์ฃผ์„ธ์š”. Compare real estate price trends across different regions in Korea."
26
+ },
27
+ {
28
+ "description": "๊ธ€๋กœ๋ฒŒ ๊ธฐํ›„ ๋ณ€ํ™”๊ฐ€ ๋†์ž‘๋ฌผ ์ƒ์‚ฐ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์„ ์‹œ๊ฐํ™”ํ•ด์ฃผ์„ธ์š”. Visualize the impact of global climate change on crop production."
29
+ },
30
+ {
31
+ "description": "์ฃผ์š” ์Šคํฌ์ธ  ๊ตฌ๋‹จ๋“ค์˜ ์ˆ˜์ต๊ตฌ์กฐ๋ฅผ ๋„๋„› ์ฐจํŠธ๋กœ ๋น„๊ตํ•ด์ฃผ์„ธ์š”. Compare revenue structures of major sports teams using donut charts."
32
+ },
33
+ {
34
+ "description": "์„ธ๊ณ„ ์—๋„ˆ์ง€ ์†Œ๋น„ ๊ตฌ์กฐ์˜ ๋ณ€ํ™”๋ฅผ ์ŠคํŠธ๋ฆผ ๊ทธ๋ž˜ํ”„๋กœ ๋ณด์—ฌ์ฃผ์„ธ์š”. Show changes in global energy consumption using stream graphs."
35
+ },
36
+ {
37
+ "description": "์†Œ์…œ ๋ฏธ๋””์–ด ํ”Œ๋žซํผ๋“ค์˜ ์‚ฌ์šฉ์ž ํ†ต๊ณ„๋ฅผ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์ฐจํŠธ๋กœ ๋ถ„์„ํ•ด์ฃผ์„ธ์š”. Analyze social media platform statistics with interactive charts."
38
+ },
39
+ {
40
+ "description": "์ „๊ธฐ์ฐจ ์‹œ์žฅ์˜ ์„ฑ์žฅ ์ถ”์ด๋ฅผ ๋‹ค์–‘ํ•œ ์ฐจํŠธ๋กœ ์‹œ๊ฐํ™”ํ•ด์ฃผ์„ธ์š”. Visualize electric vehicle market growth trends with various charts."
41
+ },
42
+ {
43
+ "description": "์„ธ๊ณ„ ์ฃผ์š” ๋„์‹œ์˜ ์ƒํ™œ๋น„ ์ง€์ˆ˜๋ฅผ ๋น„๊ตํ•˜๋Š” ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”. Create a cost of living index dashboard for major global cities."
44
+ },
45
+ {
46
+ "description": "AI/ML ๊ธฐ์ˆ  ๋ฐœ์ „ ํƒ€์ž„๋ผ์ธ์„ ์ธํ„ฐ๋ž™ํ‹ฐ๋ธŒ ์‹œ๊ฐํ™”๋กœ ๋ณด์—ฌ์ฃผ์„ธ์š”. Show AI/ML technology evolution timeline with interactive visualization."
47
+ }
48
+ ]
mouse (2).gif ADDED

Git LFS Details

  • SHA256: 55e49ab15b482f04e0da028f70ec04b331ac580ea942e0dfc828af3790da84d6
  • Pointer size: 132 Bytes
  • Size of remote file: 1.24 MB
requirements (7).txt ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ requests
2
+ gradio
3
+ pandas
4
+ selenium
5
+ Pillow
6
+ huggingface_hub
7
+ torch
8
+ dashscope
9
+ sentencepiece
10
+ modelscope_studio~=1.0.0b
11
+ anthropic
12
+ transformers
13
+ accelerate
14
+ openai
15
+
16
+ accelerate
17
+ diffusers==0.30.0
18
+ invisible_watermark
19
+ torch
20
+ transformers==4.43.3
21
+ xformers
22
+ sentencepiece
23
+ peft