Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Servent-SSRNew to Visual Studio Code? Get it now.
Servent-SSR

Servent-SSR

Eduardo de Freitas Arantes

|
4 installs
| (1) | Free
Gerador de estrutura, highlight EJS, snippets, linter e testes Playwright para o padrão Servent-SSR v7.0 (Fastify + Node.js + MPA)
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Servent-SSR — Extensão VS Code

Versão VS Code Node.js Fastify EJS

Gerador de estrutura, highlight EJS e snippets para o padrão Servent-SSR v7.0 (Fastify)

Crie módulos completos, components encapsulados, pages, partials e testes E2E
com convenções automáticas de CSS e JavaScript — em segundos.


O que é o Servent-SSR

Servent-SSR é um padrão arquitetural para aplicações MPA (Multi-Page Application) construídas com Node.js + Fastify + EJS. A arquitetura organiza o projeto em camadas bem definidas (Shell, Page, Component, Partial) e estabelece convenções explícitas de nomenclatura, encapsulamento e separação de responsabilidades.

A extensão é o braço operacional da plataforma: ela transforma as convenções arquiteturais em código concreto, eliminando trabalho manual repetitivo e garantindo conformidade automática com o padrão.

┌─────────────────────────────────────────────────────────────────┐
│                     SERVENT-SSR ECOSYSTEM                       │
├────────────┬────────────────┬──────────────────┬────────────────┤
│   SHELL    │     PAGE       │   COMPONENT      │   PARTIAL      │
│ index.ejs  │ pages/mod/pag/ │ components/cat/  │ partials/      │
│            │ ├ index.ejs    │ nome/            │ _nome.ejs      │
│ Assets     │ ├ style.css    │ ├ index.ejs      │                │
│ globais    │ └ script.js    │ ├ style.css      │ EJS puro       │
│ de public/ │                │ └ script.js      │ sem CSS/JS     │
└────────────┴────────────────┴──────────────────┴────────────────┘

✨ O que a Extensão Faz

# Funcionalidade Benefício
1 Inicializar Projeto Estrutura completa + auth JWT + plugins Fastify em segundos
2 Novo Módulo Completo (Wizard) Plugin Factory + Controller + Service + Repository + Pages + Components
3 Nova Page 3 arquivos com prefixo CSS e namespace JS derivados automaticamente
4 Novo Component Modal, sidebar ou component genérico com IIFE e window.Servent
5 Novo Partial Fragmento EJS puro em partials/
6 Servent Explorer Painel lateral com mapa visual do projeto
7 Validador em Tempo Real Diagnósticos automáticos de violações do padrão
8 Code Actions (💡) Correções automáticas com um clique
9 Highlight EJS Grammar próprio — tags <% %> coloridas sem sublinhado vermelho
10 EJS Formatter Shift+Alt+F formata .ejs preservando tags EJS intactas
11 Hover com Documentação Assinatura de components e APIs ao passar o mouse
12 Go to Definition Ctrl+Click em include() e window.Servent.*
13 Gerar Teste E2E Playwright gerado automaticamente a partir do template .ejs
14 31 Snippets EJS e JS para todos os padrões da arquitetura
15 Importar arquivo .spec Extrai estrutura de projeto a partir de um .spec do SpecForge
16 Gerar Teste Playwright Teste E2E gerado a partir do script.js do componente — métodos extraídos automaticamente
17 Linter CSS embutido Stylelint com regra servent-ssr/css-prefix — prefixo .srv- enforçado no painel Problems
18 Linter JS embutido ESLint com regras servent-ssr/namespace e servent-ssr/iife — namespace e IIFE validados ao salvar

📦 Instalação

Via VSIX (recomendado)

# 1. Clone ou baixe o repositório da extensão
# 2. Empacote (requer Node 20)
nvm use 20 && npm install -g @vscode/vsce
vsce package

# 3. Instale no VS Code
code --install-extension servent-ssr-3.1.1.vsix

Via Marketplace

Pesquise por "Servent-SSR" no painel de extensões do VS Code (Ctrl+Shift+X) ou acesse diretamente pelo Marketplace.

Requisitos

Componente Versão mínima
VS Code 1.85.0+
Node.js 18.0.0+
npm 9.0.0+

🚀 Primeiros Passos

1. Inicializar um projeto do zero

Ctrl+Shift+P → Servent-SSR: Inicializar Projeto → Confirmar
meu-projeto/
├── server.js                    ← Fastify configurado e pronto
├── package.json                 ← Dependências completas
├── .env                         ← SESSION_SECRET + JWT_SECRET + keys geradas
├── public/
│   ├── css/app.css
│   ├── js/app.js
│   └── vendor/
├── src/
│   ├── infrastructure/
│   │   ├── database/
│   │   │   ├── Repository.js    ← Classe base Sequelize
│   │   │   ├── connection.js
│   │   │   ├── migrator.js      ← Umzug configurado
│   │   │   ├── models/
│   │   │   │   └── user.model.js
│   │   │   └── migrations/
│   │   │       └── 001-create-users.js
│   │   └── plugins/
│   │       ├── session.plugin.js
│   │       ├── flash.plugin.js
│   │       ├── locals.plugin.js  ← reply.render() / reply.renderPublic()
│   │       ├── static.plugin.js
│   │       ├── view.plugin.js
│   │       ├── jwt-auth.plugin.js
│   │       └── auth-guard.js    ← isAuthenticated + requireRole()
│   └── modules/
│       └── auth/                ← Módulo completo de autenticação
│           ├── auth.plugin.js
│           ├── controllers/
│           ├── services/        ← bcrypt + JWT
│           └── domain/
└── src/views/
    ├── index.ejs                ← Shell HTML
    ├── pages/
    │   └── auth/login/          ← Page de login funcional
    │       ├── index.ejs
    │       ├── style.css
    │       └── script.js
    ├── components/
    │   ├── menus/
    │   ├── modals/
    │   └── sidebars/
    └── partials/
        ├── _page-header.ejs
        ├── _empty-state.ejs
        ├── _pagination.ejs
        └── _alert-flash.ejs

Credenciais do admin gerado: admin@servent.local / Admin@1234 Troque a senha antes do primeiro deploy em produção.

2. Instalar dependências e rodar

npm install
npx playwright install chromium  # instala o browser para testes E2E
npm run dev    # nodemon server.js → http://localhost:3000

3. Criar o primeiro módulo

Ctrl+Shift+P → Servent-SSR: Novo Módulo Completo ✨

Passo 1 — Nome do módulo:

operators

Passo 2 — Pages a criar (multi-select):

☑ list    ☑ detail    ☐ new    ☐ edit

Passo 3 — Components a criar (multi-select):

☑ modal-detail    ☐ modal-confirm    ☑ sidebar-new    ☐ sidebar-edit

Resultado gerado:

src/modules/operators/
├── operators.plugin.js           ← Two-Plugin Factory
├── controllers/
│   ├── operators.controller.js   ← GET /operators → reply.render()
│   └── operators.api.controller.js ← GET /api/operators → reply.send()
├── services/operators.service.js ← { kind, status, body }
├── repositories/operators.repository.js
└── domain/operators.domain.js

src/views/pages/operators/
├── list/   index.ejs + style.css (.srv-page-operators-list) + script.js
└── detail/ index.ejs + style.css (.srv-page-operators-detail) + script.js

src/views/components/
├── modals/detail/   index.ejs + style.css + script.js
└── sidebars/new/    index.ejs + style.css + script.js

tests/unit/operators/operators.service.test.js

O trecho de registro no server.js é copiado automaticamente para o clipboard.


🧩 Comandos Completos

Todos os comandos estão disponíveis via Ctrl+Shift+P e no menu de contexto do Explorer (botão direito em qualquer pasta).

Comando Descrição
Servent-SSR: Inicializar Projeto Gera a estrutura completa com auth JWT
Servent-SSR: Novo Módulo Completo ✨ Wizard guiado com seleção de pages e components
Servent-SSR: Novo Módulo Camadas de negócio sem seleção de pages
Servent-SSR: Nova Page index.ejs + style.css + script.js
Servent-SSR: Novo Componente Modal, sidebar ou component genérico
Servent-SSR: Novo Partial Fragmento EJS puro em partials/
Servent-SSR: Validar Arquivo Verifica conformidade do arquivo aberto
Servent-SSR: Gerar Teste E2E 🧪 Gera teste Playwright a partir do index.ejs
Servent-SSR: Atualizar Explorer Refresh manual do Servent Explorer
Servent-SSR: Gerar Teste Playwright Gera .spec.ts a partir do script.js do componente (botão direito na pasta)

🗂️ Arquitetura Shell · Page · Component · Partial

┌──────────────────────────────────────────────────────────────────────┐
│  REQUEST HTTP                                                        │
│       ↓                                                              │
│  Fastify Route → preHandler (Guard) → Controller                    │
│                                            ↓                        │
│                                        Service (lógica pura)        │
│                                            ↓                        │
│                                        Repository (Sequelize)       │
│                                            ↓                        │
│                                        reply.render(page, dados)    │
│                                            ↓                        │
│  ┌─── SHELL: src/views/index.ejs ──────────────────────────────┐    │
│  │  Assets globais de public/css/ e public/js/                 │    │
│  │                                                             │    │
│  │  ┌─── PAGE: pages/[modulo]/[pagina]/index.ejs ──────────┐  │    │
│  │  │  <style><%- include('./style.css') %></style>         │  │    │
│  │  │                                                       │  │    │
│  │  │  <%- include('components/modals/detail/index.ejs') %> │  │    │
│  │  │  <%- include('partials/_page-header.ejs') %>          │  │    │
│  │  │                                                       │  │    │
│  │  │  <script><%- include('./script.js') %></script>       │  │    │
│  │  └───────────────────────────────────────────────────────┘  │    │
│  └─────────────────────────────────────────────────────────────┘    │
│       ↓                                                              │
│  HTML COMPLETO entregue ao browser (sem hydration, sem runtime)     │
└──────────────────────────────────────────────────────────────────────┘

Regras de cada camada

Camada Tem style.css? Tem script.js? Prefixo CSS Namespace JS
Shell — (usa public/) — (usa public/) — —
Page ✅ Próprio ✅ Próprio .srv-page-[mod]-[pag] window.Servent.Pages.*
Component ✅ Próprio ✅ Próprio .srv-[cat]-[nome] window.Servent.[Cat].*
Partial ❌ Herda ❌ Herda Classes livres —

Derivação automática de convenções

components/modals/detail/     →  .srv-modal-detail
                              →  window.Servent.Modals.Detail

components/sidebars/user-new/ →  .srv-sidebar-user-new
                              →  window.Servent.Sidebars.UserNew

pages/operators/documents/list/ →  .srv-page-operators-documents-list
                                →  window.Servent.Pages.OperatorsDocumentsList

A extensão nunca pede ao desenvolvedor que defina o prefixo CSS ou namespace. Eles são calculados automaticamente.


🎨 Highlight EJS

A extensão registra o EJS como linguagem própria com uma grammar TextMate completa. Não é necessária nenhuma configuração adicional.

<%  código JS sem output  %>   ← keyword (laranja/amarelo)
<%= output escapado       %>   ← keyword escaped (verde)
<%- output HTML/unescaped %>   ← keyword unescaped (azul)
<%# comentário EJS        %>   ← comment (cinza)

Antes da extensão:

❌  <script><%-  include('./script.js') %></script>
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              Erro de sintaxe sublinhado em vermelho

Depois da extensão:

✅  <script><%- include('./script.js') %></script>
    ← HTML colorido normalmente, tags EJS coloridas corretamente

O autoclose está configurado: ao digitar <%, o VS Code fecha com %> automaticamente.


✅ Validador e Code Actions

O validador analisa arquivos Servent-SSR ao abrir e ao salvar, exibindo diagnósticos diretamente no editor.

Arquivo Problema detectado Severidade
style.css Classe .srv-* com prefixo diferente do esperado ⚠️ Aviso
script.js Ausência de IIFE 🔴 Erro
script.js window.X fora de window.Servent.* ⚠️ Aviso
index.ejs (component) Falta include('./style.css') ⚠️ Aviso
index.ejs (component) Falta include('./script.js') ⚠️ Aviso
index.ejs (component) Sem bloco de documentação de variáveis ℹ️ Info
_partial.ejs Presença de <style> ou <script> próprios ⚠️ Aviso

Code Actions — Correções com um clique (💡)

Diagnóstico Correção automática
Falta include('./style.css') Insere no topo do arquivo
Falta include('./script.js') Insere no final do arquivo
Sem documentação de variáveis Insere template <%-- Variáveis esperadas --%>
script.js sem IIFE Envolve todo o conteúdo em IIFE automaticamente
window.MinhaVar = ... Renomeia para window.Servent.MinhaVar

🔍 Hover e Go to Definition

Hover (passe o mouse)

Em .ejs — sobre um include():

╔══════════════════════════════════════════╗
║  Servent-SSR — Component                ║
║  📁 modals/detail                       ║
║  🎨 CSS: .srv-modal-detail              ║
║  🔌 JS:  window.Servent.Modals.Detail   ║
║                                          ║
║  Variáveis esperadas:                   ║
║  - title: string                        ║
║  - contentHtml: string                  ║
╚══════════════════════════════════════════╝

Em .js — sobre window.Servent.Modals.Detail:

╔══════════════════════════════════════════╗
║  Servent-SSR — window.Servent.Modals... ║
║                                          ║
║  API pública:                           ║
║  - open()                               ║
║  - close()                              ║
║                                          ║
║  [Abrir script.js]                      ║
╚══════════════════════════════════════════╝

Go to Definition (Ctrl+Click)

Contexto Comportamento
include('./components/modals/detail/index.ejs') Abre o arquivo incluído
include('./partials/_page-header.ejs') Abre o partial
window.Servent.Modals.Detail Abre o script.js na linha da API pública
window.Servent.Sidebars.UserNew Localiza e abre o script.js da sidebar

🧪 Gerador de Teste E2E

Com qualquer index.ejs de component ou page aberto:

Ctrl+Shift+P → Servent-SSR: Gerar Teste E2E 🧪

A extensão extrai automaticamente do template:

  • IDs de elementos → page.locator('#id')
  • data-attributes → page.locator('[data-*]')
  • Classes .srv-* → page.locator('.srv-*')
  • Campos de formulário → page.fill('[name="campo"]', ...)
  • Namespace window.Servent → chamadas diretas no teste

Testes gerados por tipo:

Tipo Casos de teste gerados
Modal Oculto por padrão, open(), close(), ESC, clique no backdrop
Sidebar Oculto por padrão, open(), close(), ESC, botão de fechar
Page Renderização, submit de formulário, clique em item de lista
Component Presença no DOM com seletores comentados

O arquivo é salvo em tests/e2e/ espelhando o caminho do artefato e aberto automaticamente no editor.


📦 SpecForge — Importar arquivo .spec

O SpecForge é a ferramenta de especificação do ecossistema Servent-SSR. Ele exporta arquivos .spec (ZIPs renomeados) contendo .claude/skills/, .specs/changes/ e docs/.

Ctrl+Shift+P → Servent-SSR: Inicializar Projeto → 📦 Importar arquivo .spec

O file picker filtra apenas arquivos .spec. Após a extração, o .spec é deletado automaticamente — nenhum rastro fica no projeto.

Estrutura extraída:

projeto/
├── .claude/skills/          ← Skills de arquitetura para o agente AI
├── .specs/
│   ├── changes/             ← Changes prontos para execução
│   └── executar_todas.md    ← Cole no Claude para iniciar
└── docs/                    ← Documentação do projeto

🧪 Gerar Teste Playwright

Botão direito na pasta do componente → Servent-SSR: Gerar Teste Playwright

A extensão lê o script.js, extrai os métodos da API pública e gera um .spec.ts completo em tests/e2e/components/[categoria]/[nome].spec.ts.

Exemplo — dado este script.js:

window.Servent.Modals.Detalhe = {
  open:   open,
  close:  close,
  reload: reload,
};

Gera automaticamente:

  • Teste de renderização do elemento raiz (#srv-modal-detalhe)
  • Teste de registro do namespace window.Servent.Modals.Detalhe
  • Um teste para cada método: open(), close(), reload()

Com módulo de domínio (para evitar conflito entre módulos):

User   → window.Servent.User.Modals.Detalhe
Pedidos → window.Servent.Pedidos.Modals.Detalhe

Para rodar os testes:

npm run dev              # servidor deve estar rodando
npm run test:e2e         # headless
npm run test:e2e:ui      # modo visual
npm run test:e2e:headed  # browser visível

O playwright.config.ts é gerado com baseURL lida automaticamente do .env (sem configuração manual).


🔒 Linter Embutido

O projeto gerado inclui plugins de linting que rodam ao salvar, exibindo erros no painel Problems com sublinhados no código.

ESLint — Regras Servent-SSR

Regra O que detecta Severidade
servent-ssr/iife script.js sem IIFE ou sem 'use strict' 🔴 Erro
servent-ssr/namespace Namespace errado, guard ausente, window.X fora do window.Servent 🔴 Erro

Stylelint — Regras Servent-SSR

Regra O que detecta Severidade
servent-ssr/css-prefix Classe CSS sem o prefixo .srv-[categoria]-[nome] 🔴 Erro
npm run lint       # ESLint nos script.js de componentes
npm run lint:css   # Stylelint nos style.css de componentes

Os plugins ficam em tools/eslint-plugin-servent-ssr/ e tools/stylelint-plugin-servent-ssr/ — embutidos no projeto, sem dependência externa.


📝 Snippets EJS

Digite o prefixo em qualquer arquivo .ejs e pressione Tab.

Prefixo O que gera
srv-shell Shell HTML completo com head, body, CSS/JS globais e include(pageComponent)
srv-page Page com include de style.css e script.js, div com prefixo
srv-component Component encapsulado com role e aria-label
srv-modal Modal completo: backdrop, container, header, body, footer
srv-sidebar Sidebar/offcanvas: backdrop, panel, header, body, botão de fechar
srv-include <%- include('caminho', { chave: valor }) %> com placeholders
srv-partial <%- include('partials/_nome', { dados }) %>
srv-each <% items.forEach(function(item) { %> ... <% }); %>
srv-if <% if (condition) { %> ... <% } else { %> ... <% } %>
srv-local <% if (locals.variavel) { %> ... <% } %>
srv-flash Bloco completo de flash messages (success, error, info)
srv-empty Condicional de empty state com include do partial
srv-pagination Include do partial de paginação com currentPage e totalPages

📝 Snippets JavaScript

Digite o prefixo em qualquer arquivo .js e pressione Tab.

Prefixo O que gera
srv-iife IIFE base com window.Servent, getElementById, funções privadas e API pública
srv-iife-modal IIFE completa de modal: open(data), close(), ESC, backdrop, CustomEvents
srv-iife-sidebar IIFE completa de sidebar: open(), close(), ESC, botões
srv-iife-page IIFE base de page com window.Servent.Pages.[Nome] e refresh()
srv-dispatch document.dispatchEvent(new CustomEvent('comp:acao', { detail }))
srv-listen document.addEventListener('comp:acao', function(e) { })
srv-service Método async com try/catch e retorno { kind, status, body }
srv-ok return { kind: 'json', status: 200, body: { data } }
srv-err return { kind, status: 4xx/5xx, body: { erro } } com seleção de status
srv-controller Handler SSR Fastify com verificação de out.status, flash e reply.render()
srv-api Handler JSON Fastify com reply.status(out.status).send(out.body)
srv-plugin Two-Plugin Factory completo: viewPlugin + apiPlugin + guard hook
srv-repo Método de Repository com Sequelize findAll, where e order
srv-migration Migration Umzug com up/down e seleção de operação SQL
srv-migration-table Migration createTable completa com id, coluna, timestamps
srv-migration-col Migration addColumn com tipo, allowNull, defaultValue
srv-fetch-modal fetch() + window.Servent.Modals.[Nome].open() com tratamento de erro
srv-e2e Teste E2E Playwright base com beforeAll, afterAll e it()
srv-e2e-modal Teste E2E completo de modal com casos reais

📊 Servent Explorer

Um painel dedicado na Activity Bar do VS Code com mapa visual do projeto.

SERVENT EXPLORER
├── 📄 Pages
│   ├── auth
│   │   └── login
│   │       ├── index.ejs  ← clicável
│   │       ├── style.css  ← clicável
│   │       └── script.js  ← clicável
│   └── operators
│       ├── list    → .srv-page-operators-list
│       └── detail  → .srv-page-operators-detail
│
├── 🧩 Components
│   ├── menus
│   ├── modals
│   │   └── detail  → .srv-modal-detail
│   └── sidebars
│       └── new  → .srv-sidebar-new
│
└── 🧱 Partials
    ├── _page-header.ejs
    ├── _empty-state.ejs
    ├── _pagination.ejs
    └── _alert-flash.ejs

O painel atualiza automaticamente ao salvar, criar ou deletar arquivos. O botão ✨ no header abre o Wizard diretamente.


🏗️ Casos de Uso

Tipo de projeto Como a extensão ajuda
Sistema administrativo Wizard gera cada módulo CRUD em < 1 min; guard por role pronto para usar
Portal SSR corporativo Shell único, partials reutilizáveis, Servent Explorer para navegação
E-commerce Módulos independentes por domínio; modal de detalhe e sidebar de filtro prontos
API Enterprise Two-Plugin Factory separa rotas SSR e JSON no mesmo módulo
Sistema governamental requireRole() por feature; ARIA completo nos components gerados
SaaS multi-tenant Chaves srvt_local/dev/hmg/prd geradas por ambiente

⚙️ Configurações

Configuração Valores Padrão
servent-ssr.framework fastify | express fastify

📋 Changelog

v3.1.0

  • ✅ Gerar Teste Playwright — botão direito na pasta do componente gera .spec.ts com testes por método
  • ✅ Importar arquivo .spec — integração com SpecForge no comando Inicializar Projeto
  • ✅ Playwright configurado — playwright.config.ts gerado com baseURL lida do .env
  • ✅ Scripts npm E2E — test:e2e, test:e2e:ui, test:e2e:headed adicionados
  • ✅ Linter CSS embutido — Stylelint com regra servent-ssr/css-prefix
  • ✅ Linter JS embutido — ESLint com regras servent-ssr/namespace e servent-ssr/iife
  • ✅ Namespace com módulo de domínio — suporte a window.Servent.User.Modals.Detalhe
  • ✅ SQL injection corrigido — Repository.js valida tableName no construtor
  • ✅ Umzug + Sequelize — adicionados ao package.json gerado
  • ✅ write() com aviso — alerta quando arquivo já existe em vez de ignorar silenciosamente

v3.0.2

  • ✅ EJS Formatter — Shift+Alt+F formata .ejs preservando tags EJS intactas
  • ✅ Code Actions (💡) — correções automáticas para todos os diagnósticos
  • ✅ Gerador de Teste E2E — Playwright gerado a partir do template .ejs
  • ✅ Hover com documentação — assinatura de components e window.Servent.*
  • ✅ Go to Definition — Ctrl+Click em include() e window.Servent.*
  • ✅ Novos snippets: srv-e2e, srv-e2e-modal

v2.2.0

  • ✅ Servent Explorer — painel lateral com mapa visual arquitetural
  • ✅ Wizard de módulo completo — fluxo guiado com seleção de pages e components
  • ✅ Snippets de migration: srv-migration, srv-migration-table, srv-migration-col
  • ✅ Novo comando: Servent-SSR: Novo Partial

v2.1.0

  • ✅ Validador em tempo real — DiagnosticCollection com regras de conformidade
  • ✅ Highlight EJS — grammar TextMate própria para .ejs
  • ✅ Novo comando: Servent-SSR: Validar Arquivo

v2.0.0

  • ✅ Estrutura atualizada para Servent-SSR v7.0 (Fastify)
  • ✅ Inicializar Projeto gera auth JWT completo com módulo, model, migration e seeder
  • ✅ Chaves de ambiente geradas dinamicamente: srvt_local_*, srvt_dev_*, srvt_hmg_*, srvt_prd_*
  • ✅ 14 snippets EJS e 17 snippets JS
  • ✅ Plugin factory, controllers, services, repositories e domain gerados
  • ✅ Novo comando: Servent-SSR: Novo Partial

v1.0.0

  • ✅ Comandos básicos: Inicializar Projeto, Novo Módulo, Novo Componente, Nova Page
  • ✅ Geração de Plugin Factory, Controller, Service, Repository, Domain
  • ✅ Suporte a Express

🔗 Recursos

  • Documentação completa da arquitetura Servent-SSR
  • Reportar um problema
  • Eduardo de Freitas Arantes
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft