diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 1003669..8a5c19b 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 717d172..34dcb8b 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 4027749..625c65c 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc.140359459233328 b/core/__pycache__/views.cpython-311.pyc.140359459233328 new file mode 100644 index 0000000..e69de29 diff --git a/core/migrations/0003_alter_lottery_name.py b/core/migrations/0003_alter_lottery_name.py new file mode 100644 index 0000000..cc424a2 --- /dev/null +++ b/core/migrations/0003_alter_lottery_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.7 on 2026-02-19 22:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0002_lottery_ai_predictions_lottery_analysis_window'), + ] + + operations = [ + migrations.AlterField( + model_name='lottery', + name='name', + field=models.CharField(choices=[('mega_sena', 'Mega-Sena'), ('quina', 'Quina'), ('dupla_sena', 'Dupla Sena'), ('lotomania', 'Lotomania'), ('lotofacil', 'Lotofácil'), ('timemania', 'Timemania'), ('dia_de_sorte', 'Dia de Sorte'), ('federal', 'Federal'), ('super_sete', 'Super Sete'), ('maismilionaria', '+Milionária')], max_length=50, unique=True), + ), + ] diff --git a/core/migrations/__pycache__/0003_alter_lottery_name.cpython-311.pyc b/core/migrations/__pycache__/0003_alter_lottery_name.cpython-311.pyc new file mode 100644 index 0000000..76a3f81 Binary files /dev/null and b/core/migrations/__pycache__/0003_alter_lottery_name.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index d82b5f3..131f1b2 100644 --- a/core/models.py +++ b/core/models.py @@ -17,6 +17,11 @@ class Lottery(models.Model): ('dupla_sena', 'Dupla Sena'), ('lotomania', 'Lotomania'), ('lotofacil', 'Lotofácil'), + ('timemania', 'Timemania'), + ('dia_de_sorte', 'Dia de Sorte'), + ('federal', 'Federal'), + ('super_sete', 'Super Sete'), + ('maismilionaria', '+Milionária'), ] name = models.CharField(max_length=50, choices=LOTTERY_TYPES, unique=True) min_number = models.IntegerField(default=1) diff --git a/core/templates/core/full_report.html b/core/templates/core/full_report.html new file mode 100644 index 0000000..5870235 --- /dev/null +++ b/core/templates/core/full_report.html @@ -0,0 +1,136 @@ +{% extends "base.html" %} + +{% block content %} +
+
+
+ + +
+
+

+ Relatório IA Global +

+

Análise Probabilística de Todos os Jogos Gerados em Tempo Real

+
+
+
+ ATUALIZADO: {{ current_time|date:"H:i:s" }} +
+
+ + + Voltar ao Supercomputador + +
+
+
+ +
+ {% for item in reports %} +
+
+
+

+ {{ item.lottery.get_name_display }} +

+ Concurso {{ item.last_concurso }} +
+
+
+ +
+
+ Índice de Precisão IA +
+
+ + + + +
+

{{ item.prob_index }}%

+
+
+
+

Baseado em {{ item.total_analyzed }} sorteios históricos

+
+
+ + +
+
+ Números de Elite do Funil: +
+
+ {% for n in item.elite_numbers %} +
+ {{ n }} +
+ {% endfor %} +
+
+
+ TENDÊNCIA QUENTE (TOP 5) + +
+
+ {% for n, freq in item.hot_top %} +
+
{{ n }}
+
{{ freq }}x
+
+ {% endfor %} +
+
+
+
+
+ +
+
+ {% empty %} +
+

Nenhum dado processado ainda. Inicie o Supercomputador para gerar o relatório.

+
+ {% endfor %} +
+ + +
+

+ + Este relatório é gerado através de processamento assíncrono e análise matemática pura. + As probabilidades são recalculadas a cada novo acesso. +

+
+
+
+
+ + +{% endblock %} diff --git a/core/templates/core/results_ia.html b/core/templates/core/results_ia.html index 4fc503f..5feefd8 100644 --- a/core/templates/core/results_ia.html +++ b/core/templates/core/results_ia.html @@ -1,4 +1,4 @@ -{% extends 'core/base.html' %} +{% extends 'base.html' %} {% load static %} {% block content %} @@ -33,9 +33,9 @@ {% if item.last_result %}
{% for n in item.last_numbers %} -
- {{ n|stringformat:"02d" }} +
+ {{ n }}
{% endfor %}
@@ -96,8 +96,8 @@
{% for num, freq in item.stats.most_common %} - - {{ num|stringformat:"02d" }} + + {{ num }} {% endfor %}
@@ -108,8 +108,8 @@
{% for stat in item.stats.most_delayed %} - - {{ stat.number|stringformat:"02d" }} ({{ stat.delay }}c) + + {{ stat.number }} ({{ stat.delay }}c) {% endfor %}
@@ -128,6 +128,47 @@
+ +
+
+
+
+ FUNIL DE ELITE AUTOMÁTICO +
+

Anulação automática de baixa probabilidade ativa

+
+ PRECISÃO MÁXIMA +
+ + {% if item.funnel_numbers %} +
+ {% for n in item.funnel_numbers %} +
+ {{ n }} +
+ {% endfor %} +
+ +
+ + + BAIXAR TXT + + +
+ {% else %} +

+ Filtrando números em tempo real... +

+ {% endif %} +
+
@@ -143,10 +184,10 @@ {% if item.predicted_numbers %}
{% for n in item.predicted_numbers %} -
- {{ n|stringformat:"02d" }} + {{ n }}
{% endfor %}
@@ -195,10 +236,17 @@ box-shadow: 0 0 15px rgba(16, 185, 129, 0.4); transition: transform 0.2s, box-shadow 0.2s; } - .ball-pred:hover { + .shadow-glow-gold { + box-shadow: 0 0 15px rgba(234, 179, 8, 0.4); + transition: transform 0.2s, box-shadow 0.2s; + } + .ball-pred:hover, .ball-elite:hover { transform: scale(1.15); box-shadow: 0 0 25px rgba(16, 185, 129, 0.7); } + .ball-elite:hover { + box-shadow: 0 0 25px rgba(234, 179, 8, 0.7); + } .card { transition: transform 0.3s; } diff --git a/core/templates/core/sequential_generator.html b/core/templates/core/sequential_generator.html index 4fc8007..1c7525e 100644 --- a/core/templates/core/sequential_generator.html +++ b/core/templates/core/sequential_generator.html @@ -18,6 +18,9 @@
IA NARRANDO
+ + ABRIR RELATÓRIO + Sair do Sistema
@@ -119,10 +122,10 @@
FUNIL DE ANULAÇÃO
- 0 / 31 + 0 / 60
-

Selecione até 31 números para o Supercomputador ignorar totalmente nas sequências.

+

Selecione até 60 números para o Supercomputador ignorar totalmente nas sequências.

Selecione o jogo acima
@@ -220,7 +223,7 @@ let detectedHits = []; // { type, sequence, hits } let animationId = null; let annulledFunnel = new Set(); - const MAX_FUNNEL = 31; + const MAX_FUNNEL = 60; const synth = window.speechSynthesis; let voiceEnabled = true; @@ -293,7 +296,7 @@ annulledFunnel.delete(i); } else { if (annulledFunnel.size >= MAX_FUNNEL) { - speak("Limite do funil atingido. Máximo de 31 dezenas."); + speak("Limite do funil atingido. Máximo de 60 dezenas."); return; } ball.classList.add("active"); @@ -436,7 +439,7 @@ generatorRunning = true; btnStart.classList.add("d-none"); btnPause.classList.remove("d-none"); - speak("Motor Sequencial Iniciado. Aplicando Funil de Trinta e uma Dezenas."); + speak("Motor Sequencial Iniciado. Aplicando Funil de Sessenta Dezenas."); generateChunk(); }); diff --git a/core/urls.py b/core/urls.py index c8cf561..3829068 100644 --- a/core/urls.py +++ b/core/urls.py @@ -12,4 +12,6 @@ urlpatterns = [ path('gerador-sequencial/', views.sequential_generator, name='sequential_generator'), path('api/lottery-info//', views.lottery_info_api, name='lottery_info_api'), path('resultados/', views.lottery_results, name='lottery_results'), + path('resultados/download//', views.download_funnel, name='download_funnel'), + path('supercomputador/relatorio/', views.full_report, name='full_report'), ] diff --git a/core/views.py b/core/views.py index 6972e5e..9e52477 100644 --- a/core/views.py +++ b/core/views.py @@ -372,6 +372,11 @@ def sync_results(): 'dupla_sena': 'duplasena', 'lotomania': 'lotomania', 'lotofacil': 'lotofacil', + 'timemania': 'timemania', + 'dia_de_sorte': 'diadesorte', + 'federal': 'federal', + 'super_sete': 'supersete', + 'maismilionaria': 'maismilionaria', } for lottery in loterias: @@ -391,9 +396,13 @@ def sync_results(): date_str = data.get('data') draw_date = datetime.strptime(date_str, "%d/%m/%Y").date() - # Processa os números (garante ordenação e limpeza) + # Processa os números (preserva zeros à esquerda para Federal/Super Sete) numbers_list = data.get('dezenas', []) - numbers_str = ",".join([str(int(n)) for n in numbers_list]) + # Se for Federal ou Super Sete, mantemos a formatação original (zeros à esquerda) + if lottery.name in ['federal', 'super_sete']: + numbers_str = ",".join([str(n).zfill(5 if lottery.name == 'federal' else 1) for n in numbers_list]) + else: + numbers_str = ",".join([str(int(n)) for n in numbers_list]) DrawResult.objects.create( lottery=lottery, @@ -405,13 +414,75 @@ def sync_results(): except Exception as e: print(f"Erro ao sincronizar {lottery.name}: {e}") +from django.http import JsonResponse, HttpResponse +import json + +def download_funnel(request, lottery_id): + """Gera um arquivo TXT com a elite do funil para download.""" + lottery = get_object_or_404(Lottery, id=lottery_id) + all_draws = DrawResult.objects.filter(lottery=lottery).order_by('-draw_number') + + if not all_draws.exists(): + return HttpResponse("Ainda não há dados para gerar o funil.") + + # Repete a lógica do funil para garantir sincronia total + current_draw = all_draws.first() + all_numbers_flat = [] + for d in all_draws: + all_numbers_flat.extend([n.strip() for n in d.numbers.split(',')]) + + frequency = Counter(all_numbers_flat) + last_seen = {} + for i, d in enumerate(all_draws): + for n in d.numbers.split(','): + n = n.strip() + if n not in last_seen: last_seen[n] = i + + if lottery.name == 'federal': + available = [str(i).zfill(5) for i in range(100000)] + elif lottery.name == 'super_sete': + available = [str(i) for i in range(10)] + else: + available = [str(i).zfill(2) for i in range(1, lottery.max_number + 1)] + + last_nums = [n.strip() for n in current_draw.numbers.split(',')] + funnel_scores = [] + for n in available: + if n in last_nums: continue + score = (frequency.get(n, 0) * 0.6) + (last_seen.get(n, all_draws.count()) * 0.4) + funnel_scores.append((n, score)) + + funnel_scores.sort(key=lambda x: x[1], reverse=True) + elite = [x[0] for x in funnel_scores[:lottery.numbers_to_draw]] + elite.sort() + + content = f"--- SUPERCOMPUTADOR IA V4.0 ---\n" + content += f"FUNIL DE PROBABILIDADES: {lottery.get_name_display()}\n" + content += f"DATA: {datetime.now().strftime('%d/%m/%Y %H:%M')}\n" + content += f"PRÓXIMO CONCURSO: {current_draw.draw_number + 1}\n" + content += f"-------------------------------\n" + content += f"NÚMEROS DE ELITE: {' - '.join(elite)}\n" + content += f"-------------------------------\n" + content += f"Use com responsabilidade matemática.\n" + + response = HttpResponse(content, content_type='text/plain') + filename = f"funil_{lottery.name}_{current_draw.draw_number + 1}.txt" + response['Content-Disposition'] = f'attachment; filename="{filename}"' + return response + def lottery_results(request): """Central de Resultados com Lógica de Análise Estatística Profunda IA V4.0.""" - # Tenta sincronizar novos resultados ao acessar a página - try: - sync_results() - except: - pass + # Otimização: Só sincroniza se passaram mais de 10 minutos desde o último sorteio salvo + # ou se o banco estiver muito vazio, para evitar lentidão no carregamento. + last_sync = request.session.get('last_sync_time') + now_ts = timezone.now().timestamp() + + if not last_sync or (now_ts - last_sync) > 600: # 10 minutos + try: + sync_results() + request.session['last_sync_time'] = now_ts + except: + pass loterias = Lottery.objects.all() results_data = [] @@ -422,61 +493,148 @@ def lottery_results(request): last_draws = all_draws[:10] if all_draws.exists(): - current_draw = all_draws[0] - current_numbers = [int(n) for n in current_draw.numbers.split(',')] + current_draw = all_draws.first() + current_numbers_raw = current_draw.numbers.split(',') + current_numbers = [] + for n in current_numbers_raw: + if lottery.name == 'federal': + current_numbers.append(n.zfill(5)) + elif lottery.name == 'super_sete': + current_numbers.append(n) + else: + current_numbers.append(str(int(n)).zfill(2)) # --- MOTOR DE ANÁLISE ESTATÍSTICA --- all_numbers_flat = [] for d in all_draws: - all_numbers_flat.extend([int(n) for n in d.numbers.split(',')]) + all_numbers_flat.extend([n.strip() for n in d.numbers.split(',')]) frequency = Counter(all_numbers_flat) + + # Cálculo de Atraso (Delay) - Movido para cima para evitar erros no Funil + last_seen = {} + for i, d in enumerate(all_draws): + nums = [n.strip() for n in d.numbers.split(',')] + for n in nums: + if n not in last_seen: + last_seen[n] = i + + # --- NOVO: FUNIL DE PROBABILIDADES AUTOMÁTICO IA V4.0 --- + # O Funil anula números automaticamente até encontrar a elite matemática + available_for_funnel = [] + if lottery.name == 'federal': + # Para Federal, o funil gera bilhetes de elite + available_for_funnel = [str(i).zfill(5) for i in range(100000)] + elif lottery.name == 'super_sete': + available_for_funnel = [str(i) for i in range(10)] + else: + available_for_funnel = [str(i).zfill(2) for i in range(1, lottery.max_number + 1)] + + # 1. Anula números do último sorteio (Filtro de Repetição) + last_nums = [n.strip() for n in current_draw.numbers.split(',')] + funnel_step1 = [n for n in available_for_funnel if n not in last_nums] + + # 2. Ranking de Probabilidade (Frequência + Atraso) + funnel_scores = [] + max_analyzed = all_draws.count() + for n in funnel_step1: + freq = frequency.get(n, 0) + delay = last_seen.get(n, max_analyzed) + # Score: 60% peso para frequência, 40% para tempo sem sair + score = (freq * 0.6) + (delay * 0.4) + funnel_scores.append((n, score)) + + # 3. Anulação Automática: Ordena e pega apenas a elite + funnel_scores.sort(key=lambda x: x[1], reverse=True) + + # Para a elite, queremos exatamente o número de dezenas do jogo (ou 6 para Mega) + elite_count = lottery.numbers_to_draw + funnel_elite = [x[0] for x in funnel_scores[:elite_count]] + funnel_elite.sort() + + # Formatação visual para o template + funnel_display = [] + for n in funnel_elite: + if lottery.name == 'federal': funnel_display.append(n.zfill(5)) + elif lottery.name == 'super_sete': funnel_display.append(n) + else: funnel_display.append(n.zfill(2)) + # Top 10 mais frequentes - most_common = frequency.most_common(10) + most_common = [] + for num, freq in frequency.most_common(10): + if lottery.name == 'federal': + most_common.append((num.zfill(5), freq)) + elif lottery.name == 'super_sete': + most_common.append((num, freq)) + else: + most_common.append((num.zfill(2), freq)) # Cálculo de Atraso (Delay) last_seen = {} for i, d in enumerate(all_draws): - nums = [int(n) for n in d.numbers.split(',')] + nums = [n.strip() for n in d.numbers.split(',')] for n in nums: if n not in last_seen: - last_seen[n] = i # i é o número de concursos atrás + last_seen[n] = i # Pegar as 5 dezenas mais atrasadas delays = [] - for n in range(1, lottery.max_number + 1): - delays.append({'number': n, 'delay': last_seen.get(n, len(all_draws))}) + if lottery.name == 'federal': + # Para federal, analisamos os números que já saíram nos prêmios + keys = list(frequency.keys()) + for n in keys: + delays.append({'number': n.zfill(5), 'delay': last_seen.get(n, len(all_draws))}) + elif lottery.name == 'super_sete': + for n in range(10): + delays.append({'number': str(n), 'delay': last_seen.get(str(n), len(all_draws))}) + else: + for n in range(1, lottery.max_number + 1): + num_str = str(n).zfill(2) + delays.append({'number': num_str, 'delay': last_seen.get(num_str, len(all_draws))}) most_delayed = sorted(delays, key=lambda x: x['delay'], reverse=True)[:5] # Equilíbrio Par/Ímpar do último sorteio - evens = len([n for n in current_numbers if n % 2 == 0]) - odds = len(current_numbers) - evens + evens = len([n for n in current_numbers_raw if int(n) % 2 == 0]) + odds = len(current_numbers_raw) - evens # --- Lógica de Determinação Matemática V4.0 --- - random.seed(sum(current_numbers) + current_draw.draw_number) + # (Simplificada para suportar Federal e Super Sete de forma coerente) + random.seed(sum([int(n) for n in current_numbers_raw]) + current_draw.draw_number) predicted_numbers = [] - k_inheritance = max(1, len(current_numbers)//3) - inheritance = random.sample(current_numbers, k=k_inheritance) - for n in inheritance: - shift = random.choice([-1, 0, 1]) - new_n = n + shift - if 1 <= new_n <= lottery.max_number and new_n not in predicted_numbers: - predicted_numbers.append(new_n) - available = [n for n in range(1, lottery.max_number + 1) if n not in predicted_numbers] - while len(predicted_numbers) < lottery.numbers_to_draw: - next_n = random.choice(available) - predicted_numbers.append(next_n) - available.remove(next_n) - - predicted_numbers.sort() + if lottery.name == 'federal': + # Predição para Federal: 5 novos bilhetes baseados em tendência + for _ in range(5): + pred = str(random.randint(0, 99999)).zfill(5) + predicted_numbers.append(pred) + elif lottery.name == 'super_sete': + # 7 colunas (0-9) + for _ in range(7): + predicted_numbers.append(str(random.randint(0, 9))) + else: + k_inheritance = max(1, len(current_numbers_raw)//3) + inheritance = random.sample([int(n) for n in current_numbers_raw], k=k_inheritance) + for n in inheritance: + shift = random.choice([-1, 0, 1]) + new_n = n + shift + if 1 <= new_n <= lottery.max_number and str(new_n).zfill(2) not in predicted_numbers: + predicted_numbers.append(str(new_n).zfill(2)) + + available = [str(n).zfill(2) for n in range(1, lottery.max_number + 1) if str(n).zfill(2) not in predicted_numbers] + while len(predicted_numbers) < lottery.numbers_to_draw: + next_n = random.choice(available) + predicted_numbers.append(next_n) + available.remove(next_n) + predicted_numbers.sort() results_data.append({ 'lottery': lottery, 'last_result': current_draw, 'last_numbers': current_numbers, 'predicted_numbers': predicted_numbers, + 'funnel_numbers': funnel_display, + 'funnel_raw': ",".join(funnel_elite), 'next_draw_number': current_draw.draw_number + 1, 'history': last_draws, 'stats': { @@ -497,3 +655,68 @@ def lottery_results(request): "results": results_data, "current_time": timezone.now() }) + +def full_report(request): + """Gera um relatório completo de probabilidades de todas as loterias em uma página dedicada.""" + loterias = Lottery.objects.all() + report_data = [] + + for lottery in loterias: + all_draws = DrawResult.objects.filter(lottery=lottery).order_by('-draw_number') + + if all_draws.exists(): + current_draw = all_draws.first() + + # Cálculo de Frequência + all_numbers_flat = [] + for d in all_draws: + all_numbers_flat.extend([n.strip() for n in d.numbers.split(',')]) + frequency = Counter(all_numbers_flat) + + # Cálculo de Atraso (Delay) + last_seen = {} + for i, d in enumerate(all_draws): + for n in d.numbers.split(','): + n = n.strip() + if n not in last_seen: last_seen[n] = i + + # Construção do Funil de Elite para o Relatório + if lottery.name == 'federal': + available = [str(i).zfill(5) for i in range(100000)] + elif lottery.name == 'super_sete': + available = [str(i) for i in range(10)] + else: + available = [str(i).zfill(2) for i in range(1, lottery.max_number + 1)] + + last_nums = [n.strip() for n in current_draw.numbers.split(',')] + funnel_scores = [] + max_analyzed = all_draws.count() + + for n in available: + if n in last_nums: continue + freq = frequency.get(n, 0) + delay = last_seen.get(n, max_analyzed) + score = (freq * 0.6) + (delay * 0.4) + funnel_scores.append((n, score)) + + funnel_scores.sort(key=lambda x: x[1], reverse=True) + elite = [x[0] for x in funnel_scores[:lottery.numbers_to_draw]] + elite.sort() + + # Probabilidade Matemática (Baseada no Score do Top 1) + top_score = funnel_scores[0][1] if funnel_scores else 0 + prob_index = min(99.9, (top_score / (max(frequency.values() or [1]) * 1.5)) * 100) + + report_data.append({ + 'lottery': lottery, + 'last_concurso': current_draw.draw_number, + 'elite_numbers': elite, + 'prob_index': round(prob_index, 2), + 'total_analyzed': max_analyzed, + 'hot_top': frequency.most_common(5) + }) + + return render(request, "core/full_report.html", { + "reports": report_data, + "current_time": timezone.now() + })