Ir para conteúdo
  • Cadastre-se

dev botao
  • Este tópico foi criado há 471 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Boa tarde ! Estou com uma maquina Sunmi estou tentando usar no android em um projeto. No demo do acbr ele roda e imprime como texto e bitmap, tem alguma forma dele imprimir de um arquivo PDF? Alguma sugestão?

Postado

Pelo que entendi esse FPDF-Pascal gera um arquivo PDF, eu tenho esse arquivo PDF já, mas preciso convertê-lo para bitmap. Assim posso usar o método .printBitmap() para imprimir esse arquivo na smartpos sunmi.

  • Membros Pro
Postado

Olá, Alisson, tudo bem?

Fiquei com dúvidas sobre o seu questionamento:

1 - O arquivo PDF é gerado no próprio POS android?

2 - Caso não seja, ele acessa/recebe ou "baixa" esse arquivo de um servidor?

3 - Caso a resposta ao item anterior seja positiva: o servidor poderia fazer a conversão?

Em sendo as respostas aos itens 2 e 3 positivas, como sugestão, você poderia usar o ghostscript (através de linha de comando, batch ou dll acessada diretamente por uma aplicação sua) para fazer a conversão de PDF p/ BMP e enviar o arquivo para o POS.

Usamos o ghost para converter PDFs para jpg, png, bmp, ... e sempre nos atendeu muito bem, com um ótimo desempenho, mas nunca precisamos usá-lo diretamente no android. Fiz algumas pesquisas ontem a noite e parece que dá um trabalhão para compilar o ghostscript para android diretamente dos fontes, pois não há distro oficial para o android.

Abaixo segue um script para linha de comando (também sugestão) testei com três arquivos PDFs multipaginados e funcionou com sucesso, gerando um PDF para cada página de cada arquivo:

"C:\Program Files\gs\gs10.01.2\bin\gswin64c.exe" -dNOPAUSE -dQUIET -dBATCH -sDEVICE=bmp256 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -q -sOutputFile=Pagina-%03d.bmp -r300 -f "arquivo1.pdf" -f "arquivo2.pdf" -f "arquivo3.pdf"

O comando foi testado no Windows 10, com a última versão do ghostscript - 64 bits. (substituir o trecho: "C:\Program Files\gs\gs10.01.2\bin\gswin64c.exe" pelo caminho do executável do ghostscript instalado na sua máquina).

Caso meu entendimento não tenha sido correto, antecipadamente peço desculpas.

  • Obrigado 1
Postado

o arquivo é gerado por um servidor, e transferido para o POS android.  O servidor pode fazer a alteração, mas vou tentar usar a dll pois é inviável baixar o executável do ghostscript.  

  • Membros Pro
Postado

Abaixo segue código que usamos, mas é trabalho em andamento... inspirado em pedaços de códigos diversos stackoverflow, sites gringos, ... (implementamos em FPC/Lazarus, OK?)

unit GhostScriptDLLWrapper;

{$mode ObjFPC}{$H+}

interface

uses
  Classes, SysUtils;

const

  GS_ARG_ENCODING_LOCAL = 0;
  GS_ARG_ENCODING_UTF8 = 1;
  e_Quit = -990;

type

  TGSAPIrevision = packed record
    product: PChar;
    copyright: PChar;
    revision: longint;
    revisiondat: longint;
  end;

  PGSAPIrevision = ^TGSAPIrevision;
  Pgs_main_instance = Pointer;
  PPChar = array of PChar;

  {$IFDEF WINDOWS}
     {$IFDEF WIN32}

           { gsdll32.dll }
         function gsapi_new_instance(pinstance: Pgs_main_instance;
           caller_handle: Pointer): Integer; stdcall; external 'gsdll32.dll';
         function gsapi_init_with_args(pinstance: Pgs_main_instance; argc: Integer;
           argv: PPChar): Integer; stdcall; external 'gsdll32.dll';
         function gsapi_exit(pinstance: Pgs_main_instance): Integer; stdcall;
           external 'gsdll32.dll';
         procedure gsapi_delete_instance(pinstance: Pgs_main_instance); stdcall;
           external 'gsdll32.dll';
         function gsapi_set_arg_encoding(pinstance: Pgs_main_instance; ENCODING: Integer)
           : Integer; stdcall; external 'gsdll32.dll';
     {$ENDIF}
     {$IFDEF WIN64}
           { gsdll64.dll }
         function gsapi_new_instance(pinstance: Pgs_main_instance;
           caller_handle: Pointer): Integer; stdcall; external 'gsdll64.dll';
         function gsapi_init_with_args(pinstance: Pgs_main_instance; argc: Integer;
           argv: PPChar): Integer; stdcall; external 'gsdll64.dll';
         function gsapi_exit(pinstance: Pgs_main_instance): Integer; stdcall;
           external 'gsdll64.dll';
         procedure gsapi_delete_instance(pinstance: Pgs_main_instance); stdcall;
           external 'gsdll64.dll';
         function gsapi_set_arg_encoding(pinstance: Pgs_main_instance; ENCODING: Integer)
           : Integer; stdcall; external 'gsdll64.dll';
     {$ENDIF}
  {$ENDIF}

function MergePdfsFiles(outPdf: ansistring; files: array of ansistring): Integer;
function SplitPDFFile(AInFile, AOutPDF: AnsiString; AIniPage, AEndPage: Integer): Integer;
function ConvertPDFToPNG(AResolution: AnsiString;
  AInFile: AnsiString): Integer;
function ConvertMultPDFToPNG(AResolution: AnsiString;
  AInFiles: Array of AnsiString): Integer;
function ConvertPSToPDF(): Integer;
function ConvertPDFToBMP(AResolution: AnsiString;
  AInFile: AnsiString): Integer;
function ConvertMultPDFToBMP(AResolution: AnsiString;
  AInFiles: Array of AnsiString): Integer;

implementation

function MergePdfsFiles(outPdf: ansistring; files: array of ansistring): Integer;
var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
  //minst: Pointer;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=pdfwrite';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=' + outPdf);
  for i := Low(files) to High(files) do
  begin
    setlength(gsargv, length(gsargv) + 1);
    gsargv[high(gsargv)] := pansichar(files[i]);
  end;
  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;

function SplitPDFFile(AInFile, AOutPDF: AnsiString; AIniPage, AEndPage: Integer
  😞 Integer;
var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
  //minst: Pointer;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dQUIET';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=' + AOutPDF);
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-dFirstPage=' + IntToStr(AIniPage));
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-dLastPage=' + IntToStr(AEndPage));
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=pdfwrite';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar(AInFile);


  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);

  if (code < 0) then
  begin
    result := 1;
    exit;
  end;

  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);

  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);

  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);

  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;

  result := 1;
end;

function ConvertPDFToPNG(AResolution: AnsiString;
  AInFile: AnsiString): Integer;
var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dQUIET';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=png16m';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=ProgramPage-%03d.png');
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-r' + AResolution);
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar(AInFile);
  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;

function ConvertMultPDFToPNG(AResolution: AnsiString;
  AInFiles: Array of AnsiString): Integer;
var
  code, code1, gsargc, i, llow, lhigh: Integer;
  nome1, nome2, nome3: PChar;
  lStrLstFileNames: TStringList;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';

  llow := Low(AInFiles);
  //WriteLn('Arquivo inicial, posicao: ' + IntToStr(llow));
  lhigh := High(AInFiles);
  //WriteLn('Arquivo final, posicao: ' + IntToStr(lhigh));
  //WriteLn('Posicoes do array(iniciando em zero): ' + IntToStr(High(gsargv)));

  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dQUIET';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=png16m';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=ProgramMultPage-%03d.png');
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-r' + AResolution);

  lStrLstFileNames := TStringList.Create;
  for i := Low(AInFiles) to High(AInFiles) do
  begin
    lStrLstFileNames.Add('-f' + String(AInFiles[i]));
    //WriteLn('Conteudo da StringList na posicao ' + IntToStr(i) + ' ' + lStrLstFileNames[i]);
  end;

  lhigh := High(gsargv);
  //WriteLn('Tamanho do array antes de receber as strings: ' + IntToStr(lhigh));

  setlength(gsargv, length(gsargv) + lStrLstFileNames.Count - 1);

  //WriteLn('Novo tamanho do array antes de receber as strings: ' + IntToStr(length(gsargv)));

  for i := 0 to (lStrLstFileNames.Count - 1) do
  begin
    gsargv[lhigh + i] := PChar(lStrLstFileNames[i]);
    //WriteLn('Conteudo da posicao ' + IntToStr(lhigh + i) + ' do array: ' + gsargv[lhigh + i]);
  end;

  {for i := Low(gsargv) to High(gsargv) do
  begin
    WriteLn('Conteudo da posicao ' + IntToStr(i) + ' do array: ' + gsargv[i]);
  end;}

  {for i := Low(gsargv) to High(gsargv) do
  begin
    Write(IntToStr(i) + ' - ');
    WriteLn(gsargv[i]);
  end;}

  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;

function ConvertPSToPDF: Integer;
begin

end;

function ConvertPDFToBMP(AResolution: AnsiString; AInFile: AnsiString): Integer;
var
  code, code1, gsargc, i: Integer;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dQUIET';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=bmp256';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dTextAlphaBits=4';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dGraphicsAlphaBits=4';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=ProgramPage-%03d.bmp');
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-r' + AResolution);
  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar(AInFile);
  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;

function ConvertMultPDFToBMP(AResolution: AnsiString;
  AInFiles: array of AnsiString): Integer;
var
  code, code1, gsargc, i, lhigh: Integer;
  lStr: PChar;
  lStrLstFileNames: TStringList;
  gsargv: array of pansichar;
  minst: PGSAPIrevision;
begin
(*0*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := 'gs';
(*1*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dNOPAUSE';
(*2*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dQUIET';
(*3*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dBATCH';
(*4*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-sDEVICE=bmp256';
(*5*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dTextAlphaBits=4';
(*6*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-dGraphicsAlphaBits=4';
(*7*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := '-q';
(*8*)  setlength(gsargv, length(gsargv) + 1);
  lStr := PChar('-r' + String(AResolution));
  gsargv[high(gsargv)] := pansichar(lStr);
(*9*)  setlength(gsargv, length(gsargv) + 1);
  gsargv[high(gsargv)] := pansichar('-sOutputFile=ProgramMultPage-%03d.bmp');
  lStrLstFileNames := TStringList.Create;
  for i := Low(AInFiles) to High(AInFiles) do
  begin
    lStrLstFileNames.Add('-f' + String(AInFiles[i]));
  end;
  lhigh := High(gsargv) + 1;
  setlength(gsargv, length(gsargv) + lStrLstFileNames.Count);
  for i := 0 to (lStrLstFileNames.Count - 1) do
  begin
    gsargv[lhigh + i] := PChar(lStrLstFileNames[i]);
  end;
  gsargc := length(gsargv);
  minst := Nil;
  code := gsapi_new_instance(@minst, Nil);
  if (code < 0) then
  begin
    result := 1;
    exit;
  end;
  code := gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
  if (code = 0) then
    code := gsapi_init_with_args(minst, gsargc, @gsargv[0]);
  code1 := gsapi_exit(minst);
  if ((code = 0) or (code = e_Quit)) then
    code := code1;
  gsapi_delete_instance(minst);
  if ((code = 0) or (code = e_Quit)) then
  begin
    result := 0;
    exit;
  end;
  result := 1;
end;

end.

Exemplo de uso, conversão PDF p/ BMP... (código FPC/Lazarus ... SEMPRE, CLARO...)

 

program project1;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}
  cthreads,
  {$ENDIF}
  Classes
  , SysUtils
  , GhostScriptDLLWrapper
  { you can add units after this };

var
  gPath: String;
  gReturnCode: Integer;

begin
  gReturnCode := 0;
  gPath := ExtractFilePath(ParamStr(0));
  gReturnCode := ConvertPDFToBMP('300',
                 'Arquivo1.pdf');//<-- apenas 1 arquivo
  gReturnCode := ConvertMultPDFToBMP('300',
                 [gPath + 'Arquivo1.pdf'
                 , gPath + 'Arquivo2.pdf'
                 , gPath + 'Arquivo3.pdf']);//<-- mais de um arquivo
  if gReturnCode <> 0 then
  begin
    WriteLn('Returning Code: ' + IntToStr(gReturnCode));
    ReadLn();
  end;
end.


 

  • Membros Pro
Postado

Os códigos acima funcionam com as dlls de 64 e 32 bits. Verifiquei que o arquivo do Wrapper está incompleto, mas funcionando para todas as rotinas implementadas, vou pedir o código do nosso arquivo de produção onde outras funcionalidades estão implementadas (conversão para jpg, tiff, postscript, dxf, ... realização de OCR em PDFs, ...).

 

  • Consultores
Postado

Bom dia @JOSE CHAO,

Quando for adicionar bastante código procure anexar um arquivo ao invés de colar o códig todo. Facilita na leitura do tópico.

Obrigado!

Consultor SAC ACBr

Alexandre de Paula
Ajude o Projeto ACBr crescer - Assine o SAC                    

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.  ícone Discórdia Discord   

Projeto ACBr - A maior comunidade Open Source de Automação Comercial do Brasil

 

 

  • Membros Pro
Postado

Aparentemente o TStringList não está sendo liberada na rotina ConvertMultPDFToBMP

3 minutos atrás, Alexandre de Paula disse:

Bom dia @JOSE CHAO,

Quando for adicionar bastante código procure anexar um arquivo ao invés de colar o códig todo. Facilita na leitura do tópico.

Obrigado!

Ok, perdão.

  • Curtir 1
  • Fundadores
Postado
Consultor SAC ACBr

Daniel Simões de Almeida
O melhor TEF, é com o Projeto ACBr - Clique e Conheça
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr     Telefone:(15) 2105-0750 WhatsApp(15)99790-2976.

  • Membros Pro
Postado
31 minutos atrás, Daniel Simoes disse:

Obrigado, Daniel.

Acabo de descobrir que estou sem a versão de produção na minha máquina, ficaram faltando algumas rotinas bastante úteis, vou pedir pro pessoal e posto novamente. No código anteriormente publicado o nome dos arquivos a serem gerados estão hard coded, e já vi que na função ConvertMultPDFToBMP a TStringList criada não foi destruída aí ... mem leak ..., mas os arquivos estão sendo gerados normalmente.

O código foi desenvolvido no FPC/Lazarus, mas não deve ter grandes problemas para compilar no Delphi, infelizmente não tenho instalado na minha máquina para testar.

Para quem teve interesse no código, a resolução do arquivo pode ser alterada, podendo gerar arquivos mais leves, já que arquivos BMPs com boa resolução ou de imagems grandes como uma folha A4 podem ficar pesados.

Usamos as dlls do ghostscript nos servidores para manipular arquivos e distribuir (boletos que precisam ser gerados como imagens, ...), o projeto ghostscript é bastante ativo e sempre está atualizado, o que é bom pela questão de segurança.

Mesmo em grandes mudanças de versão não recordo de grandes contratempos para usar as novas DLLs... procuramos sempre usar as mais recentes. Há algum tempo houve uma alteração que obrigou o uso da seguinte linha: 

minst := Nil;
  • Este tópico foi criado há 471 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.