;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

Como aplicativo de transporte tem ajudado a salvar vidas na Ucrânia

15.mar.2022 - Exatamente às 5h de hoje (0h no horário de Brasília), três grandes explosões consecutivas sacudiram a cidade de Kiev,  na Ucrânia. - André Liohn
15.mar.2022 - Exatamente às 5h de hoje (0h no horário de Brasília), três grandes explosões consecutivas sacudiram a cidade de Kiev, na Ucrânia. Imagem: André Liohn

Felipe Mendes

Colaboração para Tilt, em São Paulo

15/03/2022 13h01

O aplicativo Kiev Digital era utilizado pelos cidadãos da capital ucraniana para comprar agens de ônibus, pagar estacionamentos ou até mesmo algumas contas públicas. Mas agora, o app oficial da cidade está sendo utilizado para ajudar a salvar a vida de pessoas que tentam se proteger de possíveis ataques russos.

Segundo o jornal The Guardian, o Kiev Digital foi transformado em uma ferramenta que alerta sobre ataques aéreos e direciona pessoas para abrigos antiaéreos. A mudança, que ocorreu apenas 24 horas após a Rússia começar a atacar a Ucrânia, foi realizada com a ajuda do diretor de transformações digitais do país (CDTO, na sigla em inglês) e do vice-prefeito de Kiev, Petro Olenych.

Desde então, o app já emitiu milhares de alertas, compartilhou abrigos antibombas e divulgou informações sobre como os cidadãos podem apoiar o exército ucraniano, de acordo com a reportagem. Além disso, as pessoas também receberam links para fontes oficiais de informações. Até agora, mais de 1,5 milhão de pessoas já baixaram o app.

O aplicativo Kiev Digital - Reprodução - Reprodução
Tela do aplicativo Kiev Digital
Imagem: Reprodução

"O Kyiv Digital tornou-se a ferramenta essencial para alertas e alarmes na cidade. As novidades incluem mapa de abrigos antibombas, mapa de farmácias disponíveis e de o à insulina, mapa de mercearias, mapa de pontos com água e pão grátis, pet shops, sede humanitária e muito mais", disse um porta-voz do governo em entrevista ao The Guardian.

Um dos outros pontos positivos do aplicativo, segundo fontes do jornal, é que ele também avisa quando é seguro sair, já que os ataques cessaram. "Acho ótimo que eles digam quando acabou e você pode relaxar", afirmou Denys Malakhatka, pesquisador acadêmico científico.

O aplicativo também se tornou importante para quem necessita de combustível, já que inclui um mapa com postos de gasolina em funcionamento. Esse tipo de serviço é fundamental diante da crise, já que o transporte público ficou limitado com os ataques e postos foram fechados na capital ucraniana.

Google avisa sobre ataques aéreos

O Google também lançou um sistema que alerta os cidadãos ucranianos a respeito de ataques aéreos. O aviso é enviado para dispositivos com sistema operacional Android.

"Este trabalho é complementar aos sistemas de alerta de ataques aéreos existentes no país e é baseado em alertas já entregues pelo governo ucraniano", disse a empresa em seu blog.

Reforço da internet na Ucrânia

O governo ucraniano reforçou o o ao wi-fi em toda a cidade como parte do apoio à guerra digital que vem sendo travada. Segundo o The Guardian, o serviço é oferecido em mais de 200 abrigos antiaéreos para que os links contendo informações de emergência possam ser ados.

Além disso, o wi-fi ativo ajuda os cidadãos da capital ucraniana a manter o contato com parentes. "Devemos adaptar nossos serviços e temos feito. Kiev e outras cidades ucranianas estão trabalhando de forma mais coesa e produtiva do que nunca. A razão é óbvia. Defendemos nosso país, nossas cidades, nossos moradores, nossos pais, nossos filhos e nosso futuro. Esta é a nossa casa, então vamos lutar até o fim", afirmou Petro Olenych, em comunicado.

Metrô vira abrigo

Antes do início da guerra os metrôs de Kiev eram utilizados por cerca de 1 milhão de pessoas diariamente. Agora, servem de abrigos de emergência para aproximadamente 15 mil moradores da cidade, que se deitam em plataformas e corredores quando o toque de recolher começa na cidade, às 19h.

O metrô funciona apenas em uma pista a cada 90 minutos. Os outros vagões estão estacionados para que as pessoas possam esperar os ataques ou até mesmo dormirem.