Daizzyy commited on
Commit
264ec81
·
verified ·
1 Parent(s): 9bac518

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +509 -651
app.py CHANGED
@@ -1,652 +1,510 @@
1
-
2
- # streamlit_app.py
3
-
4
-
5
- # import streamlit as st
6
- # from streamlit_lottie import st_lottie
7
- # from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
8
- # import torch
9
- # import json
10
-
11
- # # ---------------- Load Model ----------------
12
- # @st.cache_resource
13
- # def load_model():
14
- # model_name = "./models" # path to your fine-tuned model
15
- # tokenizer = AutoTokenizer.from_pretrained(model_name)
16
- # model = AutoModelForSequenceClassification.from_pretrained(model_name)
17
- # classifier = pipeline("text-classification", model=model, tokenizer=tokenizer, return_all_scores=True)
18
- # return classifier
19
-
20
- # classifier = load_model()
21
-
22
- # # ---------------- CSS Styles ----------------
23
- # st.markdown(
24
- # """
25
- # <style>
26
- # body {
27
- # background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
28
- # animation: gradientBG 15s ease infinite;
29
- # height: 100vh;
30
- # }
31
-
32
- # @keyframes gradientBG {
33
- # 0% {background-position: 0% 50%;}
34
- # 50% {background-position: 100% 50%;}
35
- # 100% {background-position: 0% 50%;}
36
- # }
37
-
38
- # .title {
39
- # font-size: 55px;
40
- # font-weight: bold;
41
- # background: linear-gradient(270deg,
42
- # #ff0000, #ff7f00, #ffff00, #00ff00,
43
- # #0000ff, #4b0082, #8f00ff, #ff0000);
44
- # background-size: 1500% 1500%;
45
- # -webkit-background-clip: text;
46
- # -webkit-text-fill-color: transparent;
47
- # animation: rainbow 10s linear infinite;
48
- # margin-bottom: 10px;
49
- # }
50
-
51
- # @keyframes rainbow {
52
- # 0% {background-position: 0% 50%;}
53
- # 50% {background-position: 100% 50%;}
54
- # 100% {background-position: 0% 50%;}
55
- # }
56
-
57
- # .intro-line {
58
- # font-size: 18px;
59
- # color: white;
60
- # margin-bottom: 25px;
61
- # font-style:italic;
62
- # }
63
-
64
- # .stButton button {
65
- # display: block;
66
- # margin: 30px auto;
67
- # background: linear-gradient(90deg, #ff4b4b, #ff8c00);
68
- # color: white;
69
- # border-radius: 12px;
70
- # height: 3em;
71
- # width: 12em;
72
- # font-size: 18px;
73
- # font-weight: bold;
74
- # border: none;
75
- # box-shadow: 0px 4px 10px rgba(0,0,0,0.3);
76
- # transition: 0.3s;
77
- # }
78
- # .stButton button:hover {
79
- # transform: scale(1.1);
80
- # background: linear-gradient(90deg, #7d00ff, #00d4ff);
81
- # }
82
-
83
- # .output-box {
84
- # padding: 15px;
85
- # border-radius: 12px;
86
- # margin-top: 20px;
87
- # font-size: 20px;
88
- # font-weight: bold;
89
- # text-align: center;
90
- # }
91
- # .safe {
92
- # background-color: rgba(0,255,0,0.2);
93
- # color: #00ff7f;
94
- # }
95
- # .bully {
96
- # background-color: rgba(255,0,0,0.2);
97
- # color: #ff4b4b;
98
- # }
99
- # </style>
100
- # """,
101
- # unsafe_allow_html=True
102
- # )
103
-
104
- # # ---------------- Load Lottie Animation ----------------
105
- # with open("Cybersecurity.json", "r") as f:
106
- # lottie_anim = json.load(f)
107
-
108
- # # ---------------- Layout ----------------
109
- # col1, col2 = st.columns([2, 1])
110
-
111
- # with col1:
112
- # st.markdown("<div class='title'>Cyberbullying Detection System</div>", unsafe_allow_html=True)
113
- # st.markdown("<div class='intro-line'>This tool analyzes text messages and helps identify possible cyberbullying patterns.</div>", unsafe_allow_html=True)
114
-
115
- # with col2:
116
- # st_lottie(lottie_anim, height=250, key="cyberbully")
117
-
118
- # # ---------------- Input Section ----------------
119
- # st.markdown("### Enter a message :")
120
- # user_input = st.text_area("", "")
121
-
122
- # # ---------------- Prediction Button ----------------
123
- # if st.button("🔍 Detect"):
124
- # if not user_input.strip():
125
- # st.warning("Please enter some text.")
126
- # else:
127
- # results = classifier(user_input)[0]
128
- # best = max(results, key=lambda x: x['score'])
129
- # label = best['label']
130
- # score = best['score']
131
-
132
- # # Cyberbullying logic
133
- # if label.lower() == "not_cyberbullying":
134
- # result = f"<div class='output-box safe'>✅ Safe message (Confidence: {score:.2f})</div>"
135
- # else:
136
- # result = f"<div class='output-box bully'>⚠️ Cyberbullying detected ({label})<br>Confidence: {score:.2f}</div>"
137
-
138
- # st.markdown(result, unsafe_allow_html=True)
139
-
140
- # # Probability dictionary
141
- # probs = {r['label']: round(r['score'], 3) for r in results}
142
- # st.json(probs)
143
-
144
-
145
- # gradio_app.py
146
-
147
- import gradio as gr
148
- from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
149
- # ---------------- Load Model ----------------
150
- def load_model():
151
- model_path = "./models"
152
- tokenizer = AutoTokenizer.from_pretrained(model_path)
153
- model = AutoModelForSequenceClassification.from_pretrained(model_path)
154
- return pipeline(
155
- "text-classification",
156
- model=model,
157
- tokenizer=tokenizer,
158
- return_all_scores=True
159
- )
160
- classifier = load_model()
161
- # ---------------- Prediction Logic ----------------
162
- def predict(text):
163
- if not text.strip():
164
- return "<div class='warn'>⚠️ Please enter some text.</div>"
165
- results = classifier(text)[0]
166
- best = max(results, key=lambda x: x["score"])
167
- label = best["label"]
168
- score = best["score"]
169
- if label.lower() == "not_cyberbullying":
170
- return f"""
171
- <div class='safe'>
172
- <div class='checkmark'>✅</div>
173
- <div class='safe-text'>Safe Message</div>
174
- <div class='confidence-bar'>
175
- <div class='confidence-fill safe-fill' style='width: {score*100}%'></div>
176
- </div>
177
- <span class='confidence-score'>Confidence: {score:.2%}</span>
178
- </div>
179
- """
180
- else:
181
- return f"""
182
- <div class='bully'>
183
- <div class='warning-icon'>⚠️</div>
184
- <div class='bully-text'>Cyberbullying Detected</div>
185
- <div class='label-badge'>{label}</div>
186
- <div class='confidence-bar'>
187
- <div class='confidence-fill bully-fill' style='width: {score*100}%'></div>
188
- </div>
189
- <span class='confidence-score'>Confidence: {score:.2%}</span>
190
- </div>
191
- """
192
- # ---------------- UI ----------------
193
- with gr.Blocks(theme=gr.themes.Soft(), css="""
194
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
195
-
196
- * {
197
- margin: 0;
198
- padding: 0;
199
- box-sizing: border-box;
200
- }
201
-
202
- html, body {
203
- background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
204
- background-size: 400% 400%;
205
- animation: gradientBG 15s ease infinite;
206
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
207
- min-height: 100vh;
208
- position: fixed;
209
- width: 100%;
210
- height: 100%;
211
- }
212
-
213
- @keyframes gradientBG {
214
- 0% {background-position: 0% 50%;}
215
- 25% {background-position: 100% 50%;}
216
- 50% {background-position: 100% 100%;}
217
- 75% {background-position: 0% 100%;}
218
- 100% {background-position: 0% 50%;}
219
- }
220
-
221
- .gradio-container {
222
- background: rgba(20, 20, 40, 0.85) !important;
223
- border-radius: 25px !important;
224
- box-shadow: 0 25px 80px rgba(0, 0, 0, 0.4), inset 0 0 30px rgba(255, 255, 255, 0.1) !important;
225
- backdrop-filter: blur(15px) !important;
226
- border: 1px solid rgba(255, 255, 255, 0.15) !important;
227
- padding: 40px !important;
228
- }
229
-
230
- .title {
231
- font-size: 52px;
232
- font-weight: 900;
233
- text-align: center;
234
- background: linear-gradient(135deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
235
- -webkit-background-clip: text;
236
- -webkit-text-fill-color: transparent;
237
- background-clip: text;
238
- animation: slideInDown 1s ease-out, glow 3s ease-in-out infinite;
239
- margin-bottom: 10px;
240
- text-shadow: 0 0 30px rgba(255, 75, 75, 0.5);
241
- }
242
-
243
- @keyframes slideInDown {
244
- from {
245
- opacity: 0;
246
- transform: translateY(-50px);
247
- }
248
- to {
249
- opacity: 1;
250
- transform: translateY(0);
251
- }
252
- }
253
-
254
- @keyframes glow {
255
- 0%, 100% {
256
- text-shadow: 0 0 20px rgba(255, 75, 75, 0.5), 0 0 40px rgba(255, 140, 0, 0.3);
257
- }
258
- 50% {
259
- text-shadow: 0 0 30px rgba(75, 127, 255, 0.6), 0 0 60px rgba(125, 0, 255, 0.4);
260
- }
261
- }
262
-
263
- .subtitle {
264
- text-align: center;
265
- color: #e0e0ff;
266
- margin-bottom: 30px;
267
- font-style: italic;
268
- font-size: 16px;
269
- animation: fadeInUp 1s ease-out 0.2s both;
270
- letter-spacing: 1px;
271
- }
272
-
273
- @keyframes fadeInUp {
274
- from {
275
- opacity: 0;
276
- transform: translateY(30px);
277
- }
278
- to {
279
- opacity: 1;
280
- transform: translateY(0);
281
- }
282
- }
283
-
284
- /* Input Container */
285
- .textbox-container {
286
- animation: scaleIn 0.7s ease-out 0.3s both;
287
- }
288
-
289
- @keyframes scaleIn {
290
- from {
291
- opacity: 0;
292
- transform: scale(0.9) rotateX(10deg);
293
- }
294
- to {
295
- opacity: 1;
296
- transform: scale(1) rotateX(0deg);
297
- }
298
- }
299
-
300
- textarea {
301
- background: rgba(255, 255, 255, 0.08) !important;
302
- border: 2px solid rgba(75, 127, 255, 0.3) !important;
303
- border-radius: 15px !important;
304
- padding: 18px !important;
305
- font-size: 16px !important;
306
- color: #e0e0ff !important;
307
- transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
308
- box-shadow: 0 8px 32px rgba(75, 127, 255, 0.1), inset 0 0 20px rgba(255, 255, 255, 0.05) !important;
309
- backdrop-filter: blur(10px) !important;
310
- }
311
-
312
- textarea::placeholder {
313
- color: rgba(224, 224, 255, 0.5) !important;
314
- }
315
-
316
- textarea:focus {
317
- border-color: #4b7fff !important;
318
- box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1) !important;
319
- transform: translateY(-5px) scale(1.02);
320
- animation: inputGlow 2s ease-in-out infinite;
321
- }
322
-
323
- @keyframes inputGlow {
324
- 0%, 100% {
325
- box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1);
326
- }
327
- 50% {
328
- box-shadow: 0 20px 60px rgba(125, 0, 255, 0.5), inset 0 0 40px rgba(125, 0, 255, 0.2);
329
- }
330
- }
331
-
332
- /* Button Styling with Ripple Effect */
333
- .btn-primary {
334
- background: linear-gradient(135deg, #4b7fff, #7d00ff, #ff4b4b) !important;
335
- background-size: 300% 300% !important;
336
- border: 2px solid rgba(75, 127, 255, 0.5) !important;
337
- color: white !important;
338
- font-weight: 700 !important;
339
- font-size: 16px !important;
340
- padding: 14px 40px !important;
341
- border-radius: 50px !important;
342
- cursor: pointer !important;
343
- transition: all 0.4s ease !important;
344
- box-shadow: 0 10px 40px rgba(75, 127, 255, 0.4), inset 0 0 20px rgba(255, 255, 255, 0.1) !important;
345
- animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
346
- position: relative;
347
- overflow: hidden;
348
- }
349
-
350
- @keyframes bounceIn {
351
- 0% {
352
- opacity: 0;
353
- transform: scale(0.1) rotateZ(-45deg);
354
- }
355
- 50% {
356
- opacity: 1;
357
- transform: scale(1.1) rotateZ(10deg);
358
- }
359
- 100% {
360
- transform: scale(1) rotateZ(0deg);
361
- }
362
- }
363
-
364
- .btn-primary:hover {
365
- transform: translateY(-5px) scale(1.05);
366
- box-shadow: 0 20px 60px rgba(125, 0, 255, 0.6), inset 0 0 30px rgba(255, 255, 255, 0.15) !important;
367
- background-position: 100% 0 !important;
368
- animation: gradientShift 3s ease infinite;
369
- }
370
-
371
- @keyframes gradientShift {
372
- 0% {background-position: 0% 50%;}
373
- 50% {background-position: 100% 50%;}
374
- 100% {background-position: 0% 50%;}
375
- }
376
-
377
- .btn-primary:active {
378
- transform: translateY(-2px) scale(0.98);
379
- }
380
-
381
- /* Ripple Effect */
382
- .btn-primary::before {
383
- content: '';
384
- position: absolute;
385
- top: 50%;
386
- left: 50%;
387
- width: 0;
388
- height: 0;
389
- border-radius: 50%;
390
- background: rgba(255, 255, 255, 0.6);
391
- transform: translate(-50%, -50%);
392
- transition: width 0.6s, height 0.6s;
393
- }
394
-
395
- .btn-primary:active::before {
396
- width: 400px;
397
- height: 400px;
398
- }
399
-
400
- /* Result Cards */
401
- .safe {
402
- background: linear-gradient(135deg, rgba(0, 255, 100, 0.15), rgba(100, 255, 150, 0.08));
403
- border: 2px solid rgba(0, 255, 100, 0.4);
404
- padding: 35px;
405
- border-radius: 20px;
406
- color: #00ff64;
407
- text-align: center;
408
- animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowGreen 3s ease-in-out infinite;
409
- box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
410
- backdrop-filter: blur(15px);
411
- }
412
-
413
- .bully {
414
- background: linear-gradient(135deg, rgba(255, 0, 0, 0.15), rgba(255, 100, 100, 0.08));
415
- border: 2px solid rgba(255, 107, 107, 0.4);
416
- padding: 35px;
417
- border-radius: 20px;
418
- color: #ff6b6b;
419
- text-align: center;
420
- animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowRed 2s ease-in-out infinite;
421
- box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
422
- backdrop-filter: blur(15px);
423
- }
424
-
425
- @keyframes slideInRight {
426
- from {
427
- opacity: 0;
428
- transform: translateX(100px) rotateY(20deg);
429
- }
430
- to {
431
- opacity: 1;
432
- transform: translateX(0) rotateY(0deg);
433
- }
434
- }
435
-
436
- @keyframes cardGlowGreen {
437
- 0%, 100% {
438
- box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
439
- }
440
- 50% {
441
- box-shadow: 0 30px 80px rgba(0, 255, 100, 0.4), inset 0 0 40px rgba(0, 255, 100, 0.2);
442
- }
443
- }
444
-
445
- @keyframes cardGlowRed {
446
- 0%, 100% {
447
- box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
448
- }
449
- 50% {
450
- box-shadow: 0 30px 80px rgba(255, 107, 107, 0.4), inset 0 0 40px rgba(255, 107, 107, 0.2);
451
- }
452
- }
453
-
454
- .warn {
455
- color: #ffb700;
456
- text-align: center;
457
- font-weight: 700;
458
- font-size: 18px;
459
- animation: shake 0.5s ease-in-out, pulse 1.5s ease-in-out infinite 0.5s;
460
- padding: 20px;
461
- }
462
-
463
- @keyframes shake {
464
- 0%, 100% {transform: translateX(0);}
465
- 10%, 30%, 50%, 70%, 90% {transform: translateX(-8px);}
466
- 20%, 40%, 60%, 80% {transform: translateX(8px);}
467
- }
468
-
469
- @keyframes pulse {
470
- 0%, 100% {opacity: 1;}
471
- 50% {opacity: 0.6;}
472
- }
473
-
474
- /* Icons */
475
- .checkmark, .warning-icon {
476
- font-size: 56px;
477
- margin-bottom: 15px;
478
- animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
479
- display: inline-block;
480
- }
481
-
482
- @keyframes bounce {
483
- 0% {
484
- opacity: 0;
485
- transform: scale(0) rotateZ(-45deg);
486
- }
487
- 50% {
488
- transform: scale(1.2) rotateZ(15deg);
489
- }
490
- 100% {
491
- opacity: 1;
492
- transform: scale(1) rotateZ(0deg);
493
- }
494
- }
495
-
496
- .warning-icon {
497
- animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), pulse-warning 1.5s ease-in-out 0.8s infinite;
498
- }
499
-
500
- @keyframes pulse-warning {
501
- 0%, 100% {
502
- transform: scale(1);
503
- filter: drop-shadow(0 0 5px rgba(255, 107, 107, 0.5));
504
- }
505
- 50% {
506
- transform: scale(1.2);
507
- filter: drop-shadow(0 0 20px rgba(255, 107, 107, 1));
508
- }
509
- }
510
-
511
- /* Text */
512
- .safe-text, .bully-text {
513
- font-size: 28px;
514
- font-weight: 800;
515
- margin-bottom: 15px;
516
- animation: fadeInDown 0.8s ease-out 0.2s both;
517
- letter-spacing: 0.5px;
518
- }
519
-
520
- @keyframes fadeInDown {
521
- from {
522
- opacity: 0;
523
- transform: translateY(-20px);
524
- }
525
- to {
526
- opacity: 1;
527
- transform: translateY(0);
528
- }
529
- }
530
-
531
- .label-badge {
532
- display: inline-block;
533
- background: rgba(255, 107, 107, 0.2);
534
- border: 2px solid rgba(255, 107, 107, 0.5);
535
- padding: 10px 20px;
536
- border-radius: 25px;
537
- margin-bottom: 18px;
538
- font-size: 14px;
539
- font-weight: 700;
540
- animation: zoomIn 0.7s ease-out 0.3s both;
541
- box-shadow: 0 5px 20px rgba(255, 107, 107, 0.2);
542
- }
543
-
544
- @keyframes zoomIn {
545
- from {
546
- opacity: 0;
547
- transform: scale(0.3);
548
- }
549
- to {
550
- opacity: 1;
551
- transform: scale(1);
552
- }
553
- }
554
-
555
- /* Confidence Bar */
556
- .confidence-bar {
557
- width: 100%;
558
- height: 10px;
559
- background: rgba(255, 255, 255, 0.1);
560
- border-radius: 12px;
561
- margin-bottom: 15px;
562
- overflow: hidden;
563
- animation: fadeIn 0.8s ease-out 0.1s both;
564
- border: 1px solid rgba(255, 255, 255, 0.2);
565
- box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3);
566
- }
567
-
568
- .confidence-fill {
569
- height: 100%;
570
- border-radius: 12px;
571
- transition: width 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
572
- animation: fillWidth 1.2s ease-out;
573
- }
574
-
575
- @keyframes fillWidth {
576
- from {
577
- width: 0 !important;
578
- }
579
- }
580
-
581
- .safe-fill {
582
- background: linear-gradient(90deg, #00ff64, #00d452, #00ff64);
583
- background-size: 200% 200%;
584
- box-shadow: 0 0 25px rgba(0, 255, 100, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
585
- animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
586
- }
587
-
588
- .bully-fill {
589
- background: linear-gradient(90deg, #ff6b6b, #ff4444, #ff6b6b);
590
- background-size: 200% 200%;
591
- box-shadow: 0 0 25px rgba(255, 107, 107, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
592
- animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
593
- }
594
-
595
- @keyframes shimmer {
596
- 0%, 100% {background-position: 0% 50%;}
597
- 50% {background-position: 100% 50%;}
598
- }
599
-
600
- .confidence-score {
601
- font-size: 15px;
602
- opacity: 0.9;
603
- animation: fadeIn 0.8s ease-out 0.4s both;
604
- font-weight: 600;
605
- letter-spacing: 0.5px;
606
- }
607
-
608
- @keyframes fadeIn {
609
- from {
610
- opacity: 0;
611
- }
612
- to {
613
- opacity: 1;
614
- }
615
- }
616
-
617
- /* Responsive */
618
- @media (max-width: 768px) {
619
- .title {
620
- font-size: 36px;
621
- }
622
-
623
- .safe, .bully {
624
- padding: 25px;
625
- }
626
-
627
- html, body {
628
- background-size: 600% 600%;
629
- }
630
- }
631
- """) as demo:
632
- gr.Markdown("<div class='title'>🛡️ Cyberbullying Detection System</div>")
633
- gr.Markdown("<div class='subtitle'>End-to-end NLP system for detecting cyberbullying, including religion-based abuse</div>")
634
-
635
- with gr.Group():
636
- text_input = gr.Textbox(
637
- lines=4,
638
- placeholder="Enter a message to analyze...",
639
- label="Input Text",
640
- elem_classes="textbox-container"
641
- )
642
- detect_btn = gr.Button("🔍 Detect", variant="primary")
643
-
644
- output = gr.HTML()
645
-
646
- detect_btn.click(
647
- fn=predict,
648
- inputs=text_input,
649
- outputs=output
650
- )
651
-
652
  demo.launch()
 
1
+
2
+
3
+ # gradio_app.py
4
+
5
+ import gradio as gr
6
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, pipeline
7
+ # ---------------- Load Model ----------------
8
+ def load_model():
9
+ model_path = "."
10
+ tokenizer = AutoTokenizer.from_pretrained(model_path)
11
+ model = AutoModelForSequenceClassification.from_pretrained(model_path)
12
+ return pipeline(
13
+ "text-classification",
14
+ model=model,
15
+ tokenizer=tokenizer,
16
+ return_all_scores=True
17
+ )
18
+ classifier = load_model()
19
+ # ---------------- Prediction Logic ----------------
20
+ def predict(text):
21
+ if not text.strip():
22
+ return "<div class='warn'>⚠️ Please enter some text.</div>"
23
+ results = classifier(text)[0]
24
+ best = max(results, key=lambda x: x["score"])
25
+ label = best["label"]
26
+ score = best["score"]
27
+ if label.lower() == "not_cyberbullying":
28
+ return f"""
29
+ <div class='safe'>
30
+ <div class='checkmark'>✅</div>
31
+ <div class='safe-text'>Safe Message</div>
32
+ <div class='confidence-bar'>
33
+ <div class='confidence-fill safe-fill' style='width: {score*100}%'></div>
34
+ </div>
35
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
36
+ </div>
37
+ """
38
+ else:
39
+ return f"""
40
+ <div class='bully'>
41
+ <div class='warning-icon'>⚠️</div>
42
+ <div class='bully-text'>Cyberbullying Detected</div>
43
+ <div class='label-badge'>{label}</div>
44
+ <div class='confidence-bar'>
45
+ <div class='confidence-fill bully-fill' style='width: {score*100}%'></div>
46
+ </div>
47
+ <span class='confidence-score'>Confidence: {score:.2%}</span>
48
+ </div>
49
+ """
50
+ # ---------------- UI ----------------
51
+ with gr.Blocks(theme=gr.themes.Soft(), css="""
52
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css"/>
53
+
54
+ * {
55
+ margin: 0;
56
+ padding: 0;
57
+ box-sizing: border-box;
58
+ }
59
+
60
+ html, body {
61
+ background: linear-gradient(-45deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
62
+ background-size: 400% 400%;
63
+ animation: gradientBG 15s ease infinite;
64
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
65
+ min-height: 100vh;
66
+ position: fixed;
67
+ width: 100%;
68
+ height: 100%;
69
+ }
70
+
71
+ @keyframes gradientBG {
72
+ 0% {background-position: 0% 50%;}
73
+ 25% {background-position: 100% 50%;}
74
+ 50% {background-position: 100% 100%;}
75
+ 75% {background-position: 0% 100%;}
76
+ 100% {background-position: 0% 50%;}
77
+ }
78
+
79
+ .gradio-container {
80
+ background: rgba(20, 20, 40, 0.85) !important;
81
+ border-radius: 25px !important;
82
+ box-shadow: 0 25px 80px rgba(0, 0, 0, 0.4), inset 0 0 30px rgba(255, 255, 255, 0.1) !important;
83
+ backdrop-filter: blur(15px) !important;
84
+ border: 1px solid rgba(255, 255, 255, 0.15) !important;
85
+ padding: 40px !important;
86
+ }
87
+
88
+ .title {
89
+ font-size: 52px;
90
+ font-weight: 900;
91
+ text-align: center;
92
+ background: linear-gradient(135deg, #ff4b4b, #ff8c00, #4b7fff, #7d00ff);
93
+ -webkit-background-clip: text;
94
+ -webkit-text-fill-color: transparent;
95
+ background-clip: text;
96
+ animation: slideInDown 1s ease-out, glow 3s ease-in-out infinite;
97
+ margin-bottom: 10px;
98
+ text-shadow: 0 0 30px rgba(255, 75, 75, 0.5);
99
+ }
100
+
101
+ @keyframes slideInDown {
102
+ from {
103
+ opacity: 0;
104
+ transform: translateY(-50px);
105
+ }
106
+ to {
107
+ opacity: 1;
108
+ transform: translateY(0);
109
+ }
110
+ }
111
+
112
+ @keyframes glow {
113
+ 0%, 100% {
114
+ text-shadow: 0 0 20px rgba(255, 75, 75, 0.5), 0 0 40px rgba(255, 140, 0, 0.3);
115
+ }
116
+ 50% {
117
+ text-shadow: 0 0 30px rgba(75, 127, 255, 0.6), 0 0 60px rgba(125, 0, 255, 0.4);
118
+ }
119
+ }
120
+
121
+ .subtitle {
122
+ text-align: center;
123
+ color: #e0e0ff;
124
+ margin-bottom: 30px;
125
+ font-style: italic;
126
+ font-size: 16px;
127
+ animation: fadeInUp 1s ease-out 0.2s both;
128
+ letter-spacing: 1px;
129
+ }
130
+
131
+ @keyframes fadeInUp {
132
+ from {
133
+ opacity: 0;
134
+ transform: translateY(30px);
135
+ }
136
+ to {
137
+ opacity: 1;
138
+ transform: translateY(0);
139
+ }
140
+ }
141
+
142
+ /* Input Container */
143
+ .textbox-container {
144
+ animation: scaleIn 0.7s ease-out 0.3s both;
145
+ }
146
+
147
+ @keyframes scaleIn {
148
+ from {
149
+ opacity: 0;
150
+ transform: scale(0.9) rotateX(10deg);
151
+ }
152
+ to {
153
+ opacity: 1;
154
+ transform: scale(1) rotateX(0deg);
155
+ }
156
+ }
157
+
158
+ textarea {
159
+ background: rgba(255, 255, 255, 0.08) !important;
160
+ border: 2px solid rgba(75, 127, 255, 0.3) !important;
161
+ border-radius: 15px !important;
162
+ padding: 18px !important;
163
+ font-size: 16px !important;
164
+ color: #e0e0ff !important;
165
+ transition: all 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
166
+ box-shadow: 0 8px 32px rgba(75, 127, 255, 0.1), inset 0 0 20px rgba(255, 255, 255, 0.05) !important;
167
+ backdrop-filter: blur(10px) !important;
168
+ }
169
+
170
+ textarea::placeholder {
171
+ color: rgba(224, 224, 255, 0.5) !important;
172
+ }
173
+
174
+ textarea:focus {
175
+ border-color: #4b7fff !important;
176
+ box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1) !important;
177
+ transform: translateY(-5px) scale(1.02);
178
+ animation: inputGlow 2s ease-in-out infinite;
179
+ }
180
+
181
+ @keyframes inputGlow {
182
+ 0%, 100% {
183
+ box-shadow: 0 15px 50px rgba(75, 127, 255, 0.4), inset 0 0 30px rgba(75, 127, 255, 0.1);
184
+ }
185
+ 50% {
186
+ box-shadow: 0 20px 60px rgba(125, 0, 255, 0.5), inset 0 0 40px rgba(125, 0, 255, 0.2);
187
+ }
188
+ }
189
+
190
+ /* Button Styling with Ripple Effect */
191
+ .btn-primary {
192
+ background: linear-gradient(135deg, #4b7fff, #7d00ff, #ff4b4b) !important;
193
+ background-size: 300% 300% !important;
194
+ border: 2px solid rgba(75, 127, 255, 0.5) !important;
195
+ color: white !important;
196
+ font-weight: 700 !important;
197
+ font-size: 16px !important;
198
+ padding: 14px 40px !important;
199
+ border-radius: 50px !important;
200
+ cursor: pointer !important;
201
+ transition: all 0.4s ease !important;
202
+ box-shadow: 0 10px 40px rgba(75, 127, 255, 0.4), inset 0 0 20px rgba(255, 255, 255, 0.1) !important;
203
+ animation: bounceIn 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55) 0.4s both;
204
+ position: relative;
205
+ overflow: hidden;
206
+ }
207
+
208
+ @keyframes bounceIn {
209
+ 0% {
210
+ opacity: 0;
211
+ transform: scale(0.1) rotateZ(-45deg);
212
+ }
213
+ 50% {
214
+ opacity: 1;
215
+ transform: scale(1.1) rotateZ(10deg);
216
+ }
217
+ 100% {
218
+ transform: scale(1) rotateZ(0deg);
219
+ }
220
+ }
221
+
222
+ .btn-primary:hover {
223
+ transform: translateY(-5px) scale(1.05);
224
+ box-shadow: 0 20px 60px rgba(125, 0, 255, 0.6), inset 0 0 30px rgba(255, 255, 255, 0.15) !important;
225
+ background-position: 100% 0 !important;
226
+ animation: gradientShift 3s ease infinite;
227
+ }
228
+
229
+ @keyframes gradientShift {
230
+ 0% {background-position: 0% 50%;}
231
+ 50% {background-position: 100% 50%;}
232
+ 100% {background-position: 0% 50%;}
233
+ }
234
+
235
+ .btn-primary:active {
236
+ transform: translateY(-2px) scale(0.98);
237
+ }
238
+
239
+ /* Ripple Effect */
240
+ .btn-primary::before {
241
+ content: '';
242
+ position: absolute;
243
+ top: 50%;
244
+ left: 50%;
245
+ width: 0;
246
+ height: 0;
247
+ border-radius: 50%;
248
+ background: rgba(255, 255, 255, 0.6);
249
+ transform: translate(-50%, -50%);
250
+ transition: width 0.6s, height 0.6s;
251
+ }
252
+
253
+ .btn-primary:active::before {
254
+ width: 400px;
255
+ height: 400px;
256
+ }
257
+
258
+ /* Result Cards */
259
+ .safe {
260
+ background: linear-gradient(135deg, rgba(0, 255, 100, 0.15), rgba(100, 255, 150, 0.08));
261
+ border: 2px solid rgba(0, 255, 100, 0.4);
262
+ padding: 35px;
263
+ border-radius: 20px;
264
+ color: #00ff64;
265
+ text-align: center;
266
+ animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowGreen 3s ease-in-out infinite;
267
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
268
+ backdrop-filter: blur(15px);
269
+ }
270
+
271
+ .bully {
272
+ background: linear-gradient(135deg, rgba(255, 0, 0, 0.15), rgba(255, 100, 100, 0.08));
273
+ border: 2px solid rgba(255, 107, 107, 0.4);
274
+ padding: 35px;
275
+ border-radius: 20px;
276
+ color: #ff6b6b;
277
+ text-align: center;
278
+ animation: slideInRight 0.8s cubic-bezier(0.34, 1.56, 0.64, 1), cardGlowRed 2s ease-in-out infinite;
279
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
280
+ backdrop-filter: blur(15px);
281
+ }
282
+
283
+ @keyframes slideInRight {
284
+ from {
285
+ opacity: 0;
286
+ transform: translateX(100px) rotateY(20deg);
287
+ }
288
+ to {
289
+ opacity: 1;
290
+ transform: translateX(0) rotateY(0deg);
291
+ }
292
+ }
293
+
294
+ @keyframes cardGlowGreen {
295
+ 0%, 100% {
296
+ box-shadow: 0 20px 60px rgba(0, 255, 100, 0.25), inset 0 0 30px rgba(0, 255, 100, 0.1);
297
+ }
298
+ 50% {
299
+ box-shadow: 0 30px 80px rgba(0, 255, 100, 0.4), inset 0 0 40px rgba(0, 255, 100, 0.2);
300
+ }
301
+ }
302
+
303
+ @keyframes cardGlowRed {
304
+ 0%, 100% {
305
+ box-shadow: 0 20px 60px rgba(255, 107, 107, 0.25), inset 0 0 30px rgba(255, 107, 107, 0.1);
306
+ }
307
+ 50% {
308
+ box-shadow: 0 30px 80px rgba(255, 107, 107, 0.4), inset 0 0 40px rgba(255, 107, 107, 0.2);
309
+ }
310
+ }
311
+
312
+ .warn {
313
+ color: #ffb700;
314
+ text-align: center;
315
+ font-weight: 700;
316
+ font-size: 18px;
317
+ animation: shake 0.5s ease-in-out, pulse 1.5s ease-in-out infinite 0.5s;
318
+ padding: 20px;
319
+ }
320
+
321
+ @keyframes shake {
322
+ 0%, 100% {transform: translateX(0);}
323
+ 10%, 30%, 50%, 70%, 90% {transform: translateX(-8px);}
324
+ 20%, 40%, 60%, 80% {transform: translateX(8px);}
325
+ }
326
+
327
+ @keyframes pulse {
328
+ 0%, 100% {opacity: 1;}
329
+ 50% {opacity: 0.6;}
330
+ }
331
+
332
+ /* Icons */
333
+ .checkmark, .warning-icon {
334
+ font-size: 56px;
335
+ margin-bottom: 15px;
336
+ animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55);
337
+ display: inline-block;
338
+ }
339
+
340
+ @keyframes bounce {
341
+ 0% {
342
+ opacity: 0;
343
+ transform: scale(0) rotateZ(-45deg);
344
+ }
345
+ 50% {
346
+ transform: scale(1.2) rotateZ(15deg);
347
+ }
348
+ 100% {
349
+ opacity: 1;
350
+ transform: scale(1) rotateZ(0deg);
351
+ }
352
+ }
353
+
354
+ .warning-icon {
355
+ animation: bounce 0.8s cubic-bezier(0.68, -0.55, 0.265, 1.55), pulse-warning 1.5s ease-in-out 0.8s infinite;
356
+ }
357
+
358
+ @keyframes pulse-warning {
359
+ 0%, 100% {
360
+ transform: scale(1);
361
+ filter: drop-shadow(0 0 5px rgba(255, 107, 107, 0.5));
362
+ }
363
+ 50% {
364
+ transform: scale(1.2);
365
+ filter: drop-shadow(0 0 20px rgba(255, 107, 107, 1));
366
+ }
367
+ }
368
+
369
+ /* Text */
370
+ .safe-text, .bully-text {
371
+ font-size: 28px;
372
+ font-weight: 800;
373
+ margin-bottom: 15px;
374
+ animation: fadeInDown 0.8s ease-out 0.2s both;
375
+ letter-spacing: 0.5px;
376
+ }
377
+
378
+ @keyframes fadeInDown {
379
+ from {
380
+ opacity: 0;
381
+ transform: translateY(-20px);
382
+ }
383
+ to {
384
+ opacity: 1;
385
+ transform: translateY(0);
386
+ }
387
+ }
388
+
389
+ .label-badge {
390
+ display: inline-block;
391
+ background: rgba(255, 107, 107, 0.2);
392
+ border: 2px solid rgba(255, 107, 107, 0.5);
393
+ padding: 10px 20px;
394
+ border-radius: 25px;
395
+ margin-bottom: 18px;
396
+ font-size: 14px;
397
+ font-weight: 700;
398
+ animation: zoomIn 0.7s ease-out 0.3s both;
399
+ box-shadow: 0 5px 20px rgba(255, 107, 107, 0.2);
400
+ }
401
+
402
+ @keyframes zoomIn {
403
+ from {
404
+ opacity: 0;
405
+ transform: scale(0.3);
406
+ }
407
+ to {
408
+ opacity: 1;
409
+ transform: scale(1);
410
+ }
411
+ }
412
+
413
+ /* Confidence Bar */
414
+ .confidence-bar {
415
+ width: 100%;
416
+ height: 10px;
417
+ background: rgba(255, 255, 255, 0.1);
418
+ border-radius: 12px;
419
+ margin-bottom: 15px;
420
+ overflow: hidden;
421
+ animation: fadeIn 0.8s ease-out 0.1s both;
422
+ border: 1px solid rgba(255, 255, 255, 0.2);
423
+ box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.3);
424
+ }
425
+
426
+ .confidence-fill {
427
+ height: 100%;
428
+ border-radius: 12px;
429
+ transition: width 1.2s cubic-bezier(0.34, 1.56, 0.64, 1);
430
+ animation: fillWidth 1.2s ease-out;
431
+ }
432
+
433
+ @keyframes fillWidth {
434
+ from {
435
+ width: 0 !important;
436
+ }
437
+ }
438
+
439
+ .safe-fill {
440
+ background: linear-gradient(90deg, #00ff64, #00d452, #00ff64);
441
+ background-size: 200% 200%;
442
+ box-shadow: 0 0 25px rgba(0, 255, 100, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
443
+ animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
444
+ }
445
+
446
+ .bully-fill {
447
+ background: linear-gradient(90deg, #ff6b6b, #ff4444, #ff6b6b);
448
+ background-size: 200% 200%;
449
+ box-shadow: 0 0 25px rgba(255, 107, 107, 0.8), inset 0 0 10px rgba(255, 255, 255, 0.3);
450
+ animation: fillWidth 1.2s ease-out, shimmer 2s ease-in-out infinite;
451
+ }
452
+
453
+ @keyframes shimmer {
454
+ 0%, 100% {background-position: 0% 50%;}
455
+ 50% {background-position: 100% 50%;}
456
+ }
457
+
458
+ .confidence-score {
459
+ font-size: 15px;
460
+ opacity: 0.9;
461
+ animation: fadeIn 0.8s ease-out 0.4s both;
462
+ font-weight: 600;
463
+ letter-spacing: 0.5px;
464
+ }
465
+
466
+ @keyframes fadeIn {
467
+ from {
468
+ opacity: 0;
469
+ }
470
+ to {
471
+ opacity: 1;
472
+ }
473
+ }
474
+
475
+ /* Responsive */
476
+ @media (max-width: 768px) {
477
+ .title {
478
+ font-size: 36px;
479
+ }
480
+
481
+ .safe, .bully {
482
+ padding: 25px;
483
+ }
484
+
485
+ html, body {
486
+ background-size: 600% 600%;
487
+ }
488
+ }
489
+ """) as demo:
490
+ gr.Markdown("<div class='title'>🛡️ Cyberbullying Detection System</div>")
491
+ gr.Markdown("<div class='subtitle'>End-to-end NLP system for detecting cyberbullying, including religion-based abuse</div>")
492
+
493
+ with gr.Group():
494
+ text_input = gr.Textbox(
495
+ lines=4,
496
+ placeholder="Enter a message to analyze...",
497
+ label="Input Text",
498
+ elem_classes="textbox-container"
499
+ )
500
+ detect_btn = gr.Button("🔍 Detect", variant="primary")
501
+
502
+ output = gr.HTML()
503
+
504
+ detect_btn.click(
505
+ fn=predict,
506
+ inputs=text_input,
507
+ outputs=output
508
+ )
509
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
510
  demo.launch()