# Web Components – @govbr-ds/webcomponents

A biblioteca de Web Components do [GovBR-DS](https://gov.br/ds) é desenvolvida utilizando o [Stencil](https://stenciljs.com/), um compilador que cria Web Components (Custom Elements). O Stencil combina os melhores conceitos dos frameworks mais populares em uma ferramenta simples e eficiente. Para mais informações, visite o [site oficial do Stencil](https://stenciljs.com/).

## Demonstração 🚀

Confira nossos componentes em ação:

- [Versão 2.x](https://www.gov.br/ds/webcomponents)

## Tecnologias 💻

Este projeto utiliza as seguintes tecnologias:

1. [GovBR-DS](https://gov.br/ds/ 'GovBR-DS')
1. [Stencil](https://stenciljs.com/ 'Stencil')
1. [NX Monorepo](https://nx.dev/ 'NX Monorepo')

## O que são Web Components? ❓

Web Components são um conjunto de tecnologias que permitem criar novos elementos HTML personalizados, reutilizáveis e encapsulados para uso em páginas e aplicativos web. Baseados em padrões da web, são suportados por todos os navegadores modernos.

O diagrama abaixo ilustra os três principais componentes dos Web Components:

- **Elementos HTML personalizados**: Tags HTML definidas com JavaScript, usadas como qualquer outro elemento HTML.
- **Shadow DOM**: Um espaço de nome encapsulado para cada elemento HTML personalizado, garantindo que estilos e scripts não interfiram no restante da página.
- **Templates**: Fragmentos de HTML reutilizáveis em vários elementos.
- **Slots**: Áreas em um elemento HTML personalizado onde templates podem ser inseridos.

### Ciclo de Vida

Para entender melhor o ciclo de vida dos componentes, acesse a página [https://stenciljs.com/docs/component-lifecycle](https://stenciljs.com/docs/component-lifecycle).

## Integração com frameworks 🔗

Integrar Web Components com frameworks pode ser desafiador em algumas situações. Para facilitar, criamos bibliotecas de integração (wrappers), que encapsulam os Web Components em bibliotecas nativas de frameworks, simplificando a integração com funcionalidades como binding.

Para mais detalhes, consulte a [documentação do Stencil sobre integrações](https://stenciljs.com/docs/overview).

Vale lembrar que, em alguns casos, a integração pode não ser possível, dependendo da evolução da especificação de Web Components e do suporte dos frameworks.

## Compatibilidade de Navegadores 🌐

Esta documentação corresponde à release `>=2.0.0` do pacote `@govbr-ds/webcomponents`.

O suporte segue a política [Baseline Widely Available](https://web.dev/baseline), configurada no arquivo [`.browserslistrc`](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/.browserslistrc) e revisada a cada release. Essa política é dinâmica: não há uma versão mínima fixa válida para toda a vida do pacote. Como referência para a release atual, o alvo resolve para Chrome/Edge 121+, Firefox 122+ e Safari 17.2+; confirme a lista da release com `npx browserslist "baseline widely available"`.

Os contratos críticos são validados nos projetos automatizados de Chromium, Firefox e WebKit. Isso não equivale a declarar suporte a versões ou engines que não tenham validação automatizada.

> [!NOTE]
> Internet Explorer não é suportado. O target de compilação TypeScript é `es2020`, e o runtime requer Custom Elements, Shadow DOM e APIs DOM modernas. A aplicação consumidora continua responsável por eventuais polyfills fora do Baseline.

## Instalação 📦

Instale o pacote e os estilos base do Design System como dependências de produção:

```bash
npm install @govbr-ds/core @govbr-ds/webcomponents
# ou
yarn add @govbr-ds/core @govbr-ds/webcomponents
# ou
pnpm add @govbr-ds/core @govbr-ds/webcomponents
```

### peerDependencies

`peerDependencies` são pacotes que este pacote **não instala automaticamente** — o seu projeto precisa tê-los instalados.

**Por que existem:** O pacote depende de bibliotecas externas para posicionamento de elementos flutuantes, estilos e datas. Declará-las como peers garante que o seu app e o pacote usem a **mesma versão** dessas bibliotecas, evitando conflitos.

**O que isso implica:** Se as peers não estiverem instaladas ou forem incompatíveis, componentes como `br-datetime-picker` e `br-tooltip` podem não funcionar.

As peers declaradas neste pacote são:

| Pacote             | Versão compatível |
| ------------------ | ----------------- |
| `@govbr-ds/core`   | `>=3.6.0 <4.0.0`  |
| `@floating-ui/dom` | `>=1.7.6`         |
| `date-fns`         | `>=4.1.0`         |
| `iconify-icon`     | `3.0.2`           |

```bash
npm install @floating-ui/dom date-fns iconify-icon
# ou
pnpm add @floating-ui/dom date-fns iconify-icon
```

## Nota importante: pnpm e tree-shaking

Se ao consumir estes pacotes você notar que o bundler não está removendo código não utilizado (tree‑shaking), pode haver uma incompatibilidade com o layout padrão do pnpm.

Solução rápida (opcional, somente se precisar): crie um arquivo `.npmrc` na raiz do seu projeto com:

```properties
node-linker=hoisted
```

Por que isso ajuda: por padrão, o pnpm organiza as dependências em pastas isoladas com symlinks. Alguns bundlers/otimizadores se baseiam na estrutura de `node_modules` e no campo `sideEffects` para decidir o que pode ser eliminado. O layout hoisted aproxima o formato “achatado” (similar ao npm/yarn), facilitando essa análise e, em muitos casos, restaurando o tree‑shaking.

Observações:

- Use apenas se o tree‑shaking realmente não estiver funcionando.
- Pode aumentar o uso de disco e alterar a resolução de dependências do seu projeto.

## Uso 📚

### Passo-a-passo

Os Web Components GOVBR são elementos HTML regulares ou personalizados (Web Components). Em uma página HTML simples, podem ser usados como qualquer outro elemento.

```html
<html>
  <head>
    <script
      type="module"
      src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.esm.js"
    ></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@govbr-ds/core/dist/core-tokens.min.css" />
  </head>
  <body>
    <br-button>Clique aqui</br-button>
  </body>
</html>
```

Você pode escutar eventos padrão, como clique e mouseover, da mesma forma que faria com elementos HTML normais. Muitos componentes também emitem eventos personalizados, que recomendamos fortemente utilizar. Esses eventos funcionam como os eventos padrão, mas possuem nomes específicos. Consulte a documentação de cada componente para obter detalhes sobre os nomes e dados dos eventos.

```html
<br-button>Label</br-button>

<script>
  const button = document.querySelector('br-button')
  button.addEventListener('click', (event) => {
    console.log('Botão foi clicado', event)
  })
</script>
```

### Exemplos de uso

Disponibilizamos exemplos de como usar este projeto com diferentes tecnologias. Consulte o [nosso grupo no GitLab](https://gitlab.com/govbr-ds/bibliotecas/wc 'GovBR-DS/WC') e procure pelos projetos de 'Quickstart' para mais detalhes.

## Desenvolvimento 👨‍💻

### Scripts Disponíveis

No arquivo `package.json` e `project.json`, você encontrará diversos scripts úteis para o desenvolvimento e manutenção dos Web Components.

#### Tarefas de Build

O pacote possui diferentes níveis de build gerenciados pelo Nx. Abaixo estão os detalhes de cada tarefa:

| Tarefa | Descrição | O que gera |
| :--- | :--- | :--- |
| `build` | Tarefa principal de build para distribuição completa. | Core (`dist`), Wrappers (Angular/React/Vue), SSR (`hydrate`) e metadados (`cem`). |
| `build:dist` | Build focado na distribuição "vanilla" (puro Custom Elements). | Core (`dist`) e metadados (`cem`). Não inclui SSR/Hydrate. |
| `build:all` | Build completo de todo o ecossistema do pacote. | Tudo da tarefa `build` + Site/Playground (`www`) + Documentação técnica auto-gerada. |
| `build:hydrate` | Build específico para suporte a Server-Side Rendering (SSR). | App de hidratação em `dist/webcomponents/dist/hydrate`. |
| `build:www` | Build do playground/site de testes interno. | Pasta `www` com os componentes carregados para visualização local. |
| `build:docs` | Build de documentação técnica automática. | Gera/atualiza os arquivos `README.md` dentro da pasta de cada componente. |

#### Outros Scripts

- **`nx start webcomponents`**: Inicia o site localmente para desenvolvimento.
- **`nx run webcomponents:tests`**: Executa os testes E2E em browser mode.
- **`nx run webcomponents:lint:biome`**: Realiza a análise estática com Biome.
- **`nx run webcomponents:lint:md`**: Realiza a análise estática nos arquivos Markdown.
- **`nx run webcomponents:lint:md:fix`**: Corrige a formatação dos arquivos Markdown.
- **`nx run webcomponents:lint:styles:fix`**: Corrige a formatação dos arquivos CSS/SCSS.
- **`pnpm --dir packages/webcomponents exec vitest run --project e2e <arquivo>`**: Executa somente um teste E2E.

**Gerenciar baseline de tamanho:**

```bash
# Da raiz do monorepo:
pnpm baseline:update
pnpm baseline:compare

# Depois de um build, detalha cada JS/CSS em bruto, gzip e Brotli:
pnpm size:report
```

### Build e Documentação Autogerada

Ao gerar o `build` (ou `build:docs`) deste projeto Stencil, são automaticamente criados ou atualizados:

- O arquivo `readme.md` dentro da pasta de cada componente (contendo especificações de props, eventos, slots, etc).
- Documentações dos componentes na pasta `apps/site/docs/stencil-generated-docs`, que são consumidas pelo site oficial.

```bash
nx build webcomponents
```

## Tipagem e contratos públicos

Os tipos usados na API dos componentes são gerados a partir dos componentes Stencil e reexportados pelos wrappers Angular, React e Vue. O consumidor deve importar o tipo pelo pacote público correspondente; imports de arquivos internos não fazem parte do contrato.

### Quando um tipo fica global

`components/global.types.ts` contém apenas tipos reutilizados por dois ou mais componentes, como `BrDensity`, `BrFeedbackState`, `BrLinkTarget`, `BrNavigationMode`, `BrOrientation` e `BrProgressionType`. Eles representam vocabulário compartilhado do Design System.

Tipos específicos permanecem no diretório do componente. Por exemplo: opções e validação de `br-select`, valores e validação de `br-slider`, datas de `br-datetime-picker` e arquivos de `br-upload`. Essa organização evita transformar detalhes de implementação em API global.

Tipos de implementação, como referências de DOM e controladores internos, também ficam locais e não devem ser adicionados a `global.types.ts`. Um tipo só deve ser promovido quando for referenciado por uma propriedade, evento ou método público de mais de um componente.

`BrValidationState` permanece exportado por compatibilidade, embora não seja usado atualmente por uma API de componente. Ele não deve receber novos usos sem uma decisão de API; uma remoção fica reservada para uma versão major.

### Wrappers e geração

Os arquivos em `packages/*/stencil-generated` são artefatos gerados. Alterações de API devem começar no componente Web Component e ser refletidas pela geração dos wrappers. O job `contract_tests` do CI executa `node scripts/check-wrapper-contract.mjs` e detecta nomes antigos do `br-select` nos wrappers. Para o inventário dos scripts e seus pontos de execução, consulte o [README de scripts](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/blob/main/scripts/README.md).

Nos value accessors Angular, valores externos são tratados como `unknown` até serem validados ou convertidos pelo componente. Isso evita propagar `any` para o contrato do wrapper.

### Testes

Nossa estratégia de testes utiliza testes end-to-end (E2E) executados em navegador.

### Testes E2E (\*.e2e.tsx)

Os testes E2E rodam em browser mode com `@stencil/vitest`, usando `render()` e
`userEvent`. Cenários de viewport, regressão visual ou consultas profundas em
Shadow DOM usam a fachada tipada `createBrowserTestFixture()`.

Esse tipo de teste é fundamental para validar:

- Eventos do componente: clique, blur, change, entre outros.
- Interações do usuário: drag-drop, digitação, atalhos.
- Integrações DOM: forms, validação nativa, atributos aria-\*.
- Estilos visuais: dimensões, cores, transições.
- Shadow DOM: slots, parts, estilos encapsulados.

```typescript
import { h } from '@stencil/core'
import { describe, expect, it, render } from '@stencil/vitest'

describe('br-component', () => {
  it('deve renderizar', async () => {
    const { root } = await render(<br-component></br-component>)

    expect(root).not.toBeNull()
  })

  it('deve ter shadow root', async () => {
    const { root } = await render(<br-component></br-component>)

    expect(root).toHaveShadowRoot()
  })
})
```

Para mais informações sobre testes no Stencil, consulte a [documentação oficial](https://stenciljs.com/docs/testing-overview).

## Formatos do build 📦

A tarefa `nx build webcomponents` lê as definições de saída em [stencil.config.ts](stencil.config.ts) e gera múltiplos formatos dentro de `dist/webcomponents/dist`. Cada pasta/arquivo atende um cenário específico de consumo da biblioteca. O resumo abaixo ajuda a identificar qual artefato utilizar em cada contexto.

### Visão rápida

| Pasta/arquivo                                                  | Origem no build                                                   | Quando usar                                                                             | Observações                                                                                            |
| -------------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `cjs/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers ou runtimes que ainda resolvem CommonJS (`require`)                            | Referenciado pelo campo `main` do [package.json](package.json) e inclui `loader.cjs.js`                |
| `esm/`                                                         | `outputTargets: { type: 'dist' }`                                 | Bundlers modernos/ESBuild/Vite/Rollup com suporte a ESM e tree-shaking                  | Referenciado pelo campo `module` do `package.json`                                                     |
| `components/`                                                  | `outputTargets: { type: 'dist-custom-elements' }`                 | Importações diretas de componentes individuais, geração de *wrappers* Angular/React/Vue | Gera `.js` + `.d.ts` por componente                                                                    |
| `collection/`                                                  | `outputTargets: { type: 'dist' }` (manifest Stencil)              | Projetos Stencil que desejam consumir os componentes como dependência                   | Descrito pelos campos `collection` e `collection:main` do `package.json`                               |
| `hydrate/`                                                     | `outputTargets: { type: 'dist-hydrate-script' }`                  | SSR/pré-renderização em Node, integrações como React SSR target                         | Exporta scripts CommonJS/ESM para `@govbr-ds/webcomponents/dist/hydrate`                               |
| `loader/`                                                      | `outputTargets: { type: 'dist' }`                                 | Registro manual dos componentes em apps vanilla, integrações legadas                    | Disponibiliza `defineCustomElements()` em múltiplos formatos                                           |
| `webcomponents/`                                               | `outputTargets: { type: 'dist' }`                                 | Consumo via CDN (ex.: `<script type="module" ...>`)                                     | Contém `webcomponents.esm.js` e os chunks dinâmicos `p-*.entry.js`; os estilos vêm de `@govbr-ds/core` |
| `types/`                                                       | `generateTypeDeclarations: true` (custom elements + d.ts globais) | Autocomplete/TypeScript/IDE hints                                                       | Referenciado por `types` em `package.json`                                                             |
| `custom-elements.json` e `webcomponents.html-custom-data.json` | Derivados do compilador                                           | IntelliSense e validação em IDEs/editores                                               | VS Code utiliza via `html.customData`                                                                  |
| `index.js` / `index.cjs.js`                                    | Entradas principais do pacote                                     | Re-exportam os módulos `esm`/`cjs` e definem side-effects                               | Apontados por `module`/`main`                                                                          |

### `cjs/` – bundles CommonJS

- Contém `index.cjs.js`, `webcomponents.cjs.js` e um arquivo `*.entry.js` por componente, acompanhados dos *source maps* (`.map`).
- É resolvido sempre que o consumidor faz `require('@govbr-ds/webcomponents')` ou quando o bundler privilegia o campo `main` definido em [package.json](package.json).
- Use este formato em toolchains legadas (Node 14/16, Webpack < 4, Jest sem suporte a ESM) ou quando precisar depurar módulos CommonJS. Inclui também `loader.cjs.js`, permitindo registrar os elementos manualmente com `require('@govbr-ds/webcomponents/dist/loader')`.

### `esm/` – bundles ES Modules

- Equivalente modular do `cjs/`, com chunks otimizados (`p-*.entry.js`) e `webcomponents.esm.js`.
- É o alvo do campo `module` do pacote e atende bundlers modernos (Vite, Webpack 5+, Rollup, ESBuild) que fazem tree-shaking. Como os chunks mantêm *imports* explícitos, apenas o necessário é incluído no bundle final.
- Prefira esta saída quando o projeto já executa em módulos nativos ou quando precisa de melhor performance em builds SPA/MPA modernos.

### `components/` – `dist-custom-elements`

- Resultado do `outputTargets: { type: 'dist-custom-elements', customElementsExportBehavior: 'single-export-module' }` definido em [stencil.config.ts](stencil.config.ts).
- Cada componente possui um arquivo isolado (`br-button.js`) e o respectivo `.d.ts`. Para registrar somente um componente, importe sua função `defineCustomElement` diretamente:

  ```ts
  import { defineCustomElement as defineBrButton } from '@govbr-ds/webcomponents/dist/components/br-button.js';

  defineBrButton();
  ```

  Esse formato evita incluir o loader completo quando a aplicação usa poucos componentes.
- Esta pasta também alimenta os geradores Angular/React/Vue configurados no mesmo arquivo (`customElementsDir` aponta para `dist/components` dentro do pacote publicado). Use-a para criar *wrappers* customizados ou testar componentes isoladamente em Storybook.

### `collection/` – manifest Stencil

- Inclui `collection-manifest.json`, cópias de assets/páginas e os *proxies* de acesso (`index.js`).
- Necessário apenas para quem desenvolve outra biblioteca Stencil e deseja usar `@govbr-ds/webcomponents` como dependência, preservando metadados como slots, eventos e estilos.
- Os campos `collection` e `collection:main` no [package.json](package.json) apontam para esses arquivos para que o compilador Stencil dos consumidores encontre as definições.

### `hydrate/` – script para SSR/pré-render

- Produzido pelo target `dist-hydrate-script` e exportado como módulo CommonJS/ESM (`index.js`, `index.mjs`).
- Permite renderizar componentes em ambientes sem DOM (Node.js) e hidratar o HTML no cliente. O React SSR output target e a configuração de Vue (`hydrateModule: '@govbr-ds/webcomponents/dist/hydrate'`) dependem desta pasta.
- Utilize quando precisar pré-renderizar páginas (Next.js, Astro, custom SSR) ou ao gerar imagens/relatórios estáticos com os componentes já resolvidos.

### `loader/` – helpers para registro manual

- Disponibiliza `defineCustomElements()` e `applyPolyfills()` em diferentes formatos (`index.js`, `index.cjs.js`, `index.es2017.js`, `cdn.js`).
- Ideal para projetos vanilla ou quando o bundle principal não deve executar automaticamente o `defineCustomElements`. Você importa apenas o loader, registra os componentes no momento oportuno e mantém controle fino sobre o Custom Elements Registry.
- Use `cdn.js` em páginas HTML estáticas (por exemplo, `<script src="https://cdn.jsdelivr.net/npm/@govbr-ds/webcomponents/dist/loader/cdn.js"></script>`) quando precisa apenas do registro.

### `webcomponents/` – pacote pronto para CDN

- É a forma mais simples de consumo: `webcomponents.esm.js` + chunks `p-*.entry.js`, prontos para serem servidos via CDN.
- Recomendada para páginas estáticas, protótipos, Storybook do Design System ou integrações que não passam por bundlers. Lembre-se de importar os estilos de `@govbr-ds/core` (tokens) separadamente.
- Inclui *chunks* nomeados resolvidos dinamicamente pelo loader gerado pelo Stencil, permitindo *lazy loading* automático.

### `types/` – declarações TypeScript

- Resultado da opção `generateTypeDeclarations: true` da saída `dist-custom-elements`.
- Contém `components.d.ts` com todas as interfaces de propriedades/eventos e uma pasta `components/` com os tipos específicos. O campo `types` do `package.json` aponta para `dist/types/index.d.ts`.
- Necessário para projetos TypeScript, IDEs e também para os wrappers Angular/React/Vue, que reexportam esses tipos.

### Metadados auxiliares

- `custom-elements.json`: arquivo padrão da especificação [Custom Elements Manifest](https://github.com/webcomponents/custom-elements-manifest). Importante para ferramentas de documentação e IDEs.
- `webcomponents.html-custom-data.json`: arquivo usado pelo VS Code via `html.customData` para habilitar autocomplete e validação nos editores.
- `index.js` / `index.cjs.js`: reexportam os bundles ESM/CJS e expõem `defineCustomElements()` / `setNonce()` gerados pelo Stencil; raramente precisam ser importados diretamente.
- Documentação Markdown: gerada automaticamente em `apps/site/docs/stencil-generated-docs` via `outputTargets.docs-custom`, mas não é distribuída dentro de `dist/webcomponents`.

### Como escolher o formato correto

1. **Aplicações modernas com bundler**: instale o pacote e deixe seu bundler resolver o campo `module` → carregará `esm/` automaticamente.
2. **SSR ou pré-render**: combine `esm/` no cliente com `hydrate/` no servidor para renderização isomórfica.
3. **Integrações framework-nativas**: use os pacotes `@govbr-ds/angular|react|vue`, gerados a partir de `components/` e com tipos em `types/`.
4. **Páginas estáticas/CDN**: carregue diretamente os arquivos em `webcomponents/` e use o `loader/` se precisar controlar o registro manualmente.
5. **Toolchains legadas**: force o campo `main` e consuma `cjs/` para manter compatibilidade com CommonJS.

Manter estes contextos claros evita duplicidade de código, falta de tree-shaking ou registros repetidos de Custom Elements.

## VS Code IntelliSense

Durante o desenvolvimento de nossos Web Components, utilizamos custom elements. O VS Code, por padrão, não reconhece esses componentes, o que impede sugestões inteligentes no autocomplete. Para resolver isso, geramos um arquivo com as definições dos componentes, disponibilizado junto ao pacote npm.

Para importar no seu VS Code, adicione o seguinte campo, ajustando o caminho para o local onde o `node_modules` está armazenado no seu projeto:

```json
{
  "html.customData": ["./node_modules/@govbr-ds/webcomponents/dist/webcomponents/webcomponents.html-custom-data.json"]
}
```

## Documentações Complementares 📖

Consulte a seção sobre Web Components na nossa [Wiki](https://gov.br/ds/wiki/desenvolvimento/web-components) para obter mais informações sobre este projeto.

Para mais detalhes sobre a especificação de Web Components, recomendamos a consulta ao [MDN](https://developer.mozilla.org/pt-BR/docs/Web/Web_Components 'Web Components | MDN').

## Contribuindo 🤝

Antes de abrir um Merge Request, considere as seguintes orientações:

- Este é um projeto open-source, e contribuições são sempre bem-vindas.
- Para facilitar a aprovação da sua contribuição, utilize um título claro e explicativo no MR e siga os padrões descritos em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki').
- Deseja contribuir? Consulte o nosso guia [como contribuir](https://gov.br/ds/wiki/comunidade/contribuindo-com-o-ds/ 'Como contribuir?').

## Reportar Bugs/Problemas ou Sugestões 🐛

Caso encontre problemas ou tenha sugestões de melhorias, abra uma [issue](https://gitlab.com/govbr-ds/bibliotecas/wbc/govbr-ds-wbc/-/issues/new). Utilize o modelo apropriado e forneça o máximo de detalhes possível.

Nos comprometemos a responder a todas as issues.

## Commits 📝

Este projeto segue um padrão específico para branches e commits. Consulte a documentação em nossa [wiki](https://gov.br/ds/wiki/ 'Wiki') para entender mais sobre esses padrões.

## Precisa de ajuda? 🆘

Por favor, **não** crie issues para dúvidas gerais.

Utilize os canais abaixo para esclarecer suas dúvidas:

- Site do GovBR-DS [http://gov.br/ds](http://gov.br/ds)
- Web Components [https://gov.br/ds/webcomponents](https://gov.br/ds/webcomponents)
- Canal no Discord [https://discord.gg/U5GwPfqhUP](https://discord.gg/U5GwPfqhUP)

## Créditos 🎉

Os Web Components do [GovBR-DS](https://gov.br/ds/ 'GovBR-DS') foram desenvolvidos pelo [SERPRO](https://www.serpro.gov.br/ 'SERPRO | Serviço Federal de Processamento de Dados') em parceria com a comunidade.

