Spaces:
Sleeping
Sleeping
File size: 30,480 Bytes
0a94d20 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | Ap='FP32 (Lambat, Kualitas Terbaik)'
Ao='FP16 (Cepat, Kualitas Baik)'
An='Semua Waktu'
Am='contain'
Al='http://127.0.0.1:7860/'
Ak='Grayscale'
Aj='### β Detail Gambar\nKlik pada sebuah gambar untuk melihat detailnya.'
Ai='3 Bulan Terakhir'
Ah='2 Minggu Terakhir'
Ag='1 Minggu Terakhir'
Af='caidas/swin2sr-realworld-sr-x4-64-bsrgan-psnr'
Ae='User Agent'
Ad='IP Address'
Ac=ImportError
AJ='%Y-%m-%d %H:%M:%S'
y='secondary'
x='N/A'
w='Filename'
v='cuda'
m='primary'
l='Steps'
k='NegativePrompt'
j='utf-8'
i=str
h=Exception
g=open
b='Seed'
a='Prompt'
Z=len
T='history'
S=1.
R='Total Pengunjung'
O='title'
N=''
M=int
G='panel'
F='Timestamp'
E=print
D=True
C=False
B=None
import gradio as A,torch as H,numpy as z
from diffusers import DiffusionPipeline as Aq
import random as AK,time as A0,os as K
from datetime import datetime as n,timedelta as A1
import csv as o,pandas as I,threading as Ar
from PIL import Image as AL,ImageEnhance as c
from pathlib import Path
import uuid,urllib.parse
try:import psutil as p,platform as q;from transformers import Swin2SRForImageSuperResolution as A2,Swin2SRImageProcessor as AM;E('β
Library tambahan (psutil, transformers) berhasil diimpor.')
except Ac:E("β Peringatan: Library 'psutil' atau 'transformers' tidak ditemukan. Fitur System Monitor & Upscaler tidak akan berfungsi.");p=B;q=B;A2=B;AM=B
try:import google.generativeai as r;E("β
Library 'google-generativeai' berhasil diimpor.")
except Ac:E("β Peringatan: Library 'google-generativeai' tidak ditemukan. Fitur Chatbot & Prompt Enhancer tidak akan berfungsi.");r=B
As='\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <title>RenXploit\'s Creative AI Suite</title>\n <link rel="preconnect" href="https://fonts.googleapis.com">\n <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>\n <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Fira+Code:wght@500&display=swap" rel="stylesheet">\n <script>\n function typewriterEffect(element, text, speed) {\n let i = 0;\n element.innerHTML = ""; \n const cursor = document.createElement(\'span\');\n cursor.className = \'typewriter-cursor\';\n cursor.innerHTML = \'|\';\n element.appendChild(cursor);\n function type() {\n if (i < text.length) {\n element.insertBefore(document.createTextNode(text.charAt(i)), cursor);\n i++;\n setTimeout(type, speed);\n } else {\n cursor.style.animation = \'blink 1s step-end infinite\';\n }\n }\n type();\n }\n\n document.addEventListener("DOMContentLoaded", function(event) {\n const titleElement = document.querySelector(\'#main-title h1\');\n if (titleElement) {\n const titleText = "π RenXploit\'s Creative AI Suite π";\n titleElement.textContent = "";\n setTimeout(() => typewriterEffect(titleElement, titleText, 50), 500);\n }\n \n setInterval(() => {\n const triggerButton = document.querySelector(\'#system-info-trigger-btn button\');\n if (triggerButton) {\n triggerButton.click();\n }\n }, 5000);\n });\n </script>\n <style>\n :root { --primary-color: #00aaff; --primary-hover-color: #0088cc; --background-color: #0d1117; --content-background-color: #161b22; --border-color: #30363d; --text-color: #c9d1d9; --text-muted-color: #8b949e; --font-family-main: \'Inter\', sans-serif; --font-family-mono: \'Fira Code\', monospace; --border-radius: 12px; --shadow-light: 0 4px 14px 0 rgba(0, 170, 255, 0.1); --shadow-strong: 0 6px 20px 0 rgba(0, 170, 255, 0.15); }\n body, .gradio-container { font-family: var(--font-family-main); background-color: var(--background-color) !important; color: var(--text-color); }\n h1, h2, h3 { color: #ffffff; font-weight: 600; }\n #main-title h1 { font-size: 2.5em !important; font-weight: 700 !important; text-align: center; padding: 2rem 1rem; color: #ffffff; background: linear-gradient(90deg, #00aaff, #00ffaa); -webkit-background-clip: text; -webkit-text-fill-color: transparent; display: inline-block; }\n #main-title .typewriter-cursor { color: var(--primary-color); font-weight: bold; }\n @keyframes blink { from, to { opacity: 1 } 50% { opacity: 0 } }\n #main-subtitle p { font-size: 1.2em !important; text-align: center; color: var(--text-muted-color); margin-top: -1.5rem !important; margin-bottom: 2rem !important; }\n .gradio-tabs { border: none !important; background-color: transparent !important; margin-bottom: 1.5rem; }\n .gradio-tabs > div[role="tablist"] { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; border-bottom: 2px solid var(--border-color); padding-bottom: 10px; }\n .gradio-tabs > div[role="tablist"] > button { background-color: transparent !important; color: var(--text-muted-color) !important; border: none !important; border-bottom: 3px solid transparent !important; font-size: 1.1em !important; font-weight: 600 !important; padding: 12px 20px !important; border-radius: 8px 8px 0 0 !important; transition: all 0.3s ease; }\n .gradio-tabs > div[role="tablist"] > button:hover { background-color: var(--content-background-color) !important; color: var(--primary-color) !important; }\n .gradio-tabs > div[role="tablist"] > button.selected { color: var(--primary-color) !important; border-bottom: 3px solid var(--primary-color) !important; background-color: var(--content-background-color) !important; }\n .tabitem { background-color: transparent !important; border: none !important; padding: 0 !important; }\n .gradio-row.panel, .gradio-accordion, .gradio-group { background-color: var(--content-background-color) !important; border: 1px solid var(--border-color) !important; border-radius: var(--border-radius) !important; padding: 24px !important; box-shadow: 0 4px 6px rgba(0,0,0,0.1); }\n .gradio-accordion { margin-top: 1rem; }\n .gradio-button.primary { background: linear-gradient(90deg, var(--primary-color), #00c6ff) !important; color: #ffffff !important; font-weight: 600 !important; font-size: 1.1em !important; border-radius: 8px !important; border: none !important; padding: 12px 24px !important; transition: all 0.3s ease; box-shadow: var(--shadow-light); }\n .gradio-button.primary:hover { transform: translateY(-2px); box-shadow: var(--shadow-strong); }\n .gradio-button.secondary { background-color: var(--content-background-color) !important; border: 1px solid var(--primary-color) !important; color: var(--primary-color) !important; transition: all 0.3s ease; }\n .gradio-button.secondary:hover { background-color: var(--primary-color) !important; color: #ffffff !important; }\n .gradio-textbox, .gradio-number, .gradio-image { background-color: var(--background-color) !important; border: 1px solid var(--border-color) !important; color: var(--text-color) !important; border-radius: 8px !important; }\n .gradio-textbox textarea, .gradio-number input { color: var(--text-color) !important; }\n .gradio-textbox:focus-within, .gradio-number:focus-within { border-color: var(--primary-color) !important; box-shadow: 0 0 0 2px rgba(0, 170, 255, 0.3); }\n div.info { color: var(--text-muted-color) !important; font-style: italic; }\n #gallery, #history_gallery { border-radius: var(--border-radius) !important; overflow: hidden; border: 1px solid var(--border-color); background-color: #010409; }\n #gallery .gallery-item, #history_gallery .gallery-item { transition: transform 0.3s ease, box-shadow 0.3s ease; }\n #gallery .gallery-item:hover, #history_gallery .gallery-item:hover { transform: scale(1.03); box-shadow: 0 8px 30px rgba(0, 170, 255, 0.3); }\n .loader-container { border: 1px solid var(--border-color); border-radius: var(--border-radius); padding: 30px; background: var(--content-background-color); text-align: center; overflow: hidden; }\n .loader-text { font-family: var(--font-family-mono); font-size: 1.1em; color: var(--primary-color); margin-bottom: 20px; }\n .loader-bar-container { height: 8px; background: var(--background-color); border-radius: 4px; overflow: hidden; }\n .loader-bar { width: 100%; height: 100%; background: linear-gradient(90deg, transparent, var(--primary-color), transparent); background-size: 200% 100%; animation: scan 2s linear infinite; }\n @keyframes scan { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }\n #chatbot-container { display: flex; flex-direction: column; height: 70vh; max-height: 750px; }\n #chatbot-display { flex-grow: 1; overflow-y: auto; padding: 10px; border-bottom: 1px solid var(--border-color); }\n #chatbot-display .message { border-radius: 18px !important; padding: 12px 18px !important; box-shadow: none !important; max-width: 80%; }\n #chatbot-display .user { background-color: var(--primary-color) !important; color: white !important; align-self: flex-end; border-bottom-right-radius: 5px !important; }\n #chatbot-display .bot { background-color: var(--content-background-color) !important; border: 1px solid var(--border-color) !important; align-self: flex-start; border-bottom-left-radius: 5px !important; }\n #chat-history-sidebar { background-color: transparent !important; border: none !important; padding: 0 !important; box-shadow: none !important; }\n #chat-history-sidebar .gradio-radio > div { display: flex; flex-direction: column; gap: 8px; }\n #chat-history-sidebar .gradio-radio label { width: 100%; text-align: left; padding: 10px; border: 1px solid var(--border-color); border-radius: 8px; transition: all 0.2s ease; }\n #chat-history-sidebar .gradio-radio input:checked + label { border-color: var(--primary-color); background-color: rgba(0, 170, 255, 0.1); color: var(--primary-color); font-weight: 600; }\n .footer { text-align: center; margin: 2rem auto; padding: 1rem; color: var(--text-muted-color); border-top: 1px solid var(--border-color); }\n .footer b { color: var(--primary-color); }\n </style>\n</head>\n'
L='visitor_log.csv'
P='generation_log.csv'
U=Path('generated_images')
V=Ar.Lock()
Q=v if H.cuda.is_available()else'cpu'
E(f"β‘οΈ Menggunakan device: {Q.upper()}")
def At():
if not K.path.exists(L):
with V:
if not K.path.exists(L):
with g(L,mode='w',newline=N,encoding=j)as A:B=o.writer(A);B.writerow([F,Ad,Ae])
E(f"β
File log '{L}' berhasil dibuat.")
U.mkdir(exist_ok=D)
if not K.path.exists(P):
with V:
if not K.path.exists(P):
with g(P,mode='w',newline=N,encoding=j)as A:B=o.writer(A);B.writerow([F,w,a,k,b,l])
E(f"β
File log riwayat '{P}' dan direktori '{U}' siap.")
At()
E('β‘οΈ Memuat model SDXL-Turbo...')
AN=Aq.from_pretrained('stabilityai/sdxl-turbo',torch_dtype=H.float16 if Q==v else H.float32,variant='fp16'if Q==v else B,use_safetensors=D).to(Q)
if H.cuda.is_available():AN.enable_xformers_memory_efficient_attention()
E('β
Model SDXL-Turbo berhasil dimuat.')
A3=B
A4=B
if A2:
try:E('β‘οΈ Memuat model AI Upscaler (Swin2SR)...');A3=A2.from_pretrained(Af).to(Q);A4=AM.from_pretrained(Af);E('β
Model AI Upscaler berhasil dimuat.')
except h as Au:E(f"β Gagal memuat model Upscaler: {Au}. Fitur upscale akan dinaktifkan.")
class Av:
def __init__(A):
A.api_keys=[];A.is_configured=C
if not r:return
B=1
while D:
F=K.getenv(f"GEMINI_API_KEY_{B}")
if F:A.api_keys.append(F);B+=1
else:break
if A.api_keys:E(f"β
Berhasil memuat {Z(A.api_keys)} API Key Gemini. Sistem rotasi aktif.");A.is_configured=D
else:E('β PERINGATAN: Tidak ada API Key Gemini yang ditemukan. Fitur AI Chat & Prompt Enhancer tidak akan berfungsi.')
def chat(B,message,history,system_prompt=B):
K='parts';J='role';F=system_prompt;D=history;C=message
if not B.is_configured:return'Maaf, fitur ini tidak terkonfigurasi karena tidak ada API Key.'
try:
L=AK.choice(B.api_keys);r.configure(api_key=L);M=r.GenerativeModel('gemini-2.5-flash');A=[]
for(G,H)in D:
if G:A.append({J:'user',K:[G]})
if H:A.append({J:'model',K:[H]})
N=M.start_chat(history=A);I=C
if F and not D:I=f"{F}\n\nUser query: {C}"
O=N.send_message(I);return O.text
except h as P:E(f"β Terjadi error pada API Key Gemini: {P}");return'Terjadi kesalahan saat menghubungi API AI. Mungkin salah satu API Key tidak valid atau ada masalah jaringan. Silakan coba lagi.'
s=Av()
def Aw(request):
A=request;C=n.now().strftime(AJ);B=A.client.host if A else x;D=A.headers.get('user-agent','Unknown')if A else x
with V:
with g(L,mode='a',newline=N,encoding=j)as F:G=o.writer(F);G.writerow([C,B,D])
E(f"β
Pengunjung baru tercatat: IP {B}")
def Ax(prompt,negative_prompt,steps,seed,num_images):
C=prompt;B=seed
if not C:raise A.Error('Prompt tidak boleh kosong!')
if B==-1:B=AK.randint(0,2**32-1)
D=H.manual_seed(B);E=AN(prompt=C,negative_prompt=negative_prompt,generator=D,num_inference_steps=steps,guidance_scale=.0,num_images_per_prompt=num_images).images;return E,B
def Ay(prompt,negative_prompt,steps,seed,num_images):
G=steps;F=negative_prompt;E=prompt;yield(A.update(visible=C),A.update(visible=D,value="<div class='loader-container'><div class='loader-text'>AI sedang melukis mahakarya Anda...</div><div class='loader-bar-container'><div class='loader-bar'></div></div></div>"),A.update(interactive=C),A.update(visible=C));J=A0.time();H,B=Ax(E,F,M(G),M(seed),M(num_images));K=A0.time();L=n.now().strftime(AJ)
for(O,Q)in enumerate(H):
I=f"{M(A0.time())}_{B}_{O}.png";R=U/I;Q.save(R)
with V:
with g(P,mode='a',newline=N,encoding=j)as S:T=o.writer(S);T.writerow([L,I,E,F,B,M(G)])
W=K-J;X=f"Seed yang digunakan: {B}\nTotal waktu generasi: {W:.2f} detik";yield(A.update(value=H,visible=D),A.update(visible=C),A.update(interactive=D),A.update(value=X,visible=D))
def Az(name,email,message):
B=message
if not name or not B:A.Warning('Nama dan Pesan tidak boleh kosong!');return A.update(visible=C)
F=n.now().strftime(AJ);G=f"""--- Laporan Baru ({F}) ---
Nama: {name}
Email: {email}
Pesan: {B}
"""
with g('reports.log','a',encoding=j)as H:H.write(G)
E('β
Laporan baru telah disimpan ke reports.log');return A.update(value='β
Terima kasih! Laporan Anda telah kami terima.',visible=D)
def A5(time_filter):
J='## π 0';G=time_filter
try:
with V:
if not K.path.exists(L)or K.path.getsize(L)==0:return J,I.DataFrame({F:[],R:[]})
P=[F,Ad,Ae];A=I.read_csv(L,header=B,names=P)
if not A.empty and A.iloc[0][F]==F:A=A.iloc[1:].reset_index(drop=D)
if A.empty:return J,I.DataFrame({F:[],R:[]})
A[F]=I.to_datetime(A[F],errors='coerce');A.dropna(subset=[F],inplace=D)
if A.empty:return J,I.DataFrame({F:[],R:[]})
Q=Z(A);M=f"## π {Q:,}";A[R]=z.arange(1,Z(A)+1);H=n.now()
if G==Ag:C=A[A[F]>=H-A1(weeks=1)]
elif G==Ah:C=A[A[F]>=H-A1(weeks=2)]
elif G==Ai:C=A[A[F]>=H-A1(days=90)]
else:C=A
if C.empty:return M,I.DataFrame({F:[],R:[]})
return M,C
except h as N:O=f"Error saat memperbarui monitor: {N}";E(f"β {O}");return f"## β οΈ Error: {N}",I.DataFrame({'Error':[O]})
def A_(simple_prompt):
B=simple_prompt
if not B:A.Warning('Tolong masukkan ide Anda terlebih dahulu.');return N
if not s.is_configured:A.Error('Fitur Prompt Enhancer tidak aktif karena API Key Gemini tidak diatur.');return'Fitur tidak aktif.'
C='Anda adalah seorang ahli prompt engineering untuk model AI text-to-image seperti Stable Diffusion. Tugas Anda adalah mengubah ide sederhana dari pengguna menjadi prompt yang kaya, deskriptif, dan artistik. Fokus pada detail visual: subjek, setting, pencahayaan, gaya seni, komposisi, dan kualitas. Hasilkan HANYA prompt-nya saja dalam format teks panjang, tanpa penjelasan atau kalimat pembuka/penutup.';yield'π§ AI sedang meracik prompt ajaib untuk Anda...';D=s.chat(B,[],system_prompt=C);yield D
def B0(image_to_upscale,clarity_strength):
G=image_to_upscale;F=clarity_strength
if G is B:raise A.Error('Silakan unggah gambar terlebih dahulu.')
if A3 is B or A4 is B:raise A.Error('Fitur Upscaler tidak aktif karena model gagal dimuat.')
yield(B,'π Memproses peningkatan resolusi 4x oleh AI...')
try:
with H.no_grad():J=A4(G,return_tensors='pt').to(Q);K=A3(**J);D=K.reconstruction.data.squeeze().float().cpu().clamp_(0,1).numpy();D=z.moveaxis(D,source=0,destination=-1);D=(D*255.).round().astype(z.uint8);C=AL.fromarray(D)
if F>S:yield(C,f"β¨ Menerapkan peningkatan kejernihan (Strength: {F:.2f})...");L=c.Sharpness(C);C=L.enhance(F)
yield(C,f"β
Gambar berhasil ditingkatkan! Resolusi akhir: {C.width}x{C.height}px.")
except h as I:E(f"β Error saat upscaling: {I}");yield(B,f"β οΈ Terjadi error saat upscaling: {I}")
def AO():
if not p or not q:return'Informasi sistem tidak tersedia (library psutil tidak ditemukan).'
D=p.cpu_percent(interval=B);A=p.virtual_memory();C='Tidak terdeteksi (PyTorch tidak menemukan CUDA)'
if H.cuda.is_available():E=H.cuda.get_device_name(0);F=H.cuda.memory_allocated(0)/1024**3;G=H.cuda.get_device_properties(0).total_memory/1024**3;C=f"GPU: {E}\nVRAM Terpakai: {F:.2f} GB / {G:.2f} GB"
I=f"**Platform:** `{q.system()} {q.release()}`";return f"**CPU Terpakai:** `{D:.1f}%`\n**RAM Terpakai:** `{A.percent:.1f}% ({A.used/1024**3:.2f} GB / {A.total/1024**3:.2f} GB)`\n{C}\n---\n{I}"
def AP():
G='### π Riwayat Kosong\nBelum ada gambar yang dihasilkan.'
try:
with V:
if not K.path.exists(P):return[],I.DataFrame(),G
A=I.read_csv(P)
if A.empty:return[],A,G
B=A.sort_values(by=F,ascending=C);H=[i(U/A)for A in B[w]if(U/A).exists()];return H,B,Aj
except h as D:E(f"β Error memuat riwayat: {D}");return[],I.DataFrame(),f"### β οΈ Error\nTidak dapat memuat riwayat: {D}"
def B1(evt,history_df):
G=history_df
if not evt.selected or G.empty:return'### β Detail Gambar\nKlik gambar untuk melihat detailnya.',A.update(visible=C),A.update(visible=C),B
H=evt.index;E=G.iloc[H];I=f"""
**Prompt:** `{E[a]}`
**Negative Prompt:** `{E.get(k,x)}`
---
**Seed:** `{E[b]}` | **Steps:** `{E[l]}`
**File:** `{E[w]}` | **Dibuat:** `{E[F]}`
""";return I,A.update(visible=D),A.update(visible=C),H
def B2(selected_index,history_df):
E=history_df;D=selected_index
if D is B or E.empty:return A.update(),A.update(),A.update(),A.update(),A.update()
C=E.iloc[D];return C[a],C.get(k,N),C[b],C[l],A.Tabs(selected=0)
def B3(selected_index,history_df):
D=history_df;C=selected_index
if C is B or D.empty:return A.update(),A.update()
E=D.iloc[C];F=i(U/E[w]);return AL.open(F),A.Tabs(selected=5)
def A6(image,brightness,contrast,saturation,sharpness,filter_choice):
H=filter_choice;G=image
if G is B:return
A=G.copy()
if H==Ak:A=A.convert('L').convert('RGB')
elif H=='Sepia':
K=A.load();L,N=A.size
for I in range(N):
for J in range(L):D,E,F=A.getpixel((J,I));O,P,Q=M(.393*D+.769*E+.189*F),M(.349*D+.686*E+.168*F),M(.272*D+.534*E+.131*F);K[J,I]=min(255,O),min(255,P),min(255,Q)
C=c.Brightness(A);A=C.enhance(brightness);C=c.Contrast(A);A=C.enhance(contrast);C=c.Color(A);A=C.enhance(saturation);C=c.Sharpness(A);A=C.enhance(sharpness);return A
def B4(selected_index,history_df,request):
H=history_df;G=selected_index;F=request
if G is B or H.empty:A.Warning('Pilih gambar terlebih dahulu sebelum membagikan.');return A.update(visible=C)
E=H.iloc[G];I=i(F.url).split('?')[0]if F and hasattr(F,'url')else Al;J={'prompt':E[a],'neg':E.get(k,N),'seed':E[b],'steps':E[l]};K=urllib.parse.urlencode(J);L=f"{I}?__theme=dark&{K}";M=f"""
**URL untuk Berbagi & Isi Ulang Generator:**
`{L}`
---
**Detail untuk Disalin:**
- **Prompt:** {E[a]}
- **Negative:** {E.get(k,x)}
- **Seed:** {E[b]}
- **Steps:** {E[l]}
""";return A.update(value=M,visible=D)
def B5(chat_id,all_chats_history,request):
G=request;F=all_chats_history;B=chat_id
if not B or B not in F:return A.update(visible=C)
H=F[B][T]
if not H:return A.update(visible=C)
I=i(G.url).split('?')[0]if G and hasattr(G,'url')else Al;L=F[B][O];M=f"{I}chat/{B}?__theme=dark";E=f"### Riwayat Chat: {L}\n";E+=f"**URL Sesi:** `{I}`\n---\n"
for(J,K)in H:
if J:E+=f"\n**π€ Anda:**\n{J}\n"
if K:E+=f"\n**π€ AI:**\n{K}\n"
return A.update(value=E,visible=D)
def A7(all_chats_history):C=all_chats_history;D=i(uuid.uuid4());C[D]={O:'Percakapan Baru',T:[(B,'Halo! Saya Flood, asisten AI dari RenXploit. Ada yang bisa saya bantu?')]};E=[A[O]for A in C.values()];return C,D,C[D][T],A.update(choices=E,value=C[D][O])
def AQ(user_message,chat_id,all_chats_history):
H=user_message;G=chat_id;F=all_chats_history
if not G or G not in F:F,G,E,L=A7({})
E=F[G][T]
if Z(E)==1 and E[0][0]is B:E=[]
E.append((H,B));F[G][T]=E
if Z(E)==1:I=H[:30]+'...'if Z(H)>30 else H;F[G][O]=I
J=[A[O]for A in F.values()];yield(F,E,A.update(choices=J,value=F[G][O]),A.update(value=N),A.update(visible=C));K=s.chat(H,[A for A in E if A[0]is not B]);E[-1]=H,K;F[G][T]=E;yield(F,E,A.update(),A.update(),A.update(visible=D))
def B6(selected_title,all_chats_history):
G=all_chats_history;F=selected_title
if not F:return B,[],A.update(visible=C)
E=B
for(H,I)in G.items():
if I[O]==F:E=H;break
if E:return E,G[E][T],A.update(visible=D)
return B,[],A.update(visible=C)
with A.Blocks(theme=A.themes.Base(),head=As)as d:
A.Markdown("# π RenXploit's Creative AI Suite π",elem_id='main-title');A.Markdown('Sebuah platform lengkap untuk kreativitas Anda, ditenagai oleh AI.',elem_id='main-subtitle');J=A.State({});W=A.State(B);t=A.State(B)
with A.Tabs()as A8:
with A.TabItem('π¨ Image Generator',id=0):
with A.Row(variant=G,equal_height=C):
with A.Column(scale=1):
A.Markdown('### π **Masukan Perintah Anda**');A9=A.Textbox(label=a,placeholder='Contoh: Cinematic photo, seekor rubah merah...',lines=3,info='Jadilah sangat spesifik! Atau gunakan Prompt Enhancer.');AR=A.Textbox(label='Prompt Negatif',placeholder='Contoh: blurry, low quality, bad hands...',lines=2,info='Hal-hal yang TIDAK Anda inginkan.');B7=A.Slider(minimum=1,maximum=8,value=2,step=1,label='Jumlah Gambar');AS=A.Button('β¨ Hasilkan Gambar!',variant=m)
with A.Accordion('βοΈ Opsi Lanjutan',open=C):
AT=A.Slider(minimum=1,maximum=5,value=2,step=1,label='Langkah Iterasi (Kualitas vs Kecepatan)')
with A.Row():AA=A.Number(label=b,value=-1,precision=0,info='Gunakan -1 untuk acak.');B8=A.Button('π² Acak',variant=y)
with A.Column(scale=2):A.Markdown('### πΌοΈ **Hasil Generasi**');B9=A.Gallery(label='Hasil Gambar',show_label=C,elem_id='gallery',columns=2,object_fit=Am,height='auto');BA=A.HTML(visible=C);BB=A.Textbox(label='Informasi Generasi',visible=C,interactive=C,lines=2)
with A.TabItem('π¬ Chat with AI',id=1):
with A.Row(variant=G):
with A.Column(scale=1,min_width=250)as Bc:
A.Markdown('### ποΈ Riwayat Chat');BC=A.Button('β Obrolan Baru',variant=m)
with A.Group(elem_id='chat-history-sidebar'):X=A.Radio(label='Pilih Obrolan',choices=[],interactive=D)
with A.Row(visible=C)as AB:BD=A.Button('π Bagikan Chat')
BE=A.Textbox(label='Salin Konten Chat',lines=10,interactive=D,show_copy_button=D,visible=C)
with A.Column(scale=3):
A.Markdown('### π€ **Asisten AI Flood**')
if not s.is_configured:A.Warning('Fitur Chatbot dinonaktifkan. API Key Gemini tidak terkonfigurasi.')
else:
with A.Column(elem_id='chatbot-container'):
e=A.Chatbot(elem_id='chatbot-display',label='Flood AI',bubble_full_width=C)
with A.Row():f=A.Textbox(show_label=C,placeholder='Ketik pesan Anda di sini...',scale=5);BF=A.Button('Kirim',variant=y,scale=1)
with A.TabItem('β¨ Prompt Enhancer',id=2):
with A.Row(variant=G):
with A.Column():A.Markdown('### πͺ **Ubah Ide Jadi Prompt Ajaib**\nCukup tulis ide sederhana, dan biarkan AI menyempurnakannya menjadi prompt yang detail dan artistik.');BG=A.Textbox(label='Ide Sederhana Anda',placeholder='Contoh: seekor astronot di hutan alien',lines=3);BH=A.Button('Buat Prompt Ajaib!',variant=m);AU=A.Textbox(label='Prompt yang Disempurnakan',lines=5,interactive=D,show_copy_button=D);BI=A.Button('β‘οΈ Kirim & Pindah ke Generator')
with A.TabItem('π AI Image Upscaler',id=3):
with A.Row(variant=G,equal_height=C):
with A.Column():A.Markdown('### **Tingkatkan Resolusi Gambar**\nUnggah gambar untuk meningkatkan kualitas dan ukurannya hingga 4x lipat menggunakan AI.');BJ=A.Image(type='pil',label='Unggah Gambar Anda di Sini');BK=A.Slider(minimum=S,maximum=3.,value=S,step=.1,label='Tingkat Peningkatan Kejernihan',info='Setelah di-upscale 4x, atur kejernihan gambar di sini. 1.0 = Tanpa efek.');BL=A.Button('Tingkatkan Resolusi!',variant=m)
with A.Column():A.Markdown('### **Hasil Peningkatan Resolusi**');BM=A.Image(label='Gambar Hasil Upscale',interactive=C,show_download_button=D);BN=A.Markdown('Status: Menunggu gambar...')
with A.TabItem('πΌοΈ Galeri & Riwayat',id=4)as BO:
with A.Row(variant=G):
with A.Column(scale=2):A.Markdown('### **Galeri Hasil Generasi Anda**');AC=A.Gallery(label='Riwayat Gambar',show_label=C,columns=4,object_fit=Am,height='auto',elem_id='history_gallery');Y=A.State()
with A.Column(scale=1):
A.Markdown('### **Detail & Aksi**');AD=A.Markdown(Aj);BP=A.Button('π Segarkan Galeri',variant=y)
with A.Row(visible=C)as BQ:BR=A.Button('Kirim ke Generator');BS=A.Button('Kirim ke Editor');BT=A.Button('π Bagikan Detail')
AV=A.Textbox(label='URL & Detail untuk Dibagikan',lines=8,interactive=D,show_copy_button=D,visible=C)
with A.TabItem('π¨ Image Editor',id=5):
with A.Row(variant=G):
with A.Column(scale=1):
A.Markdown('### **Toolkit Pasca-Produksi**');AE=A.Image(type='pil',label='Unggah Gambar atau Kirim dari Riwayat')
with A.Accordion('Penyesuaian',open=D):AW=A.Slider(minimum=.5,maximum=1.5,value=S,step=.05,label='Kecerahan');AX=A.Slider(minimum=.5,maximum=1.5,value=S,step=.05,label='Kontras');AY=A.Slider(minimum=.0,maximum=2.,value=S,step=.05,label='Saturasi Warna');AZ=A.Slider(minimum=.0,maximum=3.,value=S,step=.1,label='Ketajaman')
with A.Accordion('Filter Cepat',open=D):Aa=A.Radio(['None',Ak,'Sepia'],label='Pilih Filter',value='None')
with A.Column(scale=1):A.Markdown('### **Hasil Editing**');AF=A.Image(label='Hasil Akhir',interactive=C,show_download_button=D)
with A.TabItem('π Visitor Monitor',id=6):
with A.Row(variant=G):
with A.Column():
A.Markdown('### π **Live Visitor Monitor**\nPantau jumlah total pengunjung aplikasi Anda secara real-time.')
with A.Row():
with A.Column(scale=3):AG=A.Markdown('## π Memuat data...')
with A.Column(scale=2):u=A.Radio([An,Ag,Ah,Ai],label='Tampilkan data untuk',value=An);BU=A.Button('π Segarkan Manual',variant=y)
AH=A.LinePlot(x=F,y=R,title='Grafik Pertumbuhan Pengunjung',tooltip=[F,R],height=500,interactive=D)
with A.TabItem('βοΈ System & Settings',id=7):
with A.Row(variant=G):
with A.Column():A.Markdown('### **Live System Monitor**');Ab=A.Markdown('Memuat info sistem...');BV=A.Button('Trigger System Info',visible=C,elem_id='system-info-trigger-btn')
with A.Column():
A.Markdown('### **Pengaturan Aplikasi**')
with A.Accordion('Kualitas Model',open=D):A.Radio([Ao,Ap],value=Ao if Q==v else Ap,label='Presisi Model Generator',interactive=C,info='Terkunci. Ditentukan saat aplikasi dimulai.')
with A.TabItem('π‘ Panduan Prompting',id=8):
with A.Row(variant=G):A.Markdown('## Cara Menjadi "Art Director" yang Hebat untuk AI...\n (Konten panduan Anda di sini)')
with A.TabItem('π Blog & Updates',id=9):
with A.Row(variant=G):A.Markdown("### Perkembangan Terbaru dari RenXploit's AI Suite\nv3.0 (Perbaikan Kritis): Memperbaiki bug pada fitur Share URL dan Share Detail Galeri yang disebabkan oleh perbedaan versi Gradio dan logika event yang salah.\nv2.8: Mengganti komponen `gr.Box` dengan `gr.Group` untuk kompatibilitas.\nv2.7: Perombakan total UI Chatbot dengan fitur riwayat, new chat, dan share.\nRencana Berikutnya: Menjajaki model generator gambar yang berbeda dan fitur Inpainting/Outpainting.")
with A.TabItem('βΉοΈ About & Support',id=10):
with A.Row(variant=G):
with A.Column():
A.Markdown('### Tentang Proyek dan Dukungan')
with A.Accordion("Tentang RenXploit's Creative AI Suite",open=D):A.Markdown("\n RenXploit's Creative AI Suite adalah proyek pribadi untuk mengeksplorasi AI generatif.\n Hubungi saya melalui: ngoprek.xyz/contact\n ")
with A.Accordion('Laporkan Masalah atau Beri Masukan'):BW=A.Textbox(label='Nama Anda');BX=A.Textbox(label='Email Anda (Opsional)');BY=A.Textbox(label='Pesan Anda',lines=5,placeholder='Jelaskan masalah atau ide Anda...');BZ=A.Button('Kirim Laporan',variant=m);Ba=A.Markdown(visible=C)
A.Markdown("---\n<div class='footer'><p>Dibuat dengan β€οΈ oleh <b>RenXploit</b>.</p></div>",elem_classes='footer');d.load(Aw,inputs=B,outputs=B);d.load(fn=A7,inputs=[J],outputs=[J,W,e,X]);B8.click(lambda:-1,outputs=AA);AS.click(fn=Ay,inputs=[A9,AR,AT,AA,B7],outputs=[B9,BA,AS,BB]);BC.click(fn=A7,inputs=[J],outputs=[J,W,e,X]);BF.click(fn=AQ,inputs=[f,W,J],outputs=[J,e,X,f,AB]);f.submit(fn=AQ,inputs=[f,W,J],outputs=[J,e,X,f,AB]);X.change(fn=B6,inputs=[X,J],outputs=[W,e,AB]);BD.click(fn=B5,inputs=[W,J],outputs=[BE]);BH.click(fn=A_,inputs=[BG],outputs=[AU]);BI.click(fn=lambda prompt:(prompt,A.Tabs(selected=0)),inputs=[AU],outputs=[A9,A8]);BL.click(fn=B0,inputs=[BJ,BK],outputs=[BM,BN]);BO.select(fn=AP,inputs=B,outputs=[AC,Y,AD]);BP.click(fn=AP,inputs=B,outputs=[AC,Y,AD]);AC.select(fn=B1,inputs=[Y],outputs=[AD,BQ,AV,t]);BR.click(fn=B2,inputs=[t,Y],outputs=[A9,AR,AA,AT,A8]);BS.click(fn=B3,inputs=[t,Y],outputs=[AE,A8]);BT.click(fn=B4,inputs=[t,Y],outputs=[AV]);AI=[AE,AW,AX,AY,AZ,Aa]
for Bb in[AW,AX,AY,AZ]:Bb.release(fn=A6,inputs=AI,outputs=AF)
Aa.change(fn=A6,inputs=AI,outputs=AF);AE.change(fn=A6,inputs=AI,outputs=AF);d.load(fn=A5,inputs=[u],outputs=[AG,AH]);BU.click(fn=A5,inputs=[u],outputs=[AG,AH]);u.change(fn=A5,inputs=[u],outputs=[AG,AH]);BV.click(fn=AO,inputs=B,outputs=Ab);d.load(fn=AO,inputs=B,outputs=Ab);BZ.click(fn=Az,inputs=[BW,BX,BY],outputs=[Ba])
if __name__=='__main__':d.launch(debug=D) |