refactor: redesign main action grid to 3x2 layout and update related UI components and icons
|
Before Width: | Height: | Size: 996 B After Width: | Height: | Size: 11 KiB |
@@ -1,13 +1,97 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
width="48"
|
||||
height="48"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="xml.svg"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="16.8125"
|
||||
inkscape:cx="23.97026"
|
||||
inkscape:cy="24"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<!-- Folha de documento com dobra -->
|
||||
<path d="M 8 4 L 32 4 L 42 14 L 42 44 L 8 44 Z" fill="#ffffff" stroke="#0288d1" stroke-width="2.5" stroke-linejoin="round"/>
|
||||
<path
|
||||
d="M 8 4 L 32 4 L 42 14 L 42 44 L 8 44 Z"
|
||||
fill="#ffffff"
|
||||
stroke="#0288d1"
|
||||
stroke-width="2.5"
|
||||
stroke-linejoin="round"
|
||||
id="path1" />
|
||||
<!-- Dobra de canto -->
|
||||
<path d="M 32 4 L 32 14 L 42 14 Z" fill="#b3e5fc" stroke="#0288d1" stroke-width="2" stroke-linejoin="round"/>
|
||||
<path
|
||||
d="M 32 4 L 32 14 L 42 14 Z"
|
||||
fill="#b3e5fc"
|
||||
stroke="#0288d1"
|
||||
stroke-width="2"
|
||||
stroke-linejoin="round"
|
||||
id="path2" />
|
||||
<!-- Linhas de texto representativas -->
|
||||
<line x1="14" y1="20" x2="28" y2="20" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="14" y1="25" x2="36" y2="25" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="14" y1="30" x2="36" y2="30" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="17.20446"
|
||||
x2="26.299999"
|
||||
y2="17.20446"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line2" />
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="20.747211"
|
||||
x2="34.299999"
|
||||
y2="20.747211"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line3" />
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="24.289963"
|
||||
x2="34.299999"
|
||||
y2="24.289963"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line4" />
|
||||
<!-- Etiqueta azul com sigla XML -->
|
||||
<rect x="10" y="33" width="28" height="11" rx="3" fill="#0288d1"/>
|
||||
<text x="24" y="41.5" font-family="Segoe UI, Arial, sans-serif" font-size="8" font-weight="bold" fill="#ffffff" text-anchor="middle"><XML></text>
|
||||
<rect
|
||||
x="11.3"
|
||||
y="30.799257"
|
||||
width="28"
|
||||
height="11"
|
||||
rx="3"
|
||||
fill="#0288d1"
|
||||
id="rect4" />
|
||||
<text
|
||||
x="25.296093"
|
||||
y="39.100037"
|
||||
font-family="'Segoe UI', Arial, sans-serif"
|
||||
font-size="8px"
|
||||
font-weight="bold"
|
||||
fill="#ffffff"
|
||||
text-anchor="middle"
|
||||
id="text4"><XML></text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 998 B After Width: | Height: | Size: 2.3 KiB |
@@ -35,7 +35,7 @@ O módulo de núcleo é totalmente independente de JavaFX ou bibliotecas visuais
|
||||
|
||||
### 1.2 Módulo `cybercore-ui` (Apresentação JavaFX)
|
||||
Responsável por toda a interação com o usuário:
|
||||
* **Interface Principal (`MainAppView`):** Painel de navegação moderno com alternador dinâmico de tema (Claro/Escuro), grade 3x3 de operações rápidas (PDF, XML, Arquivo Genérico, Assinatura em Lote, Assinatura Atachada, Co-Assinatura, Carimbo de Tempo, Designer de Selos, Validador) e coluna lateral de utilitários (Logs em tempo real, Configurações e Diagnóstico).
|
||||
* **Interface Principal (`MainAppView`):** Painel de navegação moderno com alternador dinâmico de tema (Claro/Escuro), grade de operações rápidas (PDF, XML, Assinatura Atachada, Designer de Selos, Validar Assinatura, Sair do Agente) e coluna lateral de utilitários (Logs em tempo real, Configurações, Tutorial, Certificados e Sobre).
|
||||
* **Diálogos de Consentimento e PIN:** Modais nativos de aprovação visual para requisições do protocolo CCSP/1 (`SignatureConfirmationDialog`, `ApplicationAuthorizeDialog`) e coleta segura de PIN de tokens (`A1PasswordDialog`).
|
||||
* **Designer de Selos Digitais (`SealDesignerDialog`):** Ferramenta com Live Preview para criação de selos visuais com controle de cores, estilo de brasão, exibição de nome completo sem truncamento e privacidade de CPF.
|
||||
* **Bandeja do Sistema (System Tray):** Execução minimizada com menu de contexto rápido para restauração da tela ou encerramento da sessão.
|
||||
|
||||
@@ -30,24 +30,18 @@ Em conformidade com os requisitos do projeto, a interface **não é uma cópia d
|
||||
|
||||
---
|
||||
|
||||
## 3. Grade Central de Ações (Hub 4x3)
|
||||
## 3. Grade Central de Ações (Hub 3x2)
|
||||
|
||||
A interface principal organiza as operações em 12 cartões modernos com cantos arredondados (8px), sombras suaves e ícones vetoriais SVG nítidos:
|
||||
A interface principal organiza as operações em 6 cartões modernos com cantos arredondados (8px), sombras suaves e ícones vetoriais SVG nítidos:
|
||||
|
||||
| Posição | Operação | Descrição |
|
||||
|---|---|---|
|
||||
| (0, 0) | **Assinar PDF** | Assinatura digital de documentos PDF com cálculo de hash SHA-256 e gravação de assinatura. |
|
||||
| (1, 0) | **Assinar XML** | Assinatura de documentos XML (estruturas fiscais, NF-e, XMLDSig). |
|
||||
| (2, 0) | **Assinar Arquivo** | Assinatura genérica de qualquer arquivo ou binário do sistema. |
|
||||
| (3, 0) | **Assinar em Lote** | Processamento simultâneo de múltiplos arquivos com barra de progresso em tempo real. |
|
||||
| (0, 1) | **Assinatura Atachada** | Assinatura embutida/anexada ao documento original (CAdES enveloped). |
|
||||
| (1, 1) | **Co-Assinar Documento** | Adição de nova assinatura a um documento previamente assinado por outro titular. |
|
||||
| (2, 1) | **Carimbo do Tempo** | Integração com protocolo RFC 3161 TSP para prova de anterioridade temporal. |
|
||||
| (3, 1) | **Assinatura LTV** | Perfil de Longa Duração com inclusão de cadeia de certificados e carimbos para validade permanente. |
|
||||
| (0, 2) | **Validar Assinatura** | Verificação de integridade criptográfica e conformidade do certificado digital. |
|
||||
| (1, 2) | **Validar Carimbo** | Verificação da autenticidade e validade temporal de tokens TSR/TSP. |
|
||||
| (2, 2) | *(Reservado)* | Espaço reservado para expansões futuras do agente. |
|
||||
| (3, 2) | **Sair do Agente** | Encerramento seguro da sessão do agente. |
|
||||
| (2, 0) | **Assinatura Atachada** | Assinatura embutida/anexada ao documento original (CAdES enveloped). |
|
||||
| (0, 1) | **Gerenciar Selos** | Abertura do Designer e Gerenciador de Selos Digitais visuais para PAdES. |
|
||||
| (1, 1) | **Validar Assinatura** | Verificação de integridade criptográfica e conformidade do certificado digital. |
|
||||
| (2, 1) | **Sair do Agente** | Encerramento seguro da sessão do agente. |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -110,11 +110,8 @@ public class CyberCoreDesktopApplication extends Application {
|
||||
mainAppView.setOnSignFile(() -> new FileSignDialog(primaryStage, "Assinar Arquivo", "*.*", SvgIcons.fileIcon(), certificateManager, signingService).show());
|
||||
mainAppView.setOnBatchSign(() -> new BatchSigningDialog(primaryStage, certificateManager, signingService).show());
|
||||
mainAppView.setOnAttachedSign(() -> new FileSignDialog(primaryStage, "Assinatura Atachada", "*.*", SvgIcons.attachedIcon(), certificateManager, signingService).show());
|
||||
mainAppView.setOnCoSign(() -> new FileSignDialog(primaryStage, "Co-Assinar Documento", "*.*", SvgIcons.coSignIcon(), certificateManager, signingService).show());
|
||||
mainAppView.setOnTimestamp(() -> new SignatureValidationDialog(primaryStage, true).show());
|
||||
mainAppView.setOnLtvSign(() -> new FileSignDialog(primaryStage, "Assinatura de Longa Duração (LTV)", "*.*", SvgIcons.ltvIcon(), certificateManager, signingService).show());
|
||||
mainAppView.setOnValidateSignature(() -> new SignatureValidationDialog(primaryStage, false).show());
|
||||
mainAppView.setOnValidateTimestamp(() -> new SignatureValidationDialog(primaryStage, true).show());
|
||||
mainAppView.setOnValidateSignature(() -> new SignatureValidationDialog(primaryStage).show());
|
||||
mainAppView.setOnManageSeals(() -> new SealManagementDialog(primaryStage).show());
|
||||
mainAppView.setOnExit(() -> {
|
||||
logger.info("Ação 'Sair' acionada na interface gráfica.");
|
||||
|
||||
@@ -35,17 +35,13 @@ public final class MainAppView {
|
||||
private final VBox root = new VBox(16);
|
||||
private final Button themeToggleBtn = new Button();
|
||||
|
||||
// Callbacks das Ações
|
||||
private Runnable onSignPdf;
|
||||
private Runnable onSignXml;
|
||||
private Runnable onSignFile;
|
||||
private Runnable onBatchSign;
|
||||
private Runnable onAttachedSign;
|
||||
private Runnable onCoSign;
|
||||
private Runnable onTimestamp;
|
||||
private Runnable onLtvSign;
|
||||
private Runnable onValidateSignature;
|
||||
private Runnable onValidateTimestamp;
|
||||
private Runnable onManageSeals;
|
||||
private Runnable onExit;
|
||||
|
||||
@@ -73,7 +69,7 @@ public final class MainAppView {
|
||||
mainContent.setAlignment(Pos.CENTER);
|
||||
VBox.setVgrow(mainContent, Priority.ALWAYS);
|
||||
|
||||
// --- Hub Central de Ações (Grid 3 colunas x 3 linhas) ---
|
||||
// --- Hub Central de Ações (Grid 3 colunas x 2 linhas) ---
|
||||
GridPane actionGrid = new GridPane();
|
||||
actionGrid.setHgap(12);
|
||||
actionGrid.setVgap(12);
|
||||
@@ -85,15 +81,10 @@ public final class MainAppView {
|
||||
actionGrid.add(createActionButton(SvgIcons.xmlIcon(), "Assinar\nXML", () -> trigger(onSignXml)), 1, 0);
|
||||
actionGrid.add(createActionButton(SvgIcons.attachedIcon(), "Assinatura\nAtachada", () -> trigger(onAttachedSign)), 2, 0);
|
||||
|
||||
// Linha 1: Formatos Avançados, Temporais e Identidade Visual
|
||||
actionGrid.add(createActionButton(SvgIcons.coSignIcon(), "Co-Assinar\nDocumento", () -> trigger(onCoSign)), 0, 1);
|
||||
actionGrid.add(createActionButton(SvgIcons.timestampIcon(), "Carimbo\ndo Tempo", () -> trigger(onTimestamp)), 1, 1);
|
||||
actionGrid.add(createActionButton(SvgIcons.sealIcon(), "Gerenciar\nSelos", () -> trigger(onManageSeals)), 2, 1);
|
||||
|
||||
// Linha 2: Auditoria, Validação e Saída
|
||||
actionGrid.add(createActionButton(SvgIcons.validateIcon(), "Validar\nAssinatura", () -> trigger(onValidateSignature)), 0, 2);
|
||||
actionGrid.add(createActionButton(SvgIcons.validateTimestampIcon(), "Validar\nCarimbo", () -> trigger(onValidateTimestamp)), 1, 2);
|
||||
actionGrid.add(createActionButton(SvgIcons.exitIcon(), "Sair do\nAgente", () -> trigger(onExit)), 2, 2);
|
||||
// Linha 1: Identidade Visual, Auditoria e Saída
|
||||
actionGrid.add(createActionButton(SvgIcons.sealIcon(), "Gerenciar\nSelos", () -> trigger(onManageSeals)), 0, 1);
|
||||
actionGrid.add(createActionButton(SvgIcons.validateIcon(), "Validar\nAssinatura", () -> trigger(onValidateSignature)), 1, 1);
|
||||
actionGrid.add(createActionButton(SvgIcons.exitIcon(), "Sair do\nAgente", () -> trigger(onExit)), 2, 1);
|
||||
|
||||
// --- Painel Lateral Direito (Ferramentas, Certificados e Diagnóstico) ---
|
||||
VBox sideColumn = new VBox(10);
|
||||
@@ -337,11 +328,8 @@ public final class MainAppView {
|
||||
public void setOnSignFile(Runnable onSignFile) { this.onSignFile = onSignFile; }
|
||||
public void setOnBatchSign(Runnable onBatchSign) { this.onBatchSign = onBatchSign; }
|
||||
public void setOnAttachedSign(Runnable onAttachedSign) { this.onAttachedSign = onAttachedSign; }
|
||||
public void setOnCoSign(Runnable onCoSign) { this.onCoSign = onCoSign; }
|
||||
public void setOnTimestamp(Runnable onTimestamp) { this.onTimestamp = onTimestamp; }
|
||||
public void setOnLtvSign(Runnable onLtvSign) { this.onLtvSign = onLtvSign; }
|
||||
public void setOnValidateSignature(Runnable onValidateSignature) { this.onValidateSignature = onValidateSignature; }
|
||||
public void setOnValidateTimestamp(Runnable onValidateTimestamp) { this.onValidateTimestamp = onValidateTimestamp; }
|
||||
public void setOnManageSeals(Runnable onManageSeals) { this.onManageSeals = onManageSeals; }
|
||||
public void setOnExit(Runnable onExit) { this.onExit = onExit; }
|
||||
|
||||
|
||||
@@ -40,7 +40,6 @@ public final class SignatureValidationDialog {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SignatureValidationDialog.class);
|
||||
|
||||
private final Stage stage;
|
||||
private final boolean isTimestamp;
|
||||
private final SignatureValidationService validationService = new SignatureValidationService();
|
||||
|
||||
private RadioButton rbAttached;
|
||||
@@ -58,15 +57,13 @@ public final class SignatureValidationDialog {
|
||||
private Button btnSaveExtracted;
|
||||
private byte[] lastExtractedContent;
|
||||
|
||||
public SignatureValidationDialog(Stage owner, boolean isTimestamp) {
|
||||
this.isTimestamp = isTimestamp;
|
||||
|
||||
public SignatureValidationDialog(Stage owner) {
|
||||
this.stage = new Stage();
|
||||
this.stage.initModality(Modality.APPLICATION_MODAL);
|
||||
if (owner != null) {
|
||||
this.stage.initOwner(owner);
|
||||
}
|
||||
this.stage.setTitle(isTimestamp ? "CyberCore Signer — Validação de Carimbo do Tempo" : "CyberCore Signer — Validação de Assinatura Digital");
|
||||
this.stage.setTitle("CyberCore Signer — Validação de Assinatura Digital");
|
||||
this.stage.setResizable(true);
|
||||
this.stage.setMinWidth(680);
|
||||
this.stage.setMinHeight(520);
|
||||
@@ -82,11 +79,10 @@ public final class SignatureValidationDialog {
|
||||
HBox header = new HBox(12);
|
||||
header.setAlignment(Pos.CENTER_LEFT);
|
||||
header.getChildren().addAll(
|
||||
isTimestamp ? SvgIcons.validateTimestampIcon() : SvgIcons.validateIcon(),
|
||||
SvgIcons.validateIcon(),
|
||||
createHeaderLabel(
|
||||
isTimestamp ? "VALIDAÇÃO DE CARIMBO DO TEMPO" : "VALIDAÇÃO DE ASSINATURA DIGITAL",
|
||||
isTimestamp ? "Verifique a autenticidade e conformidade RFC 3161 TSP."
|
||||
: "Verifique a autenticidade, integridade e certificados de assinaturas incorporadas ou destacadas."
|
||||
"VALIDAÇÃO DE ASSINATURA DIGITAL",
|
||||
"Verifique a autenticidade, integridade e certificados de assinaturas incorporadas ou destacadas."
|
||||
)
|
||||
);
|
||||
|
||||
@@ -110,11 +106,6 @@ public final class SignatureValidationDialog {
|
||||
radioRow.getChildren().addAll(rbAttached, rbDetached);
|
||||
typeBox.getChildren().addAll(lblTypeTitle, radioRow);
|
||||
|
||||
if (isTimestamp) {
|
||||
typeBox.setVisible(false);
|
||||
typeBox.setManaged(false);
|
||||
}
|
||||
|
||||
// 1. Arquivo de Assinatura / Arquivo Assinado
|
||||
VBox sigBox = new VBox(8);
|
||||
sigBox.getStyleClass().add("dialog-box");
|
||||
@@ -197,7 +188,7 @@ public final class SignatureValidationDialog {
|
||||
}
|
||||
|
||||
private void updateModeView() {
|
||||
boolean isAttached = rbAttached.isSelected() && !isTimestamp;
|
||||
boolean isAttached = rbAttached.isSelected();
|
||||
docBox.setVisible(!isAttached);
|
||||
docBox.setManaged(!isAttached);
|
||||
|
||||
@@ -205,7 +196,7 @@ public final class SignatureValidationDialog {
|
||||
lblSigPath.setText("Arquivo Assinado (.pdf, .p7m, .p7s, .xml):");
|
||||
txtSigPath.setPromptText("Selecione o arquivo assinado com dados embutidos...");
|
||||
} else {
|
||||
lblSigPath.setText(isTimestamp ? "Arquivo de Carimbo (.tsr, .tsp, .p7s):" : "Arquivo de Assinatura (.p7s, .sig):");
|
||||
lblSigPath.setText("Arquivo de Assinatura (.p7s, .sig):");
|
||||
txtSigPath.setPromptText("Selecione o arquivo de assinatura digital...");
|
||||
}
|
||||
}
|
||||
@@ -227,7 +218,7 @@ public final class SignatureValidationDialog {
|
||||
if (rbAttached.isSelected()) {
|
||||
ch.getExtensionFilters().add(new FileChooser.ExtensionFilter("Documentos Assinados (*.pdf, *.p7m, *.p7s, *.xml)", "*.pdf", "*.p7m", "*.p7s", "*.xml", "*.*"));
|
||||
} else {
|
||||
ch.getExtensionFilters().add(new FileChooser.ExtensionFilter("Assinaturas Digitais (*.p7s, *.sig, *.tsr)", "*.p7s", "*.sig", "*.tsr", "*.*"));
|
||||
ch.getExtensionFilters().add(new FileChooser.ExtensionFilter("Assinaturas Digitais (*.p7s, *.sig)", "*.p7s", "*.sig", "*.*"));
|
||||
}
|
||||
|
||||
File f = ch.showOpenDialog(stage);
|
||||
@@ -249,7 +240,7 @@ public final class SignatureValidationDialog {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isDetachedMode = rbDetached.isSelected() || isTimestamp;
|
||||
boolean isDetachedMode = rbDetached.isSelected();
|
||||
if (isDetachedMode && (docFile == null || !docFile.exists())) {
|
||||
showAlert(Alert.AlertType.WARNING, "Documento Original Não Selecionado",
|
||||
"Para validar assinatura destacada é necessário selecionar tanto o documento original quanto o arquivo de assinatura.");
|
||||
|
||||
|
Before Width: | Height: | Size: 996 B After Width: | Height: | Size: 11 KiB |
@@ -1,13 +1,97 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48" height="48">
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 48 48"
|
||||
width="48"
|
||||
height="48"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="xml.svg"
|
||||
inkscape:version="1.4.2 (f4327f4, 2025-05-13)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="namedview4"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="16.8125"
|
||||
inkscape:cx="23.97026"
|
||||
inkscape:cy="24"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="1912"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4" />
|
||||
<!-- Folha de documento com dobra -->
|
||||
<path d="M 8 4 L 32 4 L 42 14 L 42 44 L 8 44 Z" fill="#ffffff" stroke="#0288d1" stroke-width="2.5" stroke-linejoin="round"/>
|
||||
<path
|
||||
d="M 8 4 L 32 4 L 42 14 L 42 44 L 8 44 Z"
|
||||
fill="#ffffff"
|
||||
stroke="#0288d1"
|
||||
stroke-width="2.5"
|
||||
stroke-linejoin="round"
|
||||
id="path1" />
|
||||
<!-- Dobra de canto -->
|
||||
<path d="M 32 4 L 32 14 L 42 14 Z" fill="#b3e5fc" stroke="#0288d1" stroke-width="2" stroke-linejoin="round"/>
|
||||
<path
|
||||
d="M 32 4 L 32 14 L 42 14 Z"
|
||||
fill="#b3e5fc"
|
||||
stroke="#0288d1"
|
||||
stroke-width="2"
|
||||
stroke-linejoin="round"
|
||||
id="path2" />
|
||||
<!-- Linhas de texto representativas -->
|
||||
<line x1="14" y1="20" x2="28" y2="20" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="14" y1="25" x2="36" y2="25" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line x1="14" y1="30" x2="36" y2="30" stroke="#b0bec5" stroke-width="2" stroke-linecap="round"/>
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="17.20446"
|
||||
x2="26.299999"
|
||||
y2="17.20446"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line2" />
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="20.747211"
|
||||
x2="34.299999"
|
||||
y2="20.747211"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line3" />
|
||||
<line
|
||||
x1="12.3"
|
||||
y1="24.289963"
|
||||
x2="34.299999"
|
||||
y2="24.289963"
|
||||
stroke="#b0bec5"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
id="line4" />
|
||||
<!-- Etiqueta azul com sigla XML -->
|
||||
<rect x="10" y="33" width="28" height="11" rx="3" fill="#0288d1"/>
|
||||
<text x="24" y="41.5" font-family="Segoe UI, Arial, sans-serif" font-size="8" font-weight="bold" fill="#ffffff" text-anchor="middle"><XML></text>
|
||||
<rect
|
||||
x="11.3"
|
||||
y="30.799257"
|
||||
width="28"
|
||||
height="11"
|
||||
rx="3"
|
||||
fill="#0288d1"
|
||||
id="rect4" />
|
||||
<text
|
||||
x="25.296093"
|
||||
y="39.100037"
|
||||
font-family="'Segoe UI', Arial, sans-serif"
|
||||
font-size="8px"
|
||||
font-weight="bold"
|
||||
fill="#ffffff"
|
||||
text-anchor="middle"
|
||||
id="text4"><XML></text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 998 B After Width: | Height: | Size: 2.3 KiB |