Spaces:
Runtime error
Runtime error
initial commit
Browse files- README.md +6 -5
- app.py +318 -0
- prompt.txt +1 -0
- requirements.txt +19 -0
- space.yaml +8 -0
- style.css +187 -0
README.md
CHANGED
@@ -1,12 +1,13 @@
|
|
1 |
---
|
2 |
-
title: IconDDDzilla
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 5.23.
|
8 |
app_file: app.py
|
9 |
pinned: false
|
|
|
10 |
---
|
11 |
|
12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: IconDDDzilla
|
3 |
+
emoji: 🦖
|
4 |
+
colorFrom: gray
|
5 |
+
colorTo: gray
|
6 |
sdk: gradio
|
7 |
+
sdk_version: 5.23.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
+
license: apache-2.0
|
11 |
---
|
12 |
|
13 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,318 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
#import random
|
3 |
+
import datetime
|
4 |
+
import spaces
|
5 |
+
import torch
|
6 |
+
import gradio as gr
|
7 |
+
#from huggingface_hub import hf_hub_download
|
8 |
+
import traceback
|
9 |
+
from transformers import pipeline
|
10 |
+
from huggingface_hub import login
|
11 |
+
from diffusers import FluxPipeline
|
12 |
+
from deep_translator import GoogleTranslator
|
13 |
+
|
14 |
+
login(token = os.getenv('HF_TOKEN'))
|
15 |
+
|
16 |
+
print("="*50)
|
17 |
+
print(f"PyTorch version: {torch.__version__}")
|
18 |
+
print(f"CUDA available: {torch.cuda.is_available()}")
|
19 |
+
print(f"GPU count: {torch.cuda.device_count()}")
|
20 |
+
if torch.cuda.is_available():
|
21 |
+
print(f"Current device: {torch.cuda.current_device()}")
|
22 |
+
print(f"Device name: {torch.cuda.get_device_name(0)}")
|
23 |
+
print("="*50)
|
24 |
+
|
25 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
26 |
+
|
27 |
+
print(f"{datetime.datetime.now()} Загрузка модели FLUX.1-dev")
|
28 |
+
pipe = FluxPipeline.from_pretrained(
|
29 |
+
# pretrained_model_name_or_path = local_path,
|
30 |
+
"black-forest-labs/FLUX.1-dev",
|
31 |
+
torch_dtype=torch.bfloat16, # Используем bfloat16 для A100
|
32 |
+
# low_cpu_mem_usage=True, # Экономия памяти
|
33 |
+
# device_map="balanced",
|
34 |
+
# local_files_only=True
|
35 |
+
# variant="fp16",
|
36 |
+
use_safetensors=True
|
37 |
+
)
|
38 |
+
print(f"{datetime.datetime.now()} Загрузка модели FLUX.1-dev успешно завершена")
|
39 |
+
|
40 |
+
print(f"{datetime.datetime.now()} Загрузка LoRA")
|
41 |
+
pipe.load_lora_weights("Shakker-Labs/FLUX.1-dev-LoRA-add-details", weight_name="FLUX-dev-lora-add_details.safetensors")
|
42 |
+
print(f"{datetime.datetime.now()} Загрузка LoRA успешно завершена")
|
43 |
+
|
44 |
+
pipe.fuse_lora(lora_scale=1.0)
|
45 |
+
pipe.to(device)
|
46 |
+
pipe.enable_model_cpu_offload() # Выгрузка неиспользуемых компонентов
|
47 |
+
|
48 |
+
# print(f"{datetime.datetime.now()} Загрузка модели stabilityai/stable-diffusion-x4-upscaler")
|
49 |
+
# upscaler_pipeline = StableDiffusionUpscalePipeline.from_pretrained(
|
50 |
+
# "stabilityai/stable-diffusion-x4-upscaler",
|
51 |
+
# torch_dtype=torch.float16
|
52 |
+
# ).to(device)
|
53 |
+
# print(f"{datetime.datetime.now()} Загрузка модели stabilityai/stable-diffusion-x4-upscaler успешно завершена")
|
54 |
+
#
|
55 |
+
# upscaler_pipeline.enable_model_cpu_offload() # Выгрузка неиспользуемых компонентов
|
56 |
+
|
57 |
+
print(f"{datetime.datetime.now()} Загрузка модели briaai/RMBG-1.4")
|
58 |
+
bg_remover = pipeline("image-segmentation", "briaai/RMBG-1.4", trust_remote_code=True )
|
59 |
+
print(f"{datetime.datetime.now()} Загрузка модели briaai/RMBG-1.4 успешно завершена")
|
60 |
+
|
61 |
+
@spaces.GPU()
|
62 |
+
def generate_image(object_name, remove_bg=True):
|
63 |
+
try:
|
64 |
+
# Формирование промпта
|
65 |
+
object_name = translate_ru_en(object_name)
|
66 |
+
prompt = create_template_prompt(object_name)
|
67 |
+
|
68 |
+
# Для имитации генерации (можно заменить на реальный вызов ComfyUI API)
|
69 |
+
print(f"Генерация иконки для объекта: {object_name}")
|
70 |
+
print(f"Промпт: {prompt[:100]}...")
|
71 |
+
# print(f"Параметры: seed={seed}, steps={steps}, размер={width}x{height}")
|
72 |
+
print(f"Опции: remove_bg={remove_bg}")
|
73 |
+
steps = os.getenv('STEPS') if os.getenv('STEPS') is not None else 10
|
74 |
+
print(f"Шаги: {steps}")
|
75 |
+
|
76 |
+
image = pipe(
|
77 |
+
prompt,
|
78 |
+
height=1024,
|
79 |
+
width=1024,
|
80 |
+
guidance_scale=3.5,
|
81 |
+
num_inference_steps=int(steps),
|
82 |
+
generator=torch.Generator(device).manual_seed(42)
|
83 |
+
).images[0]
|
84 |
+
|
85 |
+
torch.cuda.empty_cache()
|
86 |
+
|
87 |
+
# if upscale :
|
88 |
+
# torch.cuda.empty_cache()
|
89 |
+
# upscaled_image = upscaler_pipeline(
|
90 |
+
# prompt="", # Обязательный параметр, но может быть пустым
|
91 |
+
# image=image,
|
92 |
+
# num_inference_steps=steps, # Оптимально для качества/скорости
|
93 |
+
# guidance_scale=1.0 # Минимальное значение для апскейла
|
94 |
+
# ).images[0]
|
95 |
+
# return upscaled_image
|
96 |
+
|
97 |
+
if remove_bg :
|
98 |
+
remove_bg_image = bg_remover(image)
|
99 |
+
torch.cuda.empty_cache()
|
100 |
+
return remove_bg_image
|
101 |
+
|
102 |
+
torch.cuda.empty_cache()
|
103 |
+
return image
|
104 |
+
|
105 |
+
except Exception as e:
|
106 |
+
print(f"Ошибка при генерации изображения: {e}")
|
107 |
+
traceback.print_exc()
|
108 |
+
return None
|
109 |
+
|
110 |
+
def create_template_prompt(object_name):
|
111 |
+
template = load_text("prompt.txt")
|
112 |
+
return template.format(object_name = object_name)
|
113 |
+
|
114 |
+
def translate_ru_en(text: str):
|
115 |
+
try:
|
116 |
+
# Проверка на кириллицу (если включено)
|
117 |
+
if not any('\u0400' <= char <= '\u04FF' for char in text):
|
118 |
+
return text
|
119 |
+
|
120 |
+
# Создаем переводчик
|
121 |
+
translator = GoogleTranslator(source="ru", target="en")
|
122 |
+
# Выполняем перевод
|
123 |
+
return translator.translate(text)
|
124 |
+
|
125 |
+
except Exception as e:
|
126 |
+
print(f"Ошибка перевода: {e}")
|
127 |
+
traceback.print_exc()
|
128 |
+
return text
|
129 |
+
|
130 |
+
def load_text(file_name):
|
131 |
+
with open(file_name, 'r', encoding='utf-8') as f:
|
132 |
+
return f.read()
|
133 |
+
|
134 |
+
custom_css = load_text("style.css")
|
135 |
+
|
136 |
+
# Создание интерфейса Gradio
|
137 |
+
with gr.Blocks(title="3D Icon Generator", css=custom_css, theme=gr.themes.Default()) as app:
|
138 |
+
gr.Markdown("# iconDDDzilla")
|
139 |
+
gr.Markdown("### Create 3d icons with transparent background in one click!")
|
140 |
+
|
141 |
+
with gr.Row():
|
142 |
+
with gr.Column():
|
143 |
+
# Входные параметры
|
144 |
+
object_input = gr.Textbox(label="Object name", placeholder="Type object name (for example: calendar, phone, camera)")
|
145 |
+
remove_bg_checkbox = gr.Checkbox(label="Remove background", value=True)
|
146 |
+
|
147 |
+
# with gr.Accordion("Расширенные настройки", open=False):
|
148 |
+
# custom_prompt = gr.Textbox(label="Пользовательский промпт", placeholder="Оставьте пустым для использования шаблона", lines=3)
|
149 |
+
#
|
150 |
+
# with gr.Row():
|
151 |
+
# seed = gr.Number(label="Seed", value=276789180904019, precision=0)
|
152 |
+
# steps = gr.Slider(minimum=1, maximum=5, value=5, step=1, label="Шаги")
|
153 |
+
#
|
154 |
+
# with gr.Row():
|
155 |
+
# width = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Ширина")
|
156 |
+
# height = gr.Slider(minimum=512, maximum=2048, value=1024, step=64, label="Высота")
|
157 |
+
#
|
158 |
+
# with gr.Row():
|
159 |
+
# #upscale_checkbox = gr.Checkbox(label="Применить апскейл", value=True)
|
160 |
+
# remove_bg_checkbox = gr.Checkbox(label="Удалить фон", value=False)
|
161 |
+
|
162 |
+
# Кнопка генерации
|
163 |
+
generate_btn = gr.Button("Run")
|
164 |
+
|
165 |
+
with gr.Column():
|
166 |
+
# Выходное изображение
|
167 |
+
output_image = gr.Image(label="Image")
|
168 |
+
|
169 |
+
# Примеры использования
|
170 |
+
# examples = gr.Examples(
|
171 |
+
# examples=[
|
172 |
+
# ["calendar", "", 276789180904019, 5, 1024, 1024, True],
|
173 |
+
# ["camera", "", 391847529184, 5, 1024, 1024, True],
|
174 |
+
# ["smartphone", "", 654321987654, 5, 1024, 1024, True],
|
175 |
+
# ["headphones", "", 123456789012, 5, 1024, 1024, True],
|
176 |
+
# ],
|
177 |
+
# inputs=[
|
178 |
+
# object_input,
|
179 |
+
# custom_prompt,
|
180 |
+
# seed,
|
181 |
+
# steps,
|
182 |
+
# width,
|
183 |
+
# height,
|
184 |
+
# #upscale_checkbox,
|
185 |
+
# remove_bg_checkbox
|
186 |
+
# ],
|
187 |
+
# outputs=[output_image],
|
188 |
+
# fn=generate_image,
|
189 |
+
# )
|
190 |
+
|
191 |
+
# Информация о моделях
|
192 |
+
# with gr.Accordion("Информация о используемых моделях", open=False):
|
193 |
+
# gr.Markdown("""
|
194 |
+
# ## Используемые модели
|
195 |
+
#
|
196 |
+
# - **Основная модель:** [flux1-dev-fp8.safetensors](https://huggingface.co/lllyasviel/flux1_dev/blob/main/flux1-dev-fp8.safetensors) от Stability AI
|
197 |
+
# - **Модель апскейла:** [4x_NMKD-Superscale-SP_178000_G.pth](https://huggingface.co/gemasai/4x_NMKD-Superscale-SP_178000_G) для улучшения качества изображения
|
198 |
+
# - **Модель удаления фона:** [RMBG-1.4](https://huggingface.co/briaai/RMBG-1.4) для качественного удаления фона
|
199 |
+
#
|
200 |
+
# Все модели автоматически загружаются при первом запуске приложения.
|
201 |
+
# """)
|
202 |
+
|
203 |
+
# Привязка функции к нажатию кнопки
|
204 |
+
generate_btn.click(
|
205 |
+
fn=generate_image,
|
206 |
+
inputs=[
|
207 |
+
object_input,
|
208 |
+
# custom_prompt,
|
209 |
+
# seed,
|
210 |
+
# steps,
|
211 |
+
# width,
|
212 |
+
# height,
|
213 |
+
#upscale_checkbox,
|
214 |
+
remove_bg_checkbox
|
215 |
+
],
|
216 |
+
outputs=[output_image]
|
217 |
+
)
|
218 |
+
|
219 |
+
# Запуск приложения
|
220 |
+
if __name__ == "__main__":
|
221 |
+
app.launch()
|
222 |
+
|
223 |
+
|
224 |
+
|
225 |
+
|
226 |
+
### OLD UNUSED CODE!!! BE CAREFUL!!! ###
|
227 |
+
|
228 |
+
# Создаем необходимые директории
|
229 |
+
# os.makedirs("models", exist_ok=True)
|
230 |
+
# os.makedirs("models/checkpoints", exist_ok=True)
|
231 |
+
# os.makedirs("models/loras", exist_ok=True)
|
232 |
+
# os.makedirs("models/upscale_models", exist_ok=True)
|
233 |
+
# os.makedirs("models/rembg", exist_ok=True)
|
234 |
+
# os.makedirs("outputs", exist_ok=True)
|
235 |
+
# os.makedirs("temp_uploads", exist_ok=True)
|
236 |
+
|
237 |
+
|
238 |
+
# Загрузка моделей с Hugging Face
|
239 |
+
# def download_model(repo_id, filename, local_dir):
|
240 |
+
# """Загрузка модели с Hugging Face Hub"""
|
241 |
+
# local_path = os.path.join(local_dir, filename)
|
242 |
+
# if not os.path.exists(local_path):
|
243 |
+
# print(f"Загрузка {filename} из {repo_id}...")
|
244 |
+
# try:
|
245 |
+
# file_path = hf_hub_download(
|
246 |
+
# repo_id=repo_id,
|
247 |
+
# filename=filename,
|
248 |
+
# local_dir=local_dir,
|
249 |
+
# local_dir_use_symlinks=False
|
250 |
+
# )
|
251 |
+
# print(f"Модель успешно загружена: {file_path}")
|
252 |
+
# return file_path
|
253 |
+
# except Exception as e:
|
254 |
+
# print(f"Ошибка при загрузке модели {filename}: {e}")
|
255 |
+
# return None
|
256 |
+
# else:
|
257 |
+
# print(f"Модель {filename} уже присутствует: {local_path}")
|
258 |
+
# return local_path
|
259 |
+
|
260 |
+
# Вынесем загрузку моделей за пределы функции generate_image
|
261 |
+
# это критично для работы на ZeroGPU в Hugging Face Spaces
|
262 |
+
# def download_all_models():
|
263 |
+
# models = {
|
264 |
+
# "flux": download_model(
|
265 |
+
# "lllyasviel/flux1_dev",
|
266 |
+
# "flux1-dev-fp8.safetensors",
|
267 |
+
# "models/checkpoints"
|
268 |
+
# ),
|
269 |
+
# # "upscale": download_model(
|
270 |
+
# # "gemasai/4x_NMKD-Superscale-SP_178000_G",
|
271 |
+
# # "4x_NMKD-Superscale-SP_178000_G.pth",
|
272 |
+
# # "models/upscale_models"
|
273 |
+
# # ),
|
274 |
+
# # "rembg": "briaai/RMBG-1.4" # Используем модель RMBG-1.4 через transformers pipeline
|
275 |
+
# }
|
276 |
+
# return models
|
277 |
+
|
278 |
+
# def save_uploaded_file(file):
|
279 |
+
# """Сохранение загруженного файла"""
|
280 |
+
# if file is None:
|
281 |
+
# return None
|
282 |
+
#
|
283 |
+
# filename = os.path.join("temp_uploads", f"{random.randint(1000000, 9999999)}{os.path.splitext(file.name)[1]}")
|
284 |
+
# with open(filename, "wb") as f:
|
285 |
+
# f.write(file.read())
|
286 |
+
# return filename
|
287 |
+
|
288 |
+
# Функция для получения значения по индексу (используется в ComfyUI)
|
289 |
+
# def get_value_at_index(obj, index):
|
290 |
+
# """Получение значения из объекта по индексу из экспортированного ComfyUI кода"""
|
291 |
+
# if isinstance(obj, list):
|
292 |
+
# return obj[index]
|
293 |
+
# elif isinstance(obj, tuple):
|
294 |
+
# return obj[index]
|
295 |
+
# elif isinstance(obj, dict):
|
296 |
+
# return list(obj.values())[index]
|
297 |
+
# else:
|
298 |
+
# return obj[index]
|
299 |
+
|
300 |
+
# Загрузка моделей при запуске
|
301 |
+
#models = download_all_models()
|
302 |
+
|
303 |
+
# Инициализация pipeline для удаления фона
|
304 |
+
# try:
|
305 |
+
# rembg_pipeline = pipeline("image-segmentation", model=models["rembg"], trust_remote_code=True)
|
306 |
+
# print(f"Модель удаления фона успешно загружена: {models['rembg']}")
|
307 |
+
# except Exception as e:
|
308 |
+
# print(f"Ошибка при загрузке модели удаления фона: {e}")
|
309 |
+
# rembg_pipeline = None
|
310 |
+
|
311 |
+
# Укажите абсолютный путь к модели
|
312 |
+
# model_path = os.path.abspath("models/checkpoints/flux1-dev-fp8.safetensors")
|
313 |
+
|
314 |
+
# Проверьте существование ключевого файла
|
315 |
+
# if not os.path.exists(os.path.join(model_path, "model_index.json")):
|
316 |
+
# raise FileNotFoundError(f"Модель не найдена по пути: {model_path}")
|
317 |
+
|
318 |
+
# local_path = os.path.join("models/checkpoints", "")
|
prompt.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
3D {object_name} icon: Minimal geo, layered, aluminum, acrylic, rubber, 3-point, 8k, PBR, Bezier, isometric
|
requirements.txt
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
--extra-index-url https://download.pytorch.org/whl/cu114
|
2 |
+
torch
|
3 |
+
torchvision
|
4 |
+
gradio==3.50.2
|
5 |
+
pillow>=9.5.0
|
6 |
+
numpy>=1.24.0
|
7 |
+
huggingface_hub>=0.17.0
|
8 |
+
safetensors>=0.3.0
|
9 |
+
accelerate>=0.18.0
|
10 |
+
requests>=2.28.0
|
11 |
+
opencv-python>=4.6.0
|
12 |
+
transformers
|
13 |
+
diffusers
|
14 |
+
peft
|
15 |
+
safetensors
|
16 |
+
sentencepiece
|
17 |
+
scikit-image
|
18 |
+
rembg
|
19 |
+
deep_translator
|
space.yaml
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
title: iconDDDzilla
|
2 |
+
emoji: 🦖
|
3 |
+
colorFrom: gray
|
4 |
+
colorTo: gray
|
5 |
+
sdk: gradio
|
6 |
+
sdk_version: 3.50.2
|
7 |
+
app_file: app.py
|
8 |
+
pinned: false
|
style.css
ADDED
@@ -0,0 +1,187 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
:root {
|
2 |
+
--primary: #5A54F9;
|
3 |
+
--primary-dark: #4D47D1;
|
4 |
+
--secondary: #8B84FF;
|
5 |
+
--text: #111827;
|
6 |
+
--light: #F9FAFB;
|
7 |
+
}
|
8 |
+
|
9 |
+
.gradio-container {
|
10 |
+
background: linear-gradient(135deg, #F9FAFB 0%, #E5E7EB 100%) !important;
|
11 |
+
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif !important;
|
12 |
+
max-width: 800px !important;
|
13 |
+
margin: 20px auto !important;
|
14 |
+
border-radius: 16px !important;
|
15 |
+
box-shadow: 0 10px 25px -5px rgba(90, 84, 249, 0.1) !important;
|
16 |
+
}
|
17 |
+
|
18 |
+
.dark .gradio-container {
|
19 |
+
background: linear-gradient(135deg, #1F2937 0%, #111827 100%) !important;
|
20 |
+
--text: #F9FAFB;
|
21 |
+
--light: #1F2937;
|
22 |
+
}
|
23 |
+
|
24 |
+
.gr-block {
|
25 |
+
border: none !important;
|
26 |
+
background: white !important;
|
27 |
+
border-radius: 12px !important;
|
28 |
+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05) !important;
|
29 |
+
padding: 20px !important;
|
30 |
+
margin-bottom: 24px !important;
|
31 |
+
transition: all 0.3s ease !important;
|
32 |
+
}
|
33 |
+
|
34 |
+
.dark .gr-block {
|
35 |
+
background: rgba(30, 41, 59, 0.8) !important;
|
36 |
+
backdrop-filter: blur(10px) !important;
|
37 |
+
}
|
38 |
+
|
39 |
+
.gr-block:hover {
|
40 |
+
transform: translateY(-2px) !important;
|
41 |
+
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1) !important;
|
42 |
+
}
|
43 |
+
|
44 |
+
.gr-button {
|
45 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%) !important;
|
46 |
+
color: white !important;
|
47 |
+
border: none !important;
|
48 |
+
border-radius: 8px !important;
|
49 |
+
padding: 12px 24px !important;
|
50 |
+
font-weight: 600 !important;
|
51 |
+
text-transform: uppercase !important;
|
52 |
+
letter-spacing: 0.5px !important;
|
53 |
+
transition: all 0.3s ease !important;
|
54 |
+
box-shadow: 0 4px 6px -1px rgba(90, 84, 249, 0.3) !important;
|
55 |
+
}
|
56 |
+
|
57 |
+
.gr-button:hover {
|
58 |
+
transform: translateY(-2px) !important;
|
59 |
+
box-shadow: 0 10px 15px -3px rgba(90, 84, 249, 0.4) !important;
|
60 |
+
}
|
61 |
+
|
62 |
+
.gr-button:active {
|
63 |
+
transform: scale(0.98) !important;
|
64 |
+
}
|
65 |
+
|
66 |
+
.gr-textbox, .gr-number, .gr-slider, .gr-dropdown {
|
67 |
+
border: 1px solid #e2e8f0 !important;
|
68 |
+
border-radius: 8px !important;
|
69 |
+
padding: 12px 16px !important;
|
70 |
+
background: var(--light) !important;
|
71 |
+
transition: all 0.3s ease !important;
|
72 |
+
}
|
73 |
+
|
74 |
+
.gr-textbox:focus, .gr-number:focus, .gr-dropdown:focus {
|
75 |
+
border-color: var(--primary) !important;
|
76 |
+
box-shadow: 0 0 0 2px rgba(90, 84, 249, 0.2) !important;
|
77 |
+
outline: none !important;
|
78 |
+
}
|
79 |
+
|
80 |
+
h1, h2, h3, h4 {
|
81 |
+
color: var(--text) !important;
|
82 |
+
font-weight: 600 !important;
|
83 |
+
margin-top: 0 !important;
|
84 |
+
}
|
85 |
+
|
86 |
+
.gr-markdown {
|
87 |
+
color: var(--text) !important;
|
88 |
+
line-height: 1.6 !important;
|
89 |
+
}
|
90 |
+
|
91 |
+
.progress-bar {
|
92 |
+
height: 6px !important;
|
93 |
+
border-radius: 3px !important;
|
94 |
+
background: linear-gradient(90deg, var(--primary), #93c5fd) !important;
|
95 |
+
}
|
96 |
+
|
97 |
+
.tabs {
|
98 |
+
background: transparent !important;
|
99 |
+
}
|
100 |
+
|
101 |
+
.tab-button {
|
102 |
+
border-radius: 8px 8px 0 0 !important;
|
103 |
+
margin-right: 4px !important;
|
104 |
+
transition: all 0.3s ease !important;
|
105 |
+
}
|
106 |
+
|
107 |
+
.tab-button.selected {
|
108 |
+
background: white !important;
|
109 |
+
color: var(--primary) !important;
|
110 |
+
font-weight: 600 !important;
|
111 |
+
}
|
112 |
+
|
113 |
+
.dark .tab-button.selected {
|
114 |
+
background: rgba(30, 41, 59, 0.8) !important;
|
115 |
+
}
|
116 |
+
|
117 |
+
.gr-checkbox {
|
118 |
+
margin: 12px 0 !important;
|
119 |
+
}
|
120 |
+
|
121 |
+
.gr-checkbox label {
|
122 |
+
display: flex !important;
|
123 |
+
align-items: center !important;
|
124 |
+
cursor: pointer !important;
|
125 |
+
position: relative !important;
|
126 |
+
padding-left: 35px !important;
|
127 |
+
min-height: 25px !important;
|
128 |
+
}
|
129 |
+
|
130 |
+
.gr-checkbox input[type="checkbox"] {
|
131 |
+
position: absolute !important;
|
132 |
+
opacity: 0 !important;
|
133 |
+
cursor: pointer !important;
|
134 |
+
height: 0 !important;
|
135 |
+
width: 0 !important;
|
136 |
+
}
|
137 |
+
|
138 |
+
.checkmark {
|
139 |
+
position: absolute !important;
|
140 |
+
top: 0 !important;
|
141 |
+
left: 0 !important;
|
142 |
+
height: 24px !important;
|
143 |
+
width: 24px !important;
|
144 |
+
background-color: var(--light) !important;
|
145 |
+
border: 2px solid var(--primary) !important;
|
146 |
+
border-radius: 6px !important;
|
147 |
+
transition: all 0.3s ease !important;
|
148 |
+
}
|
149 |
+
|
150 |
+
.gr-checkbox:hover .checkmark {
|
151 |
+
transform: scale(1.05) !important;
|
152 |
+
box-shadow: 0 0 0 3px rgba(90, 84, 249, 0.1) !important;
|
153 |
+
}
|
154 |
+
|
155 |
+
.gr-checkbox input:checked ~ .checkmark {
|
156 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%) !important;
|
157 |
+
border-color: var(--primary-dark) !important;
|
158 |
+
}
|
159 |
+
|
160 |
+
.checkmark:after {
|
161 |
+
content: "" !important;
|
162 |
+
position: absolute !important;
|
163 |
+
display: none !important;
|
164 |
+
}
|
165 |
+
|
166 |
+
.gr-checkbox input:checked ~ .checkmark:after {
|
167 |
+
display: block !important;
|
168 |
+
}
|
169 |
+
|
170 |
+
.gr-checkbox .checkmark:after {
|
171 |
+
left: 8px !important;
|
172 |
+
top: 4px !important;
|
173 |
+
width: 6px !important;
|
174 |
+
height: 12px !important;
|
175 |
+
border: solid white !important;
|
176 |
+
border-width: 0 2px 2px 0 !important;
|
177 |
+
transform: rotate(45deg) !important;
|
178 |
+
}
|
179 |
+
|
180 |
+
.dark .gr-checkbox .checkmark {
|
181 |
+
background-color: rgba(30, 41, 59, 0.5) !important;
|
182 |
+
border-color: #93c5fd !important;
|
183 |
+
}
|
184 |
+
|
185 |
+
.dark .gr-checkbox input:checked ~ .checkmark {
|
186 |
+
background: linear-gradient(135deg, var(--primary) 0%, #1e8a50 100%) !important;
|
187 |
+
}
|