Germinal commited on
Commit
d75be57
·
verified ·
1 Parent(s): d1c6110

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +1076 -600
index.html CHANGED
@@ -1,640 +1,1116 @@
1
  <!DOCTYPE html>
2
  <html lang="pt-BR">
3
  <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Architect Planner - Ajuste de Comportamento</title>
7
- <script src="https://cdn.tailwindcss.com"></script>
8
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
- <style>
10
- :root {
11
- --primary: #6366f1;
12
- --primary-dark: #4f46e5;
13
- --secondary: #8b5cf6;
14
- --success: #10b981;
15
- --warning: #f59e0b;
16
- --danger: #ef4444;
17
- --bg-dark: #0f172a;
18
- --bg-darker: #0b1120;
19
- --text-primary: #e2e8f0;
20
- --text-secondary: #94a3b8;
21
- }
 
 
 
22
 
23
- body {
24
- font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
25
- background: var(--bg-dark);
26
- color: var(--text-primary);
27
- }
28
 
29
- .gradient-border {
30
- background: linear-gradient(90deg, var(--primary), var(--secondary));
31
- padding: 1px;
32
- border-radius: 1rem;
33
- }
 
 
 
34
 
35
- .gradient-border-inner {
36
- background: var(--bg-darker);
37
- border-radius: 0.95rem;
38
- }
 
39
 
40
- .typing-indicator {
41
- display: flex;
42
- gap: 0.25rem;
43
- }
 
 
 
 
 
 
 
 
44
 
45
- .typing-dot {
46
- width: 0.5rem;
47
- height: 0.5rem;
48
- background: var(--text-secondary);
49
- border-radius: 50%;
50
- animation: typing 1.4s infinite ease-in-out;
51
- }
52
 
53
- .typing-dot:nth-child(1) { animation-delay: -0.32s; }
54
- .typing-dot:nth-child(2) { animation-delay: -0.16s; }
 
 
 
 
 
 
55
 
56
- @keyframes typing {
57
- 0%, 80%, 100% { transform: scale(0); }
58
- 40% { transform: scale(1); }
59
- }
60
 
61
- .fade-in {
62
- animation: fadeIn 0.3s ease-out;
63
- }
 
 
 
 
64
 
65
- @keyframes fadeIn {
66
- from { opacity: 0; transform: translateY(10px); }
67
- to { opacity: 1; transform: translateY(0); }
68
- }
 
 
69
 
70
- .action-button {
71
- transition: all 0.2s ease;
72
- border-radius: 0.5rem;
73
- font-weight: 500;
74
- padding: 0.5rem 1rem;
75
- display: inline-flex;
76
- align-items: center;
77
- gap: 0.5rem;
78
- }
79
 
80
- .action-button:hover {
81
- transform: translateY(-2px);
82
- box-shadow: 0 4px 12px rgba(0,0,0,0.15);
83
- }
84
 
85
- .markdown-content {
86
- line-height: 1.6;
87
- }
 
 
 
88
 
89
- .markdown-content h3 {
90
- color: var(--primary);
91
- margin-top: 1.5rem;
92
- margin-bottom: 0.75rem;
93
- font-size: 1.125rem;
94
- }
 
95
 
96
- .markdown-content ul {
97
- list-style-type: disc;
98
- padding-left: 1.5rem;
99
- margin-bottom: 1rem;
100
- }
101
 
102
- .markdown-content li {
103
- margin-bottom: 0.5rem;
104
- }
 
 
 
 
 
 
 
 
105
 
106
- .markdown-content code {
107
- background: rgba(30, 41, 59, 0.5);
108
- padding: 0.25rem 0.5rem;
109
- border-radius: 0.25rem;
110
- font-family: 'Fira Code', monospace;
111
- }
112
 
113
- .strategy-card {
114
- background: rgba(30, 41, 59, 0.3);
115
- border: 1px solid rgba(71, 85, 105, 0.3);
116
- border-radius: 0.75rem;
117
- padding: 1rem;
118
- margin-bottom: 1rem;
119
- }
120
 
121
- .strategy-card:hover {
122
- border-color: var(--primary);
123
- background: rgba(99, 102, 241, 0.05);
124
- }
125
 
126
- .checkbox-custom {
127
- appearance: none;
128
- width: 1.25rem;
129
- height: 1.25rem;
130
- border: 2px solid var(--text-secondary);
131
- border-radius: 0.25rem;
132
- position: relative;
133
- cursor: pointer;
134
- transition: all 0.2s;
135
- }
 
 
136
 
137
- .checkbox-custom:checked {
138
- background: var(--primary);
139
- border-color: var(--primary);
140
- }
 
 
 
 
141
 
142
- .checkbox-custom:checked::after {
143
- content: '✓';
144
- position: absolute;
145
- color: white;
146
- font-size: 0.8rem;
147
- top: 50%;
148
- left: 50%;
149
- transform: translate(-50%, -50%);
150
- }
151
 
152
- .decision-log {
153
- border-left: 3px solid var(--primary);
154
- padding-left: 1rem;
155
- margin-left: 1rem;
156
- }
 
 
 
157
 
158
- .version-badge {
159
- display: inline-block;
160
- padding: 0.25rem 0.5rem;
161
- border-radius: 0.25rem;
162
- font-size: 0.75rem;
163
- font-weight: 600;
164
- margin-left: 0.5rem;
165
- }
166
 
167
- .version-badge.v1 { background: rgba(16, 185, 129, 0.2); color: var(--success); }
168
- .version-badge.v1_1 { background: rgba(59, 130, 246, 0.2); color: #3b82f6; }
169
- .version-badge.v1_2 { background: rgba(147, 51, 234, 0.2); color: #9333ea; }
170
 
171
- .tooltip {
172
- position: relative;
173
- display: inline-block;
174
- }
175
 
176
- .tooltip .tooltiptext {
177
- visibility: hidden;
178
- background-color: var(--bg-darker);
179
- color: var(--text-primary);
180
- text-align: center;
181
- border-radius: 0.375rem;
182
- padding: 0.5rem;
183
- position: absolute;
184
- z-index: 1;
185
- bottom: 125%;
186
- left: 50%;
187
- transform: translateX(-50%);
188
- opacity: 0;
189
- transition: opacity 0.3s;
190
- white-space: nowrap;
191
- font-size: 0.75rem;
192
- }
193
 
194
- .tooltip:hover .tooltiptext {
195
- visibility: visible;
196
- opacity: 1;
197
- }
198
- </style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
  </head>
200
- <body class="min-h-screen">
201
- <div class="flex flex-col h-screen">
202
- <!-- Header -->
203
- <header class="bg-bg-darker border-b border-slate-800 px-6 py-4">
204
- <div class="flex items-center justify-between">
205
- <div class="flex items-center gap-3">
206
- <div class="w-10 h-10 bg-gradient-to-br from-indigo-600 to-purple-600 rounded-xl flex items-center justify-center text-xl shadow-lg shadow-indigo-500/20">
207
- <i class="fas fa-brain"></i>
208
- </div>
209
- <div>
210
- <h1 class="font-bold text-white text-lg">Architect Planner</h1>
211
- <p class="text-xs text-slate-400">Parceiro Técnico de Co-criação</p>
212
- </div>
213
- </div>
214
- <div class="flex items-center gap-4">
215
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-xs text-slate-400 hover:text-white transition-colors">
216
- Built with anycoder
217
- </a>
218
- <div class="w-2 h-2 rounded-full bg-green-500 shadow-[0_0_8px_#10b981]"></div>
219
- </div>
220
- </div>
221
- </header>
222
-
223
- <div class="flex flex-1 overflow-hidden">
224
- <!-- Sidebar - Chat History -->
225
- <div class="w-80 bg-slate-900 border-r border-slate-800 flex flex-col">
226
- <div class="p-4 border-b border-slate-800">
227
- <h3 class="text-sm font-semibold text-white">Histórico de Decisões</h3>
228
- </div>
229
- <div class="flex-1 overflow-y-auto p-4 space-y-4">
230
- <div class="decision-log">
231
- <div class="flex items-center gap-2 mb-2">
232
- <span class="text-xs text-slate-400">v1.0</span>
233
- <span class="version-badge v1">Arquitetura Base</span>
234
- </div>
235
- <p class="text-sm text-slate-300">Estrutura inicial do plugin definida com React e TailwindCSS</p>
236
- </div>
237
-
238
- <div class="decision-log">
239
- <div class="flex items-center gap-2 mb-2">
240
- <span class="text-xs text-slate-400">v1.1</span>
241
- <span class="version-badge v1_1">Worker Python</span>
242
- </div>
243
- <p class="text-sm text-slate-300">Adicionado worker para processamento assíncrono</p>
244
- </div>
245
- </div>
246
- </div>
247
 
248
- <!-- Main Content -->
249
- <div class="flex-1 flex flex-col overflow-hidden">
250
- <!-- Chat Interface -->
251
- <div class="flex-1 overflow-y-auto p-6 space-y-6">
252
- <!-- Initial Message -->
253
- <div class="gradient-border">
254
- <div class="gradient-border-inner p-6">
255
- <div class="flex items-start gap-4">
256
- <div class="w-8 h-8 bg-indigo-600 rounded-full flex items-center justify-center flex-shrink-0">
257
- <i class="fas fa-robot text-white text-sm"></i>
258
- </div>
259
- <div>
260
- <p class="text-sm text-slate-300 mb-4">Olá! Sou seu parceiro técnico de co-criação. Como posso ajudar a desenvolver sua ideia hoje?</p>
261
-
262
- <div class="flex gap-2">
263
- <button class="action-button bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg">
264
- <i class="fas fa-lightbulb"></i> Explicar conceito
265
- </button>
266
- <button class="action-button bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg">
267
- <i class="fas fa-cogs"></i> Ver estratégias
268
- </button>
269
- </div>
270
- </div>
271
- </div>
272
- </div>
273
- </div>
274
-
275
- <!-- Example: User asks about anti-bot -->
276
- <div class="flex justify-end">
277
- <div class="gradient-border">
278
- <div class="gradient-border-inner p-4 max-w-md">
279
- <p class="text-sm text-white">Como funciona anti-bot?</p>
280
- </div>
281
- </div>
282
- </div>
283
-
284
- <!-- Planner Response with Options -->
285
- <div class="gradient-border fade-in">
286
- <div class="gradient-border-inner p-6">
287
- <div class="flex items-start gap-4">
288
- <div class="w-8 h-8 bg-indigo-600 rounded-full flex items-center justify-center flex-shrink-0">
289
- <i class="fas fa-robot text-white text-sm"></i>
290
- </div>
291
- <div class="markdown-content">
292
- <h3>📘 Explicação: Anti-Bot</h3>
293
- <p><strong>O que é:</strong> Técnicas para evitar que sistemas automatizados (bots) interajam com seu aplicativo de maneiras indesejadas.</p>
294
-
295
- <p><strong>Como funciona:</strong> Combina múltiplas camadas de proteção para tornar difícil para bots imitar comportamento humano enquanto mantém a usabilidade para usuários reais.</p>
296
-
297
- <p><strong>Quando usar:</strong> Quando seu aplicativo está sujeito a scraping, ataques automatizados ou uso abusivo de recursos.</p>
298
-
299
- <p><strong>Riscos:</strong> Pode aumentar complexidade e custo operacional. Requer monitoramento contínuo para evitar falsos positivos.</p>
300
-
301
- <h3>🧠 Estratégias Possíveis</h3>
302
-
303
- <!-- Strategy 1 -->
304
- <div class="strategy-card">
305
- <div class="flex items-start gap-3">
306
- <input type="checkbox" class="checkbox-custom mt-1" id="ip-residential">
307
- <div>
308
- <h4 class="font-semibold text-white mb-1">Rotação de IP (Residencial)</h4>
309
- <p class="text-sm text-slate-300 mb-2">Usa IPs de provedores residenciais para parecer tráfego legítimo.</p>
310
- <div class="flex gap-4 text-xs">
311
- <span class="text-green-400">✔️ Alta legitimidade</span>
312
- <span class="text-yellow-400">⚠️ Custo elevado</span>
313
- <span class="text-blue-400">🧩 Complexidade média</span>
314
- <span class="text-purple-400">📈 Escalável</span>
315
- </div>
316
- </div>
317
- </div>
318
- </div>
319
-
320
- <!-- Strategy 2 -->
321
- <div class="strategy-card">
322
- <div class="flex items-start gap-3">
323
- <input type="checkbox" class="checkbox-custom mt-1" id="ip-datacenter">
324
- <div>
325
- <h4 class="font-semibold text-white mb-1">Rotação de IP (Datacenter)</h4>
326
- <p class="text-sm text-slate-300 mb-2">IPs mais baratos de data centers, detectáveis por alguns sistemas.</p>
327
- <div class="flex gap-4 text-xs">
328
- <span class="text-green-400">✔️ Baixo custo</span>
329
- <span class="text-yellow-400">⚠️ Fácil detecção</span>
330
- <span class="text-blue-400">🧩 Complexidade baixa</span>
331
- <span class="text-purple-400">📈 Escalável</span>
332
- </div>
333
- </div>
334
- </div>
335
- </div>
336
-
337
- <!-- Strategy 3 -->
338
- <div class="strategy-card">
339
- <div class="flex items-start gap-3">
340
- <input type="checkbox" class="checkbox-custom mt-1" id="user-agent">
341
- <div>
342
- <h4 class="font-semibold text-white mb-1">Rotação de User-Agent</h4>
343
- <p class="text-sm text-slate-300 mb-2">Altera identificadores de navegador para evitar padrões detectáveis.</p>
344
- <div class="flex gap-4 text-xs">
345
- <span class="text-green-400">✔️ Implementação simples</span>
346
- <span class="text-yellow-400">⚠️ Eficácia limitada</span>
347
- <span class="text-blue-400">🧩 Complexidade baixa</span>
348
- <span class="text-purple-400">📈 Escalável</span>
349
- </div>
350
- </div>
351
- </div>
352
- </div>
353
-
354
- <!-- Strategy 4 -->
355
- <div class="strategy-card">
356
- <div class="flex items-start gap-3">
357
- <input type="checkbox" class="checkbox-custom mt-1" id="rate-limit">
358
- <div>
359
- <h4 class="font-semibold text-white mb-1">Controle de Frequência</h4>
360
- <p class="text-sm text-slate-300 mb-2">Limita requisições por IP/usuário para evitar abuso.</p>
361
- <div class="flex gap-4 text-xs">
362
- <span class="text-green-400">✔️ Proteção básica efetiva</span>
363
- <span class="text-yellow-400">⚠️ Pode afetar UX</span>
364
- <span class="text-blue-400">🧩 Complexidade média</span>
365
- <span class="text-purple-400">📈 Escalável</span>
366
- </div>
367
- </div>
368
- </div>
369
- </div>
370
-
371
- <!-- Strategy 5 -->
372
- <div class="strategy-card">
373
- <div class="flex items-start gap-3">
374
- <input type="checkbox" class="checkbox-custom mt-1" id="captcha">
375
- <div>
376
- <h4 class="font-semibold text-white mb-1">Tratamento de CAPTCHA</h4>
377
- <p class="text-sm text-slate-300 mb-2">Soluções para resolver ou evitar CAPTCHAs em fluxos automatizados.</p>
378
- <div class="flex gap-4 text-xs">
379
- <span class="text-green-400">✔️ Alta efetividade</span>
380
- <span class="text-yellow-400">⚠️ Alto custo operacional</span>
381
- <span class="text-blue-400">🧩 Complexidade alta</span>
382
- <span class="text-purple-400">📈 Limitada</span>
383
- </div>
384
- </div>
385
- </div>
386
- </div>
387
-
388
- <!-- Action Buttons -->
389
- <div class="mt-6 pt-4 border-t border-slate-800">
390
- <h4 class="text-sm font-semibold text-white mb-3">Deseja aplicar alguma estratégia ao blueprint?</h4>
391
- <div class="flex flex-wrap gap-2">
392
- <button class="action-button bg-green-600 hover:bg-green-500 text-white px-4 py-2">
393
- <i class="fas fa-plus"></i> Adicionar Selecionadas
394
- </button>
395
- <button class="action-button bg-blue-600 hover:bg-blue-500 text-white px-4 py-2">
396
- <i class="fas fa-edit"></i> Ajustar Blueprint
397
- </button>
398
- <button class="action-button bg-slate-600 hover:bg-slate-500 text-white px-4 py-2">
399
- <i class="fas fa-times"></i> Apenas Entender
400
- </button>
401
- </div>
402
- </div>
403
- </div>
404
- </div>
405
- </div>
406
- </div>
407
-
408
- <!-- Example: User requests more info -->
409
- <div class="flex justify-end">
410
- <div class="gradient-border">
411
- <div class="gradient-border-inner p-4 max-w-md">
412
- <p class="text-sm text-white">Quais são os riscos da rotação de IP?</p>
413
- </div>
414
- </div>
415
- </div>
416
-
417
- <!-- Planner Detailed Response -->
418
- <div class="gradient-border fade-in">
419
- <div class="gradient-border-inner p-6">
420
- <div class="flex items-start gap-4">
421
- <div class="w-8 h-8 bg-indigo-600 rounded-full flex items-center justify-center flex-shrink-0">
422
- <i class="fas fa-robot text-white text-sm"></i>
423
- </div>
424
- <div class="markdown-content">
425
- <h3>⚠️ Riscos da Rotação de IP</h3>
426
-
427
- <h4 class="font-semibold text-white mt-4 mb-2">1. Bloqueio por Provedores</h4>
428
- <p class="text-sm text-slate-300 mb-3">Alguns serviços detectam e bloqueiam IPs conhecidos de data centers ou serviços de proxy.</p>
429
-
430
- <h4 class="font-semibold text-white mb-2">2. Custo Operacional</h4>
431
- <p class="text-sm text-slate-300 mb-3">Serviços de IPs residenciais podem ser caros em escala, especialmente para aplicações com alto volume de requisições.</p>
432
-
433
- <h4 class="font-semibold text-white mb-2">3. Latência Aumentada</h4>
434
- <p class="text-sm text-slate-300 mb-3">A rotação constante de IPs pode introduzir latência adicional nas requisições.</p>
435
-
436
- <h4 class="font-semibold text-white mb-2">4. Complexidade de Gerenciamento</h4>
437
- <p class="text-sm text-slate-300 mb-3">Requer lógica adicional para gerenciar pools de IPs, falhas e recuperação.</p>
438
-
439
- <div class="mt-4 pt-4 border-t border-slate-800">
440
- <div class="flex gap-2">
441
- <button class="action-button bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg">
442
- <i class="fas fa-arrow-left"></i> Voltar às Estratégias
443
- </button>
444
- <button class="action-button bg-slate-700 hover:bg-slate-600 text-white px-4 py-2 rounded-lg">
445
- <i class="fas fa-question-circle"></i> Perguntar sobre outra estratégia
446
- </button>
447
- </div>
448
- </div>
449
- </div>
450
- </div>
451
- </div>
452
- </div>
453
-
454
- <!-- Example: User approves changes -->
455
- <div class="flex justify-end">
456
- <div class="gradient-border">
457
- <div class="gradient-border-inner p-4 max-w-md">
458
- <p class="text-sm text-white">Vamos adicionar rotação de IP residencial e controle de frequência</p>
459
- </div>
460
- </div>
461
- </div>
462
-
463
- <!-- Confirmation and Update -->
464
- <div class="gradient-border fade-in">
465
- <div class="gradient-border-inner p-6">
466
- <div class="flex items-start gap-4">
467
- <div class="w-8 h-8 bg-indigo-600 rounded-full flex items-center justify-center flex-shrink-0">
468
- <i class="fas fa-robot text-white text-sm"></i>
469
- </div>
470
- <div class="markdown-content">
471
- <h3>✅ Atualização Aprovada</h3>
472
- <p class="text-sm text-slate-300 mb-4">As seguintes estratégias foram adicionadas ao blueprint atual:</p>
473
-
474
- <div class="space-y-3 mb-6">
475
- <div class="flex items-center gap-3">
476
- <i class="fas fa-check-circle text-green-400"></i>
477
- <div>
478
- <p class="font-semibold text-white">Rotação de IP (Residencial)</p>
479
- <p class="text-xs text-slate-400">Adicionado worker para gerenciamento de pool de IPs</p>
480
- </div>
481
- </div>
482
-
483
- <div class="flex items-center gap-3">
484
- <i class="fas fa-check-circle text-green-400"></i>
485
- <div>
486
- <p class="font-semibold text-white">Controle de Frequência</p>
487
- <p class="text-xs text-slate-400">Middleware de rate-limiting configurado</p>
488
- </div>
489
- </div>
490
- </div>
491
-
492
- <div class="decision-log">
493
- <div class="flex items-center gap-2 mb-2">
494
- <span class="text-xs text-slate-400">v1.2</span>
495
- <span class="version-badge v1_2">Anti-bot com rotação de IP</span>
496
- </div>
497
- <p class="text-sm text-slate-300">Estratégias de proteção contra bots implementadas (aprovado pelo usuário)</p>
498
- </div>
499
-
500
- <div class="mt-6 pt-4 border-t border-slate-800">
501
- <h4 class="text-sm font-semibold text-white mb-3">Próximos passos:</h4>
502
- <div class="flex flex-wrap gap-2">
503
- <button class="action-button bg-blue-600 hover:bg-blue-500 text-white px-4 py-2">
504
- <i class="fas fa-plus"></i> Adicionar outra funcionalidade
505
- </button>
506
- <button class="action-button bg-purple-600 hover:bg-purple-500 text-white px-4 py-2">
507
- <i class="fas fa-search"></i> Analisar impacto técnico
508
- </button>
509
- <button class="action-button bg-green-600 hover:bg-green-500 text-white px-4 py-2">
510
- <i class="fas fa-check"></i> Finalizar Planejamento
511
- </button>
512
- </div>
513
- </div>
514
- </div>
515
- </div>
516
- </div>
517
- </div>
518
- </div>
519
-
520
- <!-- Input Area -->
521
- <div class="p-4 border-t border-slate-800 bg-slate-900">
522
- <div class="relative">
523
- <textarea
524
- class="w-full bg-slate-800 border border-slate-700 rounded-xl p-3 pr-12 text-sm text-white focus:border-indigo-500 outline-none resize-none h-20 placeholder-slate-400 transition-all"
525
- placeholder="Faça uma pergunta ou solicite explicações..."
526
- ></textarea>
527
- <button class="absolute right-3 bottom-3 p-2 bg-indigo-600 hover:bg-indigo-500 text-white rounded-lg transition-colors">
528
- <i class="fas fa-paper-plane"></i>
529
- </button>
530
- </div>
531
- <div class="flex justify-between items-center mt-2">
532
- <div class="flex gap-2">
533
- <button class="text-xs text-slate-400 hover:text-white transition-colors">
534
- <i class="fas fa-paperclip mr-1"></i> Anexar contexto
535
- </button>
536
- <button class="text-xs text-slate-400 hover:text-white transition-colors">
537
- <i class="fas fa-history mr-1"></i> Histórico
538
- </button>
539
- </div>
540
- <div class="text-xs text-slate-500">
541
- <i class="fas fa-info-circle mr-1"></i> Modo: Co-criação Ativa
542
- </div>
543
- </div>
544
- </div>
545
- </div>
546
 
547
- <!-- Right Sidebar - Blueprint Status -->
548
- <div class="w-64 bg-slate-900 border-l border-slate-800 flex flex-col">
549
- <div class="p-4 border-b border-slate-800">
550
- <h3 class="text-sm font-semibold text-white">Status do Blueprint</h3>
551
- </div>
552
- <div class="flex-1 overflow-y-auto p-4">
553
- <div class="space-y-4">
554
- <div>
555
- <h4 class="text-xs text-slate-400 uppercase tracking-wider mb-2">Versão Atual</h4>
556
- <div class="flex items-center gap-2">
557
- <span class="text-lg font-bold text-white">v1.2</span>
558
- <span class="version-badge v1_2">Anti-bot</span>
559
- </div>
560
- </div>
561
-
562
- <div>
563
- <h4 class="text-xs text-slate-400 uppercase tracking-wider mb-2">Componentes</h4>
564
- <div class="space-y-2">
565
- <div class="flex items-center gap-2">
566
- <i class="fas fa-check-circle text-green-400 text-xs"></i>
567
- <span class="text-sm text-slate-300">Arquitetura Base</span>
568
- </div>
569
- <div class="flex items-center gap-2">
570
- <i class="fas fa-check-circle text-green-400 text-xs"></i>
571
- <span class="text-sm text-slate-300">Worker Python</span>
572
- </div>
573
- <div class="flex items-center gap-2">
574
- <i class="fas fa-check-circle text-green-400 text-xs"></i>
575
- <span class="text-sm text-slate-300">Anti-bot (IP + Rate)</span>
576
- </div>
577
- </div>
578
- </div>
579
-
580
- <div>
581
- <h4 class="text-xs text-slate-400 uppercase tracking-wider mb-2">Próximas Decisões</h4>
582
- <div class="space-y-1">
583
- <div class="flex items-center gap-2 text-xs text-slate-400">
584
- <i class="fas fa-circle text-yellow-500"></i>
585
- <span>Autenticação</span>
586
- </div>
587
- <div class="flex items-center gap-2 text-xs text-slate-400">
588
- <i class="fas fa-circle text-yellow-500"></i>
589
- <span>Logging e Monitoramento</span>
590
- </div>
591
- </div>
592
- </div>
593
- </div>
594
- </div>
595
- <div class="p-4 border-t border-slate-800">
596
- <button class="w-full bg-slate-700 hover:bg-slate-600 text-white py-2 rounded-lg transition-colors">
597
- <i class="fas fa-eye mr-2"></i> Visualizar Blueprint Completo
598
- </button>
599
- </div>
600
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
 
604
- <script>
605
- // Simple interaction handlers
606
- document.addEventListener('DOMContentLoaded', function() {
607
- // Auto-scroll to bottom
608
- const chatContainer = document.querySelector('.flex-1.overflow-y-auto.p-6');
609
- if (chatContainer) {
610
- chatContainer.scrollTop = chatContainer.scrollHeight;
611
- }
612
-
613
- // Button interactions
614
- document.querySelectorAll('.action-button').forEach(button => {
615
- button.addEventListener('click', function() {
616
- // Simple visual feedback
617
- this.style.transform = 'translateY(1px)';
618
- setTimeout(() => {
619
- this.style.transform = '';
620
- }, 150);
621
- });
622
- });
623
-
624
- // Checkbox interactions
625
- document.querySelectorAll('.checkbox-custom').forEach(checkbox => {
626
- checkbox.addEventListener('change', function() {
627
- const card = this.closest('.strategy-card');
628
- if (this.checked) {
629
- card.style.borderColor = 'var(--primary)';
630
- card.style.background = 'rgba(99, 102, 241, 0.05)';
631
- } else {
632
- card.style.borderColor = 'rgba(71, 85, 105, 0.3)';
633
- card.style.background = 'rgba(30, 41, 59, 0.3)';
634
- }
635
- });
636
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
  });
638
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  </body>
640
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="pt-BR">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Backend Connector</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ :root {
11
+ --primary-color: #4285f4;
12
+ --primary-hover: #3367d6;
13
+ --secondary-color: #34a853;
14
+ --accent-color: #ea4335;
15
+ --warning-color: #fbbc05;
16
+ --text-color: #202124;
17
+ --text-secondary: #5f6368;
18
+ --light-gray: #f8f9fa;
19
+ --medium-gray: #e8eaed;
20
+ --dark-gray: #dadce0;
21
+ --border-radius: 12px;
22
+ --box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
23
+ --transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
24
+ }
25
 
26
+ * {
27
+ margin: 0;
28
+ padding: 0;
29
+ box-sizing: border-box;
30
+ }
31
 
32
+ body {
33
+ font-family: 'Inter', sans-serif;
34
+ background: linear-gradient(135deg, #f5f7fa 0%, #e4e8f0 100%);
35
+ color: var(--text-color);
36
+ line-height: 1.6;
37
+ min-height: 100vh;
38
+ padding: 2rem;
39
+ }
40
 
41
+ .container {
42
+ max-width: 1400px;
43
+ margin: 0 auto;
44
+ padding: 0 1rem;
45
+ }
46
 
47
+ header {
48
+ background: white;
49
+ padding: 1.5rem 2rem;
50
+ border-radius: var(--border-radius);
51
+ box-shadow: var(--box-shadow);
52
+ margin-bottom: 2rem;
53
+ display: flex;
54
+ justify-content: space-between;
55
+ align-items: center;
56
+ flex-wrap: wrap;
57
+ gap: 1rem;
58
+ }
59
 
60
+ .header-content {
61
+ display: flex;
62
+ align-items: center;
63
+ gap: 1rem;
64
+ flex-wrap: wrap;
65
+ }
 
66
 
67
+ .logo {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 0.75rem;
71
+ font-size: 1.5rem;
72
+ font-weight: 700;
73
+ color: var(--primary-color);
74
+ }
75
 
76
+ .logo-icon {
77
+ font-size: 2rem;
78
+ color: var(--primary-color);
79
+ }
80
 
81
+ .anycoder-link {
82
+ font-size: 0.9rem;
83
+ color: var(--text-secondary);
84
+ display: flex;
85
+ align-items: center;
86
+ gap: 0.5rem;
87
+ }
88
 
89
+ .anycoder-link a {
90
+ color: var(--primary-color);
91
+ text-decoration: none;
92
+ font-weight: 500;
93
+ transition: var(--transition);
94
+ }
95
 
96
+ .anycoder-link a:hover {
97
+ text-decoration: underline;
98
+ color: var(--primary-hover);
99
+ }
 
 
 
 
 
100
 
101
+ .header-actions {
102
+ display: flex;
103
+ gap: 1rem;
104
+ }
105
 
106
+ .main-content {
107
+ display: grid;
108
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
109
+ gap: 2rem;
110
+ margin-bottom: 2rem;
111
+ }
112
 
113
+ .section {
114
+ background: white;
115
+ padding: 2rem;
116
+ border-radius: var(--border-radius);
117
+ box-shadow: var(--box-shadow);
118
+ transition: var(--transition);
119
+ }
120
 
121
+ .section:hover {
122
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
123
+ }
 
 
124
 
125
+ h2 {
126
+ color: var(--primary-color);
127
+ margin-bottom: 1.5rem;
128
+ padding-bottom: 0.75rem;
129
+ border-bottom: 2px solid var(--medium-gray);
130
+ font-size: 1.5rem;
131
+ font-weight: 600;
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 0.75rem;
135
+ }
136
 
137
+ .form-group {
138
+ margin-bottom: 1.5rem;
139
+ position: relative;
140
+ }
 
 
141
 
142
+ label {
143
+ display: block;
144
+ margin-bottom: 0.5rem;
145
+ font-weight: 500;
146
+ color: var(--text-secondary);
147
+ font-size: 0.9rem;
148
+ }
149
 
150
+ .input-wrapper {
151
+ position: relative;
152
+ }
 
153
 
154
+ input,
155
+ textarea,
156
+ select {
157
+ width: 100%;
158
+ padding: 1rem;
159
+ border: 1px solid var(--dark-gray);
160
+ border-radius: 8px;
161
+ font-size: 1rem;
162
+ transition: var(--transition);
163
+ background-color: var(--light-gray);
164
+ font-family: inherit;
165
+ }
166
 
167
+ input:focus,
168
+ textarea:focus,
169
+ select:focus {
170
+ outline: none;
171
+ border-color: var(--primary-color);
172
+ background-color: white;
173
+ box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.2);
174
+ }
175
 
176
+ textarea {
177
+ resize: vertical;
178
+ min-height: 120px;
179
+ }
 
 
 
 
 
180
 
181
+ .status-container {
182
+ display: flex;
183
+ align-items: center;
184
+ gap: 0.75rem;
185
+ padding: 0.75rem;
186
+ border-radius: 8px;
187
+ background-color: rgba(66, 133, 244, 0.1);
188
+ }
189
 
190
+ .status-indicator {
191
+ width: 12px;
192
+ height: 12px;
193
+ border-radius: 50%;
194
+ animation: pulse 2s infinite;
195
+ }
 
 
196
 
197
+ .status-connected {
198
+ background-color: var(--secondary-color);
199
+ }
200
 
201
+ .status-disconnected {
202
+ background-color: var(--accent-color);
203
+ animation: none;
204
+ }
205
 
206
+ .status-connecting {
207
+ background-color: var(--warning-color);
208
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
 
210
+ @keyframes pulse {
211
+ 0%, 100% { opacity: 1; }
212
+ 50% { opacity: 0.5; }
213
+ }
214
+
215
+ .button-group {
216
+ display: flex;
217
+ gap: 1rem;
218
+ flex-wrap: wrap;
219
+ margin-bottom: 1rem;
220
+ }
221
+
222
+ button {
223
+ padding: 0.75rem 1.5rem;
224
+ border: none;
225
+ border-radius: 8px;
226
+ cursor: pointer;
227
+ font-size: 1rem;
228
+ font-weight: 500;
229
+ transition: var(--transition);
230
+ display: inline-flex;
231
+ align-items: center;
232
+ gap: 0.5rem;
233
+ }
234
+
235
+ .btn-primary {
236
+ background-color: var(--primary-color);
237
+ color: white;
238
+ }
239
+
240
+ .btn-primary:hover:not(:disabled) {
241
+ background-color: var(--primary-hover);
242
+ transform: translateY(-1px);
243
+ }
244
+
245
+ .btn-secondary {
246
+ background-color: var(--light-gray);
247
+ color: var(--text-color);
248
+ border: 1px solid var(--dark-gray);
249
+ }
250
+
251
+ .btn-secondary:hover:not(:disabled) {
252
+ background-color: var(--medium-gray);
253
+ }
254
+
255
+ .btn-danger {
256
+ background-color: var(--accent-color);
257
+ color: white;
258
+ }
259
+
260
+ .btn-danger:hover:not(:disabled) {
261
+ background-color: #d32f2f;
262
+ }
263
+
264
+ button:disabled {
265
+ opacity: 0.6;
266
+ cursor: not-allowed;
267
+ }
268
+
269
+ .message {
270
+ padding: 1rem;
271
+ border-radius: 8px;
272
+ margin-top: 1rem;
273
+ font-size: 0.9rem;
274
+ display: none;
275
+ }
276
+
277
+ .error-message {
278
+ background-color: rgba(234, 67, 53, 0.1);
279
+ color: var(--accent-color);
280
+ border-left: 4px solid var(--accent-color);
281
+ }
282
+
283
+ .success-message {
284
+ background-color: rgba(52, 168, 83, 0.1);
285
+ color: var(--secondary-color);
286
+ border-left: 4px solid var(--secondary-color);
287
+ }
288
+
289
+ .cookie-settings {
290
+ background-color: rgba(66, 133, 244, 0.05);
291
+ padding: 1.25rem;
292
+ border-radius: 8px;
293
+ margin-bottom: 1.5rem;
294
+ border: 1px solid rgba(66, 133, 244, 0.2);
295
+ }
296
+
297
+ .cookie-header {
298
+ display: flex;
299
+ justify-content: space-between;
300
+ align-items: center;
301
+ margin-bottom: 1rem;
302
+ }
303
+
304
+ .cookie-list {
305
+ margin-bottom: 1.5rem;
306
+ }
307
+
308
+ .cookie-item {
309
+ background: white;
310
+ padding: 1rem;
311
+ border-radius: 8px;
312
+ margin-bottom: 0.75rem;
313
+ display: flex;
314
+ justify-content: space-between;
315
+ align-items: center;
316
+ box-shadow: 0 1px 2px rgba(0,0,0,0.1);
317
+ transition: var(--transition);
318
+ }
319
+
320
+ .cookie-item:hover {
321
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
322
+ }
323
+
324
+ .cookie-info {
325
+ flex: 1;
326
+ }
327
+
328
+ .cookie-name {
329
+ font-weight: 600;
330
+ color: var(--text-color);
331
+ margin-bottom: 0.25rem;
332
+ }
333
+
334
+ .cookie-value {
335
+ font-size: 0.85rem;
336
+ color: var(--text-secondary);
337
+ word-break: break-all;
338
+ }
339
+
340
+ .cookie-actions {
341
+ display: flex;
342
+ gap: 0.5rem;
343
+ margin-left: 1rem;
344
+ }
345
+
346
+ .cookie-actions button {
347
+ padding: 0.5rem;
348
+ font-size: 0.85rem;
349
+ }
350
+
351
+ .progress-container {
352
+ height: 6px;
353
+ background-color: var(--medium-gray);
354
+ border-radius: 3px;
355
+ overflow: hidden;
356
+ margin: 1.5rem 0;
357
+ box-shadow: inset 0 1px 2px rgba(0,0,0,0.1);
358
+ }
359
+
360
+ .progress-bar {
361
+ height: 100%;
362
+ background: linear-gradient(90deg, var(--primary-color), #5c86f4);
363
+ width: 0%;
364
+ transition: width 0.3s ease;
365
+ }
366
+
367
+ .response-area {
368
+ min-height: 200px;
369
+ border: 1px solid var(--dark-gray);
370
+ padding: 1.25rem;
371
+ border-radius: 8px;
372
+ background-color: var(--light-gray);
373
+ white-space: pre-wrap;
374
+ font-family: 'Roboto Mono', monospace;
375
+ overflow-y: auto;
376
+ max-height: 400px;
377
+ position: relative;
378
+ font-size: 0.9rem;
379
+ line-height: 1.5;
380
+ }
381
+
382
+ .response-header {
383
+ position: sticky;
384
+ top: 0;
385
+ background: var(--light-gray);
386
+ padding-bottom: 0.5rem;
387
+ margin-bottom: 0.5rem;
388
+ border-bottom: 1px solid var(--medium-gray);
389
+ display: flex;
390
+ justify-content: space-between;
391
+ align-items: center;
392
+ }
393
+
394
+ .copy-btn {
395
+ background: none;
396
+ border: none;
397
+ color: var(--text-secondary);
398
+ cursor: pointer;
399
+ padding: 0.25rem;
400
+ border-radius: 4px;
401
+ transition: var(--transition);
402
+ }
403
+
404
+ .copy-btn:hover {
405
+ background-color: rgba(0,0,0,0.05);
406
+ color: var(--text-color);
407
+ }
408
+
409
+ .model-selector {
410
+ position: relative;
411
+ }
412
+
413
+ .model-info {
414
+ margin-top: 0.5rem;
415
+ padding: 0.75rem;
416
+ background-color: rgba(66, 133, 244, 0.05);
417
+ border-radius: 8px;
418
+ border-left: 3px solid var(--primary-color);
419
+ display: none;
420
+ }
421
+
422
+ .model-info.show {
423
+ display: block;
424
+ }
425
+
426
+ .model-meta {
427
+ display: flex;
428
+ gap: 1rem;
429
+ font-size: 0.85rem;
430
+ color: var(--text-secondary);
431
+ }
432
+
433
+ .model-tag {
434
+ display: inline-block;
435
+ padding: 0.25rem 0.5rem;
436
+ border-radius: 4px;
437
+ font-size: 0.75rem;
438
+ font-weight: 500;
439
+ background-color: rgba(66, 133, 244, 0.1);
440
+ color: var(--primary-color);
441
+ }
442
+
443
+ @media (max-width: 768px) {
444
+ body {
445
+ padding: 1rem;
446
+ }
447
+
448
+ .main-content {
449
+ grid-template-columns: 1fr;
450
+ }
451
+
452
+ header {
453
+ flex-direction: column;
454
+ align-items: flex-start;
455
+ }
456
+
457
+ .header-actions {
458
+ width: 100%;
459
+ justify-content: flex-end;
460
+ }
461
+
462
+ .button-group {
463
+ flex-direction: column;
464
+ }
465
+
466
+ button {
467
+ width: 100%;
468
+ }
469
+ }
470
+
471
+ /* Dark mode support */
472
+ @media (prefers-color-scheme: dark) {
473
+ :root {
474
+ --primary-color: #8ab4f8;
475
+ --primary-hover: #7baaf7;
476
+ --text-color: #e8eaed;
477
+ --text-secondary: #bdc1c6;
478
+ --light-gray: #202124;
479
+ --medium-gray: #3c4043;
480
+ --dark-gray: #5f6368;
481
+ --box-shadow: 0 1px 3px rgba(0,0,0,0.3), 0 1px 2px rgba(0,0,0,0.4);
482
+ }
483
+
484
+ body {
485
+ background: linear-gradient(135deg, #1a1a1a 0%, #2d2d2d 100%);
486
+ }
487
+
488
+ .section {
489
+ background: #202124;
490
+ }
491
+
492
+ input, textarea, select {
493
+ background-color: #303134;
494
+ border-color: #5f6368;
495
+ color: #e8eaed;
496
+ }
497
+
498
+ .cookie-settings {
499
+ background-color: rgba(66, 133, 244, 0.1);
500
+ border-color: rgba(66, 133, 244, 0.3);
501
+ }
502
+
503
+ .cookie-item {
504
+ background: #2d2d2d;
505
+ }
506
+ }
507
+ </style>
508
  </head>
509
+ <body>
510
+ <div class="container">
511
+ <header>
512
+ <div class="header-content">
513
+ <div class="logo">
514
+ <i class="fas fa-robot logo-icon"></i>
515
+ <span>AI Backend Connector</span>
516
+ </div>
517
+ <div class="anycoder-link">
518
+ <i class="fas fa-code"></i>
519
+ Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
520
+ </div>
521
+ </div>
522
+ <div class="header-actions">
523
+ <button class="btn-secondary" id="toggle-theme">
524
+ <i class="fas fa-moon"></i>
525
+ <span id="theme-text">Dark Mode</span>
526
+ </button>
527
+ </div>
528
+ </header>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
529
 
530
+ <div class="main-content">
531
+ <div class="section">
532
+ <h2>
533
+ <i class="fas fa-plug"></i>
534
+ Conexão com Backend
535
+ </h2>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
 
537
+ <div class="form-group">
538
+ <label for="backend-url">URL do Backend</label>
539
+ <div class="input-wrapper">
540
+ <input type="url" id="backend-url" placeholder="https://api.example.com/endpoint">
541
+ </div>
542
+ </div>
543
+
544
+ <div class="form-group">
545
+ <label for="api-key">Chave de API</label>
546
+ <div class="input-wrapper">
547
+ <input type="password" id="api-key" placeholder="Sua chave de API">
548
+ <i class="fas fa-eye-slash toggle-password" id="toggle-api-key"></i>
549
+ </div>
550
+ </div>
551
+
552
+ <div class="form-group model-selector">
553
+ <label for="model-select">Modelo de IA</label>
554
+ <select id="model-select">
555
+ <option value="distilbert-base-uncased-finetuned-sst-2-english" data-info="Lightweight model for sentiment analysis with high accuracy.">
556
+ DistilBERT (Sentiment Analysis)
557
+ </option>
558
+ <option value="bert-base-multilingual-uncased-sentiment" data-info="Multilingual BERT model supporting 100+ languages for sentiment analysis.">
559
+ BERT Multilingual
560
+ </option>
561
+ <option value="facebook/bart-large-cnn" data-info="State-of-the-art model for text summarization with abstractive capabilities.">
562
+ BART (Summarization)
563
+ </option>
564
+ <option value="t5-small" data-info="Text-to-text transfer transformer for various NLP tasks including generation.">
565
+ T5 (Text Generation)
566
+ </option>
567
+ </select>
568
+ <div class="model-info" id="model-info">
569
+ <div class="model-meta">
570
+ <span class="model-tag">HuggingFace</span>
571
+ <span id="model-description"></span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
  </div>
573
+ </div>
574
+ </div>
575
+
576
+ <div class="form-group">
577
+ <label>Status da Conexão</label>
578
+ <div class="status-container" id="status-container">
579
+ <span class="status-indicator" id="connection-status"></span>
580
+ <span id="connection-text">Desconectado</span>
581
+ </div>
582
+ </div>
583
+
584
+ <div class="button-group">
585
+ <button class="btn-primary" id="connect-btn">
586
+ <i class="fas fa-link"></i>
587
+ Conectar ao Backend
588
+ </button>
589
+ <button class="btn-secondary" id="disconnect-btn" disabled>
590
+ <i class="fas fa-unlink"></i>
591
+ Desconectar
592
+ </button>
593
  </div>
594
+
595
+ <div id="connection-error" class="message error-message"></div>
596
+ <div id="connection-success" class="message success-message"></div>
597
+ </div>
598
+
599
+ <div class="section">
600
+ <h2>
601
+ <i class="fas fa-cookie-bite"></i>
602
+ Gerenciamento de Cookies
603
+ </h2>
604
+
605
+ <div class="cookie-settings">
606
+ <div class="cookie-header">
607
+ <h3>Cookies de Conexão</h3>
608
+ <span id="cookie-count" class="model-tag">0</span>
609
+ </div>
610
+ <div class="cookie-list" id="cookie-list">
611
+ <!-- Cookies serão listados aqui -->
612
+ </div>
613
+
614
+ <div class="form-group">
615
+ <label for="new-cookie-name">Nome do Cookie</label>
616
+ <input type="text" id="new-cookie-name" placeholder="session_id">
617
+ </div>
618
+
619
+ <div class="form-group">
620
+ <label for="new-cookie-value">Valor do Cookie</label>
621
+ <input type="text" id="new-cookie-value" placeholder="valor_do_cookie">
622
+ </div>
623
+
624
+ <div class="form-group">
625
+ <label for="new-cookie-expiry">Expiração (dias)</label>
626
+ <input type="number" id="new-cookie-expiry" value="7" min="1">
627
+ </div>
628
+
629
+ <button class="btn-secondary" id="add-cookie-btn">
630
+ <i class="fas fa-plus"></i>
631
+ Adicionar Cookie
632
+ </button>
633
+ </div>
634
+
635
+ <div class="form-group">
636
+ <button class="btn-danger" id="clear-cookies-btn">
637
+ <i class="fas fa-trash"></i>
638
+ Limpar Todos os Cookies
639
+ </button>
640
+ </div>
641
+ </div>
642
+ </div>
643
+
644
+ <div class="section">
645
+ <h2>
646
+ <i class="fas fa-paper-plane"></i>
647
+ Envio de Dados para IA
648
+ </h2>
649
+
650
+ <div class="form-group">
651
+ <label for="input-text">Texto de Entrada</label>
652
+ <textarea id="input-text" rows="6" placeholder="Digite o texto para enviar à IA..."></textarea>
653
+ </div>
654
+
655
+ <div class="form-group">
656
+ <label for="task-type">Tipo de Tarefa</label>
657
+ <select id="task-type">
658
+ <option value="text-classification">Classificação de Texto</option>
659
+ <option value="summarization">Sumarização</option>
660
+ <option value="question-answering">Resposta a Perguntas</option>
661
+ <option value="text-generation">Geração de Texto</option>
662
+ </select>
663
+ </div>
664
+
665
+ <div class="form-group">
666
+ <label for="max-length">Tamanho Máximo da Resposta</label>
667
+ <input type="range" id="max-length" value="100" min="10" max="500">
668
+ <div style="display: flex; justify-content: space-between; font-size: 0.85rem; color: var(--text-secondary);">
669
+ <span>10</span>
670
+ <span id="max-length-value">100</span>
671
+ <span>500</span>
672
+ </div>
673
+ </div>
674
+
675
+ <div class="button-group">
676
+ <button class="btn-primary" id="send-btn" disabled>
677
+ <i class="fas fa-paper-plane"></i>
678
+ Enviar para IA
679
+ </button>
680
+ <button class="btn-secondary" id="clear-btn">
681
+ <i class="fas fa-eraser"></i>
682
+ Limpar
683
+ </button>
684
+ </div>
685
+
686
+ <div class="progress-container">
687
+ <div class="progress-bar" id="progress-bar"></div>
688
+ </div>
689
+
690
+ <div class="form-group">
691
+ <label>Resposta da IA</label>
692
+ <div class="response-area" id="response-area">
693
+ <div class="response-header">
694
+ <span>A resposta da IA aparecerá aqui...</span>
695
+ <button class="copy-btn" id="copy-response" title="Copiar resposta">
696
+ <i class="far fa-copy"></i>
697
+ </button>
698
+ </div>
699
+ <div id="response-content"></div>
700
+ </div>
701
+ </div>
702
+
703
+ <div id="ai-error" class="message error-message"></div>
704
  </div>
705
+ </div>
706
+
707
+ <script>
708
+ // DOM Elements
709
+ const connectBtn = document.getElementById('connect-btn');
710
+ const disconnectBtn = document.getElementById('disconnect-btn');
711
+ const backendUrlInput = document.getElementById('backend-url');
712
+ const apiKeyInput = document.getElementById('api-key');
713
+ const modelSelect = document.getElementById('model-select');
714
+ const modelInfo = document.getElementById('model-info');
715
+ const modelDescription = document.getElementById('model-description');
716
+ const connectionStatus = document.getElementById('connection-status');
717
+ const connectionText = document.getElementById('connection-text');
718
+ const statusContainer = document.getElementById('status-container');
719
+ const connectionError = document.getElementById('connection-error');
720
+ const connectionSuccess = document.getElementById('connection-success');
721
+
722
+ const cookieList = document.getElementById('cookie-list');
723
+ const newCookieName = document.getElementById('new-cookie-name');
724
+ const newCookieValue = document.getElementById('new-cookie-value');
725
+ const newCookieExpiry = document.getElementById('new-cookie-expiry');
726
+ const addCookieBtn = document.getElementById('add-cookie-btn');
727
+ const clearCookiesBtn = document.getElementById('clear-cookies-btn');
728
+ const cookieCount = document.getElementById('cookie-count');
729
+
730
+ const inputText = document.getElementById('input-text');
731
+ const taskType = document.getElementById('task-type');
732
+ const maxLength = document.getElementById('max-length');
733
+ const maxLengthValue = document.getElementById('max-length-value');
734
+ const sendBtn = document.getElementById('send-btn');
735
+ const clearBtn = document.getElementById('clear-btn');
736
+ const progressBar = document.getElementById('progress-bar');
737
+ const responseArea = document.getElementById('response-area');
738
+ const responseContent = document.getElementById('response-content');
739
+ const copyResponseBtn = document.getElementById('copy-response');
740
+ const aiError = document.getElementById('ai-error');
741
+
742
+ const toggleApiKey = document.getElementById('toggle-api-key');
743
+ const toggleTheme = document.getElementById('toggle-theme');
744
+ const themeText = document.getElementById('theme-text');
745
+
746
+ // State
747
+ let isConnected = false;
748
+ let cookies = [];
749
+ let currentTheme = 'light';
750
+
751
+ // Initialize
752
+ document.addEventListener('DOMContentLoaded', () => {
753
+ // Load saved cookies
754
+ loadCookies();
755
+
756
+ // Set up event listeners
757
+ connectBtn.addEventListener('click', connectToBackend);
758
+ disconnectBtn.addEventListener('click', disconnectFromBackend);
759
+ addCookieBtn.addEventListener('click', addCookie);
760
+ clearCookiesBtn.addEventListener('click', clearCookies);
761
+ sendBtn.addEventListener('click', sendToAI);
762
+ clearBtn.addEventListener('click', clearInput);
763
+ copyResponseBtn.addEventListener('click', copyResponse);
764
+ toggleApiKey.addEventListener('click', togglePasswordVisibility);
765
+ toggleTheme.addEventListener('click', toggleThemeMode);
766
+ modelSelect.addEventListener('change', updateModelInfo);
767
+ maxLength.addEventListener('input', updateMaxLengthValue);
768
+
769
+ // Initialize model info
770
+ updateModelInfo();
771
+
772
+ // Check for saved theme preference
773
+ const savedTheme = localStorage.getItem('theme');
774
+ if (savedTheme) {
775
+ currentTheme = savedTheme;
776
+ updateThemeUI();
777
+ }
778
+ });
779
+
780
+ // Functions
781
+ function connectToBackend() {
782
+ const url = backendUrlInput.value.trim();
783
+ const apiKey = apiKeyInput.value.trim();
784
+
785
+ if (!url) {
786
+ showError(connectionError, 'Por favor, insira a URL do backend');
787
+ return;
788
+ }
789
+
790
+ if (!apiKey) {
791
+ showError(connectionError, 'Por favor, insira a chave de API');
792
+ return;
793
+ }
794
+
795
+ // Simulate connection
796
+ updateConnectionStatus('connecting');
797
+ showMessage(connectionSuccess, 'Conectando ao backend...');
798
+
799
+ // Simulate API call
800
+ setTimeout(() => {
801
+ isConnected = true;
802
+ updateConnectionStatus('connected');
803
+ showMessage(connectionSuccess, 'Conexão estabelecida com sucesso!');
804
+
805
+ // Enable send button
806
+ sendBtn.disabled = false;
807
+ connectBtn.disabled = true;
808
+ disconnectBtn.disabled = false;
809
+ }, 1500);
810
+ }
811
+
812
+ function disconnectFromBackend() {
813
+ if (!isConnected) return;
814
+
815
+ updateConnectionStatus('disconnected');
816
+ isConnected = false;
817
+
818
+ // Disable send button
819
+ sendBtn.disabled = true;
820
+ connectBtn.disabled = false;
821
+ disconnectBtn.disabled = true;
822
+
823
+ showMessage(connectionError, 'Conexão encerrada');
824
+ }
825
+
826
+ function updateConnectionStatus(status) {
827
+ connectionStatus.className = 'status-indicator';
828
+ connectionStatus.classList.add(`status-${status}`);
829
+
830
+ switch(status) {
831
+ case 'connected':
832
+ connectionText.textContent = 'Conectado';
833
+ statusContainer.style.backgroundColor = 'rgba(52, 168, 83, 0.1)';
834
+ break;
835
+ case 'disconnected':
836
+ connectionText.textContent = 'Desconectado';
837
+ statusContainer.style.backgroundColor = 'rgba(234, 67, 53, 0.1)';
838
+ break;
839
+ case 'connecting':
840
+ connectionText.textContent = 'Conectando...';
841
+ statusContainer.style.backgroundColor = 'rgba(251, 188, 5, 0.1)';
842
+ break;
843
+ }
844
+ }
845
+
846
+ function addCookie() {
847
+ const name = newCookieName.value.trim();
848
+ const value = newCookieValue.value.trim();
849
+ const expiry = parseInt(newCookieExpiry.value);
850
+
851
+ if (!name || !value) {
852
+ alert('Por favor, preencha o nome e o valor do cookie');
853
+ return;
854
+ }
855
+
856
+ const cookie = {
857
+ id: Date.now(),
858
+ name,
859
+ value,
860
+ expiryDays: expiry,
861
+ expiryDate: new Date(Date.now() + expiry * 24 * 60 * 60 * 1000).toISOString()
862
+ };
863
 
864
+ cookies.push(cookie);
865
+ saveCookies();
866
+ renderCookies();
867
+
868
+ // Clear inputs
869
+ newCookieName.value = '';
870
+ newCookieValue.value = '';
871
+ newCookieExpiry.value = '7';
872
+
873
+ showMessage(connectionSuccess, 'Cookie adicionado com sucesso!');
874
+ }
875
+
876
+ function clearCookies() {
877
+ if (confirm('Tem certeza que deseja limpar todos os cookies?')) {
878
+ cookies = [];
879
+ saveCookies();
880
+ renderCookies();
881
+ showMessage(connectionSuccess, 'Todos os cookies foram removidos');
882
+ }
883
+ }
884
+
885
+ function renderCookies() {
886
+ cookieList.innerHTML = '';
887
+
888
+ if (cookies.length === 0) {
889
+ cookieList.innerHTML = '<p style="text-align: center; color: var(--text-secondary);">Nenhum cookie adicionado</p>';
890
+ } else {
891
+ cookies.forEach(cookie => {
892
+ const cookieElement = document.createElement('div');
893
+ cookieElement.className = 'cookie-item';
894
+ cookieElement.innerHTML = `
895
+ <div class="cookie-info">
896
+ <div class="cookie-name">${cookie.name}</div>
897
+ <div class="cookie-value">${cookie.value}</div>
898
+ <div style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 0.25rem;">
899
+ Expires: ${new Date(cookie.expiryDate).toLocaleDateString()}
900
+ </div>
901
+ </div>
902
+ <div class="cookie-actions">
903
+ <button class="btn-secondary" title="Editar" onclick="editCookie(${cookie.id})">
904
+ <i class="fas fa-edit"></i>
905
+ </button>
906
+ <button class="btn-danger" title="Remover" onclick="removeCookie(${cookie.id})">
907
+ <i class="fas fa-trash"></i>
908
+ </button>
909
+ </div>
910
+ `;
911
+ cookieList.appendChild(cookieElement);
912
  });
913
+ }
914
+
915
+ cookieCount.textContent = cookies.length;
916
+ }
917
+
918
+ function saveCookies() {
919
+ localStorage.setItem('aiBackendCookies', JSON.stringify(cookies));
920
+ }
921
+
922
+ function loadCookies() {
923
+ const savedCookies = localStorage.getItem('aiBackendCookies');
924
+ if (savedCookies) {
925
+ cookies = JSON.parse(savedCookies);
926
+ renderCookies();
927
+ }
928
+ }
929
+
930
+ function removeCookie(id) {
931
+ cookies = cookies.filter(cookie => cookie.id !== id);
932
+ saveCookies();
933
+ renderCookies();
934
+ showMessage(connectionSuccess, 'Cookie removido');
935
+ }
936
+
937
+ function editCookie(id) {
938
+ const cookie = cookies.find(c => c.id === id);
939
+ if (cookie) {
940
+ newCookieName.value = cookie.name;
941
+ newCookieValue.value = cookie.value;
942
+ newCookieExpiry.value = cookie.expiryDays;
943
+
944
+ // Remove the cookie
945
+ removeCookie(id);
946
+ }
947
+ }
948
+
949
+ function sendToAI() {
950
+ const text = inputText.value.trim();
951
+ const task = taskType.value;
952
+ const length = maxLength.value;
953
+
954
+ if (!text) {
955
+ showError(aiError, 'Por favor, insira algum texto');
956
+ return;
957
+ }
958
+
959
+ // Disable buttons and show progress
960
+ sendBtn.disabled = true;
961
+ clearBtn.disabled = true;
962
+ progressBar.style.width = '0%';
963
+ responseContent.textContent = 'Processando sua solicitação...';
964
+
965
+ // Simulate API call with progress
966
+ let progress = 0;
967
+ const interval = setInterval(() => {
968
+ progress += 5;
969
+ progressBar.style.width = `${progress}%`;
970
+
971
+ if (progress >= 100) {
972
+ clearInterval(interval);
973
+ simulateAIResponse(text, task, length);
974
+ }
975
+ }, 300);
976
+ }
977
+
978
+ function simulateAIResponse(text, task, length) {
979
+ // Simulate different responses based on task type
980
+ let response = '';
981
+
982
+ switch(task) {
983
+ case 'text-classification':
984
+ response = `Análise de Sentimento:
985
+ - Polaridade: ${Math.random() > 0.5 ? 'Positivo' : 'Negativo'}
986
+ - Confiança: ${(Math.random() * 0.5 + 0.5).toFixed(2)}
987
+ - Emoções detectadas: ${['felicidade', 'tristeza', 'raiva', 'surpresa'][Math.floor(Math.random() * 4)]}`;
988
+ break;
989
+ case 'summarization':
990
+ response = `Resumo (${length} caracteres):
991
+
992
+ ${text.substring(0, parseInt(length))}...`;
993
+ break;
994
+ case 'question-answering':
995
+ response = `Pergunta detectada: "${text.split('?')[0]}?"
996
+
997
+ Resposta gerada:
998
+ ${text.split(' ').slice(0, 10).join(' ')}...`;
999
+ break;
1000
+ case 'text-generation':
1001
+ response = `Texto gerado (${length} tokens):
1002
+
1003
+ ${text} ${Array(10).fill('lorem ipsum ').join('')}...`;
1004
+ break;
1005
+ }
1006
+
1007
+ // Update UI
1008
+ responseContent.innerHTML = `<pre>${response}</pre>`;
1009
+ sendBtn.disabled = false;
1010
+ clearBtn.disabled = false;
1011
+ progressBar.style.width = '100%';
1012
+
1013
+ setTimeout(() => {
1014
+ progressBar.style.width = '0%';
1015
+ }, 1000);
1016
+ }
1017
+
1018
+ function clearInput() {
1019
+ inputText.value = '';
1020
+ responseContent.textContent = 'A resposta da IA aparecerá aqui...';
1021
+ aiError.style.display = 'none';
1022
+ }
1023
+
1024
+ function copyResponse() {
1025
+ const text = responseContent.textContent;
1026
+ if (!text || text.includes('aparecerá aqui')) {
1027
+ showError(aiError, 'Nada para copiar');
1028
+ return;
1029
+ }
1030
+
1031
+ navigator.clipboard.writeText(text).then(() => {
1032
+ // Show temporary checkmark
1033
+ const originalHTML = copyResponseBtn.innerHTML;
1034
+ copyResponseBtn.innerHTML = '<i class="fas fa-check"></i>';
1035
+ copyResponseBtn.style.color = 'var(--secondary-color)';
1036
+
1037
+ setTimeout(() => {
1038
+ copyResponseBtn.innerHTML = originalHTML;
1039
+ copyResponseBtn.style.color = '';
1040
+ }, 2000);
1041
+
1042
+ showMessage(connectionSuccess, 'Resposta copiada para a área de transferência!');
1043
+ }).catch(err => {
1044
+ showError(aiError, 'Falha ao copiar: ' + err);
1045
+ });
1046
+ }
1047
+
1048
+ function togglePasswordVisibility() {
1049
+ const type = apiKeyInput.getAttribute('type') === 'password' ? 'text' : 'password';
1050
+ apiKeyInput.setAttribute('type', type);
1051
+ toggleApiKey.classList.toggle('fa-eye');
1052
+ toggleApiKey.classList.toggle('fa-eye-slash');
1053
+ }
1054
+
1055
+ function toggleThemeMode() {
1056
+ currentTheme = currentTheme === 'light' ? 'dark' : 'light';
1057
+ updateThemeUI();
1058
+ localStorage.setItem('theme', currentTheme);
1059
+ }
1060
+
1061
+ function updateThemeUI() {
1062
+ if (currentTheme === 'dark') {
1063
+ document.documentElement.style.setProperty('--primary-color', '#8ab4f8');
1064
+ document.documentElement.style.setProperty('--primary-hover', '#7baaf7');
1065
+ themeText.textContent = 'Light Mode';
1066
+ toggleTheme.innerHTML = '<i class="fas fa-sun"></i><span id="theme-text">Light Mode</span>';
1067
+ } else {
1068
+ document.documentElement.style.setProperty('--primary-color', '#4285f4');
1069
+ document.documentElement.style.setProperty('--primary-hover', '#3367d6');
1070
+ themeText.textContent = 'Dark Mode';
1071
+ toggleTheme.innerHTML = '<i class="fas fa-moon"></i><span id="theme-text">Dark Mode</span>';
1072
+ }
1073
+ }
1074
+
1075
+ function updateModelInfo() {
1076
+ const selectedOption = modelSelect.options[modelSelect.selectedIndex];
1077
+ const info = selectedOption.getAttribute('data-info');
1078
+
1079
+ if (info) {
1080
+ modelDescription.textContent = info;
1081
+ modelInfo.classList.add('show');
1082
+ } else {
1083
+ modelInfo.classList.remove('show');
1084
+ }
1085
+ }
1086
+
1087
+ function updateMaxLengthValue() {
1088
+ maxLengthValue.textContent = maxLength.value;
1089
+ }
1090
+
1091
+ function showError(element, message) {
1092
+ element.textContent = message;
1093
+ element.style.display = 'block';
1094
+
1095
+ // Hide after 5 seconds
1096
+ setTimeout(() => {
1097
+ element.style.display = 'none';
1098
+ }, 5000);
1099
+ }
1100
+
1101
+ function showMessage(element, message) {
1102
+ element.textContent = message;
1103
+ element.style.display = 'block';
1104
+
1105
+ // Hide after 3 seconds
1106
+ setTimeout(() => {
1107
+ element.style.display = 'none';
1108
+ }, 3000);
1109
+ }
1110
+
1111
+ // Expose functions to global scope for button handlers
1112
+ window.removeCookie = removeCookie;
1113
+ window.editCookie = editCookie;
1114
+ </script>
1115
  </body>
1116
  </html>