Quantcast
Channel: 中级
Viewing all articles
Browse latest Browse all 669

Adicionando Plugins de Terceiros à sua App Cordova do Intel® XDK

$
0
0

Os plugins do Apache* Cordova* são ferramentas importantes para melhorar os recursos e funcionalidades da sua aplicação móvel desenvolvida em HTML5 com o Intel® XDK. Eles te fornecem uma forma de extender a API JavaScript da sua aplicação, resultando em uma melhor integração entre sua aplicação e o software e hardware do dispositivo. Existem centenas de plugins disponíveis para o Cordova (e para o Adobe* PhoneGap*) que você pode usar na sua aplicação. Eles podem ser encontrados no Registro de Plugins do Apache Cordova e em outros registros similares, bem como em muitos repositórios open source do github. Um exemplo disso, é que se você trabalha para uma grande empresa, o seu departamento de TI pode até manter um conjunto de plugins do Cordova que eles desenvolveram para suportar usuários móveis na sua empresa.

O Intel XDK referencia e utiliza os plugins do Cordova em uma variedade de locais através do ciclo de desenvolvimento de sua aplicação móvel com HTML5. A utilização mais aparente é nas abas "Projects" e "Build". Na aba "Projects" (descrita abaixo), você seleciona quais plugins do Cordova serão inclusos como parte de sua app. A aba "Build" irá então adicionar automaticamente estes plugins ao pacote de sua app quando ele fizer o empacotamento dela, permitindo assim que a API estendida fornecida por estes plugins possa ser utilizada pela sua app. Além de "Projects" e "Build", os plugins são ainda utilizados no editor Brackets (o editor de texto da aba "Develop"), e no emulador (aba "Emulate").

Na aba "Develop", os plugins são utilizados para implementar o code hiting (uma característica comum de editores de código, comumente chamada de "intelli-sense" ou "auto-hinting"). O editor automaticamente fornece sugestões de métodos e propriedades da API para as APIs centrais do Cordova e do Intel XDK. Neste momento, o code hinting é fornecido para todos os plugins principais, independente dos plugins que você selecionou como parte da sua app na aba "Projects".

A aba "Emulate" leva em consideração quais plugins core do Cordova você selecionou na aba "Projects", e irá apresentar para a sua aplicação durante a emulação apenas as APIs que corresponderem aos plugins selecionados. O conjunto completo de APIs fornecidas pelos plugins do Intel XDK estão sempre disponíveis para a aplicação durante a emulação, independente dos plugins selecionados na aba "Projects".

NOTA: As abas "Test", "Debug", "Profile" e "Services" não saão afetadas pelos plugins que você selecionou na aba "Projects". Além disso, o "App Preview" e o "App Preview Crosswalk" também não são afetados pelas configurações de plugins do seu projeto. Elas suportam apenas os plugins core do Cordova e do Intel XDK.

Somente a aba "Build" faz uso de qualquer plugin de terceiros que for especificado para ser incluído na sua app através da aba "Project". Edições futuras do Intel XDK pretendem expandir o uso de plugins de terceiro ao longo do ciclo de desenvolvimento. Por enquanto, a única forma de você testar e depurar apps que incluam plugins de terceiros é através da compilação da app e execução dela em um dispositivo real.

O que é um Plugin do Cordova?

Parafraseando o Cordova Plugin Development Guide:

Um plugin é um pacote de código que permite que sua aplicação Cordova HTML5 se comunique com a plataforma nativa onde é executada. Os plugins fornecem acesso a funcionalidades da plataforma que normalmente não estão disponíveis a aplicações baseadas em navegadores. O core do Cordova (e do Intel XDK) são implementadas como plugins. Muitos outros plugins estão disponíveis e disponibilizam funcionalidades como um scanner de código de barras, comunicação NFC e acesso aos bancos de dados nativos dos telefones e tablets (como a lista de contatos ou o calendário).

Os plugins são compostos por uma API JavaScript e por módulos de código nativo (para cada plataforma suportada pelo plugin). Estes módulos suportam a API JavasScript do plugin. Essencialmente, quando sua app chama uma API em JavaScript do plugin, ela é redirecionada para o módulo de código nativo que o suporta, que finalmente acessa a API nativa no dispositivo. Por exemplo, a API JavaScript é redirecionada para código em Java em um dispositivo Android ou código em Objective C em um dispositivo iOS. Os plugins podem ser complexos ou simples: fornecendo APIs tão complexas quanto uma engine de banco de dados persistente ou tão simples quanto um método para acender o LED de flash da câmera do dispositivo. 

Preciso aprender a escrever código nativo em Java e Objective C e C# e ???

Absolutamente não. Muitos plugins podem ser puxados diretamente de um registro de plugins ou de um repositório github e usados como estão, sem a necessidade de aprender como o plugin opera internamente. Você não precisa "compilar" nada para usar um plugin bem estruturado, muitos estão prontos para a utilização sem necessidade de nenhuma configuração ou programação adicional.

Você vai precisar aprender como utilizar a API JavaScript do plugin para poder utiliza-lo em sua aplicação. Você pode pensar em um plugin Cordova como uma biblioteca JavaScript que estende as funcionalidades nativas que sua app pode acessar, funcionalidades que tipicamente não são acessíveis por um navegador ou uma webview (o navegador embarcado que interpreta a sua aplicação HTML5 híbrida). Os plugins fornecem funcionalidades extra que distinguem uma aplicação móvel de uma web app tradicional.

Alguns pontos importantes para ter em mente sobre os plugins Cordova e o Intel XDK: 
Como muitos plugins são bibliotecas de terceiros, o Intel XDK pode não ter conhecimento explícito das funcionalidades ou código de um plugin. As ferramentas de depuração incluídas no Intel XDK fornecem suporte apenas para os plugins core do Cordova e para os plugins do Intel XDK.
Nem todos os plugins são criados igual, e muitos plugins estão disponíveis apenas para as plataformas Android e iOS. Os plugins "core" do Cordova e os plugins da API do Intel XDK suportam uma ampla lista de plataformas Cordova. Certifique-se de que os plugins que planeja utilizar suporta as plataformas que você pretende distribuir a sua app, ou utilize técnicas de detecção de plataforma e funcionalidades para implementar uma solução alternativa para plataformas não suportadas.
Nem todos os plugins suportam todas as plataformas com um comportamento idêntico da API. Em outras palavras, alguns aspectos da API de um plugin pode variar em função da plataforma (isto ocorre normalmente por conta de detalhes da plataforma, não porque o plugin é incompleto ou deficiente). Variações incluem propriedades que não tem nenhum significado em algumas plataformas, ou métodos que não existem em outras. Veja a documentação do plugin para estes detalhes (alguns plugins incluem uma seção de peculiaridades - "quirks" - em sua documentação), e utilize funções de detecção de plataforma e funcionalidades para lidar com estas peculiaridades.
O Intel XDK não inclui um mecanismo para julgar a qualidade de um plugin. Existem diversos recursos na web, incluindo as tags cordova-plugins e phonegap-plugins no StackOverflow que podem ser usadas para determinar quais plugins são mais confiáveis e como desviar dos bugs associados a plugins específicos. Além disso, você pode obter suporte diretamente do autor de muitos plugins hospedados no github, caso encontre problemas com eles.
Alguns plugins de terceiros foram escritos para versões antigas do Cordova e podem não funcionar com o Cordova 3.x. Se você não consegue encontrar uma versão de um plugin de terceiros que trabalhe com o Cordova 3.x, pode ser possível converter um plugins pré-Cordova 3.x para trabalhar com o Cordova 3.x. O Intel XDK requer plugins que tenham sido escritos para o Cordova 3.x.
As APIs "core" do Cordova e as APIs do Intel XDK foram todas escritas como plugins do Cordova 3.x. Os plugins "core" do Cordova 3.x são mantidos pela comunidade de desenvolvimento do Cordova CLI. Os plugins do Intel XDK são mantidos pelo time de desenvolvimento do Intel XDK.
Plugins de terceiros não podem ser utilizados com builds "legados" do Intel XDK (ver a aba "Build"), eles podem ser utilizados apenas com builds Cordova e Crosswalk for Android. Entretanto, builds "legados" incluem uma coleção de plugins "core" do Cordova quando você os compila com a opção "Gold"; estes plugins "legados" são baseados nna versão 2.9.0 do Cordova e podem ser habilitados na sua aplicação incluindo <script src="cordova.js"></script> depois do include do script "intelxdk.js".
Os serviços da AppMobi (como o PushMobi) que são incluídos no sistema de build "legado" não estão disponíveis como plugins do Cordova (no momento em que este documento foi escrito). Se você não consegue identificar uma alternativa equivalente e precisa utilizar um serviço da AppMobi, sua única alternativa é continuar a utilizar o sistema de build "legado" ou solicitar que a AppMobi te forneça um plugin compatível com o Cordova 3.x para o serviço deles que a sua app necessita.
Se você está  desenvolvendo seu próprio plugin Cordova você pode ter que instalar e utilizar o sistema Cordova CLI em sua máquina de desenvolvimento. Você pode compartilhar o seu plugin com outros desenvolvedores sem que eles também precisem instalar o Cordova CLI em seu sistema, somente você (o desenvolvedor do plugin) vai precisar instalar o Cordova CLI (e somente para o desenvolvimento de plugins, pois o Intel XDK não precisa do Cordova CLI instalado em sua máquina de desenvolvimento para incluir o plugin na sua app). 
O Intel XDK não fornece um mecanismo de depuração de código nativo de um plugin Cordova, o que deve ser feito usando as ferramentas de desenvolvimento de código nativo específicas da plataforma nativa. A aba "Emulate" não utiliza código nativo Cordova para simular as APIs dos plugins, ela usa um código escrito para o ambiente node-webkit em que é executada, para fornecer a simulação do componente de código nativo. Entretanto, para os plugins que a aba "Emulate" suporta, somente o componente JavaScript de cada plugin é utilizado dentro da aba "Emulate".
As aplicações Intel App Preview que você baixa das lojas para depuração rápida da sua aplicação móvel em HTML5 nos dispositivos não possuem suporte a plugins Cordova de terceiros. Para depurar uma app que precisa de um plugin não-core do Cordova, você pode usar detecção de funcionalidades para pular a depuração ou utilizar o "simular a saída" de um plugin quando ele não estiver presente (este é o caso para quando a sua aplicação está executando dentro do App Preview, na aba "Emulate" ou quando estiver usando as abas "Debug" e "Test"). Você pode compilar a sua aplicação (usando a aba "Build"), para que os plugins de terceiros sejam incluídos no pacote e finalmente executar a aplicação compilada em um dispositivo real.
Quando este documento foi escrito, as aplicações App Preview para Android, iOS e Windows 8 ainda estavam baseadas no build "legado", e portanto, não representam precisamente o comportamento da sua aplicação dentro de um container padrão Cordova. Você pode continuar a utilizar o App Preview "legado" para depurar a sua app Cordova, mas tenha em mente que existirão algumas diferenças de funcionalidades e comportamento. As apps do App Preview serão atualizadas para utilizar o container Cordova adequado para permitir a representação correta de uma aplicação Cordova.
No momento em que este documento foi escrito, o sistema de build Cordova do Intel XDK está baseado na versão 3.3 do Cordova CLI.

Incluindo um Plugin do Cordova em sua App do Intel XDK

Incluir qualquer um dos plugins "core" do Cordova ou plugins do Intel XDK em sua app é muito fácil. A aba "Projects" da sua app contém uma lista de plugins incluídos, que pode ser alterada para adicionar ou remover os plugins de sua app, simplesmente clicando na check box próxima ao nome do plugin. Veja a tela abaixo, de uma aplicação de exemplo.

Detalhes sobre quais APIs estão incluídas em cada plugin core do Cordova podem ser encontrados na Documentação do Apache Cordova, na seção API Reference. Consulte a Intel XDK API Reference Documentation para detalhes de APIs e plataformas sobre os plugins da API do Intel XDK.

Na imagem acima, existem quatro botões azuis na parte de baixo do painel de seleção dos plugins: "Select All,""Select Minimum,""Select None" e "Reset Plugin Defaults":

  • Select All: habilita TODOS os plugins core do Cordova e TODOS os plugins do Intel XDK para que sejam incluídos em sua app. Isto é conveniente, mas não recomendado para a versão de produção da sua app. Este é o estado padrão dos plugins quando você cria um novo projeto ou importa um projeto existente utilizando a versão 0876 ou anterior do Intel XDK. Incluir TODOS os plugins é a grosso modo o equivalente ao estado dos plugins existentes em uma app desenvolvida com o o sistema de build "legado". Selecionar TODOS os plugins também significa que você está sujeitando a sua app a um número elevado de permissões que deverão ser aceitas pelo usuário final durante a instalação da app (nas plataformas Android e Windows 8; o iOS solicita do usuário final a permissão durante a utilização da aplicação que necessita de uma API específica). Incluir todos os plugins também significa que sua app vai ter um tamanho maior do que o necessário. 

  • Select Minimum: habilita um pequeno conjunto de plugins do Cordova e do Intel XDK. Este é o conjunto mínimo recomendado, e não o conjunto mínimo requerido de plugins. Se você estiver utilizando o evento device ready do Intel XDK você vai precisar incluir no mínimo o plugin Intel XDK "Base". Se você está usando o evento device ready do Cordova, você não precisa incluir nenhum plugin. Obviamente, se você está usando tanto as APIs do Cordova ou Intel XDK (ou seja, APIs além das APIs padrão do HTML5), você vai precisar incluir os plugins correspondentes a cada API que sua app necessita. Veja os documentos de referências citados acima para informações sobre quais plugins fornecem quais APIs.

  • Select None: limpa todas os plugins "core" do Cordova e do Intel XDK do seu projeto. Não tem nenhum efeito em plugins de terceiros importados utilizando o painel "Third-Party Plugins".

  • Reset Plugin Defaults: reseta a versão de cada um dos plugins core do Cordova para corresponderem às versões fornecidas com o Intel XDK. Este botão não terá efeito algum se você nunca tiver alterado os números de versão de qualquer um dos plugins core do Cordova. Mais informações sobre versões dos plugins core são fornecidas abaixo. Note que os plugins do Intel XDK não possuem número de versão selecionável, portanto este botão não tem nenhum efeito nestes plugins.

Sobre os Plugins Core

Os plugins core do Cordova e os plugins do Intel XDK são incluídos no Intel XDK; como estes plugins são incluídos como parte do Intel XDK, eles possuem uma "versão padrão" associada a eles. Estas são as versões que serão utilizadas caso o botão "Reset Plugins Default" seja pressionado (como descrito acima).

Você pode alterar um número de versão de um plugin selecionando o botão editar (passe o mouse sobre o plugin, como mostra a imagem abaixo): 

e então digite o número de versão desejada para o plugin (como mostrado abaixo):

Veja as páginas de Documentação do Apache Cordova para detalhes sobre os plugins core do Cordova. O repositório do git onde cada plugin é mantido inclui detalhes sobre as versões dos plugins, etc. Você pode determinar rapidamente quais versões estão disponíveis para um determinado plugin inspecionando o Registro de Plugins do Apache Cordova. Neste momento, somente a aba "Build" utiliza o número de versão do plugin, enquanto os outros componentes do Intel XDK utilizam um conjunto fixo de plugins do Cordova.

Incluindo Plugins de Terceiros

Existem duas formas de incluir plugins de terceiros em sua aplicação: através de um repositório público ou de um diretório local. Você seleciona o método específico selecionando Import Local Plugin" ou "Get Plugin from the Web" na seção "Third-Party Plugins" do painel "Plugins and Permissions" da aba "Project".

Dois repositórios públicos são suportados: um repositório git (como o github), ou o Registro de Plugins do Apache Cordova. Quando utilizar o registro do Cordova, você só vai precisar do ID do plugin, que pode ser encontrado na entrada do plugin no registro (veja a imagem abaixo para um exemplo de como referenciar o registro do Cordova somente com o ID de um plugin). Você também pode opcionalmente fornecer um número de versão de plugin (mais informações abaixo), como parte do campo de ID do plugin na caixa de diálogo "Get Plugin from the Web".

Se o seu plugin de terceiros estiver sendo recuperado do registro do Cordova, o Nome e o ID do Plugin são suficientes. Neste caso, marque a caixa de seleção "Plugin is located in the Apache Cordova Plugins Registry" e clique no botão "Import".

De outra forma, se o seu plugin de terceiros estiver localizado em um repositório git, você também precisa incluir o endereço deste repositório. O repositório git precisa ser publicamente acessível na Internet, pois o "git pull" utilizado para recuperar o plugin será executado no servidor baseado na nuvem e não no Intel XDK; portanto ele precisa residir em um repositório gir acessível publicamente.

Se você tem familiaridade com o comando plugin add do Cordova CLI, você pode utilizar a sua sintaxe para adicionar uma versão específica de plugin baseada tanto no número da versão armazenado no registro do Cordova ou um ID de referência no git. Mais detalhes podem ser encontrados na seção Advanced Plugin Options da documentação do Cordova CLI. Se você não especificar uma versão de plugin ou ID de referência, sua app será compilada utilizando a versão mais recente disponível no registro do Cordova ou do branch padrão quando recuperada de um repositório git público.

Importando um plugin de terceiros que reside e um diretório local requer que o plugin esteja localizado dentro do diretório que contém o código fonte de sua aplicação. Normalmente este diretório é chamado "www" e está localizado dentro da pasta que contém o seu projeto (ver a seção "Project Info" na aba "Project" para o nome e a localização do seu diretório de projeto). Um plugin local será incluído com o pacote de fontes que é enviado para o servidor de build na nuvem; o conteúdo completo do seu "diretório fonte"é enviado neste pacote.

Referências aos seus plugins de terceiros, tantos os importados de pastas locais quanto os localizados em repositórios públicos, são listados na seção "Third-Party Plugins" da aba "Projects" (veja a imagem abaixo como exemplo). O campo Nome que você especificou acima é arbitrário e é usado estritamente como um identificador aqui e no log de mensagens de build. O ID de Plugin deve ser igual ao especificado dentro do arquivo plugin.xml (veja o registro ou o repositório git do plugin). Neste momento, não existe forma de editar ou inspecionar os dados que você forneceu durante o processo de importação do plugin; se você precisar alterar o Nome ou o ID do Plugin ou outros campos, você deve remover a referência ao plugin (clique no ícone (x)) e importar novamente o plugin com o Nome, ID e outros campos com seus novos valores.

A imagem abaixo mostra o que você tipicamente vai encontrar quando inspecionar um plugin que está localizado no Registro de Plugins do Apache Cordova. Note o campo de ID de plugin, plataformas suportadas, versão de plugin e versão suportada do Cordova CLI (aka "Engine Number"). No momento em que este documento foi escrito, o servidor de build do Intel XDK estava baseado no Cordova CLI versão 3.3.

Fazendo o Build da sua App Cordova

Para fazer o build do pacote da sua aplicação, baseado no container Cordova e os plugins que você selecionou, vá até a aba "Build" e selecione a plataforma para qual você quer gerar um pacote instalável, dentro da seção Cordova 3.x Hybrid Mobile App Platforms".

Ambos "Crosswalk for Android" e "Android" geram APKs para dispositivos Android. Veja o guia Using the Intel XDK “Crosswalk for Android” Build Option e o Crosswalk Overview para mais detalhes.

Quando você iniciar um build, será perguntado se pretende fazer o upload para o servidor de build ("Upload to the build server?"). Normalmente você deve selecionar "Upload Code" quando esta pergunta for feita. A exceção usual a isso é quando você tiver enviado anteriormente o seu código e compilado para uma plataforma, e agora está compilando para uma segunda plataforma sem nenhuma alteração na sua aplicação entre estes dois builds. Neste caso, não há necessidade de enviar novamente o seu código para o servidor.

Um upload feito com sucesso do pacote com os fontes da sua aplicação irá resultar em uma tela similar a mostrada abaixo. Para iniciar o build, clique no botão "Build App Now". Ao contrário do sistema "legado", não existem opções associadas a este passo; suas opções são armazenadas no arquivo intelxdk.config.platform.xml. Veja o documento Adding Build Options to Your Intel® XDK Cordova App Using intelxdk.config.additions.xml para informações sobre como adicionar opções de compilação que não são acessíveis através da aba "Projects"

Os builds de iOS builds incluem uma opção para fornecer o seu certificado de desenvolvedor Apple. Este certificado está armazenado no sistema de build junto com seu id de usuário do Intel XDK; só é necessário fornecer o certificado uma vez, para todas as aplicações que você compilar com o seu login.

Quando o sistema de build completar com sucesso, você vai ver uma tela parecida com a tela abaixo. Se o sistema de build encontrar algum problema, o log de build irá incluir uma mensagem de erro indicando a natureza do problema que está impedindo o build da aplicação. Se você encontrar erros de build, visite o fórum do Intel XDK para obter ajuda (um link para o fórum pode ser encontrado no ícone (?) dentro do Intel XDK).

Um Exemplo Simples Utilizando Plugins do Cordova

As capturas de tela de um dispositivo mostradas abaixo, apresentam uma app híbrida com HTML5 sendo executada em um dispositivo Android. Esta aplicação foi compilada utilizando os plugins mostrados nas seções anteriores deste documento. Como exemplo, os plugins core do Cordova "Device,""Media,""Accelerometer" e "Compass" foram selecionados na coluna "Core Cordova Plugins" da seção "Included Plugins" na aba "Projects" e os plugins Intel XDK "Base" foi selecionado na coluna "Intel XDK Cordova Plugins" nesta mesma seção. Além disso, o plugin de terceiros "Cordova StatusBar" foi incluído usando a funcionalidade "Get Plugin from the Web".

A app gera dinamicamente uma lista de plugins disponíveis, em runtime, inspecionando uma propriedade especial JavaScript do Cordova 3.3. Os resultados são impressos em um elemento <textarea> na parte de baixo da página index.html da app.

Note que a versão do plugin "Device" do Cordova foi alterada do padrão 0.2.5 para 0.2.10. Note ainda que a versão reportada do Cordova é 3.3.0, o que bate com a versão do Cordova CLI utilizada com o sistema de build Cordova do XDK. Ao contrário do sistema "legado" de build do Intel XDK, onde todas as APIs do Intel XDK estavam disponíveis, no sistema de build do Cordova, somente as APIs associadas aos plugins do Intel XDK que foram selecionados estão presentes, neste caso, somente os métodos e propriedades que pertencem ao plugin Intel XDK "Base".

A única diferença entre as duas capturas de tela dos dispositivos mostradas acima é a visibilidade da barra de status no alto da tela. Um toque no botão "Toggle Status Bar" chama os métodos StatusBar.hide() ou StatusBar.show() do plugin StatusBar, dependendo do estado de visibilidade da barra de status, que é determinada através da propriedade StatusBar.isVisible do plugin. Se o plugin não tivesse sido incluído, estes métodos e esta propriedade não estariam disponíveis para a app, e referências a eles resultariam em erros undefined do JavaScript.

Dispositivos Reais vs Dispositivos Simulados

A captura de tela abaixo mostra a mesma app sendo executada dentro da aba "Emulate" do Intel XDK. Existem diversas diferenças notáveis, e ajuda a ilustrar algumas diferenças chave entre executar a sua app com plugin dentro do emulador (ou no App Preview ou na aba de "Debug"), e executar a app em um dispositivo real.

Lembre-se que as capturas de tela mostradas acima foram tiradas de um dispositivo real que estava executando a app compilada com o Adroid Cordova dentro do Intel XDK, na aba "Build".

O que está diferente?

  • As versões do Cordova não batem: a aba "Emulate" está usando o Cordova 3.4, enquanto a app compilada no dispositivo está usando a versão 3.3 (na prática, é uma diferença pequena).
  • O plugin "Device", core do Cordova, está usando a versão padrão (0.2.5), enquanto a app compilada está usando uma versão mais nova, que foi especificada manualmente na aba "Projects" (0.2.10).
  • O plugin de terceiros "StatusBar" não é mostrado na lista de plugins incluídos quando a app é executada no emulador. Como resultado, tocar no botão "Toggle Status Bar" não resulta em nenhuma alteração na barra de status do dispositivo emulado, pois a API StatusBar não está presente neste ambiente de execução.

Executar esta app dentro do App Preview (indiretamente através da aba "Test" ou diretamente através do menu do App Preview) ou na aba de "Debug" (que executa a app em um build de preview especial do Crosswoalk para Android) vai mostra um outro conjunto de resultados. Se você executar esta app nestes ambientes, você verá uma lista longa de plugins "core", como se você tivesse selecionado todos os plugins disponíveis na lista "Included Plugins" na aba "Projects". Isso é normal e causado pela forma com que estas aplicações de proview funcionam. Você também não vai ver quaisquer plugins de terceiros. As APIs destes plugins de terceiros não estão acessíveis de dentro destes ambientes de testes de apps.

Uma versão da app mostrada acima pode ser encontrada neste repositório do github: https://github.com/xmnboy/test-third-party-plugin.


Viewing all articles
Browse latest Browse all 669

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>