Skip to content

Criar validações para o elemento <supplementary-material> #1111

@Rossi-Luciano

Description

@Rossi-Luciano

Objetivo

Implementar validações para o elemento <supplementary-material> e a seção <sec sec-type="supplementary-material"> conforme a especificação SPS 1.10, aumentando a conformidade de X% para 70% (7 de 10 regras).

Nota: Algumas validações para <supplementary-material> podem já estar parcialmente implementadas no repositório. Este Issue visa reavaliar, complementar e garantir cobertura completa das regras SPS 1.10.


Contexto

Material suplementar corresponde a todo conteúdo enviado separadamente do PDF do documento que complementa o trabalho publicado. No XML, deve ser representado por uma seção <sec sec-type="supplementary-material"> contendo elementos <supplementary-material> individuais. Validações corretas garantem presença de elementos obrigatórios, estrutura adequada, e conformidade com recomendações PMC/JATS.

Conformidade atual: X de 10 regras implementadas (X%)
Meta após implementação: 7 de 10 regras (70%)


Documentação SPS

Referência oficial: https://docs.google.com/document/d/1GTv4Inc2LS_AXY-ToHT3HmO66UT0VAHWJNOIqzBNSgA/edit?tab=t.0#heading=h.supplementarymaterial

Regras principais conforme SPS 1.10:

  1. Ocorrência:

    • <supplementary-material> pode aparecer zero ou mais vezes em <sec> e <article-meta>
    • <sec sec-type="supplementary-material"> deve ser a última seção de <body> ou aparecer em <back>
  2. Atributos obrigatórios:

    • @sec-type="supplementary-material" em <sec> (obrigatório)
    • @id em <supplementary-material> (obrigatório)
    • Atributos em <media>: @id, @mime-type, @mime-subtype, @xlink:href (obrigatórios)
    • Atributo em <graphic>: @xlink:href (obrigatório)
  3. Elementos obrigatórios:

    • <sec sec-type="supplementary-material"> requer <title> (obrigatório)
    • <supplementary-material> requer <label> (obrigatório)
  4. Estrutura:

    • Seção <sec sec-type="supplementary-material"> como container
    • Um elemento <supplementary-material> para cada item suplementar
    • Dentro de <supplementary-material>:
      • <graphic> para figuras
      • <media> para outros tipos (PDF, Word, Excel, vídeo, etc.)
  5. Elementos opcionais:

    • <caption> com <title> (opcional em <supplementary-material>)
  6. Restrições:

    • Proibido: uso de <inline-supplementary-material>
  7. Regras de links externos:

    • Links externos não dispensam envio do arquivo no pacote
    • Arquivo deve estar no pacote e marcado como <supplementary-material>
    • Link pode ser mantido como <ext-link> adicional no texto
  8. Distinções importantes:

    • Dataset: não é material suplementar → Declaração de Disponibilidade de Dados
    • Conteúdo no PDF: não é material suplementar → marcar com elemento semântico apropriado
    • Apêndice/Anexo: usar <app-group> e <app>, não material suplementar

Regras a Implementar

P0 – Críticas (implementar obrigatoriamente)

# Regra Nível Descrição
1 Validar presença de @id em <supplementary-material> CRITICAL O atributo @id é obrigatório em <supplementary-material>
2 Validar presença de <label> em <supplementary-material> CRITICAL O elemento <label> é obrigatório em cada <supplementary-material>
3 Validar presença de <title> em <sec sec-type="supplementary-material"> CRITICAL O elemento <title> é obrigatório em <sec sec-type="supplementary-material">
4 Validar ausência de <inline-supplementary-material> ERROR O uso de <inline-supplementary-material> não é permitido

P1 – Importantes (implementar se possível)

# Regra Nível Descrição
5 Validar presença de conteúdo (<graphic> ou <media>) WARNING <supplementary-material> deve conter <graphic> (para figuras) ou <media> (para outros tipos)
6 Validar presença de <sec sec-type="supplementary-material"> quando há <supplementary-material> WARNING Materiais suplementares devem estar dentro de <sec sec-type="supplementary-material">
7 Validar unicidade de @id em <supplementary-material> ERROR Cada <supplementary-material> deve ter um @id único

P2 – Futuras (fora do escopo deste Issue)

# Regra Motivo de exclusão
8 Validar que arquivo existe no pacote Alta complexidade - requer acesso ao sistema de arquivos
9 Validar posicionamento (última seção de body ou em back) Média complexidade - requer análise de ordem de elementos irmãos
10 Validar que conteúdo não é dataset Alta complexidade - requer análise semântica de conteúdo

Arquivos a Criar/Modificar

Avaliar existentes (podem ter validações parciais):

  • packtools/sps/models/supplementary_material.py ou similar – Verificar se modelo existe
  • packtools/sps/validation/supplementary_material.py – Verificar validações existentes
  • packtools/sps/validation/rules/supplementary_material_rules.json ou similar – Verificar configuração

Criar (se não existirem):

  • packtools/sps/models/supplementary_material.py – Modelo de extração de dados
  • packtools/sps/validation/supplementary_material.py – Validações
  • packtools/sps/validation/rules/supplementary_material_rules.json – Configuração de níveis de erro
  • tests/sps/validation/test_supplementary_material.py – Testes unitários

Referenciar (implementações similares):

  • packtools/sps/validation/sec.py – Validação de seções (já deve existir ou foi criado)
  • packtools/sps/validation/graphic.py – Validação de graphic
  • packtools/sps/validation/media.py – Validação de media
  • packtools/sps/validation/utils.py – Funções auxiliares (build_response)

Exemplos de XML

XML Válido (deve passar sem erros):

<!-- Exemplo 1: Múltiplos materiais suplementares -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <caption>
                <title>Video 1</title>
            </caption>
            <media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="1234-5678-scie-58-e1043-m1.mp4"/>
        </supplementary-material>
        <supplementary-material id="suppl2">
            <label>Supplementary material 2</label>
            <caption>
                <title>Figure 1</title>
            </caption>
            <graphic xlink:href="1234-5678-scie-58-e1043-gf3.jpg"/>
        </supplementary-material>
        <supplementary-material id="suppl3">
            <label>Supplementary material 3</label>
            <caption>
                <title>Spreadsheet 1</title>
            </caption>
            <media id="m3" mimetype="application" mime-subtype="xlsx" xlink:href="1234-5678-scie-58-e1043-md2.xlsx"/>
        </supplementary-material>
        <supplementary-material id="suppl4">
            <label>Supplementary material 4</label>
            <media id="m4" mimetype="application" mime-subtype="pdf" xlink:href="1234-5678-scie-58-e1043-md3.pdf"/>
        </supplementary-material>
    </sec>
</body>

<!-- Exemplo 2: Material suplementar com URL e arquivo no pacote -->
<back>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Material</title>
        <p>Supplementary information are available at <ext-link ext-link-type="uri" xlink:href="https://www.scielo.br/">https://www.scielo.br/</ext-link></p>
        <supplementary-material id="suppl1">
            <label>Supplementary PDF</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="1234-5678-scie-58-e1043-md1.pdf"/>
        </supplementary-material>
    </sec>
</back>

<!-- Exemplo 3: Material suplementar mínimo -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

<!-- Exemplo 4: Figura como material suplementar -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Figures</title>
        <supplementary-material id="suppl1">
            <label>Figure S1</label>
            <caption>
                <title>Additional experimental results</title>
            </caption>
            <graphic xlink:href="figure-s1.jpg"/>
        </supplementary-material>
    </sec>
</body>

<!-- Exemplo 5: Vídeo como material suplementar -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Videos</title>
        <supplementary-material id="suppl1">
            <label>Video S1</label>
            <caption>
                <title>Time-lapse experiment</title>
            </caption>
            <media id="m1" mimetype="video" mime-subtype="mp4" xlink:href="video-s1.mp4"/>
        </supplementary-material>
    </sec>
</body>

<!-- Exemplo 6: Planilha Excel como material suplementar -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Data</title>
        <supplementary-material id="suppl1">
            <label>Table S1</label>
            <caption>
                <title>Raw data</title>
            </caption>
            <media id="m1" mimetype="application" mime-subtype="xlsx" xlink:href="data.xlsx"/>
        </supplementary-material>
    </sec>
</body>

<!-- Exemplo 7: Documento Word como material suplementar -->
<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>Document S1</label>
            <media id="m1" mimetype="application" mime-subtype="docx" xlink:href="methods.docx"/>
        </supplementary-material>
    </sec>
</body>

XML Inválido – Caso 1: Sem @id em (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material>
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Atributo @id é obrigatório em <supplementary-material>

XML Inválido – Caso 2: Sem em (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Elemento <label> é obrigatório em <supplementary-material>

XML Inválido – Caso 3: Sem <title> em (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Elemento <title> é obrigatório em <sec sec-type="supplementary-material">

XML Inválido – Caso 4: Uso de (ERROR)

<body>
    <p>See <inline-supplementary-material id="is1">supplementary data</inline-supplementary-material> for details.</p>
</body>

Erro esperado: O uso de <inline-supplementary-material> não é permitido

XML Inválido – Caso 5: Sem nem (WARNING)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <p>Some text content.</p>
        </supplementary-material>
    </sec>
</body>

Erro esperado: (WARNING) <supplementary-material> deve conter <graphic> (para figuras) ou <media> (para outros tipos de conteúdo)

XML Inválido – Caso 6: fora de seção apropriada (WARNING)

<body>
    <sec>
        <title>Results</title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: (WARNING) <supplementary-material> deve estar dentro de <sec sec-type="supplementary-material">

XML Inválido – Caso 7: IDs duplicados (ERROR)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="file1.pdf"/>
        </supplementary-material>
        <supplementary-material id="suppl1">
            <label>Supplementary material 2</label>
            <media id="m2" mimetype="application" mime-subtype="pdf" xlink:href="file2.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Valor de @id duplicado em <supplementary-material>: "suppl1" (aparece 2 vezes)

XML Inválido – Caso 8: @id vazio (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Atributo @id não pode estar vazio

XML Inválido – Caso 9: vazio (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label></label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Elemento <label> não pode estar vazio

XML Inválido – Caso 10: apenas espaços (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
            <label>   </label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Elemento <label> não pode conter apenas espaços

XML Inválido – Caso 11: <title> vazio em seção (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title></title>
        <supplementary-material id="suppl1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Elemento <title> não pode estar vazio

XML Inválido – Caso 12: completamente vazio (CRITICAL)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="suppl1">
        </supplementary-material>
    </sec>
</body>

Erro esperado: <supplementary-material> está vazio. Deve conter pelo menos <label> e conteúdo (<graphic> ou <media>)

XML Inválido – Caso 13: Múltiplos (ERROR)

<body>
    <p>See <inline-supplementary-material id="is1">data 1</inline-supplementary-material> and <inline-supplementary-material id="is2">data 2</inline-supplementary-material>.</p>
</body>

Erro esperado: O uso de <inline-supplementary-material> não é permitido (encontrados 2 elementos)

XML Inválido – Caso 14: em article-meta sem seção (OK mas WARNING)

<article-meta>
    <supplementary-material id="suppl1">
        <label>Supplementary material 1</label>
        <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="supplement.pdf"/>
    </supplementary-material>
</article-meta>

Erro esperado: (WARNING) <supplementary-material> em <article-meta> deve estar acompanhado de <sec sec-type="supplementary-material"> em <body> ou <back>

XML Inválido – Caso 15: Três IDs duplicados (ERROR)

<body>
    <sec sec-type="supplementary-material" id="sec1">
        <title>Supplementary Materials</title>
        <supplementary-material id="S1">
            <label>Supplementary material 1</label>
            <media id="m1" mimetype="application" mime-subtype="pdf" xlink:href="file1.pdf"/>
        </supplementary-material>
        <supplementary-material id="S1">
            <label>Supplementary material 2</label>
            <media id="m2" mimetype="application" mime-subtype="pdf" xlink:href="file2.pdf"/>
        </supplementary-material>
        <supplementary-material id="S2">
            <label>Supplementary material 3</label>
            <media id="m3" mimetype="application" mime-subtype="pdf" xlink:href="file3.pdf"/>
        </supplementary-material>
    </sec>
</body>

Erro esperado: Valor de @id duplicado em <supplementary-material>: "S1" (aparece 2 vezes)


Padrão de Implementação

Diretrizes Gerais:

  1. Seguir padrões existentes no repositório:

    • Consultar implementações similares como sec.py, graphic.py, media.py
    • Usar estrutura de classes já estabelecida no packtools
    • IMPORTANTE: Verificar se já existem validações parciais para <supplementary-material> e integrá-las ou complementá-las
  2. Internacionalização (i18n):

    • OBRIGATÓRIO: Todas as mensagens devem suportar internacionalização
    • Usar advice_text e advice_params em build_response()
    • Consultar conversas anteriores sobre implementação de i18n no packtools
    • Referência: validações em article_contribs.py que já implementam i18n completo
  3. Validações condicionais:

    • Validações que dependem de contexto devem retornar None quando não aplicável
    • Exemplo: validação de conteúdo só se aplica se <supplementary-material> existir
    • Exemplo: validação de seção só se aplica se há <supplementary-material>
    • Usar filter_results() nos testes para remover None
  4. Uso de build_response():

    • Sempre usar parent=self.data (dict completo, nunca string)
    • Campo response deve conter: "OK", "WARNING", "ERROR", "CRITICAL"
    • Sempre fornecer advice_text e advice_params para i18n
  5. Modelo de dados:

    • Criar propriedade que retorna lista de dicionários (um para cada <supplementary-material>)
    • Cada dict deve conter: id, has_label, label_text, has_graphic, has_media, has_caption, parent_section_type, parent, parent_id, parent_lang
  6. Validação de presença de conteúdo:

    • Verificar presença de <graphic> usando XPath ou .find()
    • Verificar presença de <media> usando XPath ou .find()
    • Pelo menos um deve estar presente (WARNING)
  7. Validação de seção:

    • Verificar se <supplementary-material> está dentro de <sec sec-type="supplementary-material">
    • Verificar se seção tem <title>
    • Usar navegação de ancestrais ou XPath
  8. Validação de inline-supplementary-material:

    • Buscar elementos <inline-supplementary-material> em todo o documento
    • Reportar ERROR se qualquer um for encontrado
  9. Validação de unicidade de IDs:

    • Coletar todos os valores de @id em <supplementary-material>
    • Detectar duplicatas usando set ou Counter
    • Reportar quais IDs estão duplicados
  10. Validação de texto vazio:

    • Usar .strip() para verificar se <label> e <title> têm conteúdo real
    • Strings com apenas espaços devem ser consideradas inválidas

Testes Esperados

Casos de teste obrigatórios:

Atributo @id:

  • <supplementary-material> com @id (OK)
  • Sem @id (CRITICAL)
  • @id vazio (CRITICAL)
  • @id apenas espaços (CRITICAL)

Elemento :

  • <supplementary-material> com <label> (OK)
  • Sem <label> (CRITICAL)
  • <label> vazio (CRITICAL)
  • <label> apenas espaços (CRITICAL)
  • <label> com conteúdo válido (OK)

Seção :

  • Seção com <title> (OK)
  • Seção sem <title> (CRITICAL)
  • <title> vazio (CRITICAL)
  • <title> apenas espaços (CRITICAL)

Elemento :

  • Documento sem <inline-supplementary-material> (OK)
  • Documento com um <inline-supplementary-material> (ERROR)
  • Documento com múltiplos <inline-supplementary-material> (ERROR)

Conteúdo ( ou ):

  • Com <graphic> (OK)
  • Com <media> (OK)
  • Com ambos <graphic> e <media> (OK)
  • Sem <graphic> nem <media> (WARNING)

Contexto de seção:

  • <supplementary-material> dentro de <sec sec-type="supplementary-material"> (OK)
  • <supplementary-material> fora de seção apropriada (WARNING)
  • <supplementary-material> em <article-meta> (OK - permitido)

Unicidade de @id:

  • Um <supplementary-material> com ID único (OK)
  • Dois <supplementary-material> com IDs diferentes (OK)
  • Dois <supplementary-material> com mesmo ID (ERROR)
  • Três ou mais com IDs duplicados (ERROR)

Elemento :

  • Com <caption> (OK - opcional)
  • Sem <caption> (OK - opcional)
  • <caption> com <title> (OK)
  • <caption> vazio (OK - não obrigatório)

Tipos de conteúdo:

  • Vídeo (mp4) (OK)
  • PDF (OK)
  • Excel (xlsx) (OK)
  • Word (docx) (OK)
  • Figura (graphic) (OK)
  • Múltiplos arquivos diferentes (OK)

Múltiplos materiais:

  • Documento sem <supplementary-material> (OK - zero ou mais)
  • Documento com um <supplementary-material> (OK)
  • Documento com dois <supplementary-material> (OK)
  • Documento com múltiplos <supplementary-material> (OK)

Contextos diferentes:

  • Em <body> (OK)
  • Em <back> (OK)
  • Em <article-meta> (OK mas WARNING se sem seção)

Casos de borda:

  • <supplementary-material> vazio (CRITICAL - falta label e conteúdo)
  • Seção vazia (CRITICAL - falta title)
  • @id com caracteres especiais (OK)
  • <label> com formatação (OK)
  • Link externo com <ext-link> na seção (OK)

Total esperado: ~50 testes unitários

Estrutura de testes:

  • Usar filter_results() para remover None dos resultados
  • Asserções devem usar campo response (não is_valid)
  • Testes devem ser autocontidos e descritivos
  • Agrupar testes por categoria (id, label, title, inline, conteúdo, seção, unicidade)

Critérios de Aceite

O PR será aceito quando:

  • Verificação de validações existentes: Código existente para <supplementary-material> foi analisado e integrado ou substituído adequadamente
  • Todas as regras P0 implementadas (4 validações CRITICAL/ERROR)
  • Todas as regras P1 implementadas (3 validações WARNING/ERROR)
  • Testes unitários passando com cobertura mínima de ~50 casos
  • Nenhum teste existente quebrado
  • Arquivo supplementary_material_rules.json criado com todos os níveis de erro
  • Internacionalização completa em todas as mensagens (i18n obrigatório)
  • Código seguindo padrões do packtools (build_response, filter_results, validações condicionais)
  • Modelo de dados criado com extração adequada de todos os elementos
  • Validação de atributo @id obrigatório funcionando
  • Validação de elemento <label> obrigatório funcionando
  • Validação de <title> em seção funcionando
  • Validação de ausência de <inline-supplementary-material> funcionando
  • Validação de presença de conteúdo (<graphic> ou <media>) funcionando
  • Validação de contexto de seção funcionando
  • Validação de unicidade de IDs funcionando
  • Documentação inline clara (docstrings)

Referências

Documentação SPS:

Padrões JATS:

Padrões externos:

Referências internas packtools:

  • Internacionalização: Consultar conversas anteriores sobre implementação de i18n
  • Implementações similares: sec.py, graphic.py, media.py
  • Funções auxiliares: utils.py (build_response)

Labels Sugeridas

enhancement validation SPS-1.10 good-first-issue


Impacto Esperado

Antes:

  • Conformidade SPS 1.10 para <supplementary-material>: X% (verificar validações existentes)
  • Atributo @id pode estar ausente
  • Elemento <label> pode estar ausente
  • <title> pode estar ausente em seções
  • Uso incorreto de <inline-supplementary-material> pode passar
  • Materiais suplementares podem estar sem conteúdo
  • IDs duplicados podem não ser detectados
  • Materiais podem estar fora de seção apropriada

Depois:

  • Conformidade SPS 1.10 para <supplementary-material>: 70% (7 de 10 regras)
  • Validação CRITICAL de @id obrigatório
  • Validação CRITICAL de <label> obrigatório
  • Validação CRITICAL de <title> em seção
  • Validação ERROR de uso proibido de <inline-supplementary-material>
  • Validação WARNING de presença de conteúdo
  • Validação WARNING de contexto de seção
  • Validação ERROR de unicidade de IDs
  • ~50 testes unitários garantindo qualidade
  • Internacionalização completa (PT/EN/ES)

Benefícios:

  • Melhora a qualidade dos XMLs SciELO
  • Garante estrutura adequada de materiais suplementares
  • Detecta ausência de elementos obrigatórios antes da publicação
  • Previne uso de elementos não permitidos (inline-supplementary-material)
  • Assegura identificação adequada (id e label)
  • Promove organização adequada em seções
  • Facilita processamento automatizado de materiais suplementares
  • Garante conformidade com recomendações PMC/JATS
  • Melhora acessibilidade e descoberta de materiais suplementares
  • Facilita manutenção e depuração de XMLs

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions