lulavc commited on
Commit
112ff7a
·
verified ·
1 Parent(s): fb81eeb

v2.3: Multilingual support - EN/ES/PT/AR/HI with RTL and font support

Browse files
Files changed (1) hide show
  1. app.py +365 -3
app.py CHANGED
@@ -1,4 +1,4 @@
1
- """Z-Image-Turbo v2.0 - Optimized for ZeroGPU Best Practices"""
2
 
3
  import os
4
  import logging
@@ -8,7 +8,7 @@ import gradio as gr
8
  import requests
9
  import io
10
  import base64
11
- from typing import Tuple, Optional
12
  from PIL import Image
13
  from diffusers import DiffusionPipeline, ZImageImg2ImgPipeline
14
  from openai import OpenAI
@@ -17,6 +17,300 @@ from openai import OpenAI
17
  logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
18
  logger = logging.getLogger(__name__)
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  # Constants (replaces magic numbers)
21
  MIN_IMAGE_DIM = 512
22
  MAX_IMAGE_DIM = 2048
@@ -594,6 +888,9 @@ def transform(input_image: Optional[Image.Image], full_prompt: str, polished_dis
594
  return None, seed
595
 
596
  css = r"""
 
 
 
597
  :root {
598
  --bg-primary: #0c0c0e;
599
  --bg-secondary: #141416;
@@ -621,8 +918,32 @@ css = r"""
621
  --radius-md: 12px;
622
  --radius-lg: 16px;
623
  --transition: 0.2s ease;
 
 
 
 
624
  }
625
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
626
  .gradio-container {
627
  background: var(--bg-primary) !important;
628
  min-height: 100vh;
@@ -1007,8 +1328,19 @@ dark_theme = gr.themes.Base(
1007
  )
1008
 
1009
  with gr.Blocks(title="Z Image Turbo", css=css, theme=dark_theme) as demo:
 
 
 
 
 
 
 
 
 
 
 
1010
  gr.HTML("""
1011
- <div style="text-align: center; padding: 24px 16px 16px 16px;">
1012
  <h1 style="background: linear-gradient(135deg, #818cf8 0%, #a78bfa 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: clamp(1.5rem, 4vw, 2.2rem); margin-bottom: 8px; font-weight: 700;">
1013
  Z Image Turbo + GLM-4.6V
1014
  </h1>
@@ -1019,6 +1351,36 @@ with gr.Blocks(title="Z Image Turbo", css=css, theme=dark_theme) as demo:
1019
  If you liked it, please like it. Thank you!
1020
  </p>
1021
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1022
  """)
1023
 
1024
  with gr.Tabs():
 
1
+ """Z-Image-Turbo v2.3 - Multilingual Support"""
2
 
3
  import os
4
  import logging
 
8
  import requests
9
  import io
10
  import base64
11
+ from typing import Tuple, Optional, Dict
12
  from PIL import Image
13
  from diffusers import DiffusionPipeline, ZImageImg2ImgPipeline
14
  from openai import OpenAI
 
17
  logging.basicConfig(level=logging.INFO, format='[%(levelname)s] %(message)s')
18
  logger = logging.getLogger(__name__)
19
 
20
+ # =============================================================================
21
+ # MULTILINGUAL SUPPORT
22
+ # =============================================================================
23
+ LANGUAGES = ["English", "Español", "Português (BR)", "العربية", "हिंदी"]
24
+
25
+ TRANSLATIONS: Dict[str, Dict[str, str]] = {
26
+ "English": {
27
+ # Header
28
+ "title": "Z Image Turbo + GLM-4.6V",
29
+ "subtitle": "AI Image Generation & Transformation powered by DeepSeek Reasoning",
30
+ "like_msg": "If you liked it, please like it. Thank you!",
31
+ # Tabs
32
+ "tab_generate": "Generate",
33
+ "tab_assistant": "AI Assistant",
34
+ "tab_transform": "Transform",
35
+ # Generate tab
36
+ "prompt": "Prompt",
37
+ "prompt_placeholder": "Describe your image in detail...",
38
+ "polish_checkbox": "Prompt+ by deepseek-reasoner",
39
+ "style": "Style",
40
+ "aspect_ratio": "Aspect Ratio",
41
+ "advanced_settings": "Advanced Settings",
42
+ "steps": "Steps",
43
+ "seed": "Seed",
44
+ "random_seed": "Random Seed",
45
+ "generate_btn": "Generate",
46
+ "generated_image": "Generated Image",
47
+ "enhanced_prompt": "Enhanced Prompt",
48
+ "seed_used": "Seed Used",
49
+ "share": "Share",
50
+ # AI Assistant tab
51
+ "ai_description": "**AI-Powered Prompt Generator** - Upload an image, analyze it with GLM-4.6V, then generate optimized prompts.",
52
+ "upload_image": "Upload Image",
53
+ "analyze_btn": "Analyze Image",
54
+ "image_description": "Image Description",
55
+ "changes_request": "What changes do you want?",
56
+ "changes_placeholder": "e.g., 'watercolor style' or 'dramatic sunset lighting'",
57
+ "target_style": "Target Style",
58
+ "generate_prompt_btn": "Generate Prompt",
59
+ "generated_prompt": "Generated Prompt",
60
+ "send_to_transform": "Send to Transform Tab",
61
+ "how_to_use": "How to Use",
62
+ "how_to_use_content": """1. **Upload** an image and click "Analyze Image"
63
+ 2. **Describe** the changes you want
64
+ 3. **Generate** an optimized prompt
65
+ 4. **Send** to Transform tab to apply changes""",
66
+ # Transform tab
67
+ "transform_description": "**Transform your image** - Upload and describe the transformation. Lower strength = subtle, higher = dramatic.",
68
+ "transformation_prompt": "Transformation Prompt",
69
+ "transform_placeholder": "e.g., 'oil painting style, vibrant colors'",
70
+ "strength": "Strength",
71
+ "transform_btn": "Transform",
72
+ "transformed_image": "Transformed Image",
73
+ "example_prompts": "Example Prompts",
74
+ # Footer
75
+ "models": "Models",
76
+ "by": "by",
77
+ },
78
+ "Español": {
79
+ "title": "Z Image Turbo + GLM-4.6V",
80
+ "subtitle": "Generación y Transformación de Imágenes con IA impulsado por DeepSeek Reasoning",
81
+ "like_msg": "Si te gustó, por favor dale me gusta. ¡Gracias!",
82
+ "tab_generate": "Generar",
83
+ "tab_assistant": "Asistente IA",
84
+ "tab_transform": "Transformar",
85
+ "prompt": "Prompt",
86
+ "prompt_placeholder": "Describe tu imagen en detalle...",
87
+ "polish_checkbox": "Prompt+ por deepseek-reasoner",
88
+ "style": "Estilo",
89
+ "aspect_ratio": "Relación de Aspecto",
90
+ "advanced_settings": "Configuración Avanzada",
91
+ "steps": "Pasos",
92
+ "seed": "Semilla",
93
+ "random_seed": "Semilla Aleatoria",
94
+ "generate_btn": "Generar",
95
+ "generated_image": "Imagen Generada",
96
+ "enhanced_prompt": "Prompt Mejorado",
97
+ "seed_used": "Semilla Usada",
98
+ "share": "Compartir",
99
+ "ai_description": "**Generador de Prompts con IA** - Sube una imagen, analízala con GLM-4.6V, y genera prompts optimizados.",
100
+ "upload_image": "Subir Imagen",
101
+ "analyze_btn": "Analizar Imagen",
102
+ "image_description": "Descripción de la Imagen",
103
+ "changes_request": "¿Qué cambios quieres?",
104
+ "changes_placeholder": "ej., 'estilo acuarela' o 'iluminación de atardecer dramático'",
105
+ "target_style": "Estilo Objetivo",
106
+ "generate_prompt_btn": "Generar Prompt",
107
+ "generated_prompt": "Prompt Generado",
108
+ "send_to_transform": "Enviar a Transformar",
109
+ "how_to_use": "Cómo Usar",
110
+ "how_to_use_content": """1. **Sube** una imagen y haz clic en "Analizar Imagen"
111
+ 2. **Describe** los cambios que quieres
112
+ 3. **Genera** un prompt optimizado
113
+ 4. **Envía** a la pestaña Transformar para aplicar cambios""",
114
+ "transform_description": "**Transforma tu imagen** - Sube y describe la transformación. Menor fuerza = sutil, mayor = dramático.",
115
+ "transformation_prompt": "Prompt de Transformación",
116
+ "transform_placeholder": "ej., 'estilo pintura al óleo, colores vibrantes'",
117
+ "strength": "Fuerza",
118
+ "transform_btn": "Transformar",
119
+ "transformed_image": "Imagen Transformada",
120
+ "example_prompts": "Prompts de Ejemplo",
121
+ "models": "Modelos",
122
+ "by": "por",
123
+ },
124
+ "Português (BR)": {
125
+ "title": "Z Image Turbo + GLM-4.6V",
126
+ "subtitle": "Geração e Transformação de Imagens com IA alimentado por DeepSeek Reasoning",
127
+ "like_msg": "Se você gostou, por favor curta. Obrigado!",
128
+ "tab_generate": "Gerar",
129
+ "tab_assistant": "Assistente IA",
130
+ "tab_transform": "Transformar",
131
+ "prompt": "Prompt",
132
+ "prompt_placeholder": "Descreva sua imagem em detalhes...",
133
+ "polish_checkbox": "Prompt+ por deepseek-reasoner",
134
+ "style": "Estilo",
135
+ "aspect_ratio": "Proporção",
136
+ "advanced_settings": "Configurações Avançadas",
137
+ "steps": "Passos",
138
+ "seed": "Semente",
139
+ "random_seed": "Semente Aleatória",
140
+ "generate_btn": "Gerar",
141
+ "generated_image": "Imagem Gerada",
142
+ "enhanced_prompt": "Prompt Aprimorado",
143
+ "seed_used": "Semente Usada",
144
+ "share": "Compartilhar",
145
+ "ai_description": "**Gerador de Prompts com IA** - Envie uma imagem, analise com GLM-4.6V, e gere prompts otimizados.",
146
+ "upload_image": "Enviar Imagem",
147
+ "analyze_btn": "Analisar Imagem",
148
+ "image_description": "Descrição da Imagem",
149
+ "changes_request": "Quais mudanças você quer?",
150
+ "changes_placeholder": "ex., 'estilo aquarela' ou 'iluminação dramática de pôr do sol'",
151
+ "target_style": "Estilo Alvo",
152
+ "generate_prompt_btn": "Gerar Prompt",
153
+ "generated_prompt": "Prompt Gerado",
154
+ "send_to_transform": "Enviar para Transformar",
155
+ "how_to_use": "Como Usar",
156
+ "how_to_use_content": """1. **Envie** uma imagem e clique em "Analisar Imagem"
157
+ 2. **Descreva** as mudanças que você quer
158
+ 3. **Gere** um prompt otimizado
159
+ 4. **Envie** para a aba Transformar para aplicar mudanças""",
160
+ "transform_description": "**Transforme sua imagem** - Envie e descreva a transformação. Menor força = sutil, maior = dramático.",
161
+ "transformation_prompt": "Prompt de Transformação",
162
+ "transform_placeholder": "ex., 'estilo pintura a óleo, cores vibrantes'",
163
+ "strength": "Força",
164
+ "transform_btn": "Transformar",
165
+ "transformed_image": "Imagem Transformada",
166
+ "example_prompts": "Prompts de Exemplo",
167
+ "models": "Modelos",
168
+ "by": "por",
169
+ },
170
+ "العربية": {
171
+ "title": "Z Image Turbo + GLM-4.6V",
172
+ "subtitle": "توليد وتحويل الصور بالذكاء الاصطناعي مدعوم من DeepSeek Reasoning",
173
+ "like_msg": "إذا أعجبك، يرجى الإعجاب. شكراً لك!",
174
+ "tab_generate": "توليد",
175
+ "tab_assistant": "مساعد الذكاء الاصطناعي",
176
+ "tab_transform": "تحويل",
177
+ "prompt": "الوصف",
178
+ "prompt_placeholder": "صف صورتك بالتفصيل...",
179
+ "polish_checkbox": "تحسين+ بواسطة deepseek-reasoner",
180
+ "style": "النمط",
181
+ "aspect_ratio": "نسبة العرض",
182
+ "advanced_settings": "إعدادات متقدمة",
183
+ "steps": "الخطوات",
184
+ "seed": "البذرة",
185
+ "random_seed": "بذرة عشوائية",
186
+ "generate_btn": "توليد",
187
+ "generated_image": "الصورة المولدة",
188
+ "enhanced_prompt": "الوصف المحسن",
189
+ "seed_used": "البذرة المستخدمة",
190
+ "share": "مشاركة",
191
+ "ai_description": "**مولد الأوصاف بالذكاء الاصطناعي** - ارفع صورة، حللها باستخدام GLM-4.6V، ثم أنشئ أوصافاً محسنة.",
192
+ "upload_image": "رفع صورة",
193
+ "analyze_btn": "تحليل الصورة",
194
+ "image_description": "وصف الصورة",
195
+ "changes_request": "ما التغييرات التي تريدها؟",
196
+ "changes_placeholder": "مثال: 'نمط ألوان مائية' أو 'إضاءة غروب درامية'",
197
+ "target_style": "النمط المستهدف",
198
+ "generate_prompt_btn": "توليد الوصف",
199
+ "generated_prompt": "الوصف المولد",
200
+ "send_to_transform": "إرسال إلى التحويل",
201
+ "how_to_use": "كيفية الاستخدام",
202
+ "how_to_use_content": """1. **ارفع** صورة وانقر على "تحليل الصورة"
203
+ 2. **صف** التغييرات التي تريدها
204
+ 3. **أنشئ** وصفاً محسناً
205
+ 4. **أرسل** إلى تبويب التحويل لتطبيق التغييرات""",
206
+ "transform_description": "**حوّل صورتك** - ارفع وصف التحويل. قوة أقل = تغيير طفيف، قوة أكبر = تغيير جذري.",
207
+ "transformation_prompt": "وصف التحويل",
208
+ "transform_placeholder": "مثال: 'نمط لوحة زيتية، ألوان نابضة'",
209
+ "strength": "القوة",
210
+ "transform_btn": "تحويل",
211
+ "transformed_image": "الصورة المحولة",
212
+ "example_prompts": "أمثلة الأوصاف",
213
+ "models": "النماذج",
214
+ "by": "بواسطة",
215
+ },
216
+ "हिंदी": {
217
+ "title": "Z Image Turbo + GLM-4.6V",
218
+ "subtitle": "DeepSeek Reasoning द्वारा संचालित AI छवि निर्माण और रूपांतरण",
219
+ "like_msg": "अगर आपको पसंद आया, तो कृपया लाइक करें। धन्यवाद!",
220
+ "tab_generate": "बनाएं",
221
+ "tab_assistant": "AI सहायक",
222
+ "tab_transform": "रूपांतरित करें",
223
+ "prompt": "प्रॉम्प्ट",
224
+ "prompt_placeholder": "अपनी छवि का विस्तार से वर्णन करें...",
225
+ "polish_checkbox": "Prompt+ by deepseek-reasoner",
226
+ "style": "शैली",
227
+ "aspect_ratio": "पक्षानुपात",
228
+ "advanced_settings": "उन्नत सेटिंग्स",
229
+ "steps": "चरण",
230
+ "seed": "बीज",
231
+ "random_seed": "यादृच्छिक बीज",
232
+ "generate_btn": "बनाएं",
233
+ "generated_image": "बनाई गई छवि",
234
+ "enhanced_prompt": "उन्नत प्रॉम्प्ट",
235
+ "seed_used": "प्रयुक्त बीज",
236
+ "share": "साझा करें",
237
+ "ai_description": "**AI-संचालित प्रॉम्प्ट जनरेटर** - एक छवि अपलोड करें, GLM-4.6V से विश्लेषण करें, फिर अनुकूलित प्रॉम्प्ट बनाएं।",
238
+ "upload_image": "छवि अपलोड करें",
239
+ "analyze_btn": "छवि विश्लेषण करें",
240
+ "image_description": "छवि विवरण",
241
+ "changes_request": "आप क्या बदलाव चाहते हैं?",
242
+ "changes_placeholder": "उदा., 'वॉटरकलर शैली' या 'नाटकीय सूर्यास्त प्रकाश'",
243
+ "target_style": "लक्ष्य शैली",
244
+ "generate_prompt_btn": "प्रॉम्प्ट बनाएं",
245
+ "generated_prompt": "बनाया गया प्रॉम्प्ट",
246
+ "send_to_transform": "रूपांतरण टैब पर भेजें",
247
+ "how_to_use": "कैसे उपयोग करें",
248
+ "how_to_use_content": """1. **अपलोड** करें एक छवि और "छवि विश्लेषण करें" पर क्लिक करें
249
+ 2. **वर्णन** करें जो बदलाव आप चाहते हैं
250
+ 3. **बनाएं** एक अनुकूलित प्रॉम्प्ट
251
+ 4. **भेजें** रूपांतरण टैब पर बदलाव लागू करने के लिए""",
252
+ "transform_description": "**अपनी छवि रूपांतरित करें** - अपलोड करें और रूपांतरण का वर्णन करें। कम शक्ति = सूक्ष्म, अधिक = नाटकीय।",
253
+ "transformation_prompt": "रूपांतरण प्रॉम्प्ट",
254
+ "transform_placeholder": "उदा., 'तेल चित्रकला शैली, जीवंत रंग'",
255
+ "strength": "शक्ति",
256
+ "transform_btn": "रूपांतरित करें",
257
+ "transformed_image": "रूपांतरित छवि",
258
+ "example_prompts": "उदाहरण प्रॉम्प्ट",
259
+ "models": "मॉडल",
260
+ "by": "द्वारा",
261
+ },
262
+ }
263
+
264
+ def get_text(lang: str, key: str) -> str:
265
+ """Get translated text for a key."""
266
+ return TRANSLATIONS.get(lang, TRANSLATIONS["English"]).get(key, key)
267
+
268
+ def change_language(lang_name: str):
269
+ """Update all component labels when language changes."""
270
+ t = TRANSLATIONS.get(lang_name, TRANSLATIONS["English"])
271
+ return [
272
+ # Generate tab
273
+ gr.update(label=t["prompt"], placeholder=t["prompt_placeholder"]),
274
+ gr.update(label=t["polish_checkbox"]),
275
+ gr.update(label=t["style"]),
276
+ gr.update(label=t["aspect_ratio"]),
277
+ gr.update(label=t["steps"]),
278
+ gr.update(label=t["seed"]),
279
+ gr.update(label=t["random_seed"]),
280
+ gr.update(value=t["generate_btn"]),
281
+ gr.update(label=t["generated_image"]),
282
+ gr.update(label=t["enhanced_prompt"]),
283
+ gr.update(label=t["seed_used"]),
284
+ gr.update(value=t["share"]),
285
+ # AI Assistant tab
286
+ gr.update(value=t["ai_description"]),
287
+ gr.update(label=t["upload_image"]),
288
+ gr.update(value=t["analyze_btn"]),
289
+ gr.update(label=t["image_description"]),
290
+ gr.update(label=t["changes_request"], placeholder=t["changes_placeholder"]),
291
+ gr.update(label=t["target_style"]),
292
+ gr.update(value=t["generate_prompt_btn"]),
293
+ gr.update(label=t["generated_prompt"]),
294
+ gr.update(value=t["send_to_transform"]),
295
+ gr.update(value=t["how_to_use_content"]),
296
+ # Transform tab
297
+ gr.update(value=t["transform_description"]),
298
+ gr.update(label=t["upload_image"]),
299
+ gr.update(label=t["transformation_prompt"], placeholder=t["transform_placeholder"]),
300
+ gr.update(label=t["polish_checkbox"]),
301
+ gr.update(label=t["style"]),
302
+ gr.update(label=t["strength"]),
303
+ gr.update(label=t["steps"]),
304
+ gr.update(label=t["seed"]),
305
+ gr.update(label=t["random_seed"]),
306
+ gr.update(value=t["transform_btn"]),
307
+ gr.update(label=t["transformed_image"]),
308
+ gr.update(label=t["enhanced_prompt"]),
309
+ gr.update(label=t["seed_used"]),
310
+ gr.update(value=t["share"]),
311
+ ]
312
+
313
+ # =============================================================================
314
  # Constants (replaces magic numbers)
315
  MIN_IMAGE_DIM = 512
316
  MAX_IMAGE_DIM = 2048
 
888
  return None, seed
889
 
890
  css = r"""
891
+ /* Google Fonts for multilingual support */
892
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Noto+Sans+Arabic:wght@400;500;600;700&family=Noto+Sans+Devanagari:wght@400;500;600;700&display=swap');
893
+
894
  :root {
895
  --bg-primary: #0c0c0e;
896
  --bg-secondary: #141416;
 
918
  --radius-md: 12px;
919
  --radius-lg: 16px;
920
  --transition: 0.2s ease;
921
+ /* Font stacks */
922
+ --font-latin: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, sans-serif;
923
+ --font-arabic: 'Noto Sans Arabic', 'Tahoma', sans-serif;
924
+ --font-hindi: 'Noto Sans Devanagari', 'Mangal', sans-serif;
925
  }
926
 
927
+ /* Arabic font */
928
+ .lang-ar, .lang-ar * { font-family: var(--font-arabic) !important; }
929
+ /* Hindi font */
930
+ .lang-hi, .lang-hi * { font-family: var(--font-hindi) !important; }
931
+
932
+ /* RTL Support for Arabic */
933
+ [dir="rtl"], .rtl { direction: rtl; text-align: right; }
934
+ [dir="rtl"] .tab-nav { flex-direction: row-reverse; }
935
+ [dir="rtl"] .gr-row, [dir="rtl"] [class*="row"] { flex-direction: row-reverse; }
936
+ [dir="rtl"] input, [dir="rtl"] textarea { text-align: right; direction: rtl; }
937
+ [dir="rtl"] input[type="number"] { direction: ltr; text-align: left; }
938
+ [dir="rtl"] label, [dir="rtl"] .gr-label { text-align: right; }
939
+ [dir="rtl"] .gr-checkbox { flex-direction: row-reverse; }
940
+ [dir="rtl"] .gr-slider { direction: ltr; }
941
+ [dir="rtl"] .gr-markdown ul, [dir="rtl"] .gr-markdown ol { padding-left: 0; padding-right: 1.5em; }
942
+
943
+ /* Language selector in header */
944
+ .lang-selector-row { display: flex; justify-content: flex-end; margin-bottom: 8px; }
945
+ [dir="rtl"] .lang-selector-row { justify-content: flex-start; }
946
+
947
  .gradio-container {
948
  background: var(--bg-primary) !important;
949
  min-height: 100vh;
 
1328
  )
1329
 
1330
  with gr.Blocks(title="Z Image Turbo", css=css, theme=dark_theme) as demo:
1331
+ # Language selector at top
1332
+ with gr.Row(elem_classes="lang-selector-row"):
1333
+ lang_selector = gr.Dropdown(
1334
+ choices=LANGUAGES,
1335
+ value="English",
1336
+ label="🌐 Language",
1337
+ scale=0,
1338
+ min_width=160,
1339
+ interactive=True
1340
+ )
1341
+
1342
  gr.HTML("""
1343
+ <div style="text-align: center; padding: 8px 16px 16px 16px;">
1344
  <h1 style="background: linear-gradient(135deg, #818cf8 0%, #a78bfa 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; font-size: clamp(1.5rem, 4vw, 2.2rem); margin-bottom: 8px; font-weight: 700;">
1345
  Z Image Turbo + GLM-4.6V
1346
  </h1>
 
1351
  If you liked it, please like it. Thank you!
1352
  </p>
1353
  </div>
1354
+ <script>
1355
+ // RTL toggle based on language
1356
+ document.addEventListener('DOMContentLoaded', function() {
1357
+ const observer = new MutationObserver(function(mutations) {
1358
+ const dropdown = document.querySelector('.lang-selector-row select, .lang-selector-row input');
1359
+ if (dropdown) {
1360
+ const checkLang = () => {
1361
+ const val = dropdown.value || '';
1362
+ const html = document.documentElement;
1363
+ const body = document.body;
1364
+ if (val.includes('العربية')) {
1365
+ html.setAttribute('dir', 'rtl');
1366
+ body.classList.add('rtl', 'lang-ar');
1367
+ body.classList.remove('lang-hi');
1368
+ } else if (val.includes('हिंदी')) {
1369
+ html.removeAttribute('dir');
1370
+ body.classList.remove('rtl', 'lang-ar');
1371
+ body.classList.add('lang-hi');
1372
+ } else {
1373
+ html.removeAttribute('dir');
1374
+ body.classList.remove('rtl', 'lang-ar', 'lang-hi');
1375
+ }
1376
+ };
1377
+ dropdown.addEventListener('change', checkLang);
1378
+ checkLang();
1379
+ }
1380
+ });
1381
+ observer.observe(document.body, { childList: true, subtree: true });
1382
+ });
1383
+ </script>
1384
  """)
1385
 
1386
  with gr.Tabs():