testrro commited on
Commit
c8c6ac2
·
verified ·
1 Parent(s): 7c2596f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +206 -274
app.py CHANGED
@@ -7,35 +7,25 @@ from collections import defaultdict
7
  import math
8
  import os
9
  import traceback
10
- import json
11
- import re
12
- from fastapi import FastAPI, Request
13
- from fastapi.responses import JSONResponse
14
- import uvicorn
15
- from typing import Optional
16
 
17
  # ==================== কনফিগারেশন ====================
18
  CONFIG = {
19
  "HISTORY_LIMIT": 1000,
20
  "PINK_THRESHOLD": 3.0,
21
  "BIG_PINK_THRESHOLD": 5.0,
22
- "MAX_PREDICTION": 10000.0,
23
  }
24
 
25
- # ==================== ডেটা লোড ও টাইম-ভিত্তিক পরিসংখ্যান ====================
26
  TIME_STATS = None
27
-
28
  def load_time_statistics():
29
  global TIME_STATS
30
  try:
31
- data_path = 'data/aviator_Rounds_history_scrp.xlsx'
32
- if os.path.exists(data_path):
33
- df = pd.read_excel(data_path, sheet_name='scraping rounds crash')
34
  df = df[['ROUNDS', 'TIME ROUND']].dropna()
35
  df['multiplier'] = pd.to_numeric(df['ROUNDS'], errors='coerce')
36
  df = df.dropna()
37
  df['hour'] = pd.to_datetime(df['TIME ROUND'], format='%H:%M').dt.hour
38
-
39
  stats = df.groupby('hour')['multiplier'].agg(['mean', 'std', 'count']).to_dict('index')
40
  for h in range(24):
41
  if h not in stats:
@@ -51,85 +41,66 @@ def load_time_statistics():
51
 
52
  load_time_statistics()
53
 
54
- # ==================== স্ট্যাটিস্টিক্যাল মডেল V1-V5 ====================
55
-
56
  class StatisticalModelV1:
57
  def predict(self, history):
58
  recent = history[:15]
59
  if len(recent) < 3:
60
  return {'prediction': 1.5, 'confidence': 0.3}
61
-
62
  q1, q3 = np.percentile(recent, [25, 75])
63
  iqr = q3 - q1
64
  filtered = [x for x in recent if (q1 - 1.5*iqr) <= x <= (q3 + 1.5*iqr)]
65
  if len(filtered) < 3:
66
  filtered = recent
67
-
68
  x = np.arange(len(filtered))
69
  weights = np.linspace(1.5, 0.5, len(filtered))
70
  weights /= weights.sum()
71
-
72
  weighted_mean_x = np.average(x, weights=weights)
73
  weighted_mean_y = np.average(filtered, weights=weights)
74
-
75
  numerator = np.sum(weights * (x - weighted_mean_x) * (filtered - weighted_mean_y))
76
  denominator = np.sum(weights * (x - weighted_mean_x)**2)
77
  trend = numerator / denominator if denominator != 0 else 0
78
-
79
  prediction = np.median(filtered) + trend * 1.5
80
-
81
  cv = np.std(filtered) / (np.mean(filtered) + 0.1)
82
  confidence = min(0.85, 0.5 + len(filtered)/len(recent)*0.3 - cv*0.2)
83
-
84
  return {'prediction': float(prediction), 'confidence': float(confidence)}
85
 
86
  class StatisticalModelV2:
87
  def predict(self, history):
88
  timeframes = {'short': history[:5], 'medium': history[:10], 'long': history[:20]}
89
  preds, confs = [], []
90
-
91
  for name, data in timeframes.items():
92
  if len(data) < 3:
93
  continue
94
-
95
  ma_3 = np.mean(data[:3]) if len(data)>=3 else np.mean(data)
96
  ma_5 = np.mean(data[:5]) if len(data)>=5 else ma_3
97
-
98
  ema = data[0]
99
  alpha = 0.3
100
  for v in data[1:]:
101
  ema = alpha*v + (1-alpha)*ema
102
-
103
  x = np.arange(len(data))
104
  trend = np.polyfit(x, data, 1)[0]
105
-
106
  base = np.mean([ma_3, ma_5, ema])
107
  preds.append(base + trend * len(data) / 10)
108
  confs.append(min(0.9, 0.5 + len(data)/40))
109
-
110
  if not preds:
111
  return {'prediction': 1.5, 'confidence': 0.3}
112
-
113
  weights = {'short':0.5, 'medium':0.3, 'long':0.2}
114
  final_pred = 0
115
  total_weight = 0
116
-
117
  for i, name in enumerate(timeframes.keys()):
118
  if i < len(preds):
119
  w = weights.get(name, 0.2) * confs[i]
120
  final_pred += preds[i] * w
121
  total_weight += w
122
-
123
  final_pred /= total_weight if total_weight else 1
124
  confidence = np.mean(confs) * 0.9
125
-
126
  return {'prediction': float(final_pred), 'confidence': float(confidence)}
127
 
128
  class StatisticalModelV3:
129
  def detect_cycles(self, history):
130
  if len(history) < 10:
131
  return None
132
-
133
  cycles = []
134
  for period in range(3, 7):
135
  corrs = []
@@ -142,14 +113,11 @@ class StatisticalModelV3:
142
  corrs.append(abs(corr))
143
  if corrs and np.mean(corrs) > 0.6:
144
  cycles.append({'period': period, 'strength': float(np.mean(corrs))})
145
-
146
  return cycles if cycles else None
147
-
148
  def predict(self, history):
149
  recent = history[:20]
150
  cycles = self.detect_cycles(recent)
151
  cycle_pred = None
152
-
153
  if cycles:
154
  best = max(cycles, key=lambda x: x['strength'])
155
  period = best['period']
@@ -157,14 +125,11 @@ class StatisticalModelV3:
157
  next_val = recent[period:period+1]
158
  if next_val:
159
  cycle_pred = next_val[0] * (1 + best['strength'] * 0.1)
160
-
161
  base_pred = np.median(recent)
162
  if cycle_pred:
163
  base_pred = (base_pred + cycle_pred) / 2
164
-
165
- prediction = max(1.05, base_pred)
166
  confidence = min(0.9, 0.5 + len(recent)/40 + (0.15 if cycles else 0))
167
-
168
  return {'prediction': float(prediction), 'confidence': float(confidence)}
169
 
170
  class StatisticalModelV4:
@@ -172,65 +137,49 @@ class StatisticalModelV4:
172
  self.performance = []
173
  self.bias = 0
174
  self.volatility_regime = 'normal'
175
-
176
  def detect_volatility(self, history):
177
  if len(history) < 10:
178
  return 'normal'
179
  recent_vol = np.std(history[:5])
180
  long_vol = np.std(history[:20]) if len(history)>=20 else recent_vol
181
-
182
  if recent_vol > long_vol * 1.5:
183
  return 'high'
184
  elif recent_vol < long_vol * 0.5:
185
  return 'low'
186
  else:
187
  return 'normal'
188
-
189
  def predict(self, history):
190
  recent = history[:15]
191
  self.volatility_regime = self.detect_volatility(history)
192
-
193
  mean_val, median_val = np.mean(recent), np.median(recent)
194
-
195
  x = np.arange(len(recent))
196
  weights = np.exp(-0.2 * x)
197
  weights /= weights.sum()
198
-
199
  weighted_mean_x = np.average(x, weights=weights)
200
  weighted_mean_y = np.average(recent, weights=weights)
201
-
202
  numerator = np.sum(weights * (x - weighted_mean_x) * (recent - weighted_mean_y))
203
  denominator = np.sum(weights * (x - weighted_mean_x)**2)
204
  trend = numerator / denominator if denominator != 0 else 0
205
-
206
  preds = {'mean': mean_val, 'median': median_val, 'trend': median_val + trend * len(recent) * 0.5}
207
  w = {'mean': 0.3, 'median': 0.4, 'trend': 0.3}
208
-
209
  if self.volatility_regime == 'high':
210
  w['median'] *= 1.5
211
  elif self.volatility_regime == 'low':
212
  w['trend'] *= 1.3
213
-
214
  total = sum(w.values())
215
  for k in w:
216
  w[k] /= total
217
-
218
  prediction = sum(preds[k] * w[k] for k in preds) + self.bias
219
-
220
  confidence = 0.5 + len(recent)/30
221
  if self.volatility_regime == 'high':
222
  confidence *= 0.8
223
  elif self.volatility_regime == 'low':
224
  confidence *= 1.2
225
-
226
  if self.performance:
227
  recent_perf = np.mean(self.performance[-10:]) if len(self.performance)>=10 else np.mean(self.performance)
228
  confidence *= (1 + recent_perf * 0.1)
229
-
230
  confidence = min(0.9, confidence)
231
-
232
- return {'prediction': float(max(1.05, prediction)), 'confidence': float(confidence)}
233
-
234
  def update(self, actual, predicted):
235
  error = abs(actual - predicted) / actual
236
  acc = max(0, 1 - error)
@@ -242,14 +191,11 @@ class StatisticalModelV4:
242
  class StatisticalModelV5:
243
  def __init__(self):
244
  self.n_estimators = 10
245
-
246
  def predict(self, history):
247
  if len(history) < 10:
248
  return {'prediction': 1.5, 'confidence': 0.5}
249
-
250
  recent = history[:10]
251
  trees = []
252
-
253
  for _ in range(self.n_estimators):
254
  idx = np.random.choice(len(recent), size=len(recent), replace=True)
255
  sample = [recent[i] for i in idx]
@@ -257,32 +203,183 @@ class StatisticalModelV5:
257
  trees.append(np.mean(sample))
258
  else:
259
  trees.append(np.median(sample))
260
-
261
  pred = float(np.mean(trees))
262
  return {'prediction': pred, 'confidence': 0.7}
263
 
264
- # ==================== V6 মডেল (টাইম-ভিত্তিক) ====================
265
-
266
  class StatisticalModelV6:
267
  def __init__(self, time_stats):
268
  self.time_stats = time_stats
269
-
270
  def predict(self, history, current_hour=None):
271
  if current_hour is None:
272
  current_hour = datetime.now().hour
273
-
274
  stats = self.time_stats.get(current_hour, {'mean': 1.8, 'std': 1.0})
275
  base_pred = np.median(history[:5]) if len(history)>=5 else 1.5
276
-
277
  alpha = 0.3
278
  prediction = base_pred * (1 - alpha) + stats['mean'] * alpha
279
  confidence = min(0.85, 0.5 + stats.get('count', 100) / 500)
280
-
281
  return {'prediction': float(prediction), 'confidence': float(confidence), 'hour': current_hour}
282
 
283
- # ==================== েম্বল পেডিক্ট ====================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
- class EnsemblePredictorV6:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
286
  def __init__(self, time_stats):
287
  self.models = {
288
  'v1': StatisticalModelV1(),
@@ -290,50 +387,40 @@ class EnsemblePredictorV6:
290
  'v3': StatisticalModelV3(),
291
  'v4': StatisticalModelV4(),
292
  'v5': StatisticalModelV5(),
293
- 'v6': StatisticalModelV6(time_stats)
 
294
  }
295
- self.ensemble_weights = {'v1':0.2, 'v2':0.2, 'v3':0.15, 'v4':0.15, 'v5':0.15, 'v6':0.15}
296
  self.performance = defaultdict(list)
297
-
298
  def predict(self, history):
299
  if len(history) < 5:
300
  return self._default_prediction(f"মাত্র {len(history)}টি রাউন্ড, ৫টি প্রয়োজন")
301
-
302
  current_hour = datetime.now().hour
303
  preds = {}
304
  confs = {}
305
-
306
  for name, model in self.models.items():
307
- try:
308
- if name == 'v6':
309
- res = model.predict(history, current_hour)
310
- else:
311
- res = model.predict(history)
312
- preds[name] = res['prediction']
313
- confs[name] = res.get('confidence', 0.5)
314
- except Exception as e:
315
- print(f"মডেল {name} এ সমস্যা: {e}")
316
- preds[name] = 1.5
317
- confs[name] = 0.3
318
-
319
  for name in self.ensemble_weights:
320
  if name in self.performance and self.performance[name]:
321
  recent_acc = np.mean(self.performance[name][-20:]) if len(self.performance[name])>=20 else np.mean(self.performance[name])
322
  self.ensemble_weights[name] = 0.1 + recent_acc * 0.8
323
-
324
  total = sum(self.ensemble_weights.values())
325
  for name in self.ensemble_weights:
326
  self.ensemble_weights[name] /= total
327
-
328
  final_pred = 0
329
  total_weight = 0
330
  for name, pred in preds.items():
331
  weight = self.ensemble_weights.get(name, 0.2) * confs[name]
332
  final_pred += pred * weight
333
  total_weight += weight
334
-
335
  final_pred /= total_weight if total_weight else 1
336
-
337
  recent = history[:10]
338
  vol = np.std(recent) / (np.mean(recent)+0.1)
339
  if vol > 0.5:
@@ -342,30 +429,26 @@ class EnsemblePredictorV6:
342
  state = "স্থিতিশীল ✨"
343
  else:
344
  state = "সাধারণ ➡️"
345
-
346
  confidence = np.mean(list(confs.values())) * 0.9
347
  if vol < 0.2:
348
  confidence *= 1.1
349
  elif vol > 0.5:
350
  confidence *= 0.9
351
  confidence = min(0.95, confidence)
352
-
353
  all_preds = list(preds.values())
354
  std = np.std(all_preds) if len(all_preds)>1 else 0.2
355
  spread = std * (2 - confidence)
356
  spread = max(0.1, min(1.5, spread))
357
  interval = (max(1.01, final_pred - spread/2), final_pred + spread/2)
358
-
359
  if final_pred > 3.0:
360
  decision = "বড় 🚀"
361
  elif final_pred > 1.8:
362
  decision = "মাঝারি 💪"
363
  else:
364
  decision = "ছোট 🎯"
365
-
366
  hour_stats = TIME_STATS.get(current_hour, {'mean':1.8, 'count':0})
367
  time_info = f"বর্তমান ঘণ্টা: {current_hour}:00 – ঐতিহাসিক গড়: {hour_stats['mean']:.2f}x (ডাটা: {hour_stats['count']}টি)"
368
-
369
  summary = (
370
  f"🎯 **প্রেডিকশন ইন্টারভ্যাল**: {interval[0]:.2f}x – {interval[1]:.2f}x\n"
371
  f"📊 **এক্সপেক্টেড মাল্টিপ্লায়ার**: {final_pred:.2f}x\n"
@@ -375,7 +458,6 @@ class EnsemblePredictorV6:
375
  f"⏰ **টাইম ফিচার**: {time_info}\n"
376
  f"📌 **ডাটা পয়েন্ট**: {len(history)}টি রাউন্ড"
377
  )
378
-
379
  return {
380
  'summary': summary,
381
  'prediction': final_pred,
@@ -385,7 +467,6 @@ class EnsemblePredictorV6:
385
  'analysis': state,
386
  'hour': current_hour
387
  }
388
-
389
  def _default_prediction(self, msg):
390
  return {
391
  'summary': f"⚠️ {msg}\n\n📊 ডিফল্ট প্রেডিকশন: 1.50x (কনফিডেন্স 30%)",
@@ -397,62 +478,32 @@ class EnsemblePredictorV6:
397
  }
398
 
399
  # ==================== অ্যাপ্লিকেশন ক্লাস ====================
400
-
401
  class AviatorPredictorApp:
402
  def __init__(self):
403
  self.history = []
404
- self.model = EnsemblePredictorV6(TIME_STATS)
405
-
406
  def add_round(self, multiplier):
407
- try:
408
- if multiplier is None:
409
- return self.get_all_outputs(error="মাল্টিপ্লায়ার দেওয়া হয়নি")
410
-
411
- val = float(multiplier)
412
-
413
- if val <= 0:
414
- return self.get_all_outputs(error="ইনভ্যালিড মাল্টিপ্লায়ার (১.০ এর বেশি দিন)")
415
-
416
- self.history.insert(0, val)
417
- if len(self.history) > CONFIG["HISTORY_LIMIT"]:
418
- self.history = self.history[:CONFIG["HISTORY_LIMIT"]]
419
-
420
- return self.get_all_outputs()
421
-
422
- except ValueError:
423
- return self.get_all_outputs(error=f"ইনভ্যালিড সংখ্যা: {multiplier}")
424
- except Exception as e:
425
- traceback.print_exc()
426
- return self.get_all_outputs(error=f"⚠️ ত্রুটি: {str(e)}")
427
-
428
  def reset(self):
429
  self.history = []
430
  for _ in range(20):
431
  self.history.append(round(random.uniform(1.0, 3.5), 2))
432
  self.history.sort(reverse=True)
433
  return self.get_all_outputs()
434
-
435
  def get_all_outputs(self, error=None):
436
  if error:
437
  table = [[i+1, "?.??x"] for i in range(min(20, len(self.history)))] or [[1, "1.00x"]]
438
  return [table, f"⚠️ {error}"]
439
-
440
- try:
441
- pred_result = self.model.predict(self.history)
442
- table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
443
- return [table, pred_result['summary']]
444
- except Exception as e:
445
- traceback.print_exc()
446
- table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
447
- return [table, f"⚠️ প্রেডিকশনে সমস্যা: {str(e)}"]
448
-
449
- # ==================== অ্যাপ ইনিশিয়ালাইজ ====================
450
-
451
- predictor_app = AviatorPredictorApp()
452
- predictor_app.reset()
453
 
454
  # ==================== কাস্টম CSS ====================
455
-
456
  CUSTOM_CSS = """
457
  .gradio-container {
458
  background: #0a0a0f !important;
@@ -460,165 +511,46 @@ CUSTOM_CSS = """
460
  font-family: 'Inter', sans-serif !important;
461
  }
462
  footer {visibility: hidden}
463
- h1 {
464
- color: #00d4ff !important;
465
- text-align: center;
466
- margin-bottom: 20px;
467
- text-shadow: 0 0 10px #00d4ff;
468
- }
469
- .gr-box {
470
- border: 1px solid #333 !important;
471
- background: rgba(255,255,255,0.05) !important;
472
- }
473
- .gr-button-primary {
474
- background: linear-gradient(135deg, #00d4ff, #0088ff) !important;
475
- border: none !important;
476
- }
477
- .gr-button-secondary {
478
- background: rgba(255,255,255,0.1) !important;
479
- border: 1px solid #00d4ff !important;
480
- margin-top: 20px !important;
481
- }
482
- .gr-dataframe {
483
- background: rgba(255,255,255,0.05) !important;
484
- }
485
  """
486
 
487
  # ==================== গ্র্যাডিও ইন্টারফেস ====================
 
 
488
 
489
- with gr.Blocks(title="AVOLD V6 Predictor") as demo:
490
  gr.HTML("""
491
  <div style="text-align: center; margin-bottom: 20px;">
492
- <h1 style="color: #00d4ff; font-size: 48px; margin: 0;">✈️ AVOLD V6</h1>
493
- <p style="color: #888; font-size: 14px;">সময়-ভিতিভিয়টরেডিক্টর – ৬টি মডেলএনসেম্বল</p>
494
  </div>
495
  """)
496
-
497
  with gr.Row():
498
- inp = gr.Number(label="নতুন মাল্টিপ্লায়ার", value=1.0, step=0.1, minimum=1.0, maximum=None)
499
  add_btn = gr.Button("➕ যোগ করুন", variant="primary")
500
-
501
  prediction_box = gr.Textbox(label="🧠 প্রেডিকশন রিপোর্ট", lines=10, interactive=False)
502
  rounds_table = gr.Dataframe(label="📜 শেষ ৫০ রাউন্ড", headers=["রাউন্ড", "মাল্টিপ্লায়ার"], row_count=10)
503
  reset_btn = gr.Button("🔄 রিসেট ডাটা", variant="secondary")
504
-
505
  add_btn.click(
506
- fn=predictor_app.add_round,
507
  inputs=inp,
508
  outputs=[rounds_table, prediction_box]
509
  )
510
-
511
  reset_btn.click(
512
- fn=predictor_app.reset,
513
  outputs=[rounds_table, prediction_box]
514
  )
515
-
516
  demo.load(
517
- fn=predictor_app.get_all_outputs,
518
  outputs=[rounds_table, prediction_box]
519
  )
520
 
521
- # ==================== FastAPI অ্যাপ তৈরি ====================
522
-
523
- # FastAPI অ্যাপ তৈরি করা
524
- app = FastAPI()
525
-
526
- # রুট URL-এ স্বাগতম বার্তা
527
- @app.get("/")
528
- async def root():
529
- return {"message": "AVOLD V6 Predictor API", "status": "running", "endpoints": ["/api/status", "/api/add_crash"]}
530
-
531
- # API স্ট্যাটাস এন্ডপয়েন্ট
532
- @app.get("/api/status")
533
- async def api_status():
534
- """
535
- API স্ট্যাটাস চেক করার জন্য
536
- """
537
- return {
538
- "status": "active",
539
- "total_rounds": len(predictor_app.history),
540
- "last_10_rounds": [f"{x:.2f}" for x in predictor_app.history[:10]]
541
- }
542
-
543
- # ক্র্যাশ ভ্যালু যোগ করার এন্ডপয়েন্ট
544
- @app.post("/api/add_crash")
545
- async def add_crash_api(request: Request):
546
- """
547
- ShareX থেকে JSON ডাটা গ্রহণ করে ইতিহাসে যোগ করে
548
- """
549
- crash_value = None # আগেই ডিফাইন করে রাখা
550
-
551
- try:
552
- # JSON বডি পার্স করা
553
- try:
554
- data = await request.json()
555
- crash_value = data.get("crash_value")
556
-
557
- if crash_value is None:
558
- crash_value = data.get("value") or data.get("multiplier")
559
- except json.JSONDecodeError:
560
- return JSONResponse(
561
- status_code=400,
562
- content={"status": "error", "message": "Invalid JSON format"}
563
- )
564
-
565
- if crash_value is None:
566
- return JSONResponse(
567
- status_code=400,
568
- content={"status": "error", "message": "crash_value, value, অথবা multiplier প্রদান করুন"}
569
- )
570
-
571
- # OCR থেকে আনা টেক্সট ক্লিন করা (যেমন "2.45x" থেকে "2.45")
572
- if isinstance(crash_value, str):
573
- # শুধু সংখ্যা ও ডট রাখা
574
- crash_value = re.sub(r'[^\d.]', '', crash_value)
575
- if not crash_value: # যদি খালি হয়ে যায়
576
- return JSONResponse(
577
- status_code=400,
578
- content={"status": "error", "message": "OCR থেকে কোনো সংখ্যা পাওয়া যায়নি"}
579
- )
580
-
581
- # সংখ্যায় রূপান্তর
582
- try:
583
- val = float(crash_value)
584
- except ValueError:
585
- return JSONResponse(
586
- status_code=400,
587
- content={"status": "error", "message": f"ইনভ্যালিড সংখ্যা: {crash_value}"}
588
- )
589
-
590
- if val <= 1.0:
591
- return JSONResponse(
592
- status_code=400,
593
- content={"status": "error", "message": f"মাল্টিপ্লায়ার ১.০ এর বেশি হতে হবে (পাওয়া গেছে: {val})"}
594
- )
595
-
596
- # ইতিহাসে যোগ করা
597
- predictor_app.add_round(val)
598
-
599
- return JSONResponse(
600
- status_code=200,
601
- content={
602
- "status": "success",
603
- "message": f"ক্র্যাশ ভ্যালু {val:.2f}x যোগ করা হয়েছে",
604
- "total_rounds": len(predictor_app.history)
605
- }
606
- )
607
-
608
- except Exception as e:
609
- traceback.print_exc()
610
- return JSONResponse(
611
- status_code=500,
612
- content={"status": "error", "message": f"সার্ভার ত্রুটি: {str(e)}"}
613
- )
614
-
615
- # ==================== মাউন্ট গ্র্যাডিও অ্যাপ ====================
616
-
617
- # গ্র্যাডিও অ্যাপকে FastAPI-তে মাউন্ট করা
618
- app = gr.mount_gradio_app(app, demo, path="/")
619
-
620
- # ==================== মেইন ফাংশন ====================
621
-
622
  if __name__ == "__main__":
623
- import uvicorn
624
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
7
  import math
8
  import os
9
  import traceback
 
 
 
 
 
 
10
 
11
  # ==================== কনফিগারেশন ====================
12
  CONFIG = {
13
  "HISTORY_LIMIT": 1000,
14
  "PINK_THRESHOLD": 3.0,
15
  "BIG_PINK_THRESHOLD": 5.0,
 
16
  }
17
 
18
+ # ==================== টাইম-ভিত্তিক পরিসংখ্যান (V6) ====================
19
  TIME_STATS = None
 
20
  def load_time_statistics():
21
  global TIME_STATS
22
  try:
23
+ if os.path.exists('aviator_Rounds_history_scrp.xlsx'):
24
+ df = pd.read_excel('aviator_Rounds_history_scrp.xlsx', sheet_name='scarping rounds crash')
 
25
  df = df[['ROUNDS', 'TIME ROUND']].dropna()
26
  df['multiplier'] = pd.to_numeric(df['ROUNDS'], errors='coerce')
27
  df = df.dropna()
28
  df['hour'] = pd.to_datetime(df['TIME ROUND'], format='%H:%M').dt.hour
 
29
  stats = df.groupby('hour')['multiplier'].agg(['mean', 'std', 'count']).to_dict('index')
30
  for h in range(24):
31
  if h not in stats:
 
41
 
42
  load_time_statistics()
43
 
44
+ # ==================== স্ট্যাটিস্টিক্যাল মডেল V1-V5 (আগের মতো) ====================
 
45
  class StatisticalModelV1:
46
  def predict(self, history):
47
  recent = history[:15]
48
  if len(recent) < 3:
49
  return {'prediction': 1.5, 'confidence': 0.3}
 
50
  q1, q3 = np.percentile(recent, [25, 75])
51
  iqr = q3 - q1
52
  filtered = [x for x in recent if (q1 - 1.5*iqr) <= x <= (q3 + 1.5*iqr)]
53
  if len(filtered) < 3:
54
  filtered = recent
 
55
  x = np.arange(len(filtered))
56
  weights = np.linspace(1.5, 0.5, len(filtered))
57
  weights /= weights.sum()
 
58
  weighted_mean_x = np.average(x, weights=weights)
59
  weighted_mean_y = np.average(filtered, weights=weights)
 
60
  numerator = np.sum(weights * (x - weighted_mean_x) * (filtered - weighted_mean_y))
61
  denominator = np.sum(weights * (x - weighted_mean_x)**2)
62
  trend = numerator / denominator if denominator != 0 else 0
 
63
  prediction = np.median(filtered) + trend * 1.5
 
64
  cv = np.std(filtered) / (np.mean(filtered) + 0.1)
65
  confidence = min(0.85, 0.5 + len(filtered)/len(recent)*0.3 - cv*0.2)
 
66
  return {'prediction': float(prediction), 'confidence': float(confidence)}
67
 
68
  class StatisticalModelV2:
69
  def predict(self, history):
70
  timeframes = {'short': history[:5], 'medium': history[:10], 'long': history[:20]}
71
  preds, confs = [], []
 
72
  for name, data in timeframes.items():
73
  if len(data) < 3:
74
  continue
 
75
  ma_3 = np.mean(data[:3]) if len(data)>=3 else np.mean(data)
76
  ma_5 = np.mean(data[:5]) if len(data)>=5 else ma_3
 
77
  ema = data[0]
78
  alpha = 0.3
79
  for v in data[1:]:
80
  ema = alpha*v + (1-alpha)*ema
 
81
  x = np.arange(len(data))
82
  trend = np.polyfit(x, data, 1)[0]
 
83
  base = np.mean([ma_3, ma_5, ema])
84
  preds.append(base + trend * len(data) / 10)
85
  confs.append(min(0.9, 0.5 + len(data)/40))
 
86
  if not preds:
87
  return {'prediction': 1.5, 'confidence': 0.3}
 
88
  weights = {'short':0.5, 'medium':0.3, 'long':0.2}
89
  final_pred = 0
90
  total_weight = 0
 
91
  for i, name in enumerate(timeframes.keys()):
92
  if i < len(preds):
93
  w = weights.get(name, 0.2) * confs[i]
94
  final_pred += preds[i] * w
95
  total_weight += w
 
96
  final_pred /= total_weight if total_weight else 1
97
  confidence = np.mean(confs) * 0.9
 
98
  return {'prediction': float(final_pred), 'confidence': float(confidence)}
99
 
100
  class StatisticalModelV3:
101
  def detect_cycles(self, history):
102
  if len(history) < 10:
103
  return None
 
104
  cycles = []
105
  for period in range(3, 7):
106
  corrs = []
 
113
  corrs.append(abs(corr))
114
  if corrs and np.mean(corrs) > 0.6:
115
  cycles.append({'period': period, 'strength': float(np.mean(corrs))})
 
116
  return cycles if cycles else None
 
117
  def predict(self, history):
118
  recent = history[:20]
119
  cycles = self.detect_cycles(recent)
120
  cycle_pred = None
 
121
  if cycles:
122
  best = max(cycles, key=lambda x: x['strength'])
123
  period = best['period']
 
125
  next_val = recent[period:period+1]
126
  if next_val:
127
  cycle_pred = next_val[0] * (1 + best['strength'] * 0.1)
 
128
  base_pred = np.median(recent)
129
  if cycle_pred:
130
  base_pred = (base_pred + cycle_pred) / 2
131
+ prediction = max(1.05, min(10000.0, base_pred)) # ক্যাপ বাড়ানো হয়েছে
 
132
  confidence = min(0.9, 0.5 + len(recent)/40 + (0.15 if cycles else 0))
 
133
  return {'prediction': float(prediction), 'confidence': float(confidence)}
134
 
135
  class StatisticalModelV4:
 
137
  self.performance = []
138
  self.bias = 0
139
  self.volatility_regime = 'normal'
 
140
  def detect_volatility(self, history):
141
  if len(history) < 10:
142
  return 'normal'
143
  recent_vol = np.std(history[:5])
144
  long_vol = np.std(history[:20]) if len(history)>=20 else recent_vol
 
145
  if recent_vol > long_vol * 1.5:
146
  return 'high'
147
  elif recent_vol < long_vol * 0.5:
148
  return 'low'
149
  else:
150
  return 'normal'
 
151
  def predict(self, history):
152
  recent = history[:15]
153
  self.volatility_regime = self.detect_volatility(history)
 
154
  mean_val, median_val = np.mean(recent), np.median(recent)
 
155
  x = np.arange(len(recent))
156
  weights = np.exp(-0.2 * x)
157
  weights /= weights.sum()
 
158
  weighted_mean_x = np.average(x, weights=weights)
159
  weighted_mean_y = np.average(recent, weights=weights)
 
160
  numerator = np.sum(weights * (x - weighted_mean_x) * (recent - weighted_mean_y))
161
  denominator = np.sum(weights * (x - weighted_mean_x)**2)
162
  trend = numerator / denominator if denominator != 0 else 0
 
163
  preds = {'mean': mean_val, 'median': median_val, 'trend': median_val + trend * len(recent) * 0.5}
164
  w = {'mean': 0.3, 'median': 0.4, 'trend': 0.3}
 
165
  if self.volatility_regime == 'high':
166
  w['median'] *= 1.5
167
  elif self.volatility_regime == 'low':
168
  w['trend'] *= 1.3
 
169
  total = sum(w.values())
170
  for k in w:
171
  w[k] /= total
 
172
  prediction = sum(preds[k] * w[k] for k in preds) + self.bias
 
173
  confidence = 0.5 + len(recent)/30
174
  if self.volatility_regime == 'high':
175
  confidence *= 0.8
176
  elif self.volatility_regime == 'low':
177
  confidence *= 1.2
 
178
  if self.performance:
179
  recent_perf = np.mean(self.performance[-10:]) if len(self.performance)>=10 else np.mean(self.performance)
180
  confidence *= (1 + recent_perf * 0.1)
 
181
  confidence = min(0.9, confidence)
182
+ return {'prediction': float(max(1.05, min(10000.0, prediction))), 'confidence': float(confidence)}
 
 
183
  def update(self, actual, predicted):
184
  error = abs(actual - predicted) / actual
185
  acc = max(0, 1 - error)
 
191
  class StatisticalModelV5:
192
  def __init__(self):
193
  self.n_estimators = 10
 
194
  def predict(self, history):
195
  if len(history) < 10:
196
  return {'prediction': 1.5, 'confidence': 0.5}
 
197
  recent = history[:10]
198
  trees = []
 
199
  for _ in range(self.n_estimators):
200
  idx = np.random.choice(len(recent), size=len(recent), replace=True)
201
  sample = [recent[i] for i in idx]
 
203
  trees.append(np.mean(sample))
204
  else:
205
  trees.append(np.median(sample))
 
206
  pred = float(np.mean(trees))
207
  return {'prediction': pred, 'confidence': 0.7}
208
 
 
 
209
  class StatisticalModelV6:
210
  def __init__(self, time_stats):
211
  self.time_stats = time_stats
 
212
  def predict(self, history, current_hour=None):
213
  if current_hour is None:
214
  current_hour = datetime.now().hour
 
215
  stats = self.time_stats.get(current_hour, {'mean': 1.8, 'std': 1.0})
216
  base_pred = np.median(history[:5]) if len(history)>=5 else 1.5
 
217
  alpha = 0.3
218
  prediction = base_pred * (1 - alpha) + stats['mean'] * alpha
219
  confidence = min(0.85, 0.5 + stats.get('count', 100) / 500)
 
220
  return {'prediction': float(prediction), 'confidence': float(confidence), 'hour': current_hour}
221
 
222
+ # ==================== রিপোজিটরি থেকে নেওয়া ML ডেসমূহ (Python র্ট) ====================
223
+ # (JavaScript Tampermonkey script থেকে অনুবাদিত)
224
+
225
+ class NeuralNetwork:
226
+ def __init__(self):
227
+ self.weights = {
228
+ 'input': np.random.randn(15) * 0.1,
229
+ 'hidden': np.random.randn(10) * 0.1,
230
+ 'output': np.random.randn(5) * 0.1
231
+ }
232
+ self.performance_history = []
233
+ def extract_features(self, history):
234
+ recent = history[:12]
235
+ features = []
236
+ for val in recent:
237
+ features.append(math.log(val + 0.1) / math.log(10))
238
+ mean_val = np.mean(recent) if recent else 1.5
239
+ std_val = np.std(recent) if recent else 0.2
240
+ features.append(mean_val)
241
+ features.append(std_val / (mean_val + 0.1))
242
+ if len(recent) >= 3:
243
+ trend = (recent[0] - recent[-1]) / len(recent)
244
+ features.append(trend)
245
+ else:
246
+ features.append(0)
247
+ pink_count = sum(1 for v in recent if v >= CONFIG["PINK_THRESHOLD"])
248
+ features.append(pink_count / len(recent) if recent else 0)
249
+ while len(features) < 15:
250
+ features.append(0)
251
+ return np.array(features[:15])
252
+ def predict(self, history):
253
+ if len(history) < 5:
254
+ return {'prediction': 1.5, 'confidence': 0.3}
255
+ features = self.extract_features(history)
256
+ hidden = np.tanh(np.dot(features, self.weights['input'][:len(features)]))
257
+ output = np.tanh(hidden * np.mean(self.weights['hidden']))
258
+ prediction = 1.5 + (output * 3.0)
259
+ prediction = max(1.05, min(10000.0, prediction))
260
+ confidence = min(0.9, 0.5 + (len(history) / 200) + abs(output) * 0.2)
261
+ analysis = "Neural: strong" if output > 0.6 else "Neural: weak"
262
+ return {'prediction': float(prediction), 'confidence': float(confidence), 'analysis': analysis}
263
+
264
+ class SequenceAnalyzer:
265
+ def __init__(self):
266
+ self.max_pattern_length = 6
267
+ def find_patterns(self, history):
268
+ patterns = []
269
+ for length in range(2, min(self.max_pattern_length, len(history) // 2)):
270
+ for i in range(len(history) - length * 2):
271
+ pattern = history[i:i+length]
272
+ next_seq = history[i+length:i+length*2]
273
+ similarity = self.calculate_similarity(pattern, next_seq)
274
+ if similarity > 0.6:
275
+ patterns.append({'pattern': pattern, 'next': next_seq, 'similarity': similarity, 'length': length})
276
+ return patterns
277
+ def calculate_similarity(self, seq1, seq2):
278
+ if len(seq1) != len(seq2) or len(seq1) == 0:
279
+ return 0
280
+ diffs = [abs(seq1[i] - seq2[i]) / (max(seq1[i], seq2[i]) + 0.1) for i in range(len(seq1))]
281
+ avg_diff = np.mean(diffs) if diffs else 1
282
+ return max(0, 1 - avg_diff)
283
+ def predict(self, history):
284
+ if len(history) < 4:
285
+ return {'prediction': 1.5, 'confidence': 0.3}
286
+ patterns = self.find_patterns(history)
287
+ if not patterns:
288
+ return {'prediction': 1.5, 'confidence': 0.4}
289
+ best = max(patterns, key=lambda p: p['similarity'] * p['length'])
290
+ trend = (best['pattern'][-1] - best['pattern'][0]) / len(best['pattern'])
291
+ prediction = best['pattern'][-1] + trend
292
+ prediction = max(1.05, min(10000.0, prediction))
293
+ confidence = best['similarity'] * 0.8
294
+ return {'prediction': float(prediction), 'confidence': float(confidence)}
295
 
296
+ class MarkovChain:
297
+ def __init__(self):
298
+ self.transition_matrix = defaultdict(lambda: defaultdict(float))
299
+ self.states = ['very_low', 'low', 'medium', 'high', 'pink']
300
+ def discretize(self, value):
301
+ if value < 1.3:
302
+ return 'very_low'
303
+ elif value < 1.8:
304
+ return 'low'
305
+ elif value < 2.5:
306
+ return 'medium'
307
+ elif value < CONFIG["PINK_THRESHOLD"]:
308
+ return 'high'
309
+ else:
310
+ return 'pink'
311
+ def build_model(self, history):
312
+ self.transition_matrix.clear()
313
+ for i in range(len(history) - 1):
314
+ current = self.discretize(history[i])
315
+ next_state = self.discretize(history[i+1])
316
+ self.transition_matrix[current][next_state] += 1
317
+ for state in self.transition_matrix:
318
+ total = sum(self.transition_matrix[state].values())
319
+ if total > 0:
320
+ for next_state in self.transition_matrix[state]:
321
+ self.transition_matrix[state][next_state] /= total
322
+ def predict(self, history):
323
+ if len(history) < 2:
324
+ return {'prediction': 1.5, 'confidence': 0.3}
325
+ self.build_model(history)
326
+ current_state = self.discretize(history[0])
327
+ probs = self.transition_matrix.get(current_state, {})
328
+ if not probs:
329
+ probs = {'very_low':0.2, 'low':0.4, 'medium':0.25, 'high':0.1, 'pink':0.05}
330
+ state_values = {'very_low':1.15, 'low':1.5, 'medium':2.2, 'high':2.8, 'pink':4.5}
331
+ prediction = sum(state_values[s] * probs.get(s,0) for s in self.states) / (sum(probs.values()) or 1)
332
+ confidence = max(probs.values()) * 0.9 if probs else 0.3
333
+ return {'prediction': float(prediction), 'confidence': float(confidence)}
334
+
335
+ class StatisticalPredictor:
336
+ def predict(self, history):
337
+ recent = history[:15]
338
+ mean_val = np.mean(recent)
339
+ median_val = np.median(recent)
340
+ x = np.arange(len(recent))
341
+ trend = np.polyfit(x, recent, 1)[0] if len(recent) > 1 else 0
342
+ std_val = np.std(recent)
343
+ prediction = median_val + trend * 1.5
344
+ if std_val > 1.0:
345
+ prediction += random.uniform(-0.5, 0.5)
346
+ prediction = max(1.05, min(10000.0, prediction))
347
+ confidence = min(0.8, 0.5 + (len(history)/200) - (std_val/10))
348
+ return {'prediction': float(prediction), 'confidence': float(confidence)}
349
+
350
+ class RepositoryEnsemble:
351
+ """রিপোজিটরির এনসেম্বল মডেল (পোর্টেড)"""
352
+ def __init__(self):
353
+ self.models = {
354
+ 'neural': NeuralNetwork(),
355
+ 'sequence': SequenceAnalyzer(),
356
+ 'markov': MarkovChain(),
357
+ 'stat': StatisticalPredictor()
358
+ }
359
+ self.weights = {'neural':0.35, 'sequence':0.30, 'markov':0.20, 'stat':0.15}
360
+ self.performance = defaultdict(list)
361
+ def predict(self, history):
362
+ if len(history) < 5:
363
+ return {'prediction': 1.5, 'confidence': 0.3}
364
+ preds = {}
365
+ confs = {}
366
+ for name, model in self.models.items():
367
+ res = model.predict(history)
368
+ preds[name] = res['prediction']
369
+ confs[name] = res['confidence']
370
+ total_weight = 0
371
+ weighted_sum = 0
372
+ for name, pred in preds.items():
373
+ w = self.weights.get(name, 0.2) * confs[name]
374
+ weighted_sum += pred * w
375
+ total_weight += w
376
+ final_pred = weighted_sum / total_weight if total_weight > 0 else 1.5
377
+ final_pred = max(1.05, min(10000.0, final_pred))
378
+ confidence = np.mean(list(confs.values())) * 0.9
379
+ return {'prediction': float(final_pred), 'confidence': float(confidence)}
380
+
381
+ # ==================== চূড়ান্ত এনসেম্বল (V1-V6 + Repository) ====================
382
+ class EnsemblePredictorV7:
383
  def __init__(self, time_stats):
384
  self.models = {
385
  'v1': StatisticalModelV1(),
 
387
  'v3': StatisticalModelV3(),
388
  'v4': StatisticalModelV4(),
389
  'v5': StatisticalModelV5(),
390
+ 'v6': StatisticalModelV6(time_stats),
391
+ 'repo': RepositoryEnsemble()
392
  }
393
+ self.ensemble_weights = {'v1':0.15, 'v2':0.15, 'v3':0.1, 'v4':0.1, 'v5':0.1, 'v6':0.1, 'repo':0.3}
394
  self.performance = defaultdict(list)
 
395
  def predict(self, history):
396
  if len(history) < 5:
397
  return self._default_prediction(f"মাত্র {len(history)}টি রাউন্ড, ৫টি প্রয়োজন")
 
398
  current_hour = datetime.now().hour
399
  preds = {}
400
  confs = {}
 
401
  for name, model in self.models.items():
402
+ if name == 'v6':
403
+ res = model.predict(history, current_hour)
404
+ else:
405
+ res = model.predict(history)
406
+ preds[name] = res['prediction']
407
+ confs[name] = res.get('confidence', 0.5)
408
+ # ওয়েট আপডেট (পারফরমেন্স ভিত্তিক)
 
 
 
 
 
409
  for name in self.ensemble_weights:
410
  if name in self.performance and self.performance[name]:
411
  recent_acc = np.mean(self.performance[name][-20:]) if len(self.performance[name])>=20 else np.mean(self.performance[name])
412
  self.ensemble_weights[name] = 0.1 + recent_acc * 0.8
 
413
  total = sum(self.ensemble_weights.values())
414
  for name in self.ensemble_weights:
415
  self.ensemble_weights[name] /= total
 
416
  final_pred = 0
417
  total_weight = 0
418
  for name, pred in preds.items():
419
  weight = self.ensemble_weights.get(name, 0.2) * confs[name]
420
  final_pred += pred * weight
421
  total_weight += weight
 
422
  final_pred /= total_weight if total_weight else 1
423
+ # মার্কেট স্টেট
424
  recent = history[:10]
425
  vol = np.std(recent) / (np.mean(recent)+0.1)
426
  if vol > 0.5:
 
429
  state = "স্থিতিশীল ✨"
430
  else:
431
  state = "সাধারণ ➡️"
 
432
  confidence = np.mean(list(confs.values())) * 0.9
433
  if vol < 0.2:
434
  confidence *= 1.1
435
  elif vol > 0.5:
436
  confidence *= 0.9
437
  confidence = min(0.95, confidence)
 
438
  all_preds = list(preds.values())
439
  std = np.std(all_preds) if len(all_preds)>1 else 0.2
440
  spread = std * (2 - confidence)
441
  spread = max(0.1, min(1.5, spread))
442
  interval = (max(1.01, final_pred - spread/2), final_pred + spread/2)
443
+ # ডিসিশন
444
  if final_pred > 3.0:
445
  decision = "বড় 🚀"
446
  elif final_pred > 1.8:
447
  decision = "মাঝারি 💪"
448
  else:
449
  decision = "ছোট 🎯"
 
450
  hour_stats = TIME_STATS.get(current_hour, {'mean':1.8, 'count':0})
451
  time_info = f"বর্তমান ঘণ্টা: {current_hour}:00 – ঐতিহাসিক গড়: {hour_stats['mean']:.2f}x (ডাটা: {hour_stats['count']}টি)"
 
452
  summary = (
453
  f"🎯 **প্রেডিকশন ইন্টারভ্যাল**: {interval[0]:.2f}x – {interval[1]:.2f}x\n"
454
  f"📊 **এক্সপেক্টেড মাল্টিপ্লায়ার**: {final_pred:.2f}x\n"
 
458
  f"⏰ **টাইম ফিচার**: {time_info}\n"
459
  f"📌 **ডাটা পয়েন্ট**: {len(history)}টি রাউন্ড"
460
  )
 
461
  return {
462
  'summary': summary,
463
  'prediction': final_pred,
 
467
  'analysis': state,
468
  'hour': current_hour
469
  }
 
470
  def _default_prediction(self, msg):
471
  return {
472
  'summary': f"⚠️ {msg}\n\n📊 ডিফল্ট প্রেডিকশন: 1.50x (কনফিডেন্স 30%)",
 
478
  }
479
 
480
  # ==================== অ্যাপ্লিকেশন ক্লাস ====================
 
481
  class AviatorPredictorApp:
482
  def __init__(self):
483
  self.history = []
484
+ self.model = EnsemblePredictorV7(TIME_STATS)
 
485
  def add_round(self, multiplier):
486
+ if multiplier <= 0:
487
+ return self.get_all_outputs(error="ইনভ্যালিড মাল্টিপ্লায়ার (১.০ এর বেশি দিন)")
488
+ self.history.insert(0, float(multiplier))
489
+ if len(self.history) > CONFIG["HISTORY_LIMIT"]:
490
+ self.history = self.history[:CONFIG["HISTORY_LIMIT"]]
491
+ return self.get_all_outputs()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  def reset(self):
493
  self.history = []
494
  for _ in range(20):
495
  self.history.append(round(random.uniform(1.0, 3.5), 2))
496
  self.history.sort(reverse=True)
497
  return self.get_all_outputs()
 
498
  def get_all_outputs(self, error=None):
499
  if error:
500
  table = [[i+1, "?.??x"] for i in range(min(20, len(self.history)))] or [[1, "1.00x"]]
501
  return [table, f"⚠️ {error}"]
502
+ pred_result = self.model.predict(self.history)
503
+ table = [[i+1, f"{val:.2f}x"] for i, val in enumerate(self.history[:50])]
504
+ return [table, pred_result['summary']]
 
 
 
 
 
 
 
 
 
 
 
505
 
506
  # ==================== কাস্টম CSS ====================
 
507
  CUSTOM_CSS = """
508
  .gradio-container {
509
  background: #0a0a0f !important;
 
511
  font-family: 'Inter', sans-serif !important;
512
  }
513
  footer {visibility: hidden}
514
+ h1 { color: #00d4ff !important; text-align: center; margin-bottom: 20px; text-shadow: 0 0 10px #00d4ff; }
515
+ .gr-box { border: 1px solid #333 !important; background: rgba(255,255,255,0.05) !important; }
516
+ .gr-button-primary { background: linear-gradient(135deg, #00d4ff, #0088ff) !important; border: none !important; }
517
+ .gr-button-secondary { background: rgba(255,255,255,0.1) !important; border: 1px solid #00d4ff !important; margin-top: 20px !important; }
518
+ .gr-dataframe { background: rgba(255,255,255,0.05) !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
  """
520
 
521
  # ==================== গ্র্যাডিও ইন্টারফেস ====================
522
+ app = AviatorPredictorApp()
523
+ app.reset() # শুরুতে ২০টি র‍্যান্ডম রাউন্ড
524
 
525
+ with gr.Blocks(css=CUSTOM_CSS, theme='dark', title="AVOLD V7 Predictor") as demo:
526
  gr.HTML("""
527
  <div style="text-align: center; margin-bottom: 20px;">
528
+ <h1 style="color: #00d4ff; font-size: 48px; margin: 0;">✈️ AVOLD V7</h1>
529
+ <p style="color: #888; font-size: 14px;">হাইবিনসম্বল – আনা্ট্যাটিস্টিক্যাল মডেল + িপোজিটরি ML</p>
530
  </div>
531
  """)
532
+
533
  with gr.Row():
534
+ inp = gr.Number(label="নতুন মাল্টিপ্লায়ার (যেকোনো মান)", value=1.0, step=0.1, minimum=1.0, maximum=None)
535
  add_btn = gr.Button("➕ যোগ করুন", variant="primary")
536
+
537
  prediction_box = gr.Textbox(label="🧠 প্রেডিকশন রিপোর্ট", lines=10, interactive=False)
538
  rounds_table = gr.Dataframe(label="📜 শেষ ৫০ রাউন্ড", headers=["রাউন্ড", "মাল্টিপ্লায়ার"], row_count=10)
539
  reset_btn = gr.Button("🔄 রিসেট ডাটা", variant="secondary")
540
+
541
  add_btn.click(
542
+ fn=app.add_round,
543
  inputs=inp,
544
  outputs=[rounds_table, prediction_box]
545
  )
 
546
  reset_btn.click(
547
+ fn=app.reset,
548
  outputs=[rounds_table, prediction_box]
549
  )
 
550
  demo.load(
551
+ fn=app.get_all_outputs,
552
  outputs=[rounds_table, prediction_box]
553
  )
554
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  if __name__ == "__main__":
556
+ demo.launch(server_name="0.0.0.0", server_port=7860)