Pular para o conteúdo

Flags de fingerprint

A identidade é controlada por switches de linha de comando do Chromium. O SDK os define a partir de opções nomeadas; com o build aberto, você também pode passá-los como args para o seu próprio launcher.

A maioria dos switches existe nos dois builds. Alguns são exclusivos do build licenciado (Grátis com GitHub ou Pro) — a lista de switches abaixo os marca com a revisão do motor que os adicionou. Sem uma chave de licença, o SDK roda o build aberto, no qual essas opções não têm efeito.

O modelo de seed

Tudo parte de --fingerprint=<seed>. A seed (um inteiro ou qualquer string) deriva a persona de forma determinística — e perturba as duas superfícies renderizadas listadas mais abaixo, em o que recebe farbling:

Desde a build licenciada do Chromium 156 (r51), essa derivação acontece no serviço de personas da Clearcote: o lançador o consulta a cada início com o token de execução da licença e entrega ao navegador a persona assinada, sem a qual ele se recusa a iniciar. Mesma seed, mesma identidade que no r50. Licenças offline permanecem no r50 até existir um pacote de personas offline.

  • Mesma seed ⇒ mesma identidade em toda inicialização na mesma máquina e na mesma versão do navegador — um visitante que volta. Tudo o que uma página consegue ler volta idêntico: a GPU, a tela, o hardware, as fontes e as vozes, e os resultados de canvas, WebGL e áudio. A única exceção é a estimativa de velocidade da conexão (o tempo de ida e volta e a largura de banda em navigator.connection), que acompanha a sua rede real, como acontece no Chrome.
  • Nova seed ⇒ uma identidade nova e plausível.
  • O ruído de canvas e WebGL é derivado por site (inspirado no farbling do Brave), então esses hashes mudam de um domínio para outro. A persona em si — GPU, tela, hardware, fontes — é a mesma em todo lugar, como seria a de uma máquina real.

A mesma seed em máquinas diferentes

A placa de vídeo que uma persona declara vem do fabricante da placa com que a máquina de fato renderiza (NVIDIA, Intel ou AMD), então os pixels e os limites gráficos que uma página mede pertencem ao tipo de placa que é informado à própria página. Numa máquina sem placa de vídeo, a persona declara gráficos integrados: a partir do 154 r37, da Intel ou da AMD; no r36, só da Intel. Assim, uma seed reporta uma placa de vídeo diferente em máquinas cujas placas são de fabricantes diferentes — por design.

No build licenciado, a partir do 154 r36, o fabricante de GPU da máquina também pode mudar o resto do hardware. Um computador de entrada não vem com placa de vídeo dedicada, então, numa máquina com placa NVIDIA, uma seed que declararia hardware de entrada (4 a 6 threads de processador, 4 a 8 GB de memória, uma tela pequena) passa a declarar hardware intermediário ou melhor, e nunca uma tela sensível ao toque. Por isso, cerca de metade de todas as seeds reporta, numa máquina NVIDIA, threads de processador e memória diferentes dos que reporta numa máquina Intel, AMD ou sem placa de vídeo, e algumas também um tamanho de tela diferente. Em máquinas com o mesmo fabricante de GPU, a identidade de uma seed é a mesma.

A partir do 154 r37, a gama de placas de onde as máquinas de um fabricante tiram a delas vem do tráfego real de navegadores: cada modelo é tão provável quanto no mundo real, então uma frota de personas se parece com uma frota de máquinas reais. Por isso, a maioria das seeds declara no r37 uma placa diferente da que declarava no r36; o resto do hardware deriva como no r36.

Desde 2026-10-26 (r52, e também nos launches do r51, porque o serviço de personas deriva a identidade), o padrão é o persona schema 7: a placa de vídeo define o tipo de máquina — notebook ou desktop, geração do processador, threads, memória e tela, incluindo a escala de exibição em que os notebooks realmente rodam. Uma seed sorteia uma máquina diferente da que sorteava antes dessa data.

Para manter uma única identidade para uma seed em várias máquinas:

  • Rode-a em máquinas com o mesmo fabricante de GPU — por exemplo, um único tipo de servidor em produção.
  • Fixe o fabricante de GPU passando --fingerprint-gpu-host-vendor=nvidia (ou intel, amd) nos args do seu launcher. A persona então deriva a identidade como faria numa máquina com placa desse fabricante, onde quer que rode. Fixe o fabricante das máquinas em que a persona mais roda: numa máquina cuja placa é de outro fabricante, a placa que ela declara deixa de corresponder à que renderiza.
  • Mantenha as identidades criadas do r45 ao r51 (antes de 2026-10-26) com persona_schema=5 / personaSchema: 5 (--fingerprint-schema=5), e as do 154 r37 ao 155 r44 com persona_schema=4 / personaSchema: 4. Os dois schemas estão congelados: uma seed deriva neles a mesma identidade para sempre.
  • Mantenha as identidades criadas no 154 r36 com persona_schema=3 / personaSchema: 3 (--fingerprint-schema=3). Toda seed então deriva exatamente o que derivava no r36, campo por campo, inclusive a placa de vídeo.
  • Mantenha as identidades criadas antes do r36 com persona_schema=2 / personaSchema: 2 (--fingerprint-schema=2). Toda seed então deriva exatamente o que derivava do 153 r29 ao 154 r35, campo por campo: a placa de vídeo continua acompanhando o fabricante de GPU da máquina; o resto do hardware, não.

Sem seed não há identidade por persona: toda inicialização no mesmo tipo de máquina parece igual. Dê a cada identidade a sua própria seed.

Prefere a identidade de uma máquina real à identidade sintética derivada da seed? Capture um Chrome doador com o coletor e importe-o via --fingerprint-profile=<gzip+base64 JSON> (ou pela opção fingerprint_profile / fingerprintProfile do SDK, que faz o gzip+base64 por você) em vez de uma seed. Os campos presentes no perfil sobrescrevem o que o navegador reportaria; os ausentes recorrem aos padrões do navegador. Não passe uma seed de --fingerprint junto com um perfil: a seed adiciona ruído ao canvas, que a pontuação estrita lê como adulteração ao lado dos valores de uma máquina real, e o perfil já fornece a identidade (veja Perfis e persistência). Os dois builds leem perfis importados; no build licenciado, eles se aplicam por completo a partir do 151 r19. Veja o guia do Playwright para saber como importar um perfil capturado pelo SDK.

O que recebe farbling e o que, de propósito, não recebe

Perturbar uma superfície traz desvinculação entre identidades, mas custa coerência, e essa troca não compensa em todo lugar. O Clearcote aplica farbling às duas superfícies em que o ruído fica mais perto da variação normal de hardware, e deixa o resto sem perturbação — porque, nelas, um valor perturbado chama mais atenção do que um valor compartilhado. Sem perturbação não quer dizer intocado, porém: alguns valores ainda são substituídos por inteiro a partir da persona, como a tabela e a nota abaixo dela detalham. Alguns verificadores ainda conseguem sinalizar o próprio ruído; quando isso importa, fingerprintNoise: false o desliga e mantém a identidade (veja Como a detecção funciona).

SuperfícieRuído por seedPor quê
Canvas 2D — toDataURL, getImageData e as outras formas de uma página exportar um canvas (no build licenciado, todos os caminhos de exportação concordam a partir do 152 r21)SimA leitura de pixels já varia entre máquinas reais conforme a GPU, o driver e o caminho de rasterização, então uma pequena perturbação fica dentro da dispersão natural.
WebGL — readPixels, toDataURLSimMesmo raciocínio. No build licenciado a partir do 154 r34, disableGpuFingerprint muda só o que a GPU reporta: readPixels e as exportações de um canvas WebGL mantêm o ruído do seed e concordam entre si. No build aberto e em builds licenciados mais antigos, ele também desliga o ruído do readPixels, enquanto as exportações continuam com ruído, então combine-o ali com fingerprintNoise: false para que toda leitura do canvas concorde. fingerprintNoise: false desliga o ruído de WebGL em todo lugar.
Áudio — valores das amostras do AudioContextNão — por designA saída do Web Audio é determinística para um mesmo pipeline. Perturbá-la significa ou uma taxa de amostragem fora da especificação (44099.99 em vez de 44100), ou amostras que nenhum renderizador padrão produz — nos dois casos, valores que um navegador real não consegue emitir, o que denuncia mais do que dois perfis compartilharem um hash de áudio. Os escalares reportados são outra história e seguem, sim, a persona — veja abaixo.
Client rects & métricas de textoNão — por designRects são um resultado do layout: seguem as fontes, o device pixel ratio, o nível de zoom e o locale, e só mudam quando eles mudam. Um perfil importado com outro pixel ratio, ou outro idioma (que pode mudar as fontes padrão), gera outro layout; seeds diferentes na mesma máquina fazem o layout com as mesmas fontes e o mesmo pixel ratio, então reportam os mesmos rects. Detectores percebem ruído nos rects sem nenhum valor armazenado, testando-os contra respostas conhecidas de antemão. O CreepJS exige que uma caixa de 100×100 girada em 45° gere o hash 9d9215cc com pixel ratio 1, que right - left seja exatamente igual a width, que dois elementos idênticos meçam o mesmo e que um elemento vazio meça zero. O Chrome genuíno reporta x, y, width e height de um rect como números exatos de precisão simples (float32), algo que ruído adicionado em JavaScript raramente preserva. Ruído adicionado depois do layout falha nessas verificações, por menor que seja. Brave, a proteção contra fingerprinting do Firefox e do Tor Browser e o Camoufox também deixam os rects intactos; o Camoufox removeu seu ruído na largura dos glifos em setembro de 2026 porque nenhuma máquina real produz essas larguras.
WebGPU — adapter e limitesNãoSegue a GPU da persona, e não a seed, então continua de acordo com o que o WebGL reporta. Duas APIs de GPU na mesma página apontando fabricantes diferentes é algo que se lê numa única chamada.

A consequência prática para quem trabalha com várias contas: canvas e WebGL separam suas identidades; áudio renderizado e client rects, não. Essas são propriedades da máquina por baixo — o mesmo host renderiza o mesmo pipeline de áudio e compõe o texto com as mesmas fontes e o mesmo pixel ratio seja qual for a seed carregada, exatamente como aconteceria com duas pessoas diferentes em hardware idêntico. Se um alvo correlaciona justamente por essas superfícies, a resposta são máquinas separadas, não outro switch.

Uma exceção que vale conhecer: os três escalares do AudioContext seguem, sim, a persona. sampleRate, baseLatency e outputLatency vêm da persona sempre que há uma ativa — uma seed de --fingerprint ou um perfil importado — e por isso variam de uma identidade para outra, em vez de expor o backend de áudio do host. Sem nenhum dos dois, os três vêm direto da máquina real. Uma taxa que a página pede explicitamente continua sendo respeitada, e outputLatency continua passando pelo quantizador do próprio Chrome, que depende de permissão. A partir do 153 r26, baseLatency também acompanha o tamanho de renderização que a página pede, e um contexto que ainda não começou a renderizar reporta a mesma latência que um Chrome comum.

Onde o ruído cai (r57)

A partir do r57, na build licenciada, o ruído de leitura de canvas e WebGL só altera um pixel quando nenhum dos seus quatro vizinhos tem a mesma cor. Áreas planas — uma forma sólida, um bloco preenchido, um fundo limpo — são lidas exatamente como foram desenhadas, como em hardware real. Bordas de texto, curvas e degradês continuam com o ruído da seed, então os perfis mantêm hashes de canvas diferentes. Antes do r57 uma área plana dentro de uma leitura também recebia ruído, então um verificador que desenha uma forma sólida e calcula o hash (o “Masking detected” do PixelScan) conseguia provar que os pixels tinham sido alterados.

Um readPixels parcial de WebGL (um retângulo menor que o canvas) não enxerga os pixels logo fora dele. Por isso, por padrão, o motor lê o retângulo junto com uma margem de um pixel em volta numa única leitura da GPU, e cada pixel da borda recebe exatamente o ruído que uma leitura completa do canvas daria; a leitura custa o mesmo que no Chrome.

Opção do SDK (Node / Python / .NET)Profile ManagerPadrãoO que muda
flatAreaNoise / flat_area_noise / FlatAreaNoiseRuído em áreas planas (estilo r56)desativadotrue traz de volta o ruído do r56: áreas planas também recebem ruído. Use para manter o hash de canvas de um perfil de antes do r57. Verificadores que calculam o hash de uma forma sólida voltam a indicar mascaramento. Switch: --fingerprint-noise-flat-areas.
webglReadMargin / webgl_read_margin / WebglReadMarginMargem em leituras parciais de WebGLativadofalse lê só o retângulo, sem a margem. Um ou dois pixels da borda de uma leitura parcial podem então diferir de uma leitura completa do mesmo canvas. Sem efeito com o ruído em áreas planas ativado. Switch: --fingerprint-webgl-no-read-margin.

As duas configurações valem para todas as formas de uma página ler os pixels (getImageData, toDataURL, toBlob, readPixels), então as leituras de um mesmo canvas continuam batendo. Motores anteriores ao r57 sempre se comportam como flatAreaNoise: true, e o SDK e o Profile Manager ignoram as duas configurações neles. No Docker, defina CC_FLAT_AREA_NOISE e CC_WEBGL_READ_MARGIN. As configurações chegam com o SDK 0.68.8 e o Profile Manager 0.40.0.

Superfícies secundárias coerentes

Além dos sinais com ruído, o motor mantém as superfícies secundárias da persona de acordo com um Chrome real na plataforma da persona. Por padrão, o SDK usa o sistema operacional do seu host como plataforma; os valores específicos do Windows abaixo valem para uma persona Windows.

  • Os limites de WebGL (WebGL1 + WebGL2) seguem a GPU da persona sempre que esta máquina consegue sustentá-los. Um limite nunca é reportado acima do que o driver real impõe; por isso, num renderizador por software, alguns valores ficam abaixo dos da GPU indicada.
  • UNMASKED_RENDERER / UNMASKED_VENDOR são constantes durante a sessão — uma única GPU em todos os sites, acompanhando a persona, em vez de um indício que muda por origem.
  • navigator.getBattery() reporta um desktop ligado na tomada (carregando, nível 1.0, sem descarga), e navigator.connection, um perfil residencial (effectiveType 4g, rtt/downlink arredondados, saveData desligado).
  • navigator.keyboard.getLayoutMap() retorna um mapa US-QWERTY e, numa persona Windows, o AudioContext reporta a taxa de amostragem e a latência da pilha de áudio do Windows.
  • Claro ou escuro — a partir do 154 r32, a persona prefere um esquema de cores (cerca de uma em cada três prefere o escuro; --fingerprint-color-scheme=light|dark escolhe), e prefers-color-scheme, matchMedia, o header Sec-CH-Prefers-Color-Scheme e as cores de sistema do CSS concordam entre si. O SDK (0.41.0+) deixa desligada a emulação de esquema de cores do Playwright num build assim, para que nada contradiga a persona.
  • Fontes — numa persona Windows, o texto tem as alturas de linha e as larguras de fontes comuns de uma máquina Windows, e as fontes que uma página pede pelo nome se comportam como no Windows (154 r32). Uma fonte genuína instalada na máquina é usada como ela mesma; no Linux, liste as suas com fontDirs.
  • window.getScreenDetails() reporta um único monitor coerente; @media (pointer: fine) / (hover: hover) correspondem a um desktop com mouse.
  • URLs — sob uma persona Windows, new URL("C:/").protocol retorna file: e, a partir do 153 r26, todas as formas de uma página montar uma URL dão a mesma resposta. navigator.share / canShare ficam expostos para combinar com o UA do Windows.
  • WebGPU — as informações do adapter + limites/features de navigator.gpu acompanham a mesma GPU do WebGL (no build licenciado, restritas ao que o host consegue entregar).
  • Locale — Accept-Language, navigator.language, a lista completa de navigator.languages e Intl (thread principal + workers) vêm todos de uma única lista (acceptLanguage, ou geoip). O SDK define --accept-lang e --lang por você; usando os switches diretamente, passe os dois.
  • Síntese de voz — speechSynthesis serve o conjunto de vozes da persona, incluindo as vozes de rede do Google que um Chrome daquela versão lista (153 r27). fingerprintVoices: false mantém as vozes da própria máquina (152 r22).
  • Hardware — a leitura de velocidade do processador (navigator.cpuPerformance) segue a persona, e não o processador real (152 r20), e o teto de memória dos scripts (performance.memory.jsHeapSizeLimit) segue a memória que a persona declara (153 r26).
  • Codecs & dispositivos — MediaCapabilities.decodingInfo() reporta uma matriz de codecs da persona, e enumerateDevices(), um conjunto de dispositivos de mídia da persona (ids estáveis por seed, rótulos vazios antes da permissão).
  • UA-CH de alta entropia — bitness=64 / wow64=false / model; numa persona Linux, platformVersion vem vazio, como reporta o Chrome genuíno no Linux (153 r26). navigator.storage.estimate() reporta uma cota de disco realista quando você define storageQuota.

Experimental: canvas bridge com GPU real

Se quiser, encaminhe as operações de canvas / WebGL para um host remoto com GPU real, para que as leituras (getImageData / toDataURL / readPixels / measureText) sejam coerentes com a GPU que você apresenta — mesmo em hardware que não consegue renderizá-la localmente. Como o que se encaminha são as operações (e não imagens pré-gravadas), isso dá conta da maioria dos canvases, não só de probes conhecidos. Ative com --canvas-bridge-url=ws://host:port (mais --no-sandbox); sem ele, tudo roda localmente, exatamente como antes. O servidor de renderização controla um navegador no host com GPU real (um Chrome comum via CDP, ou um Clearcote headless). Veja o guia do canvas bridge para a configuração completa.

Overrides nativos de metadados & light_stealth

Junto com a persona derivada da seed, um conjunto de overrides nativos de valor único permite falsificar valores individuais de navigator/screen diretamente — hardwareConcurrency, deviceMemory, colorDepth, devicePixelRatio, maxTouchPoints e (opt-in) as dimensões de screen/avail*. Cada um é lido direto pelo seu getter, com a precedência flag > persona do --fingerprint > host real; assim, um valor fixo vence qualquer seed, e os overrides funcionam com ou sem uma seed de --fingerprint — eles nunca acionam o mecanismo de persona.

O SDK agrupa um subconjunto leve atrás de uma única flag, light_stealth: ela aplica um entre poucos pacotes de metadados coerentes (hardwareConcurrency, deviceMemory, colorDepth, devicePixelRatio, maxTouchPoints) usando apenas esses switches nativos. A seed só escolhe o pacote e não é repassada ao motor, então não há ruído de canvas nem de WebGL, e todas as sessões light_stealth numa mesma máquina compartilham o hash de canvas do host — use uma seed de fingerprint por conta, sem lightStealth, quando esses hashes precisarem ser diferentes. O ClientHello do TLS e a versão real do navegador não mudam. As dimensões de screen propositalmente não são falsificadas por padrão (opt-in via screenWidth etc.), porque uma tela falsa que não bate com a superfície de renderização real é fácil de perceber; num display sem escala, confira se o devicePixelRatio escolhido combina com ele, ou defina-o você mesmo. Uma opção explícita sempre vence o preset.

javascript
import { launch } from "clearcote";
// one coherent metadata bundle; "my-seed" only picks which one — no seed reaches the engine, so no canvas noise:
const browser = await launch({ lightStealth: true, fingerprint: "my-seed" });

// or set individual values by hand (no --fingerprint needed):
const b2 = await launch({
  hardwareConcurrency: 8,
  deviceMemory: 8,
  devicePixelRatio: 1.25,
  maxTouchPoints: 0,
});

Todos os switches

Filtre por nome ou efeito, ou restrinja a um subsistema. Clique em um switch para ler o que ele faz e ver a sua forma válida mais curta.

Identidade e persona

Seed mestre (int ou string). Deriva a persona inteira (GPU, tela, hardware, fontes) e comanda o ruído de canvas e WebGL por site. Idioma e fuso horário não derivam do seed: vêm de --accept-lang / --timezone (SDK: acceptLanguage, timezone ou geoip). O áudio renderizado e os client rects não são perturbados; os escalares sampleRate/baseLatency/outputLatency do AudioContext vêm da persona quando há uma ativa — veja a documentação de fingerprint. Mesmo seed ⇒ mesma identidade na mesma máquina e na mesma versão do navegador; em máquinas com outro fabricante de GPU, a identidade é diferente (veja a documentação de fingerprint e --fingerprint-gpu-host-vendor).

Hardware e tela
GPU e WebGPU
Rede e locale
Ruído
Canvas bridge
Mídia e compatibilidade
Outras

Exemplos

Estes são conjuntos de flags de linha de comando puros. Para fluxos completos em Python e Node, veja Exemplos.

Uma identidade Windows completa e coerente:

bash
--fingerprint=acme-tenant-7 \
--fingerprint-platform=windows \
--fingerprint-brand=Chrome \
--accept-lang=en-US,en \
--lang=en-US \
--timezone=America/New_York \
--fingerprint-hardware-concurrency=8

Uma identidade Windows com strings de GPU personalizadas, no formato em que o ANGLE as reporta no Windows:

bash
--fingerprint=42 \
--fingerprint-platform=windows \
--fingerprint-gpu-vendor="Google Inc. (NVIDIA)" \
--fingerprint-gpu-renderer="ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 (0x00002504) Direct3D11 vs_5_0 ps_5_0, D3D11)"

As strings mudam o que é reportado, não o que desenha: os pixels continuam vindo da GPU desta máquina. Indique a GPU em que você realmente renderiza, ou use o canvas bridge. A plataforma macos no build aberto muda só as strings de identidade (UA, client hints, navigator.platform); no build licenciado, desde o 155 r47, ela descreve um Mac real, com o chip, os threads, a memória, a tela, o renderer gráfico, a versão do macOS e as vozes que combinam entre si. Já android é uma persona mobile de melhor esforço.

Fixe uma localização junto com o fuso horário dela, para que a geolocalização e o relógio concordem:

bash
--fingerprint=nyc-1 \
--timezone=America/New_York \
--fingerprint-location=40.7128,-74.0060

Importe os valores de uma máquina real

Em vez de uma seed sintética, você pode reportar os valores exatos que um Chrome real reportou — strings de GPU + tabela de getParameter, tela, fontes, vozes, áudio. Os valores são substituídos; a renderização continua sendo feita pela sua própria máquina, então um perfil não dá canvases diferentes a duas contas — uma seed de --fingerprint por conta, sim. Use um ou outro, não os dois: um perfil para os valores de uma máquina real, uma seed para separar a renderização por conta. Pegue um perfil na biblioteca curada clearcote-profiles (milhares de perfis de máquinas reais, marcados por fabricante de GPU) ou capture o seu com o coletor, depois carregue-o e comprove que ele foi carregado:

javascript
import { launch } from "clearcote";
// path to a captured .json profile, a profile object, or a JSON string
const browser = await launch({ fingerprintProfile: "./real-machine.json" });
// fields present in the profile override what the browser would report;
// absent fields keep the browser's defaults. Pass no fingerprint seed alongside a profile.

Fluxo de captura: abra a página do coletor num Chrome real que você quer clonar, exporte o JSON e passe-o via fingerprintProfile (SDK) / --fingerprint-profile (motor). Verifique com tools/fingerprint-collect/verify_profile.py.

O que cada patch faz

Cada switch do build aberto corresponde a um patch legível do motor: os diffs ficam em patches/, com um resumo de uma linha de cada um em patches/README.md. Os switches marcados como “build licenciado” vêm do conjunto de patches próprio do build licenciado, que não é público.

A coerência importa mais do que qualquer valor isolado: mantenha plataforma, fuso horário, locale e GPU plausíveis em conjunto. Veja Arquitetura para entender como o motor os mantém consistentes, e Como a detecção funciona para saber por que isso é melhor do que falsificar valores via JavaScript.
O diff

38.921 linhas entre o Chromium original e o Clearcote Pro.

Essa é a distância entre o build Pro e o Chromium que o Google distribui. Cada valor que um site pode ler é definido onde o Chromium o calcula, então a página, seus workers e seus iframes descrevem o mesmo dispositivo.

  • Canvas
  • WebGL
  • WebGPU
  • Áudio
  • Fontes
  • Tela e janela
  • WebRTC
  • TLS
  • Client hints
  • Tempo de entrada
  • Vozes e codecs
Leia os patches do build aberto no GitHub

Build Pro, contado na pilha de patches do r57 (Chromium 156.0.8078.47). O build aberto gratuito é um conjunto de patches menor e público.

Chromium 156.0.8078.47 → Clearcote Pro r57

345 files changed, 35915 insertions(+), 3006 deletions(-)

240 patches

Arquivos alterados, por área

  • Motor de renderização (Blink)118
  • Navegador (chrome/)52
  • Camada content42
  • Componentes39
  • Pilha de rede22
  • Interface e janelas14
  • TLS (BoringSSL)11
  • V8 e URL17
  • Todo o resto30