Pesquisar este blog

quinta-feira, 29 de setembro de 2022

Uma ilustração da segurança da urna eletrônica brasileira

Abigail Pereira Aranha

1) Introdução

Eu espero que esta não seja a última oportunidade que eu tenho de abordar e você de entender a questão da urna eletrônica brasileira. Por que tantas pessoas duvidam da urna eletrônica brasileira? Porque não são todos os brasileiros que só sabem usar Excel pra fazer tabela de texto, ou que nunca leram o código-fonte de uma página da internet em HTML.

A urna eletrônica brasileira é de primeira geração. Países desenvolvidos usam urnas de segunda geração e de terceira geração (com comprovante impresso). Não só países desenvolvidos: Paraguai e Argentina já usam urnas de terceira geração, o Paraguai depois de recusar urnas brasileiras que ia receber de graça.

Aqui, eu vou dar só uma noção de como é possível fraudar uma eleição com urna eletrônica sem comprovante impresso por voto. Nós não conhecemos (eu e você leitor) o programa da urna eletrônica, e mesmo que eu conhecesse (e fosse especialista em Ciência da Computação), eu não poderia explicar os eventuais problemas em um texto de 20 mil ou 30 mil caracteres para o público geral. Mas uma coisa que eu posso fazer, dentro do pouco que eu sei de computação (que, digo de passagem, já me faz produzir textos mais bonitos no código-fonte e na visualização que os de muitos colunistas de portais grandes da imprensa), é dar uma visão didática do problema. Eu vou literalmente desenhar e explicar o desenho.

Você vai ver que o programa do exemplo didático é até bobinho. Eu vou mostrar o código-fonte e vou deixar comentários pra você entender o programa especificamente e até entender um pouco de Javascript, se você não sabia nada. Haverá quem não aguente ler nem comigo explicando, porque tem dificuldade com linguagem de programação e vai achar o programa grande. Então, qual a possibilidade de fraude em uma urna eletrônica com um programa que ninguém viu e que é, certamente, milhares de vezes maior? ("Milhares" não é uma hipérbole)

Vou desenhar aqui algumas falácias dos defensores da urna eletrônica brasileira (algumas das menos estúpidas ou menos óbvias):

1) A zerézima (o comprovante com 0 votos para todos os candidatos antes do começo da votação) prova que o sistema não tem fraude.

2) A urna eletrônica não identifica (ou não pode identificar) o voto do eleitor. Se lembra de quando você vai votar e o mesário digita o número do seu título num teclado antes de você ir pra urna?

3) Não precisamos dos comprovantes por voto (sem identificação do eleitor) porque temos os boletins de urna dando os totais de votos da seção.

4) Uma urna ou um computador que faça a contagem dos votos não permite que o resultado seja manipulado por acesso remoto; portanto, o processo eleitoral está protegido de fraude por este meio.

5) Se alguém questionar o resultado da eleição, é só fazer a conferência dos boletins de urna e pronto, está provada a lisura do processo eleitoral.

2) Sobre o exemplo didático

O programa que está no próximo subtítulo é um Javascript que tem o código-fonte no subtítulo seguinte. Você pode copiar tudo (de <html> a </html>) em um editor de texto simples (como Bloco de Notas ou WordPad) e salvar com um nome com extensão .htm ou .html. Se você quiser gravar a execução, você precisa gravar com um nome diferente pra preservar a tela inicial original.

Peço a sua atenção, no exemplo, pra quem vai aparecer como líder das pesquisas e pro candidato que tem mais intenção de votos. E pra candidata Abigail Piranha, que não é muito cotada, mas a direita conservadora e a esquerda atacam por ódio pelas ideias dela. Ela defende o Ateísmo e faz muito sucesso pelos vídeos vazados da sua vida de promiscuidade e por alguns textos que ela já publicou sobre Política em dois blogues na internet, um dos quais também tem conteúdo pornográfico. Então, ela ganhou uma intenção de votos para Presidente da República que não dá pra ganhar, mas também não é desprezível. Mesmo assim, os institutos de pesquisa trabalham pra abaixar o percentual dela.

O leitor pode fazer a simulação e a manipulação dar um resultado muito diferente do esperado. Eu até tentei ajustar isso, mas eu consigo mostrar, do jeito que está, que uma distorção encomendada é possível.

3) A simulação

Clique o botão "CONFIRMA" para prosseguir a simulação. Serão 10 eleitores.

É só confirmar a opção que vai aparecer na tela (os votos são reais simulados com números aleatórios). A tabela "Registro interno" abaixo dá o histórico em tempo real.

PRESIDENTE

_ _

Registro interno
candidato hora

4) O código-fonte

<html>
  <head>
    <title>Simulação didática de uma urna eletrônica de 1ª geração</title>
  </head>
<body>
  <!--
  Autora: Abigail Pereira Aranha
  Conteúdo incluído no texto "Uma ilustração da segurança da urna eletrônica brasileira", nos meus blogues abaixo:
  A Vez das Mulheres de Verdade
  * Reflexões sobre política e cotidiano com um pouco de Ateísmo, Direitos Humanos dos Homens e ataques ao LGBT-Feminismo e à castidade.
  * avezdasmulheres.blogspot.com
  A Vez dos Homens que Prestam
  * Tudo isso mais aquele conteúdo que dizem que é adulto e dizem que só rapaz adolescente gosta.
  * avezdoshomens.blogspot.com
  -->
<script>
  // Os comentários vão ajudar a entender o programa
  HORA_INICIO = 480; // Minutos desde 00:00 (08:00)
  HORA_FIM = 1020; // Minutos desde 00:00 (17:00)
  NUM_ZONA = 666; // Número da zona eleitoral
  NUM_SECAO = 147; // Número da seção
  // A matriz a seguir é a da lista dos candidatos. O atributo "cont" dá o número de votos.
  const lista_opcao_cadastro = [
    {numero: 31, nome: "Leôncio Empresário", cont: 0},
    {numero: 32, nome: "Victor Honesto", cont: 0},
    {numero: 38, nome: "Pedro José Proudhon", cont: 0},
    {numero: 46, nome: "Abigail Piranha", cont: 0},
    {numero: 66, nome: "Mauro José Stalin", cont: 0}
  ];
  // O que vem entre aspas é valor de texto. Para dar um valor de texto, nós colocamos o valor entre aspas ou atribuímos o valor de outra variável com valor de texto.
  lista_opcao_percentuais = [27, 41, 5, 5, 22]; // Respectivamente, os percentuais reais de intenção de voto para os candidatos.
  lista_opcao_pesquisa = [27, 13, 5, 2, 53]; // Respectivamente, os percentuais de intenção de voto para os candidatos nas pesquisas oficiais.
  relatorio_oficial = [0, 0, 0, 0, 0]; // Respectivamente, os números de votos dados dos candidatos no boletim público.
  TOTAL_NOMES = 5; // O tamanho (número de elementos) das matrizes anteriores, que é o número de candidatos.
  // A matriz a seguir é a do cadastro dos eleitores, com nome, título de eleitor e endereço de cada um.
  const pessoas = [
    {nome: "Winston Smith Salomão", titulo: 827675, endereco: "Av. Londres, 208 - Oceania I"},
    {nome: "Júlia Valente Smith Salomão", titulo: 828812, endereco: "Av. Birmingham, 425 - Oceania II"},
    {nome: "Osmar Celso Nazaré da Silva", titulo: 4619210, endereco: "R. Padre Anchieta, 267 A - São Pedro"},
    {nome: "Arnold Gladstone Stuart", titulo: 24068, endereco: "R. Los Angeles, 1320 - Nova Inglaterra"},
    {nome: "Meredith Faith Lawson Stuart", titulo: 27161, endereco: "R. Los Angeles, 1320 - Nova Inglaterra"},
    {nome: "Ernesto Guevara", titulo: 2065016, endereco: "Av. Buenos Aires, 1755 apto. 902 - Rio da Prata"},
    {nome: "Olga Prestes", titulo: 2726855, endereco: "R. Betânia, 10 casa 2 - Galileia"},
    {nome: "Maria Goretti Pureza de Morais", titulo: 1863101, endereco: "R. Nossa Senhora da Rosa Mística, 64 - Paraíso"},
    {nome: "Francisco de Assis", titulo: 1906859, endereco: "R. Nossa Senhora da Rosa Mística, 134 - Paraíso"},
    {nome: "Rita de Cássia Flores", titulo: 2919682, endereco: "R. Santa Rita de Cássia, 5 - Paraíso"}
  ];
  // A seguir, a matriz que vai receber os dados de opção escolhida e hora da votação para cada eleitor. Os índices dos termos de u'a matriz começam de 0 por padrão. Os atributos "opcao", "horaminutos" e "horatexto" vão ser atualizados na votação.
  const selecao = [
    {nome: pessoas[0].nome, titulo: pessoas[0].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[1].nome, titulo: pessoas[1].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[2].nome, titulo: pessoas[2].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[3].nome, titulo: pessoas[3].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[4].nome, titulo: pessoas[4].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[5].nome, titulo: pessoas[5].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[6].nome, titulo: pessoas[6].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[7].nome, titulo: pessoas[7].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[8].nome, titulo: pessoas[8].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"},
    {nome: pessoas[9].nome, titulo: pessoas[9].titulo, opcao: 0, horaminutos: 0, horatexto: "07:50"}
  ];
  TOTAL_PART = 10; // O tamanho (número de elementos) das matrizes anteriores, que é o número de eleitores da seção.
  primeira_tela = false; // Esta variável é pra marcar se a simulação já começou, vai mudar para "true" quando a função tela_inicial (mais à frente) for executada.
  part = 0; // Número de votantes até o momento
  i = 0; // Este é um contador que vai ser usado em várias partes do programa
  hora1 = Math.random()*(HORA_FIM - HORA_INICIO); // O método Math.random() gera um número aleatório de 0 a 1, não incluído o 1. O asterisco é o sinal de multiplicação.
  hora1 = Math.round(HORA_INICIO + 0.25 * hora1); // Você pode ver "hora1" dos dois lados da igualdade. Várias linguagens de programação permitem isso, atribuir a uma variável um valor em função do que já está lá dentro. O método Math.round(x) dá o arredondamento do número x.
  horario = hora1; // Hora da votação do primeiro eleitor, em minutos depois da meia-noite. Eu montei aquela equação da linha anterior de uma forma que não dê uma hora muito tarde. Os outros eleitores vão vir na sequência acima, da matriz "pessoas".
  /*
  A função a seguir vai preparar a tela pro primeiro voto. Para confirmar os votos, a função é a "confirmacao".
  Vamos simular os votos reais de 10 eleitores ao acaso, seguindo a aleatoriedade com a tendência dada na matriz "lista_opcao_percentuais".
   */
  function tela_inicial() {
    opcao_random = 1 + Math.round(99 * Math.random()); // De novo, os métodos Math.round() e Math.random(). O valor desta variável "opcao_random" é inteiro de 1 a 100.
    /*
    Um laço "while" é repetido enquanto a condição entre parênteses é atendida. Quando não é, o programa vai pra linha seguinte. O laço "while" a seguir vai dar em que faixa vai cair aquele número aleatório.
    O esquema é o seguinte: o primeiro candidato tem um percentual de intenção de voto igual a lista_opcao_percentuais[0] (as matrizes começam do índice 0). Se o número aleatório for menor que ou igual a este valor, o programa nem entra neste laço. i = 0, a opção escolhida vai ser a primeira da lista (índice 0).
    Se o número aleatório for maior que este valor, o programa entra neste laço, o número aleatório é subtraído daquele primeiro percentual lista_opcao_percentuais[0], i aumenta em 1, e o programa volta ao começo do laço aplicando o mesmo raciocínio para o valor seguinte.
    */
    while (opcao_random > lista_opcao_percentuais[i]) {
      opcao_random -= lista_opcao_percentuais[i]; // Ao valor da variável no primeiro membro, é atribuído o valor que está lá menos o que está no segundo membro.
      i++; // O valor de i é aumentado de 1
    }
    // Depois de executada esta função, vamos ver um cabeçalho dando a introdução do truque.
    // Na variável "texto_real", vão aparecer os percentuais reais. Na variável "texto_pesquisa", vão aparecer os percentuais das pesquisas.
    // Na variável "texto_zero", vai aparecer o registro dos números iniciais de votos para cada candidato, que realmente é zero para todos.
    texto_real = "\n<p><b>Percentuais reais</b></p>\n"; // A expressão "\n" é marca de parágrafo.
    texto_pesquisa = "\n<p><b>Percentuais das pesquisas</b></p>\n";
    texto_zero = "\n<p><b>Contagem inicial</b></p>\n";
    // Um laço "for" é uma repetição que usa uma variável inteira como contador. Começa com for (let contador = valor inicial; condição; contador++ pra aumentar de 1 em 1 ou contador-- pra diminuir).
    // O laço "for" a seguir vai emendar uma linha a cada uma das 3 variáveis anteriores. A variável TOTAL_NOMES tem o valor 5; então, a variável j vai de 0 a 4. M[j] é o termo na posição j + 1 da matriz M, elemento.campo é o atributo "campo" da variável "elemento".
    // O sinal +, quando algum dos termos é texto, é concatenação. Por exemplo: 8 + 40 = 48 (número), mas 8 + ":" + 40 = "8:40" (texto, String).
    for (let j = 0; j < TOTAL_NOMES; j++) {
      // Entre parênteses, a seguir, uma condicional em notação reduzida: (condição ? fazer isso se a condição é atendida : fazer isso se não é). Isso pode ser feito quando os dois casos só têm uma linha de comando.
      texto_real = texto_real + "<p>" + lista_opcao_cadastro[j].numero + " (" + lista_opcao_cadastro[j].nome + ")" + (lista_opcao_percentuais[j] < 10 ? ": 0" : ": ") + lista_opcao_percentuais[j] + "%</p>\n";
      texto_pesquisa = texto_pesquisa + "<p>" + lista_opcao_cadastro[j].nome + (lista_opcao_pesquisa[j] < 10 ? ": 0" : ": ") + lista_opcao_pesquisa[j] + "%</p>\n";
      texto_zero = texto_zero + "<p>" + lista_opcao_cadastro[j].numero + ": " + lista_opcao_cadastro[j].cont + "</p>\n";
    }
    selecao[0].horaminutos = horario; // Aquela variável "horario" lá em cima, usada aqui. O valor dela vai entrar no atributo "horaminutos" o termo na posição 1 (índice 0) da matriz "selecao".
    selecao[0].horatexto = (selecao[0].horaminutos < 600 ? "0" + Math.trunc(selecao[0].horaminutos / 60).toString() : Math.trunc(selecao[0].horaminutos / 60).toString()) + ":" + ((selecao[0].horaminutos % 60) < 10 ? "0" + (selecao[0].horaminutos % 60).toString() : (selecao[0].horaminutos % 60).toString()); // O valor do atributo "horaminutos" transformado em uma hora no formato "hh:mm".
    selecao[0].opcao = lista_opcao_cadastro[i].numero; // O valor de i que sai daquele laço "while" é usado aqui. O número da matriz "lista_opcao_cadastro" na posição i + 1 vai ser a opção escolhida pelo primeiro eleitor. É o valor do atributo "opcao" do elemento de "selecao" com índice 0.
    document.getElementById("real").innerHTML = texto_real; // Aqui, o atributo "innerHTML" é o conteúdo do elemento com o identificador "real". No caso, é uma célula de tabela logo depois do fim do script (td id="real").
    document.getElementById("pesquisa").innerHTML = texto_pesquisa;
    document.getElementById("ponto_zero").innerHTML = texto_zero;
    document.getElementById("tela_numero").innerHTML = lista_opcao_cadastro[i].numero; // O número que aparece na tela, no identificador "tela_numero" na segunda tabela
    document.getElementById("tela_nome").innerHTML = lista_opcao_cadastro[i].nome; // O nome que aparece na tela, no identificador "tela_nome" na segunda tabela
    primeira_tela = true; // A variável tinha valor "false" antes.
  }
  // A função a seguir é pra editar a tela em uma simulação de aleatoriedade seguindo os percentuais de intenção de voto dados na matriz "lista_opcao_percentuais".
  // Esta função vai ser solicitada pela função "confirmacao". O argumento "item_selecao" corresponde ao eleitor, é um elemento da matriz "selecao".
  function tela_voto(item_selecao) {
    horario = Math.round(horario + (HORA_FIM - horario) * 0.1 * (part + 1) * Math.random()); // A variável "horario" era correspondente à hora em que o eleitor anterior votou e passa a ser a hora em que o eleitor selecionado votou (a função vai ser solicitada na função "confirmacao", que vai ser solicitada lá em baixo no botão "CONFIRMA", id="botao_verde").
     // Eu usei o multiplicador 0.1 * (part + 1), que vai dar de 0,2 a 1, pra evitar cair em um horário muito tarde. Ah, nos números na programação, o separador de parte decimal é o ponto. Vírgula é separador de milhar.
    item_selecao.horaminutos = horario;
    item_selecao.horatexto = (item_selecao.horaminutos < 600 ? "0" + Math.trunc(item_selecao.horaminutos / 60).toString() : Math.trunc(item_selecao.horaminutos / 60).toString()) + ":" + ((item_selecao.horaminutos % 60) < 10 ? "0" + (item_selecao.horaminutos % 60).toString() : (item_selecao.horaminutos % 60).toString()); // O valor do atributo "horaminutos" transformado em uma hora no formato "hh:mm".
    i = 0; // Novamente, a variável i que começa igual a 0 e, na linha seguinte, um número aleatório inteiro de 1 a 100, pra ser usado no mesmo esquema usado na função "tela_inicial".
    opcao_random = 1 + Math.round(99 * Math.random());
    while (opcao_random > lista_opcao_percentuais[i]) {
      opcao_random -= lista_opcao_percentuais[i];
      i++;
    }
    item_selecao.opcao = lista_opcao_cadastro[i].numero; // O valor de i que sai do laço "while" é usado aqui. O número da matriz "lista_opcao_cadastro" na posição i + 1 vai ser a opção escolhida pelo eleitor correspondente à variável "item_selecao".
    document.getElementById("tela_numero").innerHTML = lista_opcao_cadastro[i].numero; // O número que aparece na tela, no identificador "tela_numero" na segunda tabela
    document.getElementById("tela_nome").innerHTML = lista_opcao_cadastro[i].nome; // O nome que aparece na tela, no identificador "tela_nome" na segunda tabela
  }
  // A função a seguir é só pra colocar o valor do atributo "titulo" do elemento da matriz "pessoas" no formato de 7 casas decimais com separador de milhar. É só pra estética.
  // No Javascript, "function" pode ser tanto um trecho que vai modificar alguma variável fora dela, como as anteriores, quanto aquilo de que a gente se lembra como função na Matemática, y = f(x).
  function TextoTitulo(x) {
    digitos = Math.trunc(Math.log10(x)) + 1; // Um número entre 10 elevado a n (sendo n natural) e 10 elevado a n + 1 menos 1 tem n + 1 algarismos. O logaritmo decimal deste número tem parte inteira n.
    casas = 7;
    titulotexto = (x % 10).toString(); // Resto da divisão de x por 10 convertido de número para texto (String)
    x = Math.trunc(x / 10); // Quociente da divisão de x por 10
    // A variável "titulotexto" já entra no laço abaixo com um dígito. Por isso a variável j começa de 2. A cada 3 casas, um ponto é adicionado antes (o número é formado do último pro primeiro dígito).
    for (j = 2; j <= casas; j++) {
      ((j % 3) === 0 ? titulotexto = "." + (x % 10) + titulotexto : titulotexto = (x % 10) + titulotexto); // A condicional na notação reduzida de novo.
      // (j % 3) é o resto da divisão de j por 3. Quando usamos só um sinal de igual, atribuímos à variável no primeiro membro o valor no segundo. Pra igualdade mesmo, usamos três sinais de igual.
      x = Math.trunc(x / 10);
    }
    return titulotexto; // Quando a "function" é como aquelas funções da Matemática, y = f(x), z = f(x, y), o comando "return" dá o resultado final.
  }
  // A função a seguir é a que está por trás do botão verde "CONFIRMA" (button id="botao_verde").
  function confirmacao() {
    // Condicional: se (if) a condição entre parênteses é atendida, é executado o que está entre as chaves; se não (else), o que está entre as chaves depois do "else". O "if" pode não ter o "else".
    // Neste "if", vamos preencher a tabela que aparece abaixo da urna. São 10 linhas com id de linha01 a linha10. No começo, essa tabela está invisível.
    if (part < TOTAL_PART) {
      // O comando "switch" é como se fosse várias condicionais (if) em sequência. Se a variável entre parênteses tem um certo valor, é executado o que vem depois de "case", o valor, dois pontos. O comando "break" é pra sair do "switch".
      switch (part) {
        case 0: // Lá no começo, part = 0. Quando apertamos o botão verde "CONFIRMA" na primeira vez, a tela muda mas o valor de "part" continua 0. No final da execução desta função, "part" passa a ser 1.
          document.getElementById("linha01").innerHTML = "\n<td>" + selecao[0].opcao + "</td>\n<td>" + selecao[0].horatexto + "</td>\n"; // A linha tr id="linha01" vai ser preenchida com parágrafo, uma célula (td), parágrafo, outra célula, parágrafo. O mesmo raciocínio é aplicado para os elementos id de linha02 a linha10.
          lista_opcao_cadastro[i].cont++; // O atributo "cont", que dá o número de votos, do elemento na posição i + 1 da lista de candidatos é aumentado em 1. O valor de i vem da função "tela_inicial" na primeira vez ou da função "tela_voto", chamada na vez anterior em que esta função "confirmacao" foi executada.
          c = i; // O valor de i vai mudar dentro da função "tela_voto", que vai ser chamada na linha seguinte. Então, a variável c vai guardar este valor, que vai ser usado mais adiante.
          tela_voto(selecao[1]);
          break;
        // Para part valendo de 0 a 8, o esquema é o mesmo.
        case 1:
          document.getElementById("linha02").innerHTML = "\n<td>" + selecao[1].opcao + "</td>\n<td>" + selecao[1].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[2]);
          break;
        case 2:
          document.getElementById("linha03").innerHTML = "\n<td>" + selecao[2].opcao + "</td>\n<td>" + selecao[2].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[3]);
          break;
        case 3:
          document.getElementById("linha04").innerHTML = "\n<td>" + selecao[3].opcao + "</td>\n<td>" + selecao[3].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[4]);
          break;
        case 4:
          document.getElementById("linha05").innerHTML = "\n<td>" + selecao[4].opcao + "</td>\n<td>" + selecao[4].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[5]);
          break;
        case 5:
          document.getElementById("linha06").innerHTML = "\n<td>" + selecao[5].opcao + "</td>\n<td>" + selecao[5].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[6]);
          break;
        case 6:
          document.getElementById("linha07").innerHTML = "\n<td>" + selecao[6].opcao + "</td>\n<td>" + selecao[6].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[7]);
          break;
        case 7:
          document.getElementById("linha08").innerHTML = "\n<td>" + selecao[7].opcao + "</td>\n<td>" + selecao[7].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[8]);
          break;
        case 8:
          document.getElementById("linha09").innerHTML = "\n<td>" + selecao[8].opcao + "</td>\n<td>" + selecao[8].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          tela_voto(selecao[9]);
          break;
        // Quando part = 9, é a vez do último eleitor e aí vamos para o encerramento.
        case 9:
          document.getElementById("linha10").innerHTML = "\n<td>" + selecao[9].opcao + "</td>\n<td>" + selecao[9].horatexto + "</td>\n";
          lista_opcao_cadastro[i].cont++;
          c = i;
          document.getElementById("botao_verde").innerHTML = "Relatório"; // O conteúdo do button id="botao_verde" muda de "CONFIRMA" para "Relatório"
          break;
      }
      part++; // Soma 1 ao valor da variável "part"
      // A seguir, vai ser preparada a contagem em tempo real dos votos por candidato, que vai aparecer ao lado da tabela "Registro interno".
      document.getElementById("sequencia").innerHTML = "\n<p>Pra conferir a contagem</p>\n"; // No começo, antes do primeiro voto, a célula id="sequencia" está vazia. Aqui, ela vai ser preenchida. Quando esta função "confirmacao" for executada de novo, o valor que estava lá vai ser apagado e preenchido de novo.
      // A linha anterior dá o cabeçalho. O laço "for" a seguir vai preencher a contagem dos votos por candidato. Para j de 0 a 4, lista_opcao_cadastro[j].numero dá o número do candidato na posição j + 1 da lista; lista_opcao_cadastro[j].nome dá o nome, concatenado entre um parêntese abrindo depois de um espaço (" (") e um parêntese fechando; lista_opcao_cadastro[j].cont dá o número de votos.
      for (let j = 0; j < TOTAL_NOMES; j++) {
        if (j === c) {
          document.getElementById("sequencia").innerHTML = document.getElementById("sequencia").innerHTML + "<p style=\"background-color: #FFFF80\">" + lista_opcao_cadastro[j].numero + " (" + lista_opcao_cadastro[j].nome + "): " + lista_opcao_cadastro[j].cont + "</p>\n";
        } else {
          document.getElementById("sequencia").innerHTML = document.getElementById("sequencia").innerHTML + "<p>" + lista_opcao_cadastro[j].numero + " (" + lista_opcao_cadastro[j].nome + "): " + lista_opcao_cadastro[j].cont + "</p>\n";
        }
      }
      // Você notou que na lista da contagem em tempo real, o número de votos do último candidato votado aparece com destaque amarelo? E se lembra de que eu disse que ia precisar do valor do i e guardei o valor na variável c (antes de ser mudado)?
      // O contador j do laço "for" vai de 0 a TOTAL_NOMES - 1. TOTAL_NOMES é o número de candidatos. Quando j é igual a c (três sinais de igual), a formatação do parágrafo (<p>) é cor de fundo ("background-color") igual a #ffff80, ou rgb(255, 255, 128), que é aquele tom de amarelo.
      // Ah, e pra sair um valor de texto com aspas (dentro do valor), não dá pra colocar só as aspas, é preciso usar um escape, no caso, \". Nós vimos antes outro caso de escape, com \n para marca de parágrafo.
    } else {
      registro(); // Depois de a variável "part" entrar com valor 9 e sair com valor TOTAL_PART, que é 10, nós vamos executar a função de novo e ela vai cair aqui. Todos os eleitores já votaram e a eleição acabou. E o comando aqui é executar a função a seguir.
    }
  }
  /*
  LÁ VEM O GOLPE!
  */
  function registro() {
    // A variável "texto_relatorio_oficial" vai dar o "boletim público", que vai aparecer acima do botão verde (eu coloquei lá pra economia de espaço e pra chamar a atenção do leitor).
    texto_relatorio_oficial = "\n<p><b>BOLETIM PÚBLICO</b></p>";
    texto_relatorio_oficial = texto_relatorio_oficial + "\n<p><b>ZONA " + NUM_ZONA + ", SEÇÃO " + NUM_SECAO + "</b></p>"; // Até aqui é o cabeçalho.
    // O laço "for" a seguir é pra produzir o registro que vai ser oferecido ao público. Aquele registro real não vai ser afetado.
    // O esquema do laço é o mesmo que o da simulação dos votos, mas são duas situações diferentes. Lá, os candidatos são escolhidos com números aleatórios para simular os votos dentro da tendência geral. Aqui, os números aleatórios vão seguir a tendência das pesquisas publicadas (a matriz "lista_opcao_pesquisa", não "lista_opcao_percentuais"), simulando uma aleatoriedade segundo as pesquisas.
    for (let j = 0; j < TOTAL_PART; j++) {
      controle_pesquisa = 0;
      opcao_random = Math.round(1 + 99 * Math.random()); // O resultado dá entre 1 e 100
      while (opcao_random > lista_opcao_pesquisa[controle_pesquisa]) {
        opcao_random -= lista_opcao_pesquisa[controle_pesquisa];
        controle_pesquisa++;
      }
      relatorio_oficial[controle_pesquisa]++;
    }
    // O laço "for" foi executado para o total de eleitores igual a TOTAL_PART, que é 10, distribuindo os votos aleatoriamente seguindo a tendência das pesquisas.
    // O laço "for" a seguir vai preencher as linhas abaixo do cabeçalho. O atributo "numero" de "lista_opcao_cadastro[j]" dá o número do candidato na posição j + 1 da lista. A mesma posição na matriz "relatorio_oficial" dá o número de votos que vai ser atribuído a ele.
    for (let j = 0; j < TOTAL_NOMES; j++) {
      texto_relatorio_oficial = texto_relatorio_oficial + "\n<p>" + lista_opcao_cadastro[j].numero + ": " + relatorio_oficial[j] + "</p>";
    }
    document.getElementById("extrato_publico").innerHTML = texto_relatorio_oficial + document.getElementById("extrato_publico").innerHTML; // A célula da segunda tabela com id="extrato_publico" estava só com o botão verde "CONFIRMA". Aqui, vai exibir também o "boletim público".
    // Se lembra de que eu disse que o registro real não foi afetado? Ele vai ser mostrado aqui.
    document.getElementById("extrato_reservado_moldura").style = "text-align: justify; font-family: Courier New; font-size: 10pt; padding: 8pt; border-top: solid; border-top-color: #800000; border-top-width: 2pt; border-right: solid; border-right-color: #800000; border-right-width: 2pt; border-bottom: solid; border-bottom-color: #800000; border-bottom-width: 2pt; border-left: solid; border-left-color: #800000; border-left-width: 2pt";
    // O identificador "extrato_reservado_moldura" é o de uma tabela abaixo da tabela "Registro interno". Essa tabela estava invisível, agora vai, entre outros atributos, ganhar uma borda vermelho escuro (cor #800000 de todos os lados).
    document.getElementById("extrato_reservado_corpo").innerHTML = "\n<tr>\n<td colspan=5><b>RELATÓRIO INTERNO - ZONA " + NUM_ZONA + ", SEÇÃO " + NUM_SECAO + "</b></td>\n</tr>"; // O identificador "extrato_reservado_corpo" é o do corpo (tbody) da tabela "extrato_reservado_moldura"
    // Para criar uma célula "td", precisamos ter a linha "tr", que precisa estar dentro do corpo "tbody". A célula acima vai abranger 5 colunas (colspan=5), as 5 da tabela.
    cabecalho_reservado = "\n<tr>\n<td width=10><b>n</b></td>\n<td width=280><b>nome</b></td>\n<td width=80><b>título</b></td>\n<td width=400><b>endereço</b></td>\n<td width=80><b>hora</b></td>\n</tr>"; // Essa é a linha de cabeçalho da seção da tabela, com 5 colunas.
    // O laço "for" a seguir vai preencher as linhas da seção correspondente aos votos de cada candidato.
    for (let j = 0; j < TOTAL_NOMES; j++) {
      subtitulo_num = lista_opcao_cadastro[j].numero;
      subtitulo_nome = lista_opcao_cadastro[j].nome;
      // A seguir, o cabeçalho da seção, com uma célula que abrange as 5 colunas.
      document.getElementById("extrato_reservado_corpo").innerHTML = document.getElementById("extrato_reservado_corpo").innerHTML + "\n<tr>\n<td colspan=5><b>Candidato: " + subtitulo_num + " (" + subtitulo_nome.toUpperCase() + ")" + "</b></td>\n</tr>"; // O método toUpperCase() coloca um texto em letras maiúsculas.
      cont_reservado = 0;
      // O laço "for" a seguir vai percorrer a lista dos eleitores conferindo se o atributo "opcao" é igual ao atributo "numero" do candidato índice j.
      for (let k = 0; k < TOTAL_PART; k++) {
        if (selecao[k].opcao === subtitulo_num) { // Aqui foi achado um eleitor.
          cont_reservado++; // A variável cont_reservado, que é o contador, aumenta em 1
          // Na condicional (if) a seguir, se o eleitor achado é o primeiro da lista (a variável "cont_reservado" é igual a 1), o corpo da tabela ganha aquela linha da variável "cabecalho_reservado" mais a primeira linha de dados. Se não (else), ganha só a próxima linha de dados.
          if (cont_reservado === 1) {
            document.getElementById("extrato_reservado_corpo").innerHTML = document.getElementById("extrato_reservado_corpo").innerHTML + cabecalho_reservado + "\n<tr>\n<td>" + cont_reservado + "</td>\n<td>" + pessoas[k].nome + "</td>\n<td>" + TextoTitulo(pessoas[k].titulo) + "</td>\n<td>" + pessoas[k].endereco + "</td>\n<td>" + selecao[k].horatexto + "</td>\n</tr>";
          } else {
            document.getElementById("extrato_reservado_corpo").innerHTML = document.getElementById("extrato_reservado_corpo").innerHTML + "\n<tr>\n<td>" + cont_reservado + "</td>\n<td>" + pessoas[k].nome + "</td>\n<td>" + TextoTitulo(pessoas[k].titulo) + "</td>\n<td>" + pessoas[k].endereco + "</td>\n<td>" + selecao[k].horatexto + "</td>\n</tr>";
          }
        }
      }
      // É possível a variável "cont_reservado" sair do laço anterior com valor 0, porque o candidato não teve votos. Neste caso, a linha abaixo do cabeçalho da seção vai ganhar a linha a seguir.
      if (cont_reservado === 0) {
        document.getElementById("extrato_reservado_corpo").innerHTML = document.getElementById("extrato_reservado_corpo").innerHTML + "\n<tr>\n<td colspan=5>* * * NENHUM VOTO * * *</td>\n</tr>";
      }
    }
    document.getElementById("extrato_reservado_corpo").innerHTML = document.getElementById("extrato_reservado_corpo").innerHTML + "\n"; // Um parágrafo no final só por estética.
    document.getElementById("botao_verde").innerHTML = "Veja o relatório interno abaixo"; // Aquele button id="botao_verde" muda de novo
  }
</script>
<!--
  Finalmente acabou o script! A partir daqui, está o que você vê na tela.
  Ah, e você pode observar que comentários no Javascript vêm depois de duas barras ou entre /* e */ (quando começa com duas barras, acaba no fim da linha); no HTML, começa com sinal de menor, ponto de exclamação, dois hífens e termina com dois hífens, sinal de maior.
-->
<table cellpadding="2" cellspacing="2">
  <tbody>
    <tr>
      <td colspan=3 height="40" style="vertical-align: bottom; text-align: center; font-family: Tahoma, DejaVu Sans; font-size: 10pt;">
        <p>Clique o botão "CONFIRMA" para prosseguir a simulação. Serão 10 eleitores.</p>
        <p>É só confirmar a opção que vai aparecer na tela (os votos são reais simulados com números aleatórios). A tabela "Registro interno" abaixo dá o histórico em tempo real.</p>
      </td>
    </tr>
    <tr>
      <!-- Esta linha vai ser editada na função "tela_inicial", document.getElementById(id entre aspas).innerHTML -->
      <td id="real" width=250 style="text-align: justify; font-family: Courier New; font-size: 10pt;"></td>
      <td id="pesquisa" width=250 style="text-align: justify; font-family: Courier New; font-size: 10pt;"></td>
      <td id="ponto_zero" width=160 style="text-align: justify; font-family: Courier New; font-size: 10pt;"></td>
    </tr>
  </tbody>
</table>
<p></p> <!-- Um parágrafo só pra dar espaço entre as tabelas -->
<table cellpadding="10" cellspacing="8">
  <tbody>
    <tr>
      <td width="400" height="200" style="vertical-align: middle; background-color: #d0d0d0; border-top: solid; border-top-color: #800000; border-top-width: 2pt; border-right: solid; border-right-color: #800000; border-right-width: 2pt; border-bottom: solid; border-bottom-color: #800000; border-bottom-width: 2pt; border-left: solid; border-left-color: #800000; border-left-width: 2pt">
        <p style="text-align: center; font-family: Arial Rounded MT Bold, Franklin Gothic Medium; font-size: 12pt;">PRESIDENTE</p>
        <!-- Os dois parágrafos a seguir têm os valores que você vai ver na tela no começo. Quando você clica no botão verde "CONFIRMA", os valores mudam na função "tela_inicial" na primeira vez e na função "tela_voto" nas outras. -->
        <p id="tela_numero" style="text-align: center; font-family: Bookman Old Style; font-size: 30pt; font-weight: bold;">_ _</p>
        <p id="tela_nome" style="text-align: center; font-family: Arial Rounded MT Bold, Franklin Gothic Medium; font-size: 12pt;"></p>
      </td>
      <!--
      Esta é a célula que começa só com o botão verde e mostra o "boletim público" no final. É editada na função "registro" (document.getElementById("extrato_publico").innerHTML).
      O atributo "onclick" do elemento "button" define o que vai ser feito se o "button" é clicado. Aqui, o comando é uma condicional simplificada: se a variável "primeira_tela" tem valor TRUE, função "confirmacao"; se não é (o valor é FALSE), função "tela_inicial".
      -->
      <td id="extrato_publico" width="200" height="200" style="text-align: justify; font-family: Courier New; font-size: 10pt; vertical-align: bottom; text-align: center; border-top: solid; border-top-color: #800000; border-top-width: 2pt; border-right: solid; border-right-color: #800000; border-right-width: 2pt; border-bottom: solid; border-bottom-color: #800000; border-bottom-width: 2pt; border-left: solid; border-left-color: #800000; border-left-width: 2pt">
        <button id="botao_verde" type="button" style="text-align: center; background-color: #008000; font-family: Bookman Old Style; font-size: 12pt; color: #FFFFC0; font-weight: bold" onclick="(primeira_tela ? confirmacao() : tela_inicial())">CONFIRMA</button>
      </td>
    </tr>
  </tbody>
</table>
<p></p>
<table cellspacing="16"> <!-- E aqui temos tabelas aninhadas: são duas células, cada uma tem uma tabela dentro. -->
  <tbody>
    <tr>
      <td>
        <table cellpadding="2" cellspacing="2" border="2" style="border-color: rgb(128, 0, 0)"> <!-- Tabela 1: "Registro interno", que dá a votação em tempo real. -->
          <tbody>
            <tr>
              <td colspan=2 style="vertical-align: bottom; text-align: center; font-family: Bookman Old Style; font-size: 12pt; font-weight: bold;">Registro interno</td>
            </tr>
            <tr style="text-align: center; font-family: Courier New; font-size: 10pt; font-weight: bold;">
              <td width=90>candidato</td>
              <td width=80>hora</td>
            </tr>
            <!-- As 10 linhas a seguir vão ser preenchidas uma a uma na função "confirmacao". -->
            <tr id="linha01" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha02" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha03" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha04" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha05" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha06" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha07" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha08" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha09" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
            <tr id="linha10" style="text-align: justify; font-family: Courier New; font-size: 10pt;"></tr>
          </tbody>
        </table>
      </td>
      <td>
        <table cellpadding="2" cellspacing="2" border="2" style="border-color: rgb(128, 0, 128)"> <!-- Tabela 2: Contagem dos votos em tempo real. A única célula, id="sequencia", é editada na função "confirmacao" (document.getElementById("sequencia").innerHTML). -->
          <tbody>
            <tr>
              <td id="sequencia" width=250 style="vertical-align: top; text-align: justify; font-family: Courier New; font-size: 10pt; padding: 8pt;"></td>
            </tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>
<p></p>
<!--
O "relatório interno" vai aparecer aqui. No começo, é uma tabela vazia e invisível.
Depois de executada a função "registro", a tabela (id="extrato_reservado_moldura") ganha uma borda vermelho escuro (as variáveis border color ganham o valor #800000, ou rgb(128, 0, 0)). A mesma função "registro" preenche o corpo da tabela, que tem o identificador "extrato_reservado_corpo".
Deixo a observação de que não é preciso que todos os dados estejam gravados na urna. Um programa pode associar o "log" dos votos com o "log" da liberação do voto para cada número do título, ou o mesmo programa pode fazer o registro das duas coisas. O arquivo com essas informações pode dar os dados brutos para um outro programa buscar outros dados em outro banco de dados, e o programa dá um relatório como este (ou dados brutos para um outro programa).
-->
<table id="extrato_reservado_moldura" cellpadding="2" cellspacing="2">
  <tbody id="extrato_reservado_corpo" cellpadding="2" cellspacing="2">
  </tbody>
</table>
</body>
</html>

Texto original em português sem fotos e vídeos de putaria no A Vez das Mulheres de Verdade: "Uma ilustração da segurança da urna eletrônica brasileira", https://avezdasmulheres.blogspot.com/2022/09/uma-ilustracao-da-seguranca-da-urna.html.
Texto original em português com fotos e vídeos de putaria no A Vez dos Homens que Prestam: "Uma ilustração da segurança da urna eletrônica brasileira", https://avezdoshomens.blogspot.com/2022/09/uma-ilustracao-da-seguranca-da-urna.html.

Nenhum comentário:

Postar um comentário

Abigail Pereira Aranha no VK: vk.com/abigail.pereira.aranha
E-mail: saindodalinha2@gmail.com

Related Posts Plugin for WordPress, Blogger...

AddThis