Captura de documentos - SelphID
Este componente precisa de uma versão mínima do iOS9
Introdução
Este componente é responsável pela captura e análise de documentos de identidade, permitindo extrair informações estruturadas e obter imagens processadas do documento.
Suas principais funcionalidades são:
Gerenciamento interno da câmera e das permissões.
Assistência guiada para a captura do anverso e verso do documento.
Extração automática de dados por meio de OCR.
Obtenção de imagens processadas do documento e de elementos associados (rosto, assinatura etc.).
Alto nível de configuração: países, idiomas, tipos e modelos de documentos.
Para uma integração básica do SDK, consulte a seção Lançamento simplificado. Nesta página, são detalhadas as informações específicas para o uso deste componente.
Dependências
Para evitar conflitos e problemas de compatibilidade, se o projeto contiver versões antigas de bibliotecas da Facephi (Widgets), elas devem ser removidas completamente antes de instalar os componentes do SDK Mobile.
CocoaPods
As bibliotecas da Facephi são distribuídas remotamente por meio de gerenciadores de dependências. As dependências obrigatórias que deverão ter sido instaladas previamente (adicionando-as ao arquivo Podfile do projeto) são:
pod 'FPHISDKMainComponent', '~> $VERSION'Para instalar o componente SelphID, adicione a dependência correspondente no
Podfiledo projeto.
Swift Package Manager (SPM)
Se você usar SPM, certifique-se de que as dependências obrigatórias do SDK estejam instaladas previamente.
Para instalar o componente SelphID, inclua-o nos módulos do projeto.
Permissões
No aplicativo cliente onde os componentes serão integrados, é necessário incorporar o seguinte elemento no arquivo Info.plist:
Controladores disponíveis
Controlador
Descrição
SelphIDController
Controlador principal de reconhecimento de documentos
Lançamento simplificado
Depois que o SDK for iniciado e uma nova operação for criada, o componente pode ser lançado usando qualquer um de seus controladores disponíveis, conforme a funcionalidade necessária.
Recebimento do resultado
O resultado da execução é retornado em um objeto SdkResult, que contém:
selphIDResult.finishStatusselphIDResult.errorTypeselphIDResult.data
Recebimento de erros
finishStatus: Isso nos indicará se a operação foi concluída corretamente. Valores possíveis:
errorType: Erros próprios do widget.
No iOS, errorType é um ErrorType do SDK. Em um timeout, o enum Swift pode ser .SDK_TIMEOUT, .SELPHID_TIMEOUT(UIImage?, UIImage?) ou, se interpolado diretamente, exibir nomes como SDK_TIMEOUT ou SELPHID_TIMEOUT. No iOS não existe um caso TIMEOUT sem prefixo.
Para serializar o erro, deve-se utilizar:
Isso retorna SPD_TIMEOUT tanto se o enum for SDK_TIMEOUT quanto SELPHID_TIMEOUT.
Comportamento em timeout
Em um timeout, o resultado tem:
finishStatus:STATUS_ERRORdata:nil(não é retornado umSelphIDResult)errorType:.SDK_TIMEOUTou.SELPHID_TIMEOUT(UIImage?, UIImage?)
O caso SELPHID_TIMEOUT preserva, quando disponíveis, as imagens brutas do documento capturadas antes do timeout (rawFrontDocument e rawBackDocument do widget). não faz parte de data nem é retornado como rawFrontDocument / rawBackDocument do resultado de sucesso; só pode ser lido no iOS por meio de pattern matching sobre errorType:
Se o timeout chegar como SDK_TIMEOUT, não inclui imagens brutas. Se chegar como SELPHID_TIMEOUT, as imagens associadas podem ser nil quando o timeout ocorre pela via de erro do widget (FWMETimeout) em vez do delegate captureTimeout().
Para integrações nativas do iOS, o valor serializado deve ser tratado como SPD_TIMEOUT (inclui tanto SDK_TIMEOUT quanto SELPHID_TIMEOUT do enum).
No iOS, propriedades como timeoutDiagnostic ou captureProgress não são incluídas no SdkResult de erro. O componente usa captureProgress internamente para exibir a mensagem da tela de diagnóstico quando showDiagnostic está ativo.
Se showDiagnostic está ativo, o callback output não é invocado no instante do timeout: primeiro é exibida a tela de diagnóstico e o resultado é entregue ao pressionar fechar. Com showDiagnostic desativado, o callback é executado imediatamente.
A lista a seguir inclui erros do contrato multiplataforma; alguns não ocorrem no iOS (por exemplo, SPD_MOVE_FAIL).
SPD_APPLICATION_CONTEXT_ERROR: O contexto de aplicação necessário é nulo.
SPD_BAD_EXTRACTOR_CONFIGURATION_ERROR: Widget: Configuração do extrator incorreta
SPD_CAMERA_PERMISSION_DENIED: O usuário rejeitou as permissões.
SPD_CANCEL_BY_USER: O usuário cancelou o processo.
SPD_CANCEL_LAUNCH: Foi feita uma cancelamento geral do SDK.
SPD_COMPONENT_LICENSE_ERROR: A licença do componente não está correta.
SPD_CONTROL_NOT_INITIALIZATED_ERROR: Widget: Erro de inicialização
SPD_EMPTY_LICENSE: O String de licença está vazio.
SPD_EXTRACTION_LICENSE_ERROR: Widget: Erro de licença
SPD_HARDWARE_ERROR: Widget: Erro de hardware
SPD_INITIALIZATION_ERROR: Erro de inicialização.
SPD_MOVE_FAIL: O usuário não se moveu como foi especificado no processo.
SPD_NO_DATA_ERROR: Os dados de entrada são nulos.
SPD_OPERATION_NOT_CREATED: Não há nenhuma operação em andamento.
SPD_RESOURCES_NOT_FOUND: Não foi encontrado o zip de recursos
SPD_SETTINGS_PERMISSION_ERROR: Widget: Erro de permissões
SPD_TIMEOUT: Timeout no processo (
SDK_TIMEOUTouSELPHID_TIMEOUTdo enum).SPD_UNEXPECTED_CAPTURE_ERROR: Widget: Erro na captura
SPD_UNKNOWN_ERROR: Erro desconhecido
SPD_WIDGET_RESULT_DATA_ERROR: Erro nos dados de saída do widget
Recebimento de execução correta - data
O conteúdo do campo data depende do componente. No caso de SelphID, são retornados os seguintes campos:
frontDocument / tokenFrontDocument
A imagem frontal do documento processada, limpa e recortada pelas bordas e seu token correspondente.
backDocument / tokenBackDocument
A imagem traseira do documento processada, limpa e recortada pelas bordas e seu token associado.
faceImage / tokenFaceImage
A imagem do rosto encontrada no documento, caso exista, e seu token associado.
documentCaptured
Esta propriedade indica o modelo de documento que foi capturado quando uma busca é realizada no modo SMSearch. Dessa forma, a aplicação pode saber qual modelo, dentre todos os permitidos, foi detectado.
matchingSidesScore
Esta propriedade retorna um cálculo da semelhança dos dados lidos entre a frente e o verso do documento. O cálculo é realizado verificando a semelhança entre os campos comuns lidos em ambas as faces. O resultado do cálculo será um valor entre 0.0 e 1.0 no caso de existirem campos comuns no documento. Quanto maior for o valor, mais semelhantes serão os dados comparados. Se o cálculo retornar -1.0, significa que o documento não contém campos comuns ou ainda não há informações das duas faces.
Propriedade captureProgress
Esta propriedade retorna o estado em que o processo de captura se encontrava quando o widget terminou com sucesso (STATUS_OK). Em um timeout, data é nil e este valor não é incluído no SdkResult do callback de erro. Estes são os possíveis valores:
0: Na leitura da frente, o widget terminou sem conseguir detectar nada. Geralmente quando nenhum documento é colocado.
1: Na leitura da frente, o widget terminou tendo detectado parcialmente um documento. Nesse caso, alguns dos elementos esperados conseguiram ser detectados, mas não todos os necessários.
2: Na leitura da frente, o widget terminou tendo concluído a detecção de todos os elementos do documento. Se o widget termina nesse estado, é porque a análise de OCR não pôde ser concluída com sucesso.
3: Na leitura da frente, o widget terminou tendo analisado e extraído todo o OCR do documento. Este é o estado em que terminaria uma leitura correta da frente de um documento.
Os estados de 4 a 7 são exatamente iguais, só que se referem ao resultado do processo quando o verso é analisado.
ocrResults
Este dicionário contém todos os dados detectados no documento. As chaves de cada campo são codificadas de tal forma que a própria chave contém informações de onde o valor foi obtido. Assim, por exemplo, a chave Front/MRZ/DocumentNumber indica o valor de DocumentNumber que foi lido na frente do documento e na região do MRZ. Essas chaves dependem do documento capturado e, portanto, serão diferentes entre distintos países e modelos de documento. O dicionário também contém chaves com nomes mais genéricos e que não carregam informação relativa à localização. Essas chaves contêm o dado mais completo de todos os lidos para esse campo.
Essas chaves são as seguintes:
FirstName: O valor associado a essa chave contém o nome do usuário.
LastName: O valor associado a essa chave contém o sobrenome do usuário.
DateOfBirth: O valor associado a essa chave contém a data de nascimento detectada no documento.
Gender: O valor associado a essa chave contém o sexo do usuário detectado no documento.
Nationality: O valor associado a essa chave contém a nacionalidade do usuário detectada no documento.
DocumentNumber: O valor associado a essa chave contém o número do documento.
DateOfExpiry: O valor associado a essa chave contém a data de expiração do documento.
Issuer: O valor associado a essa chave contém o emissor do documento.
DateofIssue: O valor associado a essa chave contém a data de emissão do documento.
PlaceOfBirth: O valor associado a essa chave contém o local de nascimento do usuário.
Endereço: O valor associado a essa chave contém o endereço detectado no documento.
Adicionalmente, são adicionadas chaves do próprio objeto results para facilitar sua busca:
DocumentCaptured: Valor do modelo de documento que foi capturado conforme o .xml de modelos. Corresponde à propriedade documentCaptured.
MatchingSidesScore: Valor que indica a correspondência entre as faces lidas do documento. Corresponde à propriedade matchingSidesScore.
countryCaptured
País do documento.
documentTypeCaptured
Tipo de documento. Corresponde aos do item 5.1.10.
personalData
Conjunto reduzido de dados obtidos do usuário:
issuer
documentNumber
issueDate
expiryDate
name
surname
fullName
gender
birthDate
birthPlace
nationality
address
nfcKey
numSupport
mrz
Informações avançadas
Seletor de documentos - OPCIONAL
showDocumentSelector
Ativação da tela de seletor de documentos. Ela será exibida assim que o controlador for lançado.
enabledCountries
Lista de países em ISO2 que aparecerão no seletor. Se seu valor for nulo ou não contiver valores válidos, serão exibidos todos os disponíveis pelo SDK.
enabledDocumentTypes
Lista de tipos de documentos que aparecerão no seletor de tipos de documentos. Se seu valor for nulo ou não contiver valores, serão exibidos todos os disponíveis pelo SDK.
Configuração avançada
O componente é configurado por meio de um objeto SelphIDConfigurationData.
debug
Ativação do modo de depuração do componente.
resourcesPath
Define o caminho onde se encontra o arquivo de recursos do widget. Esse arquivo contém tanto os recursos gráficos quanto os recursos de localização. Esse caminho deve ser especificado em relação à pasta ‘Resources’ da aplicação principal.
wizardMode
Indica se o widget fica configurado para realizar a captura de ambas as partes (frente e verso) do documento uma após a outra. Nesse modo, o widget seria lançado apenas uma vez e, ao terminar de capturar a frente, continuaria em seguida com o verso.
showResultAfterCapture
Indica se deve ou não ser exibida uma tela com a imagem capturada do documento após o processo de análise. Nessa tela, é dada ao usuário a possibilidade de repetir o processo de captura caso a imagem obtida do documento não esteja correta.
showTutorial
Indica se o widget ativa a tela de tutorial. Nessa tela, é explicado de forma intuitiva como a captura é realizada.
tutorialOnly
Indica se o widget deve ser lançado apenas para exibir o tutorial.
scanMode
Indica o modo de escaneamento OCR dos documentos. Dependendo da escolha, serão escaneados e buscados vários tipos de documentos ou um específico. Esse modo pode ser de três tipos:
SelphIDScanMode.MODE_GENERIC: O modo genérico que permite escanear qualquer tipo de documento, independentemente do país ou do tipo de documento. O resultado desse modo não é tão preciso quanto os seguintes, mas permite escanear vários documentos padrão.
SelphIDScanMode.MODE_SEARCH: O modo de busca permitirá utilizar uma whitelist e blacklist, e buscará nos documentos que atendam a essas condições. Essas condições são indicadas na variável "specificData". Dessa forma, é possível realizar a busca limitando o número de modelos, tornando-a muito mais precisa do que no caso genérico.
SelphIDScanMode.MODE_SPECIFIC: Busca de um documento específico. Essas condições são indicadas na propriedade "specificData" mostrada a seguir.
SpecificData
Esta propriedade permite definir quais documentos serão escaneados durante o processo, caso o modo de escaneamento (scanMode) seja declarado como SMSearch ou SMSpecific.
Um exemplo de configuração que permita escanear todos os documentos de nacionalidade espanhola seria o seguinte:
tokenImageQuality
Indica a quantidade de qualidade que se deseja receber nas imagens tokenizadas. Valor entre 0 e 1.
DocumentType
Os valores permitidos são os seguintes:
SelphIDDocumentType.ID_CARD: O widget fica configurado para realizar a captura de documentos de identidade.
SelphIDDocumentType.PASSPORT: O widget fica configurado para realizar a captura de passaportes.
SelphIDDocumentType.DRIVERS_LICENSE: O widget fica configurado para realizar a captura de carteiras de motorista.
SelphIDDocumentType.FOREIGN_CARD: O widget fica configurado para realizar a captura de documentos estrangeiros.
SelphIDDocumentType.CUSTOM: O widget fica configurado para realizar a captura de outro tipo de documento que não corresponde a nenhuma das categorias anteriores.
DocumentSide
Os valores permitidos são os seguintes:
SelphIDDocumentSide.FRONT: O widget fica configurado para realizar a captura da parte frontal do documento.
SelphIDDocumentSide.BACK: O widget fica configurado para realizar a captura da parte traseira do documento.
SelphIDDocumentSide.ALL: O widget fica configurado para realizar a captura de ambas as partes do documento.
Timeout
É um enumerado que define o timeout da captura de um lado do documento. Tem 3 valores possíveis:
SelphIDTimeout.SHORT: 15 segundos.
SelphIDTimeout.MEDIUM: 20 segundos.
SelphIDTimeout.LONG: 25 segundos.
SelphIDTimeout.VERY_LONG: 60 segundos.
videoFilename
Define o caminho absoluto do nome do arquivo no qual será gravado um vídeo do processo de captura. A aplicação é responsável por solicitar as permissões necessárias ao telefone caso esse caminho exija permissões adicionais. O widget, por padrão, não realizará nenhum processo de gravação, a menos que um caminho de arquivo seja especificado por este método.
DocumentModels
Esta propriedade permite, por meio de uma string em formato xml, configurar a modelagem dos documentos que o widget tentará capturar. A definição dessa modelagem se encontra, por padrão, em um .xml de modelos que está no .zip de recursos. Com essa propriedade, é possível permitir que uma aplicação atualize, em tempo real, a modelagem dos documentos.
Nota: Esta propriedade não altera o conteúdo do arquivo de recursos.
generateRawImages
Esta propriedade configura o widget para retornar a imagem completa da câmera que foi usada para capturar o documento. Essas imagens são retornadas nas propriedades rawFrontDocument e rawBackDocument do objeto results respectivamente.
tokenPreviousCaptureData
Quando a captura do documento é realizada em 2 chamadas, esta propriedade permite passar um dicionário com as informações da captura anterior. Dessa maneira, o widget pode combinar os resultados de ambas as leituras de forma inteligente e, assim, retornar as informações combinadas de ambas as capturas. Também permite ao widget calcular um grau de semelhança dos dados de ambas as faces.
No caso de a captura de ambas as faces do documento ser realizada em uma única chamada, isso não é necessário, já que o widget faz esse processo internamente.
translationsContent
Esta propriedade avançada permite, por meio de uma string em formato xml, configurar a tradução dos literais exibidos durante o processo.
Nota: Esta propriedade não altera o conteúdo do arquivo de recursos.
viewsContent
Esta propriedade avançada permite, por meio de uma string em formato xml, configurar as telas do widget.
Nota: Esta propriedade não altera o conteúdo do arquivo de recursos.
showDiagnostic
Exibir telas de diagnóstico ao final do processo
showPreviousTip
Mostra uma tela anterior ao lançamento da captura com informações sobre o processo a ser realizado e um botão para o lançamento.
vibrationEnabled
Indica se deseja um feedback de vibração ao final do processo.
animateDismiss
Indica se o fechamento do SDK é animado ao finalizar o processo. Disponível desde 2.8.1.
Personalização do componente
Além das alterações que podem ser feitas no nível do SDK (as quais são explicadas no documento de Personalização do SDK), este componente específico permite a modificação de sua interface.
Cores
O componente, além das cores padrão existentes na seção geral de personalização, dispõe de duas cores específicas para a tela do seletor:
sdkSelectorBackgroundColor: É a cor usada para o fundo da tela de seleção. Não confundir com sdkBackgroundColor.
sdkCardBackgroundColor: É a cor usada para o fundo dos "cards" de seleção.
Imagens
O componente, além das imagens padrão existentes na seção geral de personalização, dispõe de imagens específicas para a tela do seletor. A lista pode ser vista acessando o enumerado R.Image.
Textos
Os textos podem ser personalizados sobrescrevendo as chaves correspondentes em Localizable.strings.
As chaves com o sufixo _alt são usadas para acessibilidade (VoiceOver).
Exemplo de modificação do texto COMEÇAR para é:
É preciso ir ao arquivo Localizable.strings da pasta es.lproj (se essa pasta não existir, será necessário criá-la).
"selphid_component_tip_button_message"="COMEÇAR";
Se uma chave não estiver definida, será usado o valor padrão.
selphid_component_tutorial_message_1
Procure um fundo com bom contraste.
selphid_component_tutorial_message_2
Coloque o documento dentro do quadro.
selphid_component_tutorial_message_3
Evite brilhos que dificultem a leitura do documento.
selphid_component_tip_message
Foque seu documento dentro do quadro. A foto será tirada automaticamente.
selphid_component_tip_title
Foto do documento
selphid_component_tip_button
COMEÇAR
selphid_component_tip_close_button_alt
VOLTAR
selphid_component_tip_button_alt
Iniciar captura de documento
selphid_component_tip_anim_id_alt
Coloque seu Documento de identidade na horizontal e aponte seu celular na vertical.
selphid_component_tip_anim_passport_alt
Animação de um celular tirando uma foto de um Passaporte. O documento aparece na horizontal, aberto na página onde aparece a foto. O celular está na vertical. Na tela do celular aparece um quadro. Quando a página do Passaporte se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tip_anim_driving_alt
Animação de um celular tirando uma foto de uma Licença de motorista. O documento aparece na horizontal, e o celular está na vertical. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tutorial_1_anim_id_alt
Coloque seu Documento de identidade na horizontal e aponte seu celular na vertical.
selphid_component_tutorial_2_anim_id_alt
Coloque o documento sobre uma superfície com uma cor diferente da do documento.
selphid_component_tutorial_3_anim_id_alt
Há reflexos no documento.
selphid_component_tutorial_1_anim_pass_alt
É mostrado um Passaporte branco, sobre um fundo branco. As bordas do documento não são distinguidas com clareza. Por meio de uma animação, o fundo muda de cor.
selphid_component_tutorial_2_anim_pass_alt
Um celular tira uma foto de um Passaporte. O documento aparece na horizontal, e o celular está na vertical. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tutorial_3_anim_pass_alt
Um Passaporte, visto de frente. Ao incliná-lo, aparecem reflexos sobre o documento.
selphid_component_tutorial_1_anim_driving_alt
É mostrada uma Licença de motorista branca, sobre um fundo branco. As bordas do documento não são distinguidas com clareza. Por meio de uma animação, o fundo muda de cor.
selphid_component_tutorial_2_anim_driving_alt
Um celular tira uma foto de uma Licença de motorista. O documento aparece na horizontal, e o celular está na vertical. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tutorial_3_anim_driving_alt
Uma Licença de motorista, vista de frente. Ao incliná-la, aparecem reflexos sobre o documento.
selphid_component_tip_health_alt
Animação de um celular tirando uma foto de um cartão de saúde. O documento aparece na horizontal, e o celular está na vertical. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tutorial_1_anim_health_alt
É mostrado um cartão de saúde branco, sobre um fundo branco. As bordas do documento não são distinguidas com clareza. Por meio de uma animação, o fundo muda de cor.
selphid_component_tutorial_2_anim_health_alt
Um celular tira uma foto de um cartão de saúde. O documento aparece na horizontal, e o celular está na vertical. Na tela do celular aparece um quadro. Quando o documento se encaixa dentro do quadro, o aplicativo tira uma foto.
selphid_component_tutorial_3_anim_health_alt
Um cartão de saúde, visto de frente. Ao incliná-lo, aparecem reflexos sobre o documento.
selphid_component_tip_custom_alt
selphid_component_tutorial_1_anim_custom_alt
selphid_component_tutorial_2_anim_custom_alt
selphid_component_tutorial_3_anim_custom_alt
selphid_component_timeout_title
Tempo esgotado
selphid_component_timeout_front_desc
Verifique se a frente do documento está dentro do quadro e os dados estão visíveis.
selphid_component_timeout_back_desc
Verifique se o verso do documento está dentro do quadro e os dados estão visíveis.
selphid_component_timeout_desc
Verifique se o documento está dentro do quadro e os dados estão visíveis.
selphid_selector_title
Faça seu onboarding
selphid_selector_country_label
De qual país é o seu documento?
selphid_selector_country_search_label
Escolha um país
selphid_selector_country_search_placeholder
Procure um país
selphid_selector_country_no_results
Sem resultados
selphid_selector_document_label
Qual documento você usará?
selphid_selector_document_dialog_title
Escolha o documento
selphid_selector_continue
CONTINUAR
selphid_selector_type_id_card
Documento de identidade
selphid_selector_type_passport
Passaporte
selphid_selector_type_drivers_license
Licença de motorista
selphid_selector_type_foreign_card
Cartão de residência
selphid_selector_type_credit_card
Cartão de crédito
selphid_selector_type_custom
Personalizado
selphid_selector_type_visa
Visto
selphid_selector_exit_alert_finish
Finalizar
selphid_selector_exit_alert_question
Tem certeza de que deseja finalizar o processo?
Aceitar
selphid_selector_exit_alert_accept
selphid_selector_exit_alert_cancel
Cancelar
Animações
As animações da dica anterior e dos tutoriais são Lottie (.json).
Para substituí-las:
Adicione o arquivo na pasta
Resources.Mantenha exatamente o mesmo nome do arquivo.
Se não forem substituídas, as animações padrão serão exibidas.
selphid_anim_tip_id_male
Animação para a dica anterior do Documento de identidade
selphid_anim_tip_pass_male
Animação para a dica anterior do Passaporte
selphid_anim_tip_driver_male
Animação para a dica anterior da Licença de motorista
selphid_anim_tuto_id_1
Primeira animação do tutorial do Documento de identidade
selphid_anim_tuto_id_2
Segunda animação do tutorial do Documento de identidade
selphid_anim_tuto_id_3
Terceira animação do tutorial do Documento de identidade
selphid_anim_tuto_pass_1
Primeira animação do tutorial do Passaporte
selphid_anim_tuto_pass_2
Segunda animação do tutorial do Passaporte
selphid_anim_tuto_pass_3
Terceira animação do tutorial do Passaporte
selphid_anim_tuto_driving_1
Primeira animação do tutorial da Licença de motorista
selphid_anim_tuto_driving_2
Segunda animação do tutorial da Licença de motorista
selphid_anim_tuto_driving_3
Terceira animação do tutorial da Licença de motorista
selphid_anim_tuto_custom_1
Primeira animação do tutorial para um documento personalizado
selphid_anim_tuto_custom_2
Segunda animação do tutorial para um documento personalizado
selphid_anim_tuto_custom_3
Terceira animação do tutorial para um documento personalizado
Atualizado