BrazilUtils 0.2

A BrazilUtils visa aumentar a qualidade e produtividade de programadores que precisem de rotinas específicas ligadas ao dia-a-dia brasileiro.

Serve para que eu e outros colegas não tenhamos que escrever cada um por sua conta rotinas para validar Inscrição Estadual, CPF/CNPJ, conversão de valores métricos, colocar valores em Real por extenso, além de outras features que vêm por aí.

Afinal, duas ou mais cabeças fazem algo melhor do que uma.

Agora eu não entendi. Então qual o seu interesse aqui? Mais uma vez, sugiro que você estude um pouco melhor a API - nem estou falando da implementação - e veja os últimos posts na primeira thread sobre a BrazilUtils. Terá respostas para muitas de suas perguntas.

A BrazilUtils visa aumentar a qualidade e produtividade de programadores que precisem de rotinas específicas ligadas ao dia-a-dia brasileiro.

Serve para que eu e outros colegas não tenhamos que escrever cada um por sua conta rotinas para validar Inscrição Estadual, CPF/CNPJ, conversão de valores métricos, colocar valores em Real por extenso, além de outras features que vêm por aí.

Afinal, duas ou mais cabeças fazem algo melhor do que uma.

Agora eu não entendi. Então qual o seu interesse aqui? [/quote]

Um subconjunto de uma API ainda é uma API…Eu estava especificamente falando da API de datas !
Como a BrazilUtils para datas seria usada na prática , exemplos de casos de uso para que eu entenda a diferença entre ela e outras API de data que existem. Uma vez que o objetivo não é inventar a roda então qual é o objetivo dessa parte da API ?
Deu para entender ?

Sim, agora ficou claro! 8)

Acontece que nós não temos um conjunto fechado e pronto de requisitos. Nós estamos aberto para solicitações de features a partir da comunidade, e entre essas funcionalidades estava algo relacionado a datas.

Mas exatamente o que relacionado a datas, isso nunca ficou claro e é por isso que não temos nada sobre isso ainda na BrazilUtils.

Damos prioridade aos requisitos que já estão bem definidos. Por exemplo, assim que eu terminar de escrever o tutorial da versão 0.1, começarei a implementar a normalização de endereços.

Essa normalização de endereços depende do Douglas. Trata-se de padronizar a forma escrita de um endereço num software. Por exemplo, quando alguém escrever “R. ERNESTO da SilvA, 168”, após a normalização o endereço poderá ficar “Rua Ernesto da Silva, 168”.

Isso é bem trabalhoso por causa da quantidade de logradouros e da imensa variedade com que são escritos, além de ter que que contar com flexibilidade de configuração - talvez alguém possa querer normalizar tudo para maiúsculas.

Se você tiver interesse em colaborar, acho que pode começar por aqui, nos ajudar nessa feature. Mas, como disse, essa funcionalidade de normalização depende do Douglas, o que equivale a dizer que ele tem o know-how sobre isso e tudo passa sobre o crivo dele.

Então a primeira coisa que temos que fazer antes de enviar código é obter maiores informações para que isso não fique dependendo demais dele e fique parado caso ele não tenha tempo de trabalhar na BrazilUtils.

Exato.Esse é o ponto. :wink:
Imagine só o tempo que se perde só procurando requisitos para essas rotinas…

Douglas, essa é pra você. Estava fazendo testes adicionais como combinado, daí encontrei um erro.

public static boolean isValid(String cpf) { String s = cpf.replaceAll("[^0-9]*", ""); if (s.length() != CPF_DIGITS) { return CpfCnpj.isValid(cpf); } return false; }

Esse modo está retornando falso quando o CPF é verdadeiro e vice-versa. Segue o código corrigido (só troquei != por ==). public static boolean isValid(String cpf) { String s = cpf.replaceAll("[^0-9]*", ""); if (s.length() == CPF_DIGITS) { return CpfCnpj.isValid(cpf); } return false; }

Aí Sérgião, o pessoal do Ohloh discorda de você!

[quote]
BrazilUtils API is written mostly in Java.

Across all Java projects on Ohloh, 35% of all source code lines are comments. For BrazilUtils API, this figure is 45%.

This high number of comments puts BrazilUtils API among the highest one-third of all Java projects on Ohloh.

A high number of comments might indicate that the code is well-documented and organized, and could be a sign of a helpful and disciplined development team.[/quote]

Sobre normalização de endereços:
1 - Qual é a lista dos Tipos de Logradouro que será adotada? tem uma que eu estava usando na versão que não fo disponibilizada que era baseada no site do correio). Essa questão parece boba mas não é. O que fazermos com tipos de logradouro de sistema legados? No meu sistema, aqui, tem “Buraco”, “Vala” e “Trincheira” entre outros :shock:. Todos aceitos pelos correios.
2 - Quais são os campos usados no endereço? Estava assim: TipoLogradouro, NomeLogradouro, Numero, Complemento, Bairro, Municipio, UF e CEP. Devemos usar País também? Mais algum?
3 - Tinha pensado em 2 classes pra fazer isso (além do endereco) Normalizador e Normalizacao. Onde um normalizador aplica uma (ou mais) normalização sobre um endereço. O Normalizador contém uma ou várias Normalizações. Assim o cliente da API pode implementar uma NormalizacaoEspecializado oumemso um NormalizadorEspecializado que já é iniciado com algumas Normalizações dentro dele. Normalizador tem add e remove pra colocar e tirar Normalizações. algu assim … :smiley:
4 - Os Tipos de Logradouro virão em um XML ou similar? A lista de municípios também? Em resumo: O que fazer com as listas?

Esses três pontos já são um bom ponto de início. Gostaria da opinião de vocês.

A Lista de logradouros está hardcoded nos fontes, mas seria interessante realmente usar xml. A ideia da normalização é boa , contudo voto a favor de usar Format como base de tudo o que seja mexer con texto. Normalização seria FormatRule ou mesmo NormalizationRule
Se vc der uma olhada no codigo verá divisão do endereço , veja tb o codigo que eu deixei antes e compare. Eu acho que deveria ter pais sim
e cep e como campos especiais, porque isso permitirá implementar um serviço de busca de endereço pro cep.

Minha opinião:

  1. Os logradouros suportados pela API devem ser os mesmo que os Correios aceitam, sem tirar nem pôr. Se acrescentarmos ou retirarmos algo, um carteiro novato pode se perder.

  2. País também, com certeza! E se algum exportador utilizar a API?

  3. Esse “algu assim” é um começo. Podemos implementar isso, testar e ver onde podemos melhorar. Acho melhor debater em cima de algo concreto. Temos que literalmente experimentar, só filosofar não vai levar a nada.

  4. XML. Vamos ter que compilar os oitocentos milhões de municípios brasileiros? :-o

[quote=RafaelRio]
4) XML. Vamos ter que compilar os oitocentos milhões de municípios brasileiros? :-o [/quote]

Não é um XML com os nomes dos lougradouros, é um XML com os tipos de logradouro.

Enquanto não ha nada concreto para discutir sobre, deixem-me so chamar a atenção para 2 pontos:

  1. Normalização de endereços é um assunto complicado. tanto que ha programas proprietários para isso. Tudo bem que façamos uma normalizaão simples, que acaba sendo quase que apenas uma formatação, mas acho que não podemos ir muito mais longe… Ou seja, descobrir a 1001 formas de escrever rua ou avenida não é tão simples quanto parece. (envolve ter um banco de dados ou vários e processá-los)
  2. Nem todos os endereços têm a mesma estrutura. E já que se falou de colocar o pais, então cada pais tem a sua estrutura. Mas mesmo apenas no brasil existem várias estrutura, por exemplo como eu separo este endereço dos campos municipio/bairro/logradouro/numero/complemento ?

Estrada Ponta Leste, Km 07
Estrada Parque ? Km 17 ? Abobral

A resposta é: não separo. Posso dizer que o logradouro é do tipo estrada e o nome e dizer que km X é o numero ou o complemento, mas não terei bairro , por exemplo. Tlv nem municipio. E numero/complemento é em quilometros ? Como eu formato isso depois ?

A API de endereços parte do principio que todos os endereços tem esse campos, mas isso não é verdade para o Brasil e muito menos para os outros paises.

A validação de CNPJ e afins é muito util realmente , mas Datas e Endereços dava uma API por si mesma. E o pior é que excepto as validações , o resto é muito susceptivel de internacilização/localização o que dificulta muito o problema.
Agora , alguém pode dizer para focar apenas no Brasil e esquecer os outros paises. Tudo bem, mas então no brasil ninguém manipula endereços/telefones/unidades de outros países ?
Acho que vcs têm que ficar conscientes do trabalho em que se vão meter se quiserem fazer algo minimamente util. Colocar municipio/bairro/logradouro/numero/complemento num bean e jogar um formatdor em cima não vai resolver o problema… afinal isso é o que todo o mundo faz porque provavelmente tem um banco com esses campos.

Então, eu acho que poderiamos fazer :

  1. API de validação de CNPJ , CPF e afins - é realmente util ter isto pronto

  2. API de manipulação de dinheiro - é simples de fazer e é util.

  3. Criptografia simples - tb util pois deve ser usado para passwords e todo o sistema que se preze te password.

  4. API de tempo - Aqui temos vários graus conforme o problema que queremos resolver ( que ainda ninguem disse qual é…)
    4.a) Uma classe que extenda Calendar e possibilite as operações isHoliday(), isWorkingDay() e isWeekend() - simples demais, mas util
    4.b) Uma classe que não herde de Calendar , mas o use internamente e possibilite as mesmas operações - simples tb , na realidade a questão está na compatibilidade deste classe
    4.c) Uma API simples para escreve datas sem hora, etc… junto com a classe de 4.b) destinando-se a facilitar o transporte de datas e tempos entre camadas com suporte para conversão para datas do java.sql algo como CalendarDate date = new CalendarDate(2007,1,1);
    java.sql.Date sqlDate = date.toSQL(); Também o suporte a intervalos de datas e horários, o que tb é simples e util.
    4.d) A API de 4.c mais um mecanismo de calcular diferença e soma de temos com e sem timezone. Tb conversão de horas entre time zones
    4.e) A API de 4.d mais facilidade de conversão entre os diversos tipos de objectos definidos.

  5. API de Quantidades/Unidades aka Métricas (cuidado que esta palavra não se usa neste como sinônimo de medida física) - Esta tb é dificil deêm uma olhada em JScience para terem uma ideia de onde pode chegar a complexidade.
    Aqui é muito importante o objectivo! Pelo que foi dito o objectivo é a conversão. Ora mas isso é exactamente o mais dificil!
    5.a) Tal como está agora o negocio seria ter uma classe para cada dimensão e métodos para converter essa dimenção entre N combinações de unidades, por exemplo: Temperature.celciusToFahrenheit() e Temperature.fahrenheitToCelcius() e Temperature.kelvinToCelcius() e
    Temperature.celciusToKelvin() e assim vai.
    5.b)Tudo bem, mas isto implica num código imenso e pouco organizado.
    Tlv seja uma boa pensar no conceito de conversor

Converter
convert (numero)
invert():Converter

Ali eu escrevi numero pq não sei em que classe colocar. double é RUIM , mas tb não sei que precisão é necessária. Suspeito, contudo, que se tratando de unidades especiais como de energia, o uso é cientfico, então tvl seja bom usar BigDecimal.
5.c) Ou criar um objeto semelhante a money que agrega um valor e uma unidade. E por falar nisso uma classe de unidade.

Com os conversores não temos que ter uma classe para cada dimensão e poderemos ter um registro central (padrão registry) para obter os conversores exemplo:

Mesure x = new Mesure(40, Unit.CELCIUS)
Converter converter = ConversionUtils.getConverter(Unit.CELCIUS , Unit.FAHRENHEIT);
Mesure y = converter.convert(x);
Mesure x = converter.invert().convert(y); // isto resultaria em x de novo

Ou
Mesure x = new Mesure(40, Unit.CELCIUS);
Mesure y = ConversionUtils.convertTo(x, Unit.FAHRENHEIT);

E poderiamos fazer
Mesure x = new Mesure(40, Unit.CELCIUS);
Mesure y = new Mesure(60, Unit.CELCIUS);

Mesure media = x.plus(y).divide(2); // 50 ºC

e
Mesure x = new Mesure(4, Unit.METER);
Mesure area = x.time(x); // 16 metros quadrados

5.d) permitir operações com unidades diferentes mas que são da mesma especie, por exemplo grama com quilo ou km com milha.

5.e) permitir conversões por translação. Por exemplo, se não tiver o conversor km -&gt milha , poderia ter km -&gt pé e pé -&gt milha , o sistema concatenaria os dois para constuir um conversor km -&gt milha (esta é bem mais avançada mas diminuir a necessidade de criar muitos conversores)

O trabalho forte é criar os conversores para os pares de unidades e registrar no ConversionUtils

  1. Sistema de endereços. Aqui o negocio é bem mais complexo. ´8E necessário definir um escopo para isto.

Proponho que se lista listagem como TODO pela ordem. Apenas os itens mais avançados de 4,5 e 6 podem ser bem complicados. o resto é simples, simples

P.S. ainda não vi comentários às classes que enviem …

[quote=sergiotaborda][quote=RafaelRio]
4) XML. Vamos ter que compilar os oitocentos milhões de municípios brasileiros? :-o [/quote]

Não é um XML com os nomes dos lougradouros, é um XML com os tipos de logradouro.
[/quote]
Não diga! :-o

Era sobre isso a que estava me referindo. Douglas, vamos ter que compilar todos os municípios brasileiros?

Sérgião, só para esclarecer alguns pontos:

Tem API’s proprietárias para geração de código de barras, e qual o problema disso? A API de código de barras da BrazilUtils está muio bem feita e será extendida.

A normalização é só para endereços brasileiros, ao menos por enquanto. O objetivo é cobrir cerca de 90% dos casos; impossível abraçar tudo.

[quote]5.b)Tudo bem, mas isto implica num código imenso e pouco organizado.
Tlv seja uma boa pensar no conceito de conversor [/quote]
Eu já tinha falado antes(tópico anterior) para não usarem/compararem com o JScience que é algo beemm mais pesado/elaborado no assunto.
Não será tão imenso assim.Eu já tô copiando a estrutura do onlineconversion, serão umas 25 classes e suas respectivas interfaces de constantes.

[quote] Suspeito, contudo, que se tratando de unidades especiais como de energia, o uso é cientfico, então tvl seja bom usar BigDecimal.
[/quote]
Nós já usamos BD, e deixamos que o usuário faça a escolha de escala.

[quote]Mesure x = new Mesure(40, Unit.CELCIUS)
Converter converter = ConversionUtils.getConverter(Unit.CELCIUS , Unit.FAHRENHEIT); [/quote]
Na verdade, se vc ver posts anteriores, jáhavíamos discutido sobre isso, e o ideal seria usar Reflection e vc só daria um KM.To(Miles), mas devemos lembrar que a base é a JDK 1.4, e há um custo para issoq ficou inferior nas versões mais recentes.

Aí tá o problema…

Aproveitando a deixa, aqui tem um cadastro nacional de municípios, pode servir para algo:
http://www.tse.gov.br/eleicoes/estatisticas/2000/estatistica/2000/municipios.txt

vc não leu no meu post anterior: no fim de semana!Se eu for ler agora, vai ser uma olhada rápida e eu posso deixar passar alguma coisa. :wink:

Depois de ler todas as mensagens do topico anterior dedicado ao BrazilUtils … (os quotes são meros lembretes)

Existe uma dúvida elementar que nasceu no principio e a meu ver não está resolvida. A API é um canivete suiço que pretende ser genérica mas não muito além do brasil. Esta frase contem diverssos problemas de definição de escopo. Se a api é para ser apenas brasileira não faz sentido nomes em ingles nem preocupações com localização nem nada dessas coisas que complicam o design. Se ele é para ter um nucleo universal que se estende em alguns pontos, em particular, para o brasil ai ha que rever o proprio nome da API
Se a API é brasileira o javadoc deve ser em portugues, se a API não é brasileira tem que ser em ingles e com ouro nome pois não é mais BrazilUtils se é para programdores de quaalquer pais usarem.
Esta indefinição é extremamente confusa e irrirante.

Li vários comentários sobre outros programaodres de outros paises usarem a API. Otimo, então deixemos eles entenderem a API e coloquemos um nucleo universal. Se não fizermos isso não ha como ninguem fora daqui ter sequer a ideia de usar esta api.
uma frase que achei interessante foi

como se “metricas brasileiras” existisse. Existem unidades usadas mais em alguns paises e menos nos outros e são TANTAS que foi preciso convencionar quais usar. O Sistema Internacional de Undades que é o padrão oficial do Brasil , tb é de muitos outros paises. A forma como a API de unidades está desenhada nunca irá contemplar todas as possibilidades. Por isso, 1) desiste-se e quem quiser use o JScience 2) Implementa-se o ultra-mega-muit-básico, que de tão básico é inutil 3) ou leva-se a feature a sério!!
Eu acho que se não for a sério, é melhor abolir de vez. Tal como está é muito ingénuo.

Da forma como ele está desenhado eu tenho ideia que o tamanho do pacote de métricas será … imensurável. E isso so significa uma coisa: ninguem vai usar.

Data por extenso - alguem sugeriu - que tal usar DateFormat … ora utilidade é uma coisa desconhecimento da API padrão é outra.

CpfCnpj !? o que diabo é isso ? : Um objeto que é simultamente um e outro ? é como ter um objecto HomemMulher
A API está cheia de nomes ruins como este, confusos pq que não são claros (não respeitam o principio numero de OO : espelhar a realidade)
Que tal CP com duas filhas CPF e CNPJ ? Mas tem outros exemplos…

[quote]
-Vou imprimir esse tópico inteiro pra aprender mais sobre desenvolvimento de software
(…)

  • (…) so fuja do codigo do (…), a menos que vc queira aprender por exemplo reverso

[quote]

Não sei o que vcs fazem na vida , mas segundo as opiniões não é programar… Eu espero que o esforço para desenvolver a API seja sério.

Será uma biblioteca de validação SIM! e tem que tem que se propor uma arquitectura SIM! Não ha casa sem arquitetura - tb não ha software, especialmente bibliotecas de uso generico.
Arriscado ? Quer dizer que depois de todo o tempo usado para criar a API ela não vai ser usada nunca pq os seus projetistas não tiveram coragem para arriscar ser mais generalistas e menos preocupados com o seu umbigo brasileiro ? Se é isso digam agora, porque em uma semana de texto ainda não vi nenhuma conversa.

[quote] A API é um canivete suiço que pretende ser genérica mas não muito além do brasil. Esta frase contem diverssos problemas de definição de escopo. Se a api é para ser apenas brasileira não faz sentido nomes em ingles nem preocupações com localização nem nada dessas coisas que complicam o design. Se ele é para ter um nucleo universal que se estende em alguns pontos, em particular, para o brasil ai ha que rever o proprio nome da API
Se a API é brasileira o javadoc deve ser em portugues, se a API não é brasileira tem que ser em ingles e com ouro nome pois não é mais BrazilUtils se é para programdores de quaalquer pais usarem.
[/quote]
Aí eu discordo violentamente de vc.Até email de americano perguntando sobre a API eu recebi.O “foco” será o Brasil, mas utilidades gerais como códigos de barras, e outros são universais.BrazilUtils é um nome para focar a API, não diz que a API é inteiramente brasileira.Vc sabe como os EUA se referem ao próprio país?“America”.Peraí, “America” não é a do Sul,Do Norte e a Central???Um pouco de autoestima é legal nessa hora.E qualquer API java que será mexida por alguém que não esteja restrito a uma empresa específica, tem que ter javadoc em inglês.Isso não muda.O seu compilador traduz if para se???
O escopo da API é: canivete-suiço.Principalmente problemas de programadores brasileiros.

[quote]
2) Implementa-se o ultra-mega-muit-básico, que de tão básico é inutil 3) ou leva-se a feature a sério!! [/quote]
Aí vc cai naquilo que eu lhe falei antes.É inútil?(??)O americano queria uma coisa mastigada de métricas,simples, mas não o JScience(q tá beem mais maduro agora). :wink:

Isso é uma gambiarra e se vc leu realmente o tópico todo vc já sabe o porquê: porque irá mudar.Talvez até a forma de cálculo(nacionalmente).
O meu erro foi não por “beta” no jar… o pessoal cobrava tanto um release, que lançamos e deixamos de acertar uns detalhes.

Sérgião, é a terceira vez que digo para você estudar a API e o tópico anterior. Ou seria a quarta? Já perdi a conta.

Esse comentário, entre outros, mostra que você não fez o dever de casa. Isso já foi discutido, inclusive fui eu o primeiro a criticar essa classe CpfCnpj.

No primeiro tópico da BrazilUtils tem uma reimplementação dessa API que eu fiz, eliminando a CpfCnpj, entre outras mudanças. O Douglas explicou o porquê da existência da CpfCnpj, e pela enésima vez: essa API está sujeita a mudanças.

Errado! Um exportador brasileiro de softwares para - exemplo - Japão, gostaria muito de ter em suas mãos uma JapanUtils toda comentada em inglês.

Sérgio, isso aqui é um trabalho voluntário e estamos fazendo o melhor que podemos no tempo que dispomos. Não estamos preocupados em fazer algo perfeito, mas sim algo útil e concreto. Não adianta filosofar, filosofar, filosofar e filosofar e não criar nada.

Você não viu meus comentários porque eles seriam um pouquinho rudes. Do tipo: legal que você está contribuindo com código, mas não acha que deveria primeiro entender o que acontece para depois implementar algo?

Sinceramente, minha paciência com seus questionamentos se esgotou. Se tiver uma duvida, traga algo novo, ou então procure direito nos tópicos passados.

Com todo amor, respeito e carinho :lol:
Rafael Fiume.

O erro foi não deixar claro quais foram as features que saíram na versão 0.1, como havia comentado antes.

E a API de validação CPF/CNPJ deveria ter sido lançada num .jar diferente, já que é a única que foi lançada e está sujeita a mudanças.

Caboblinho está vendo o código no CVS e achando que a BrazilUtils 0.1 é aquilo ali. Tudo coisa que já conversamos, então vamos melhorar o processo de lançamento para a versão 0.2.

Em anexo o aport desta semana. Deixarei outros post com um mini tutorial de cda feature mas eis as novas features implementadas

[list]
CryptoUtil
Money
Interval
Datas - primeira fase
[/list]

Sérgio, eu t^lendo aquele código anterior que vc postou agora.
Ponha as features q vc fez concentradas num único tópico!!!Abrir muitos tópicos deixa o pessoal perdido!
Ah, o pack de métricas que tá naquele exemplo do CVS não tem NADA a ver com o que foi comitado.Aquele é muuuito antigo…“BrazilianMetrics”, eu desisti disso na primeira palavrinha do cv :shock:

Depois eu posto minhas considerações sobre o seu código!

[quote=Ironlynx]Sérgio, eu t^lendo aquele código anterior que vc postou agora.
Ponha as features q vc fez concentradas num único tópico!!!Abrir muitos tópicos deixa o pessoal perdido!
[/quote]

Eu já coloquei neste topico faz dias… o que está em topicos separados é o uso das features.

Como assim, o codigo no java.net não é o codigo actual ? Então qual é , e como eu o obtenho ?

[quote] duvida é a seguite : não sei até que ponto a API deve ficar amarrada a consideracoes apenas brasileiras. Parece-me que sendo uma API de localização de aplicações ela tem que ser especifica, mas isso não significa que não se possam deixar ganchos para facilitar o trabalho de extençao e mesmo a compreencao da API. Com vista isto introduzi dois conceitos o t
de Unidade Territorial (TU) e o pais (Country)
TU tem dois atributos : codigo do pais e codigo de TU que seria o codigo da ISO 3166-2 , que no caso do brasil são as siglas dos estados.
FIz a UF herdar de TU por uma questão para que de certa forma se possa ser compativel com a ISO e ao mesmo tempo poder diferenciar explicitamente as UF . A UF tem um nome em protugues que a TU não tem ( e não teria como ter) . A classe Brazil que falei antes é um Country. e as UF são TU. [/quote]
Lendo seu tópico e seu código, acho que não é bem por aí…
Talvez seja melhor colocarmos um BR no package para identificar que a feature é brasileira.O mundo é muito distinto, e colocar cada agregação de estado como TU(Eu preferiria q nesse caso fosse por extenso para poder dizer que cada UF é uma UnidadeTerritorial).O Brasil nem é uma federação autêntica(apesar do República Federativa do Brasil…)

Mas eu gostei da parte do Address.Country fica beeem organizado para dizer que uma feature é “daquele” país. :smiley:

O verdadeiro pack de métricas é beem mais simples que aquele(tá no anexo).É só Interface-Implementação.Não foi feito para ser sofisticado.O exemplo é o onlineconversion.

Quando me mandar um código do CVS, diga em quais packages vc mexeu se não o tio Iron fica perdido…Imagina com mais de 1MB de source! :shock: