@trismegisto/spine 3.3.3 → 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +15 -2
  2. package/fesm2022/trismegisto-spine-audit.mjs +6 -6
  3. package/fesm2022/trismegisto-spine-audit.mjs.map +1 -1
  4. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-BAfeLyTB.mjs → trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs} +8 -8
  5. package/fesm2022/{trismegisto-spine-auto-service-auto-service-client.component-BAfeLyTB.mjs.map → trismegisto-spine-auto-service-auto-service-client.component-kAXaCM5W.mjs.map} +1 -1
  6. package/fesm2022/{trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs → trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs} +251 -85
  7. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-DE2QIGRH.mjs.map +1 -0
  8. package/fesm2022/{trismegisto-spine-auto-service-auto-service-news-page.component-CBemH4hr.mjs → trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs} +2 -2
  9. package/fesm2022/{trismegisto-spine-auto-service-auto-service-news-page.component-CBemH4hr.mjs.map → trismegisto-spine-auto-service-auto-service-news-page.component-BW7BJ0oD.mjs.map} +1 -1
  10. package/fesm2022/{trismegisto-spine-auto-service-auto-service-ratings-page.component-C_THGTkw.mjs → trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs} +2 -2
  11. package/fesm2022/{trismegisto-spine-auto-service-auto-service-ratings-page.component-C_THGTkw.mjs.map → trismegisto-spine-auto-service-auto-service-ratings-page.component-CHPU-QLJ.mjs.map} +1 -1
  12. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs +3733 -0
  13. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-CkiCTmXD.mjs.map +1 -0
  14. package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs} +7 -7
  15. package/fesm2022/{trismegisto-spine-auto-service-auto-service.component-QsIQ61w2.mjs.map → trismegisto-spine-auto-service-auto-service.component-D58Ht9PH.mjs.map} +1 -1
  16. package/fesm2022/{trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs → trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs} +12 -3
  17. package/fesm2022/trismegisto-spine-auto-service-groups.technical-CB1D3ANC.mjs.map +1 -0
  18. package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs} +7 -2
  19. package/fesm2022/{trismegisto-spine-auto-service-groups.usage-OvWjNeeT.mjs.map → trismegisto-spine-auto-service-groups.usage-De2MhlE7.mjs.map} +1 -1
  20. package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs} +14 -1
  21. package/fesm2022/{trismegisto-spine-auto-service-suggestions.technical-BtUK6sKD.mjs.map → trismegisto-spine-auto-service-suggestions.technical-CGBBzAR8.mjs.map} +1 -1
  22. package/fesm2022/{trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs → trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs} +26 -3
  23. package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-DnAJS-Z0.mjs.map +1 -0
  24. package/fesm2022/trismegisto-spine-auto-service.mjs +24 -11
  25. package/fesm2022/trismegisto-spine-auto-service.mjs.map +1 -1
  26. package/fesm2022/{trismegisto-spine-layout-suggestions-page.component-xI2gDMok.mjs → trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs} +3 -3
  27. package/fesm2022/{trismegisto-spine-layout-suggestions-page.component-xI2gDMok.mjs.map → trismegisto-spine-layout-suggestions-page.component-CEKMqera.mjs.map} +1 -1
  28. package/fesm2022/{trismegisto-spine-layout-trismegisto-spine-layout-Clphrsgc.mjs → trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs} +428 -93
  29. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs.map +1 -0
  30. package/fesm2022/trismegisto-spine-layout.mjs +1 -1
  31. package/fesm2022/trismegisto-spine-side-panel.mjs +1 -1
  32. package/fesm2022/trismegisto-spine-side-panel.mjs.map +1 -1
  33. package/fesm2022/trismegisto-spine.mjs +528 -10
  34. package/fesm2022/trismegisto-spine.mjs.map +1 -1
  35. package/package.json +6 -6
  36. package/types/trismegisto-spine-auto-service.d.ts +20 -4
  37. package/types/trismegisto-spine-auto-service.d.ts.map +1 -1
  38. package/types/trismegisto-spine-layout.d.ts +327 -63
  39. package/types/trismegisto-spine-layout.d.ts.map +1 -1
  40. package/types/trismegisto-spine.d.ts +221 -3
  41. package/types/trismegisto-spine.d.ts.map +1 -1
  42. package/fesm2022/trismegisto-spine-auto-service-auto-service-groups.component-BYjIQ9ID.mjs.map +0 -1
  43. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-mMjE3JOL.mjs +0 -2179
  44. package/fesm2022/trismegisto-spine-auto-service-auto-service-suggestions-page.component-mMjE3JOL.mjs.map +0 -1
  45. package/fesm2022/trismegisto-spine-auto-service-groups.technical-_jQrg1Qh.mjs.map +0 -1
  46. package/fesm2022/trismegisto-spine-auto-service-suggestions.usage-BwO9Hjsx.mjs.map +0 -1
  47. package/fesm2022/trismegisto-spine-layout-trismegisto-spine-layout-Clphrsgc.mjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trismegisto-spine-layout-trismegisto-spine-layout-DiAfxIGP.mjs","sources":["../../../projects/ui/layout/src/header/app-launcher.component.ts","../../../projects/ui/layout/src/header/app-launcher.component.html","../../../projects/ui/layout/src/brand.token.ts","../../../projects/ui/layout/src/header/brand.component.ts","../../../projects/ui/layout/src/settings/account-security.service.ts","../../../projects/ui/layout/src/account-preferences/account-preferences.service.ts","../../../projects/ui/layout/src/setup/initial-setup.service.ts","../../../projects/ui/layout/src/session-token.ts","../../../projects/ui/layout/src/news/news.service.ts","../../../projects/ui/layout/src/ratings/ratings.service.ts","../../../projects/ui/layout/src/ratings/rating-stars.component.ts","../../../projects/ui/layout/src/ratings/rating-form.component.ts","../../../projects/ui/layout/src/ratings/rating-window.component.ts","../../../projects/ui/layout/src/ratings/rate-app-button.component.ts","../../../projects/ui/layout/src/inbox/inbox.ts","../../../projects/ui/layout/src/inbox/inbox.service.ts","../../../projects/ui/layout/src/inbox/inbox-button.component.ts","../../../projects/ui/layout/src/logout/logout.service.ts","../../../projects/ui/layout/src/settings/settings.service.ts","../../../projects/ui/layout/src/shortcuts/shortcut.service.ts","../../../projects/ui/layout/src/header/header.component.ts","../../../projects/ui/layout/src/header/header.component.html","../../../projects/ui/layout/src/workspace/spine-workspace-nav.service.ts","../../../projects/ui/layout/src/sidebar/sidebar.component.ts","../../../projects/ui/layout/src/sidebar/sidebar.component.html","../../../projects/ui/layout/src/setup/initial-setup.component.ts","../../../projects/ui/layout/src/setup/initial-setup.component.html","../../../projects/ui/layout/src/news/news.component.ts","../../../projects/ui/layout/src/shortcuts/shortcuts-cheatsheet.component.ts","../../../projects/ui/layout/src/shortcuts/shortcuts-cheatsheet.component.html","../../../projects/ui/layout/src/features/spine-features.ts","../../../projects/ui/layout/src/idle/idle.service.ts","../../../projects/ui/layout/src/notices/notices.service.ts","../../../projects/ui/layout/src/start-page/start-page.service.ts","../../../projects/ui/layout/src/settings/account-activity.component.ts","../../../projects/ui/layout/src/settings/account-security.state.ts","../../../projects/ui/layout/src/settings/account-reauth.component.ts","../../../projects/ui/layout/src/settings/account-mfa.component.ts","../../../projects/ui/layout/src/settings/account-mfa.component.html","../../../projects/ui/layout/src/settings/app-tokens.service.ts","../../../projects/ui/layout/src/settings/ai-agent.component.ts","../../../projects/ui/layout/src/settings/default-badge.component.ts","../../../projects/ui/layout/src/settings/account-recovery-codes.component.ts","../../../projects/ui/layout/src/settings/account-sessions.component.ts","../../../projects/ui/layout/src/settings/account-sessions.component.html","../../../projects/ui/layout/src/settings/app-tokens.component.ts","../../../projects/ui/layout/src/settings/app-tokens.component.html","../../../projects/ui/layout/src/settings/members-loader.ts","../../../projects/ui/layout/src/settings/my-groups.service.ts","../../../projects/ui/layout/src/settings/my-group.component.ts","../../../projects/ui/layout/src/settings/my-group.component.html","../../../projects/ui/layout/src/settings/my-groups.component.ts","../../../projects/ui/layout/src/settings/my-groups.component.html","../../../projects/ui/layout/src/ratings/app-rating-summary.component.ts","../../../projects/ui/layout/src/settings/settings-panel.component.ts","../../../projects/ui/layout/src/settings/settings-panel.component.html","../../../projects/ui/layout/src/docs/docs.service.ts","../../../projects/ui/layout/src/ratings/rate-screen-button.component.ts","../../../projects/ui/layout/src/suggestions/suggestion-screens.ts","../../../projects/ui/layout/src/suggestions/suggestions.service.ts","../../../projects/ui/layout/src/suggestions/suggestions-page.ts","../../../projects/ui/layout/src/suggestions/suggestions-dialog.component.ts","../../../projects/ui/layout/src/suggestions/suggestions-dialog.component.html","../../../projects/ui/layout/src/suggestions/suggest-button.component.ts","../../../projects/ui/layout/src/workspace/spine-page-actions.directive.ts","../../../projects/ui/layout/src/workspace/spine-page-bar.component.ts","../../../projects/ui/layout/src/workspace/spine-tab.ts","../../../projects/ui/layout/src/workspace/spine-page-panel.component.ts","../../../projects/ui/layout/src/workspace/panel-local-link.directive.ts","../../../projects/ui/layout/src/docs/markdown-sanitize.ts","../../../projects/ui/layout/src/docs/markdown.component.ts","../../../projects/ui/layout/src/docs/docs-modal.component.ts","../../../projects/ui/layout/src/connection/connection-banner.component.ts","../../../projects/ui/layout/src/idle/idle-warning.component.ts","../../../projects/ui/layout/src/workspace/spine-unsaved-changes.ts","../../../projects/ui/layout/src/layout.component.ts","../../../projects/ui/layout/src/suggestions/suggestion-chat.component.ts","../../../projects/ui/layout/src/suggestions/tag-row.component.ts","../../../projects/ui/layout/src/trismegisto-spine-layout.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\nimport { ChangeDetectorRef, Component, OnInit, ChangeDetectionStrategy, inject } from '@angular/core';\nimport { AppDef, AuthorizationService, RealmAppsService } from '@orfeu/angular/core';\nimport { MenuButtonComponent, MenuItem } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\n\n/**\n * Seletor de aplicações do realm: um `hm-menu-button` próprio, só com o ícone de grade, que abre a lista das\n * aplicações num `hm-menu` dele (o mesmo componente — e o mesmo visual — do menu do perfil, mas um menu à parte;\n * teclado, foco e `role=\"menu\"` vêm do `hm-menu`). Escolher um item abre a aplicação em nova aba, sem `opener`.\n */\n@Component({\n selector: 'spine-app-launcher',\n imports: [CommonModule, MenuButtonComponent],\n templateUrl: './app-launcher.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './app-launcher.component.scss',\n})\nexport class AppLauncherComponent implements OnInit {\n protected readonly text = inject(SPINE_MESSAGES).header;\n private readonly cdr = inject(ChangeDetectorRef);\n\n public apps: AppDef[] = [];\n public items: MenuItem[] = [];\n public loading = false;\n\n constructor(\n private authService: AuthorizationService,\n private realmAppsService: RealmAppsService,\n ) {}\n\n async ngOnInit(): Promise<void> {\n this.loading = true;\n const token = this.authService.getToken();\n // O client atual (o app em que o usuário já está) já vem excluído aqui —\n // OpenIDController.view no argos filtra por client_id no próprio backend\n // (apps/argos/auth/server/.../openid.controller.ts), então não há\n // necessidade de repetir essa checagem no front.\n try {\n // Ordem alfabética pelo nome (pt-BR, sem diferenciar maiúsculas nem acentos).\n this.apps = [...((await this.realmAppsService.getApplications(token)) ?? [])]\n .sort((a, b) => a.name.localeCompare(b.name, 'pt-BR', { sensitivity: 'base' }));\n } catch {\n // Sem a lista não há o que oferecer: o botão some, em vez de ficar carregando para sempre.\n this.apps = [];\n } finally {\n this.loading = false;\n // O título \"Aplicações\" é o groupTitle do primeiro item (mesmo cabeçalho de grupo do hm-menu).\n this.items = this.apps.map((app, i) => ({\n id: app.id,\n label: app.name,\n icon: 'applications',\n ...(i === 0 ? { groupTitle: this.text.apps } : {}),\n }));\n // A lista chega fora de qualquer evento do template: sem isto, app zoneless não redesenha.\n this.cdr.markForCheck();\n }\n }\n\n open(id: string): void {\n const app = this.apps.find((a) => a.id === id);\n const url = app ? safeAppUrl(app.app_url) : null;\n if (url) window.open(url, '_blank', 'noopener,noreferrer');\n }\n}\n\n/**\n * Endereço da aplicação só se for http(s) (absoluto, ou relativo a esta página). O `app_url` vem do cadastro\n * do realm: `javascript:`, `data:` e afins nunca são abertos.\n */\nfunction safeAppUrl(raw: string | null | undefined): string | null {\n if (!raw) return null;\n try {\n const url = new URL(raw, globalThis.location?.href);\n return url.protocol === 'https:' || url.protocol === 'http:' ? url.href : null;\n } catch {\n return null;\n }\n}\n","<div class=\"app-launcher-trigger\" *ngIf=\"loading || apps.length > 0\">\n <hm-menu-button [label]=\"text.apps\" icon=\"grid\" [showArrow]=\"false\" [disabled]=\"loading\" [items]=\"items\"\n (chosen)=\"open($event)\"></hm-menu-button>\n</div>\n","import { InjectionToken, Type } from '@angular/core';\n\n/**\n * Componente de marca que o header do shell desenha no lugar da imagem de `SpineConfig.logo` (tem\n * prioridade sobre ela). Injeção em vez de projeção de conteúdo porque o `LayoutComponent` é montado\n * pelo `Router`, não pelo template do app — não existe `<ng-content>` alcançável de fora. O componente\n * fica dentro do link da marca (que leva à home): não ponha link nem botão nele, e se ele for só\n * imagem, dê nome acessível ou deixe o `appName` visível (`showAppName`, padrão `true`).\n * `null` (padrão) usa a imagem. Ex.: `{ provide: SPINE_BRAND, useValue: MarcaComponent }` no\n * `app.config.ts`.\n */\nexport const SPINE_BRAND = new InjectionToken<Type<unknown> | null>('SPINE_BRAND', {\n providedIn: 'root',\n factory: () => null,\n});\n","import { NgComponentOutlet, NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, inject, input, signal } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { SPINE_CONFIG, ThemeService, resolveSpineLogo } from '@trismegisto/spine';\nimport { SPINE_BRAND } from '../brand.token';\n\n/**\n * Marca do header: logo do app (`SpineConfig.logo`, padrão `assets/images/logo.svg`) + `appName`, dentro\n * de um link para a home. Ordem: componente de `SPINE_BRAND` > imagem > só o nome.\n *\n * - Tema escuro usa `logo.dark` quando houver; se ele falhar, volta para `logo.light`.\n * - Imagem que não carrega (404/erro) some — nada de ícone quebrado — e o nome aparece mesmo com\n * `showAppName: false`, para o link nunca ficar sem texto.\n * - Texto alternativo: `logo.alt` se configurado; senão o `appName` quando o nome está escondido, e vazio\n * (imagem decorativa) quando o nome já está ao lado — o leitor de tela não lê o nome duas vezes.\n */\n@Component({\n selector: 'spine-brand',\n imports: [RouterLink, NgTemplateOutlet, NgComponentOutlet],\n template: `\n @if (homeRoute()) {\n <a class=\"brand\" [routerLink]=\"homeRoute()\" [title]=\"label()\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </a>\n } @else {\n <span class=\"brand\" [title]=\"label()\">\n <ng-container *ngTemplateOutlet=\"content\" />\n </span>\n }\n <ng-template #content>\n @if (brand) {\n <ng-container *ngComponentOutlet=\"brand\" />\n } @else if (src(); as s) {\n <img class=\"brand__logo\" [src]=\"s\" [alt]=\"alt()\" (error)=\"onError(s)\" />\n }\n @if (nameVisible()) {\n <span class=\"brand__name\">{{ appName }}</span>\n }\n </ng-template>\n `,\n styleUrl: './brand.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpineBrandComponent {\n /** Rota da home (primeira rota navegável); `null` desenha a marca sem link. */\n readonly homeRoute = input<string | null>(null);\n /** Dica do link (ex.: \"Página inicial\"). */\n readonly label = input('');\n\n private readonly config = inject(SPINE_CONFIG, { optional: true });\n private readonly theme = inject(ThemeService);\n protected readonly brand = inject(SPINE_BRAND);\n protected readonly appName = this.config?.appName ?? 'Hermes';\n private readonly sources = resolveSpineLogo(this.config?.logo);\n private readonly showAppName = this.config?.showAppName !== false;\n /** Endereços que já deram erro nesta sessão do componente. */\n private readonly failed = signal<ReadonlySet<string>>(new Set());\n\n /** Imagem a mostrar agora (tema atual, sem as que falharam); `null` = nenhuma. */\n readonly src = computed<string | null>(() => {\n const logo = this.sources;\n if (!logo || this.brand) return null;\n const failed = this.failed();\n if (this.theme.current === 'dark' && logo.dark && !failed.has(logo.dark)) return logo.dark;\n return failed.has(logo.light) ? null : logo.light;\n });\n\n readonly nameVisible = computed(() => this.showAppName || (!this.brand && !this.src()));\n\n readonly alt = computed(() => this.sources?.alt ?? (this.nameVisible() ? '' : this.appName));\n\n onError(src: string): void {\n if (this.failed().has(src)) return;\n this.failed.update((set) => new Set(set).add(src));\n }\n}\n","import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { AUTH_CONFIG, AuthorizationService } from '@orfeu/angular/core';\n\n/** Um método de verificação em duas etapas, como o Argos devolve (nunca o segredo do TOTP). */\nexport interface AccountMethod {\n method_id: string;\n /** `totp`, `email`, `sms`... (nome fixo do método no Argos). */\n method_name: string;\n active: boolean;\n /** E-mail/telefone mascarados. */\n secret?: string;\n}\n\n/** `GET {api}/security`: métodos, política do realm, códigos de recuperação e estado da reautenticação. */\nexport interface AccountOverview {\n user: { username: string; name: string | null; email: string };\n policy: { required: boolean };\n methods: AccountMethod[];\n recovery_codes: { remaining: number };\n /** Id do \"método\" código de recuperação (reautenticação com um código). */\n recovery_method_id: string;\n reauthenticated: boolean;\n reauth_expires_in: number;\n /** Só na resposta do cadastro do primeiro método: os códigos de recuperação, exibidos uma vez. */\n recovery_codes_issued?: string[];\n}\n\n/** Uma sessão (um login num navegador) e os aplicativos que a usam. */\nexport interface AccountSession {\n id: string;\n /** A sessão deste login (a do token do app). */\n current: boolean;\n /** Outra sessão do mesmo navegador. */\n this_device: boolean;\n device: { browser?: string | null; os?: string | null; mobile: boolean; label: string };\n ip: string | null;\n created_at: string;\n last_seen_at: string;\n /** `false`: o login no Argos venceu, só o refresh de algum aplicativo segue vivo. */\n sso_active: boolean;\n clients: { client_id: string; name: string | null }[];\n}\n\n/** Uma tentativa de entrar na conta (`GET {api}/activity`): sucesso, falha ou cancelamento. */\nexport interface AccountActivityEntry {\n id: string;\n /** Data e hora (ISO). */\n at: string;\n result: 'success' | 'failure' | 'cancelled';\n /** `local`, `mfa`, `github`, `google`, `keycloak`, `entraid`. */\n method: string;\n /** Motivo da falha (`bad_password`, `mfa_failed`, `locked`…); `null` no sucesso. */\n reason: string | null;\n ip: string | null;\n device: { browser?: string | null; os?: string | null; mobile: boolean; label: string };\n /** Aplicativo em que a pessoa tentou entrar. */\n client: { client_id: string; name: string | null } | null;\n}\n\nexport interface AccountActivityPage {\n attempts: AccountActivityEntry[];\n total: number;\n limit: number;\n offset: number;\n /** Começo da janela (90 dias). */\n since: string;\n}\n\n/** Crachás da pessoa nesta aplicação e o padrão guardado no Argos (`GET {api}/badges`). */\nexport interface AccountBadges {\n client: { id: string; name: string | null };\n badges: { id: string; name: string }[];\n default_badge_id: string | null;\n active_badge_id: string | null;\n}\n\n/** Preferências guardadas na conta para esta aplicação (`GET/PUT {api}/preferences`). */\nexport interface AccountPreferences {\n preferences: Record<string, unknown>;\n updated_at: string | null;\n}\n\nexport type AccountReauth = { password: string } | { method_id: string; code: string };\n\n/**\n * Base da API da conta no Argos: `{authority}/api/realms/{realm}/account` — o mesmo `{authority}/api` que o\n * `@orfeu/angular` usa para o OIDC (a `authority` já traz o contexto do serviço, ex.: `https://host/argos`).\n * Sem `authority`/`realm` (ou com o `CHANGE_ME` de um environment ainda não preenchido) devolve `null`.\n */\nexport function argosAccountApi(authority: string | null | undefined, realm: string | null | undefined): string | null {\n const realmId = realm?.trim();\n if (authority == null || !realmId || authority.includes('CHANGE_ME') || realmId.includes('CHANGE_ME')) return null;\n return `${authority.trim().replace(/\\/+$/, '')}/api/realms/${encodeURIComponent(realmId)}/account`;\n}\n\n/**\n * Conta do usuário no Argos (verificação em duas etapas, códigos de recuperação, sessões) pela API da conta\n * com Bearer: o access token da sessão do app (`@orfeu/angular`), no header `Authorization` — o mesmo jeito\n * que o Orfeu fala com o Argos (ex.: `switchBadge`). O Argos reconhece a sessão SSO pelo `sid` do token; não\n * há cookie envolvido. Token vencido (`401 invalid_token`): renova uma vez (`silentRenew`) e repete.\n * `available` é falso sem `AUTH_CONFIG` utilizável.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineAccountSecurityService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly config = inject(AUTH_CONFIG, { optional: true });\n\n readonly baseUrl = argosAccountApi(this.config?.authority, this.config?.realmId);\n readonly available = !!this.baseUrl;\n\n overview(): Promise<AccountOverview> {\n return this.send('GET', '/security');\n }\n\n reauthenticate(proof: AccountReauth): Promise<{ reauthenticated: boolean; reauth_expires_in: number }> {\n return this.send('POST', '/reauth', proof);\n }\n\n requestReauthCode(methodId: string): Promise<{ method_id: string; expires_in: number }> {\n return this.send('POST', '/reauth/request', { method_id: methodId });\n }\n\n configure(methodId: string, email?: string): Promise<{ method_id: string; secret?: string; qrcode?: string; expires_in?: number }> {\n return this.send('POST', '/mfa/configure', email ? { method_id: methodId, email } : { method_id: methodId });\n }\n\n register(methodId: string, code: string): Promise<AccountOverview> {\n return this.send('POST', '/mfa/register', { method_id: methodId, code });\n }\n\n remove(methodId: string): Promise<AccountOverview> {\n return this.send('POST', '/mfa/remove', { method_id: methodId });\n }\n\n regenerateRecoveryCodes(): Promise<{ recovery_codes: string[]; remaining: number }> {\n return this.send('POST', '/recovery-codes', {});\n }\n\n sessions(): Promise<{ sessions: AccountSession[] }> {\n return this.send('GET', '/sessions');\n }\n\n endSession(sid: string): Promise<{ ended: boolean; current: boolean }> {\n return this.send('DELETE', `/sessions/${encodeURIComponent(sid)}`);\n }\n\n endOtherSessions(): Promise<{ ended: number }> {\n return this.send('DELETE', '/sessions/others');\n }\n\n /** Entradas e tentativas desta conta nos últimos 90 dias, da mais recente. `result` filtra só sucessos ou falhas. */\n activity(params: { limit?: number; offset?: number; result?: 'success' | 'failure' } = {}): Promise<AccountActivityPage> {\n const query = new URLSearchParams();\n if (params.limit) query.set('limit', String(params.limit));\n if (params.offset) query.set('offset', String(params.offset));\n if (params.result) query.set('result', params.result);\n const qs = query.toString();\n return this.send('GET', `/activity${qs ? `?${qs}` : ''}`);\n }\n\n badges(): Promise<AccountBadges> {\n return this.send('GET', '/badges');\n }\n\n /** Crachá com que o login entra nesta aplicação (`null` volta ao padrão: o de menor nível). */\n setDefaultBadge(badgeId: string | null): Promise<{ default_badge_id: string | null }> {\n return this.send('PUT', '/badges/default', { badge_id: badgeId });\n }\n\n preferences(): Promise<AccountPreferences> {\n return this.send('GET', '/preferences');\n }\n\n /** Substitui o documento de preferências desta aplicação na conta (até 16 KB). */\n savePreferences(preferences: Record<string, unknown>): Promise<AccountPreferences> {\n return this.send('PUT', '/preferences', { preferences });\n }\n\n /** Preferências da pessoa que valem em todos os apps (`GET {api}/preferences/global`). */\n globalPreferences(): Promise<AccountPreferences> {\n return this.send('GET', '/preferences/global');\n }\n\n /** Substitui o documento global (até 16 KB). */\n saveGlobalPreferences(preferences: Record<string, unknown>): Promise<AccountPreferences> {\n return this.send('PUT', '/preferences/global', { preferences });\n }\n\n private async send<T>(method: AccountMethodVerb, path: string, body?: object): Promise<T> {\n try {\n return await this.request<T>(method, path, body);\n } catch (err) {\n if (!(err instanceof HttpErrorResponse && err.status === 401 && err.error?.error === 'invalid_token')) throw err;\n await this.auth.silentRenew();\n return this.request<T>(method, path, body);\n }\n }\n\n private request<T>(method: AccountMethodVerb, path: string, body?: object): Promise<T> {\n if (!this.baseUrl) return Promise.reject(new Error('[hermes-spine] API da conta sem AUTH_CONFIG (authority/realmId).'));\n const headers = new HttpHeaders({ Authorization: `Bearer ${this.auth.getToken() ?? ''}` });\n return firstValueFrom(this.http.request<T>(method, `${this.baseUrl}${path}`, { body, headers }));\n }\n}\n\ntype AccountMethodVerb = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\n/** Código de erro que o Argos devolveu (`{ error: 'invalid_code' }`), ou `''`. */\nexport function accountErrorCode(err: unknown): string {\n if (!(err instanceof HttpErrorResponse)) return '';\n const code = (err.error as { error?: unknown } | null)?.error;\n return typeof code === 'string' ? code : err.status === 0 ? 'network' : '';\n}\n","import { DestroyRef, Injectable, PLATFORM_ID, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { HERMES_THEME_CONFIG, HermesDensity, HermesSidebarService, HermesThemeMode, HermesThemeService } from '@trismegisto/angular';\nimport {\n DensityService, SPINE_CONFIG, SpineHourCyclePreference, SpinePreferencesService, SpineQuickAccessService, SpineStartPagePreference,\n ThemePresetService, ThemeService,\n} from '@trismegisto/spine';\nimport { HermesFont, HermesMotionPreference, Weekday } from '@trismegisto/primitives';\nimport { SpineAccountSecurityService } from '../settings/account-security.service';\n\n/** Versão do documento guardado na conta (muda só se o formato deixar de ser compatível). */\nconst DOC_VERSION = 1;\n/** Espera depois da última mudança antes de gravar. */\nexport const SPINE_PREFERENCES_SAVE_DELAY_MS = 1500;\n/** Favoritos guardados na conta (o servidor aceita até 16 KB no documento inteiro). */\nconst MAX_FAVORITES = 40;\n/** Quanto o login espera a conta responder antes de seguir com o que está no navegador. */\nconst READY_TIMEOUT_MS = 2000;\n/** `<prefixo do tema>_setup_done`: configuração inicial feita neste navegador. */\nconst SETUP_DONE_SUFFIX = '_setup_done';\n\n/** Documento de preferências guardado no Argos (`PUT {api}/preferences`): chaves planas, todas opcionais. */\nexport interface SpineAccountPreferencesDoc {\n v: number;\n themeMode?: HermesThemeMode;\n family?: string;\n density?: HermesDensity;\n font?: string;\n sidebar?: 'auto' | 'fixed' | 'compact';\n language?: string;\n timeZone?: string;\n textScale?: number;\n motion?: HermesMotionPreference;\n hourCycle?: SpineHourCyclePreference;\n weekStart?: Weekday | null;\n characterKeys?: boolean;\n idleMinutes?: number;\n startPage?: SpineStartPagePreference;\n notices?: Record<string, boolean>;\n browserNotices?: boolean;\n /** Dividir a área de abas em painéis (`SpinePreferencesService.splitTabs`). */\n splitTabs?: boolean;\n favorites?: unknown[];\n}\n\n/**\n * Chaves que são da pessoa, não do app: com o Argos que tem `{api}/preferences/global`, vão no documento global e\n * valem em todos os apps (escolhidas uma vez). O resto (menu lateral, dividir abas, atalhos, inatividade, tela inicial,\n * avisos, favoritos) continua no documento do app.\n */\nexport const SPINE_GLOBAL_PREFERENCE_KEYS = [\n 'themeMode', 'family', 'density', 'font', 'textScale', 'motion', 'language', 'timeZone', 'hourCycle', 'weekStart',\n] as const satisfies readonly (keyof SpineAccountPreferencesDoc)[];\n\n/** Documento global (`PUT {api}/preferences/global`): aparência e região, mais a configuração inicial feita. */\nexport type SpineGlobalPreferencesDoc = Pick<SpineAccountPreferencesDoc, 'v' | (typeof SPINE_GLOBAL_PREFERENCE_KEYS)[number]> & {\n /** A configuração inicial já foi feita (ou pulada): não aparece de novo em nenhum app. */\n setupDone?: boolean;\n};\n\n/** `local`: só no navegador (recurso desligado, sem API da conta, ou Argos sem o endpoint). */\nexport type SpineAccountPreferencesStatus = 'idle' | 'local' | 'loading' | 'saving' | 'synced' | 'error';\n\n/**\n * Preferências na conta (`SpineFeatures.accountPreferences`): espelha no Argos (`GET/PUT {api}/preferences`, por\n * usuário e aplicação) o que o painel de configurações guarda no navegador — tema, cor, densidade, fonte, menu\n * lateral, dividir abas, idioma, fuso, relógio, primeiro dia da semana, tamanho do texto, animações, atalhos de tecla\n * única, inatividade, tela inicial, tipos de aviso e favoritos. As telas Aparência, Região etc. não mudam: o\n * armazenamento local continua sendo a fonte de cada tela, e este serviço só sincroniza.\n *\n * - No início da sessão (`start()`, chamado pelo layout e pelo `/callback`), lê a conta e aplica o que estiver lá\n * (pelos mesmos `set*` das telas); favoritos são somados (os da conta primeiro). Conta vazia recebe o que está no\n * navegador.\n * - Depois, cada mudança é gravada na conta, agrupada (`SPINE_PREFERENCES_SAVE_DELAY_MS`).\n * - Sem a API da conta, com o recurso desligado ou com um Argos que não tem o endpoint (404/400), fica só no\n * navegador (`status() === 'local'`), sem erro na tela.\n * - Com o documento global (`{api}/preferences/global`), a aparência e a região (`SPINE_GLOBAL_PREFERENCE_KEYS`)\n * vão nele e valem em todos os apps; o do app fica com o resto. Na leitura, o do app é aplicado primeiro (o que\n * ele ainda tiver de antes do global) e o global por cima. Argos sem a rota global: tudo no do app, como antes.\n *\n * Também guarda se a configuração inicial já foi feita (`setupDone`): no documento global quando há, senão no\n * navegador. Quem já tinha aparência guardada (na conta ou no navegador) conta como feita.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineAccountPreferencesService {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly api = inject(SpineAccountSecurityService);\n private readonly preferences = inject(SpinePreferencesService);\n private readonly quickAccess = inject(SpineQuickAccessService);\n private readonly hermesTheme = inject(HermesThemeService);\n private readonly themeConfig = inject(HERMES_THEME_CONFIG);\n private readonly theme = inject(ThemeService);\n private readonly density = inject(DensityService);\n private readonly presets = inject(ThemePresetService);\n private readonly sidebar = inject(HermesSidebarService);\n\n /** Recurso ligado e API da conta disponível. */\n readonly enabled = !!inject(SPINE_CONFIG, { optional: true })?.features?.accountPreferences && this.api.available;\n readonly status = signal<SpineAccountPreferencesStatus>(this.enabled ? 'idle' : 'local');\n /** Hora da última leitura/gravação bem-sucedida. */\n readonly syncedAt = signal<Date | null>(null);\n /** Configuração inicial feita (ou pulada). `null` enquanto a conta não respondeu. */\n readonly setupDone = signal<boolean | null>(this.enabled ? null : this.localSetupDone());\n\n /** O documento que o navegador tem agora. */\n readonly snapshot = computed<SpineAccountPreferencesDoc>(() => {\n const p = this.preferences;\n return {\n v: DOC_VERSION,\n themeMode: this.hermesTheme.mode(),\n family: this.hermesTheme.family(),\n density: this.hermesTheme.density(),\n font: this.hermesTheme.font(),\n sidebar: this.sidebar.mode(),\n language: p.language(),\n timeZone: p.timeZone(),\n textScale: p.textScale(),\n motion: p.motion(),\n hourCycle: p.hourCycle(),\n weekStart: p.weekStart(),\n characterKeys: p.characterKeys(),\n idleMinutes: p.idleMinutes(),\n startPage: p.startPage(),\n notices: { ...p.noticeTypes() },\n browserNotices: p.browserNotices(),\n splitTabs: p.splitTabs(),\n favorites: this.quickAccess.favorites().slice(0, MAX_FAVORITES).map((f) => ({ ...f })),\n };\n });\n\n private loaded = false;\n /** O Argos tem o documento global (lido com sucesso nesta sessão). */\n private globalOn = false;\n private lastSaved = '';\n private lastSavedGlobal = '';\n private timer: ReturnType<typeof setTimeout> | null = null;\n private readyPromise: Promise<void> | null = null;\n\n constructor() {\n if (!this.enabled || !this.browser) return;\n effect(() => {\n const { app, global } = this.split();\n if (!this.loaded || (stable(app) === this.lastSaved && (!global || stable(global) === this.lastSavedGlobal))) return;\n untracked(() => this.schedule());\n });\n inject(DestroyRef).onDestroy(() => this.clearTimer());\n }\n\n /**\n * Lê a conta e aplica (uma vez por sessão do app; chamadas seguintes devolvem a mesma promessa). Nunca rejeita.\n */\n start(): Promise<void> {\n if (!this.enabled || !this.browser) return Promise.resolve();\n this.readyPromise ??= this.load();\n return this.readyPromise;\n }\n\n /** Como `start()`, mas sem esperar mais que `timeoutMs` (o login não fica parado se o Argos demorar). */\n ready(timeoutMs = READY_TIMEOUT_MS): Promise<void> {\n return Promise.race([this.start(), new Promise<void>((resolve) => setTimeout(resolve, timeoutMs))]);\n }\n\n /** Grava agora o que estiver pendente (\"Sincronizar agora\"); relê a conta se ela ainda não respondeu. */\n async syncNow(): Promise<void> {\n if (!this.enabled) return;\n if (!this.loaded) {\n this.readyPromise = this.load();\n await this.readyPromise;\n return;\n }\n this.clearTimer();\n await this.save(true);\n }\n\n /** Marca a configuração inicial como feita (concluída ou pulada): vai para a conta com o resto, ou fica aqui. */\n completeSetup(): void {\n this.writeLocalSetupDone();\n this.setupDone.set(true);\n }\n\n private async load(): Promise<void> {\n this.status.set('loading');\n try {\n const [{ preferences }, global] = await Promise.all([this.api.preferences(), this.loadGlobal()]);\n const remote = isDoc(preferences) ? preferences : null;\n const remoteGlobal = global && isDoc(global) ? (global as SpineGlobalPreferencesDoc) : null;\n this.globalOn = global !== null;\n if (remote) this.apply(remote);\n if (remoteGlobal) this.apply(remoteGlobal);\n // Feita: marcada no global, ou a pessoa já tinha aparência guardada (no app, de antes do global, ou aqui).\n const done = remoteGlobal?.setupDone === true || remote?.themeMode !== undefined\n || remoteGlobal?.themeMode !== undefined || this.localSetupDone();\n if (done) this.writeLocalSetupDone();\n this.setupDone.set(done);\n this.loaded = true;\n this.syncedAt.set(new Date());\n this.lastSaved = remote ? stable(remote) : '';\n this.lastSavedGlobal = remoteGlobal ? stable(remoteGlobal) : '';\n const { app, global: next } = this.split();\n // A conta pode ter menos do que o navegador (favoritos somados, chave nova, documento vazio): grava a diferença.\n if (!remote || (next && !remoteGlobal)) await this.save();\n else if (stable(app) !== this.lastSaved || (next && stable(next) !== this.lastSavedGlobal)) this.schedule();\n else this.status.set('synced');\n } catch (err) {\n this.failed(err);\n }\n }\n\n /** O documento global, ou `null` quando o Argos não tem a rota (versão anterior): aí tudo fica no do app. */\n private async loadGlobal(): Promise<Record<string, unknown> | null> {\n try {\n return (await this.api.globalPreferences()).preferences ?? {};\n } catch (err) {\n if (err instanceof HttpErrorResponse && (err.status === 404 || err.status === 405)) return null;\n throw err;\n }\n }\n\n /** O que vai em cada documento agora. Sem o global, tudo no do app. */\n private split(): { app: SpineAccountPreferencesDoc; global: SpineGlobalPreferencesDoc | null } {\n const snapshot = this.snapshot();\n const setupDone = this.setupDone() === true;\n if (!this.globalOn) return { app: snapshot, global: null };\n const app: Record<string, unknown> = { ...snapshot };\n const global: Record<string, unknown> = { v: DOC_VERSION };\n for (const key of SPINE_GLOBAL_PREFERENCE_KEYS) {\n global[key] = snapshot[key];\n delete app[key];\n }\n if (setupDone) global['setupDone'] = true;\n return { app: app as unknown as SpineAccountPreferencesDoc, global: global as SpineGlobalPreferencesDoc };\n }\n\n /** Aplica o documento da conta pelos mesmos caminhos das telas (cada `set*` também grava no navegador). */\n private apply(doc: SpineAccountPreferencesDoc): void {\n const p = this.preferences;\n if (doc.themeMode && doc.themeMode !== this.hermesTheme.mode()) this.theme.setMode(doc.themeMode);\n if (doc.family && doc.family !== this.hermesTheme.family()) {\n const family = this.presets.families.find((f) => f.id === (this.themeConfig.aliases?.[doc.family!] ?? doc.family));\n if (family) this.presets.setPreset(family);\n }\n if (doc.density && doc.density !== this.hermesTheme.density()) this.density.setDensity(doc.density);\n if (doc.font && doc.font !== this.hermesTheme.font()) {\n const fonts = this.hermesTheme.fonts ?? [];\n if (!fonts.length || fonts.some((f) => f.id === doc.font)) this.hermesTheme.setFont(doc.font as HermesFont);\n }\n if (doc.sidebar && doc.sidebar !== this.sidebar.mode()) this.sidebar.setMode(doc.sidebar);\n if (typeof doc.language === 'string' && doc.language !== p.language()) p.setLanguage(doc.language);\n if (typeof doc.timeZone === 'string' && doc.timeZone !== p.timeZone()) p.setTimeZone(doc.timeZone);\n if (typeof doc.textScale === 'number' && doc.textScale !== p.textScale()) p.setTextScale(doc.textScale);\n if (doc.motion && doc.motion !== p.motion()) p.setMotion(doc.motion);\n if (doc.hourCycle !== undefined && doc.hourCycle !== p.hourCycle()) p.setHourCycle(doc.hourCycle);\n if (doc.weekStart !== undefined && doc.weekStart !== p.weekStart()) p.setWeekStart(doc.weekStart);\n if (typeof doc.characterKeys === 'boolean' && doc.characterKeys !== p.characterKeys()) p.setCharacterKeys(doc.characterKeys);\n if (typeof doc.idleMinutes === 'number' && doc.idleMinutes !== p.idleMinutes()) p.setIdleMinutes(doc.idleMinutes);\n if (typeof doc.startPage === 'string' && doc.startPage !== p.startPage()) p.setStartPage(doc.startPage);\n if (doc.notices && typeof doc.notices === 'object') p.setNoticeTypes({ ...p.noticeTypes(), ...doc.notices });\n // O aviso do navegador depende da permissão DESTE navegador: a conta só desliga, nunca liga sozinha.\n if (doc.browserNotices === false && p.browserNotices()) p.setBrowserNotices(false);\n if (typeof doc.splitTabs === 'boolean' && doc.splitTabs !== p.splitTabs()) p.setSplitTabs(doc.splitTabs);\n if (Array.isArray(doc.favorites)) {\n const remote = doc.favorites;\n const ids = new Set(remote.map((f) => (f as { id?: unknown })?.id));\n const localOnly = this.quickAccess.favorites().filter((f) => !ids.has(f.id));\n this.quickAccess.setFavorites([...remote, ...localOnly]);\n }\n }\n\n private schedule(): void {\n this.clearTimer();\n this.status.set('saving');\n this.timer = setTimeout(() => void this.save(), SPINE_PREFERENCES_SAVE_DELAY_MS);\n }\n\n /** Grava o que mudou desde a última gravação (`force`: os dois documentos, mudados ou não). */\n private async save(force = false): Promise<void> {\n this.timer = null;\n const { app, global } = this.split();\n const json = stable(app);\n const globalJson = global ? stable(global) : '';\n this.status.set('saving');\n try {\n await Promise.all([\n force || json !== this.lastSaved ? this.api.savePreferences(app as unknown as Record<string, unknown>) : null,\n global && (force || globalJson !== this.lastSavedGlobal) ? this.api.saveGlobalPreferences(global as Record<string, unknown>) : null,\n ]);\n this.lastSaved = json;\n if (global) this.lastSavedGlobal = globalJson;\n this.syncedAt.set(new Date());\n this.status.set('synced');\n } catch (err) {\n this.failed(err);\n }\n }\n\n private failed(err: unknown): void {\n // A configuração inicial não fica presa esperando a conta: vale o que o navegador sabe.\n if (this.setupDone() === null) this.setupDone.set(this.localSetupDone());\n // Argos sem o endpoint (versão anterior) ou sem client no token: fica só no navegador, sem insistir.\n if (err instanceof HttpErrorResponse && (err.status === 404 || err.status === 400 || err.status === 405)) {\n this.status.set('local');\n this.loaded = false;\n return;\n }\n this.status.set('error');\n }\n\n /** Configuração inicial feita neste navegador, ou aparência já escolhida aqui antes de ela existir. */\n private localSetupDone(): boolean {\n if (!this.browser) return true;\n const prefix = this.themeConfig.storagePrefix;\n try {\n return [SETUP_DONE_SUFFIX, '_theme_mode', '_theme', '_theme_family', '_density', '_font']\n .some((suffix) => localStorage.getItem(`${prefix}${suffix}`) !== null);\n } catch {\n return true; // sem localStorage não dá para lembrar: não insiste a cada entrada\n }\n }\n\n private writeLocalSetupDone(): void {\n try {\n localStorage.setItem(`${this.themeConfig.storagePrefix}${SETUP_DONE_SUFFIX}`, '1');\n } catch {\n /* sem localStorage */\n }\n }\n\n private clearTimer(): void {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n }\n}\n\n/** JSON com as chaves dos objetos em ordem (a conta pode devolver outra ordem). */\nexport function stable(value: unknown): string {\n return JSON.stringify(value, (_key, v: unknown) =>\n v && typeof v === 'object' && !Array.isArray(v)\n ? Object.fromEntries(Object.entries(v as Record<string, unknown>).sort(([a], [b]) => a.localeCompare(b)))\n : v);\n}\n\nfunction isDoc(value: unknown): value is SpineAccountPreferencesDoc {\n return !!value && typeof value === 'object' && !Array.isArray(value) && typeof (value as { v?: unknown }).v === 'number';\n}\n","import { Injectable, Injector, effect, inject, signal, untracked } from '@angular/core';\nimport { SPINE_CONFIG } from '@trismegisto/spine';\nimport { SpineAccountPreferencesService } from '../account-preferences/account-preferences.service';\n\n/** `full`: aparência e depois o essencial (primeiro acesso, \"Refazer\"). `essentials`: só os cartões do essencial. */\nexport type SpineInitialSetupMode = 'full' | 'essentials';\n\n/** Etapa na tela: a escolha de aparência ou os cartões do essencial. */\nexport type SpineInitialSetupStep = 'appearance' | 'essentials';\n\n/**\n * Configuração inicial em tela cheia (`spine-initial-setup`, montada no layout): no primeiro acesso a pessoa escolhe\n * tema, cor, densidade, tamanho do texto, fonte e animações, com a prévia ao lado, e depois vê o essencial (busca,\n * abas, favoritos, configurações). Pode pular a qualquer momento: pular também conta como feita.\n *\n * \"Feita\" é da pessoa, não do app (`SpineAccountPreferencesService.setupDone`, no documento global do Argos): quem\n * fez num sistema não a vê de novo em outro. Sem a conta, fica no navegador. Desligada com\n * `SpineFeatures.initialSetup: false`.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineInitialSetupService {\n private readonly preferences = inject(SpineAccountPreferencesService);\n private readonly injector = inject(Injector);\n\n /** Ligada (padrão) ou desligada pelo app (`SpineFeatures.initialSetup: false`). */\n readonly enabled = inject(SPINE_CONFIG, { optional: true })?.features?.initialSetup !== false;\n readonly isOpen = signal(false);\n readonly mode = signal<SpineInitialSetupMode>('full');\n readonly step = signal<SpineInitialSetupStep>('appearance');\n\n private asked = false;\n\n /**\n * Chamado uma vez pelo layout na entrada: abre se a configuração ainda não foi feita. Espera a conta responder\n * (`setupDone` deixa de ser `null`), sem prazo: quem decide é a conta, e a falha dela cai no que o navegador sabe.\n */\n maybeOpen(): void {\n if (!this.enabled || this.asked) return;\n this.asked = true;\n if (this.decide()) return;\n const watcher = effect(() => {\n if (this.preferences.setupDone() === null) return;\n untracked(() => this.decide());\n watcher.destroy();\n }, { injector: this.injector });\n }\n\n /** Abre a configuração inteira (aparência e o essencial), mesmo já feita: \"Refazer\" nas configurações. */\n open(): void {\n this.mode.set('full');\n this.step.set('appearance');\n this.isOpen.set(true);\n }\n\n /** Só os cartões do essencial (\"Rever o essencial\": menu do perfil, atalhos, tela inicial). */\n openEssentials(): void {\n this.mode.set('essentials');\n this.step.set('essentials');\n this.isOpen.set(true);\n }\n\n next(): void {\n if (this.step() === 'appearance') this.step.set('essentials');\n else this.finish();\n }\n\n back(): void {\n if (this.mode() === 'full' && this.step() === 'essentials') this.step.set('appearance');\n }\n\n /** Concluída ou pulada: marca como feita e fecha. */\n finish(): void {\n if (this.mode() === 'full') this.preferences.completeSetup();\n this.isOpen.set(false);\n }\n\n /** `true` quando já deu para decidir (feita ou aberta agora). */\n private decide(): boolean {\n const done = this.preferences.setupDone();\n if (done === null) return false;\n if (!done) this.open();\n return true;\n }\n}\n","import { HttpHeaders } from '@angular/common/http';\nimport { firstValueFrom, filter, type Observable } from 'rxjs';\nimport type { AuthorizationService } from '@orfeu/angular/core';\n\n/** O que o helper usa do `AuthorizationService` além do `getToken()`. */\ninterface SessionAware {\n readonly authenticated?: boolean;\n readonly isAuth$?: Observable<boolean>;\n}\n\n/** Monta a requisição com os cabeçalhos dados (assinatura de chamada: o check-strings lê `=> Tipo<` como texto). */\ninterface SessionRequest<T> {\n (headers: HttpHeaders): Observable<T>;\n}\n\n/**\n * Manda uma requisição ao argos-admin com o token da sessão em `x-access-token`. Com token na mão, sai na hora (token\n * vencido é com o interceptor do Orfeu, que troca pelo renovado). Sem token ainda — o cabeçalho, as novidades e a\n * avaliação chamam a API assim que aparecem, às vezes antes de o Orfeu restaurar a sessão —, espera a sessão ser\n * aplicada (`isAuth$`) em vez de sair sem token (o servidor respondia \"Access token required\"). Orfeu sem `isAuth$`, ou\n * sem `AuthorizationService` (app ou teste sem Orfeu): sai com o que houver.\n */\nexport function sendWithSession<T>(\n auth: AuthorizationService | null | undefined,\n send: SessionRequest<T>,\n): Promise<T> {\n const now = auth?.getToken();\n if (now || !auth) return firstValueFrom(send(tokenHeaders(now)));\n const session = auth as unknown as SessionAware;\n if (!session.isAuth$ || session.authenticated !== false) return firstValueFrom(send(tokenHeaders(now)));\n return firstValueFrom(session.isAuth$.pipe(filter(Boolean))).then(() => firstValueFrom(send(tokenHeaders(auth.getToken()))));\n}\n\nfunction tokenHeaders(token: string | null | undefined): HttpHeaders {\n return new HttpHeaders({ 'x-access-token': token ?? '' });\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable, Injector, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { HermesToastService } from '@trismegisto/angular';\nimport { SPINE_ADMIN_API, SPINE_CONFIG, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { formatMessage, urlPath } from '@trismegisto/primitives';\nimport { SpineAccountPreferencesService } from '../account-preferences/account-preferences.service';\nimport { SpineInitialSetupService } from '../setup/initial-setup.service';\nimport { sendWithSession } from '../session-token';\n\n/** Espera depois da entrada (ou do fim da configuração inicial) antes do aviso, para não emendar com ela. */\nconst ANNOUNCE_DELAY_MS = 1200;\n/** Quantas das mais recentes a entrada lê: decidem o aviso, a contagem do menu e o card do Início. */\nconst LATEST_LIMIT = 20;\n\n/** Quem escreveu a novidade, como o argos-admin devolve (nome ou usuário, e a foto). */\nexport interface SpineNewsAuthor {\n readonly name: string;\n readonly picture: string | null;\n}\n\n/**\n * Tipo da novidade: só texto (`informativo`); \"o que há de novo\", com introdução e a lista de mudanças\n * (`implementacao`); ou \"como era x como ficou\", com introdução e o antes e o agora (`alteracao`).\n */\nexport type SpineNewsKind = 'informativo' | 'implementacao' | 'alteracao';\n\n/** Uma novidade na lista (`GET /me/news`): sem o corpo. */\nexport interface SpineNewsSummary {\n readonly id: string;\n /** Servidor antigo não manda: vale `informativo`. */\n readonly kind?: SpineNewsKind;\n readonly title: string;\n readonly summary: string;\n readonly published_at: string;\n readonly author: SpineNewsAuthor | null;\n}\n\n/**\n * Uma novidade aberta (`GET /me/news/:id`): com o conteúdo, já saneado pelo servidor ao gravar. `body_html` é o texto\n * (no informativo) ou a introdução (nos outros tipos); `items` é a lista da implementação; `before_html` e `after_html`,\n * os dois lados da alteração.\n */\nexport interface SpineNewsDetail extends SpineNewsSummary {\n readonly body_html: string;\n readonly items?: readonly string[];\n readonly before_html?: string;\n readonly after_html?: string;\n /** Alterada depois de publicada: quem editou por último e quando (servidor antigo não manda). */\n readonly edited?: (SpineNewsAuthor & { readonly at: string }) | null;\n}\n\n/** Uma página da lista. */\nexport interface SpineNewsPage {\n readonly news: readonly SpineNewsSummary[];\n readonly total: number;\n readonly page: number;\n readonly limit: number;\n}\n\n/**\n * Novidades do app, escritas por quem o administra (auto-serviço ou painel central do Argos) e lidas de\n * `argos-admin /me/news` — sempre da aplicação LOGADA e só as publicadas, na validade e para o público da pessoa (o\n * servidor filtra). Sem `SPINE_ADMIN_API` (ou sem HTTP) não há novidades e nada aparece, sem erro.\n *\n * Sem interromper ninguém:\n * - na entrada (`announceOnEntry`), lê as mais recentes e avisa no canto as ainda não anunciadas (\"Novidade: …\" ou\n * \"N novidades\", com \"Ver\"), uma vez por novidade e depois da configuração inicial;\n * - o menu do perfil mostra quantas faltam ver (`unseenCount`) e o Início lista as primeiras (`highlights`);\n * - \"Ver\" (aviso, menu, Início, configurações) abre o painel lateral (`showAll`), paginado; abrir uma novidade\n * (`markSeen`) a marca como vista.\n *\n * \"Anunciada\", \"vista\" e \"favorita\" são por app, por navegador e por id (`hermes_<clientId>_news_*`): novidade de um\n * app não some por ter sido vista em outro no mesmo domínio. \"Marcar como não lida\" (`markUnseen`) desfaz o \"vista\".\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineNewsService {\n // Opcionais: o cabeçalho, o painel de configurações e o Início injetam este serviço sempre; app (ou teste) sem HTTP\n // nem Orfeu só fica sem novidades.\n private readonly http = inject(HttpClient, { optional: true });\n private readonly auth = inject(AuthorizationService, { optional: true });\n private readonly adminApi = inject(SPINE_ADMIN_API, { optional: true });\n private readonly toast = inject(HermesToastService);\n private readonly text = inject(SPINE_MESSAGES).news;\n private readonly setup = inject(SpineInitialSetupService);\n private readonly preferences = inject(SpineAccountPreferencesService);\n private readonly injector = inject(Injector);\n private readonly seenKey: string;\n private readonly announcedKey: string;\n private readonly favoritesKey: string;\n\n /** Há onde buscar (argos-admin configurado). */\n readonly available = !!this.adminApi && !!this.http;\n readonly isOpen = signal(false);\n /** Novidade a abrir junto com o painel (o Início pede uma específica); o painel consome e limpa. */\n readonly requested = signal<string | null>(null);\n /** As mais recentes (primeira página), lidas em `refresh`. */\n readonly latest = signal<readonly SpineNewsSummary[]>([]);\n /** Há alguma novidade para a pessoa — o item \"Novidades\" do menu só aparece com isto. */\n readonly hasAny = computed(() => this.latest().length > 0);\n /** As mais recentes para o card do Início; `unseen` = ainda não aberta neste navegador. */\n readonly highlights = computed(() => {\n this.seenVersion();\n const seen = this.read(this.seenKey);\n return this.latest().map((n) => ({ id: n.id, title: n.title, text: n.summary, unseen: !seen.has(n.id) }));\n });\n /** Quantas das mais recentes ainda não foram abertas (a contagem do menu do perfil). */\n readonly unseenCount = computed(() => this.highlights().filter((h) => h.unseen).length);\n /** Muda quando o \"já visto\" é gravado, para quem lê `isUnseen`/`highlights` reler. */\n readonly seenVersion = signal(0);\n /** Muda quando os favoritos mudam, para quem lê `isFavorite` reler. */\n readonly favoritesVersion = signal(0);\n\n private announced = false;\n\n constructor() {\n const ns = inject(SPINE_CONFIG, { optional: true })?.clientId;\n const prefix = ns ? `hermes_${ns}` : 'hermes';\n this.seenKey = `${prefix}_news_seen`;\n this.announcedKey = `${prefix}_news_announced`;\n this.favoritesKey = `${prefix}_news_favorites`;\n }\n\n /** Relê as mais recentes; qualquer falha deixa a lista vazia (o item some em vez de mostrar um erro sem contexto). */\n async refresh(): Promise<void> {\n if (!this.available) return;\n try {\n const res = await this.page(1, LATEST_LIMIT);\n this.latest.set(res.news ?? []);\n } catch {\n this.latest.set([]);\n }\n }\n\n /** Uma página da lista (`page` a partir de 1). Falha propaga: o painel mostra o erro com \"Tentar de novo\". */\n page(page: number, limit: number): Promise<SpineNewsPage> {\n return sendWithSession(this.auth, (headers) => this.http!.get<SpineNewsPage>(`${this.adminApi}/me/news`, {\n headers,\n params: { page, limit },\n }));\n }\n\n /** Uma novidade com o corpo. */\n detail(id: string): Promise<SpineNewsDetail> {\n return sendWithSession(this.auth, (headers) => this.http!.get<SpineNewsDetail>(`${this.adminApi}/me/news${urlPath`/${id}`}`, { headers }));\n }\n\n /**\n * Chamado uma vez pelo layout na entrada: lê as mais recentes, espera a configuração inicial se decidir (e terminar,\n * se abriu) e avisa no canto as ainda não anunciadas. Nunca abre o painel sozinho.\n */\n async announceOnEntry(): Promise<void> {\n if (this.announced || !this.available) return;\n this.announced = true;\n await this.refresh();\n if (this.pending().length === 0) return;\n const watcher = effect(() => {\n const done = this.preferences.setupDone();\n // Sem decisão ainda, ou a configuração vai abrir (ou está aberta): espera.\n if (done === null || this.setup.isOpen() || (!done && this.setup.enabled)) return;\n watcher.destroy();\n untracked(() => setTimeout(() => this.announce(), ANNOUNCE_DELAY_MS));\n }, { injector: this.injector });\n }\n\n /** Abre o painel lateral com a lista; as mais recentes deixam de ser anunciadas (o selo \"Nova\" fica até abrir). */\n showAll(): void {\n this.write(this.announcedKey, this.latest().map((n) => n.id));\n this.isOpen.set(true);\n }\n\n /** Abre o painel já com uma novidade aberta (o card do Início). */\n showItem(id: string): void {\n this.requested.set(id);\n this.showAll();\n }\n\n close(): void {\n this.isOpen.set(false);\n this.requested.set(null);\n }\n\n /** Ainda não aberta neste navegador. Lê `seenVersion` (reage a `markSeen`). */\n isUnseen(id: string): boolean {\n this.seenVersion();\n return !this.read(this.seenKey).has(id);\n }\n\n /** Abriu a novidade: vista (e anunciada) neste navegador. */\n markSeen(id: string): void {\n this.write(this.seenKey, [id]);\n this.write(this.announcedKey, [id]);\n this.seenVersion.update((v) => v + 1);\n }\n\n /** \"Marcar como não lida\": volta o selo \"Nova\" (e conta de novo no menu e no Início); não volta a ser anunciada. */\n markUnseen(id: string): void {\n this.remove(this.seenKey, id);\n this.seenVersion.update((v) => v + 1);\n }\n\n /** Favorita neste navegador. Lê `favoritesVersion` (reage a `toggleFavorite`). */\n isFavorite(id: string): boolean {\n this.favoritesVersion();\n return this.read(this.favoritesKey).has(id);\n }\n\n /** Liga ou desliga o favorito (marcador do painel). */\n toggleFavorite(id: string): void {\n if (this.read(this.favoritesKey).has(id)) this.remove(this.favoritesKey, id);\n else this.write(this.favoritesKey, [id]);\n this.favoritesVersion.update((v) => v + 1);\n }\n\n private announce(): void {\n const pending = this.pending();\n if (pending.length === 0) return;\n this.write(this.announcedKey, pending.map((n) => n.id));\n const message = pending.length === 1\n ? formatMessage(this.text.toastOne, { title: pending[0].title })\n : formatMessage(this.text.toastMany, { count: pending.length });\n this.toast.info(message, { action: { label: this.text.see, run: () => this.showAll() } });\n }\n\n /** Mais recentes ainda não vistas nem anunciadas. */\n private pending(): readonly SpineNewsSummary[] {\n const seen = this.read(this.seenKey);\n const announced = this.read(this.announcedKey);\n return this.latest().filter((n) => !seen.has(n.id) && !announced.has(n.id));\n }\n\n private read(key: string): Set<string> {\n try {\n return new Set(JSON.parse(localStorage.getItem(key) || '[]') as string[]);\n } catch {\n return new Set();\n }\n }\n\n private remove(key: string, id: string): void {\n try {\n const set = this.read(key);\n if (!set.delete(id)) return;\n localStorage.setItem(key, JSON.stringify([...set]));\n } catch {\n /* sem localStorage: nada guardado, nada a tirar */\n }\n }\n\n private write(key: string, ids: readonly string[]): void {\n if (ids.length === 0) return;\n try {\n const set = this.read(key);\n ids.forEach((id) => set.add(id));\n localStorage.setItem(key, JSON.stringify([...set]));\n } catch {\n /* sem localStorage: avisa de novo na próxima entrada, sem quebrar nada */\n }\n }\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable, inject, signal } from '@angular/core';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { SPINE_ADMIN_API, SPINE_CONFIG } from '@trismegisto/spine';\nimport { sendWithSession } from '../session-token';\n\n/** O que se avalia: a ferramenta inteira (`app`) ou uma tela (`screen`). */\nexport type SpineRatingScope = 'app' | 'screen';\n\n/** Alvo de uma avaliação. Tela: `screenPath` é a chave (a rota); `screenLabel`, o caminho legível que vai junto. */\nexport interface SpineRatingTarget {\n scope: SpineRatingScope;\n screenPath?: string | null;\n screenLabel?: string | null;\n}\n\n/** A avaliação da pessoa como o argos-admin devolve (`/me/ratings`). */\nexport interface SpineRating {\n scope: SpineRatingScope;\n screen_path: string | null;\n screen_label: string | null;\n /** 0 a 10 (10 = 5 estrelas; 7 = 3,5). */\n score: number;\n comment: string | null;\n created_at: string;\n updated_at: string;\n}\n\n/** Média da ferramenta que qualquer pessoa logada vê (`/me/ratings/summary`): 0 a 10 com uma casa, ou `null`. */\nexport interface SpineRatingAverage {\n average: number | null;\n total: number;\n}\n\n/** Chave de um alvo (\"app\" ou \"screen:<rota>\"): o que foi avaliado nesta sessão e a troca de alvo da janela. */\nexport const ratingTargetKey = (t: SpineRatingTarget) => (t.scope === 'screen' ? `screen:${t.screenPath ?? ''}` : 'app');\nconst keyOf = ratingTargetKey;\n\n/** Teto do comentário (o mesmo do servidor e da coluna). */\nexport const SPINE_RATING_COMMENT_MAX = 500;\n\n/**\n * Avaliações da pessoa (nota de 0 a 10, 5 estrelas com meia, e um comentário) — `argos-admin /me/ratings`, sempre da\n * aplicação LOGADA (o servidor tira o client do token da sessão) e uma por escopo/tela: avaliar de novo substitui. Liga\n * com `SpineFeatures.ratings` e só com `SPINE_ADMIN_API`; sem os dois, `enabled` é falso e nada de avaliação aparece.\n *\n * `windowTarget` é o que a janela de avaliação (flutuante, montada no cabeçalho) está avaliando: `openApp` (a estrela\n * do cabeçalho e Configurações › Sobre) e `openScreen` (a estrela da barra da página) trocam o alvo da mesma janela, e\n * `closeWindow` fecha. `appRated` diz se a pessoa já avaliou a ferramenta (a estrela do cabeçalho fica cheia) e\n * `appAverage` é a média da ferramenta (Configurações › Sobre); os dois são lidos uma vez, por quem os mostra.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineRatingsService {\n // Opcionais: a barra da página e o cabeçalho injetam este serviço sempre, e um app (ou teste) sem HTTP nem Orfeu só\n // fica sem o recurso, em vez de quebrar a injeção da barra inteira.\n private readonly http = inject(HttpClient, { optional: true });\n private readonly auth = inject(AuthorizationService, { optional: true });\n private readonly adminApi = inject(SPINE_ADMIN_API, { optional: true });\n\n /** Ligado por padrão (como as sugestões): só `features.ratings: false` desliga; sem a API da conta ou HTTP, nada. */\n readonly enabled = inject(SPINE_CONFIG, { optional: true })?.features?.ratings !== false && !!this.adminApi && !!this.http;\n /** O que a janela de avaliação está avaliando; `null` = fechada. Uma janela só, para a ferramenta e para a tela. */\n readonly windowTarget = signal<SpineRatingTarget | null>(null);\n /** Alvos avaliados nesta sessão do app (a estrela da barra fica cheia); não pergunta ao servidor a cada tela. */\n private readonly ratedNow = signal<ReadonlySet<string>>(new Set());\n /** A pessoa já avaliou a ferramenta (servidor, lido uma vez por `checkAppRated`, ou gravado agora). */\n readonly appRated = signal(false);\n /** Média da ferramenta (`loadAppAverage`); `null` enquanto não foi lida. */\n readonly appAverage = signal<SpineRatingAverage | null>(null);\n private appRatedChecked = false;\n\n private get url(): string {\n return `${this.adminApi}/me/ratings`;\n }\n\n /** \"Avaliar o {app}\": abre a janela (ou troca o conteúdo dela) para a ferramenta. */\n openApp(): void {\n if (this.enabled) this.windowTarget.set({ scope: 'app' });\n }\n\n /** \"Avaliar esta tela\": abre a janela (ou troca o conteúdo dela) para a tela. */\n openScreen(target: SpineRatingTarget): void {\n if (this.enabled) this.windowTarget.set(target);\n }\n\n closeWindow(): void {\n this.windowTarget.set(null);\n }\n\n isRated(target: SpineRatingTarget): boolean {\n return this.ratedNow().has(keyOf(target));\n }\n\n /**\n * Lê uma vez se a pessoa já avaliou a ferramenta (a estrela do cabeçalho). Falha de rede deixa vazia, sem aviso:\n * avaliar continua funcionando, só a estrela não sabe da avaliação antiga.\n */\n async checkAppRated(): Promise<void> {\n if (!this.enabled || this.appRatedChecked) return;\n this.appRatedChecked = true;\n try {\n if (await this.mine({ scope: 'app' })) this.appRated.set(true);\n } catch {\n this.appRatedChecked = false;\n }\n }\n\n /** Média e total da ferramenta (`GET /me/ratings/summary`); quem mostra trata a falha. */\n async loadAppAverage(): Promise<SpineRatingAverage> {\n const res = await sendWithSession(this.auth, (headers) => this.http!.get<SpineRatingAverage>(`${this.url}/summary`, { headers }));\n const out = { average: res?.average ?? null, total: res?.total ?? 0 };\n this.appAverage.set(out);\n return out;\n }\n\n /** A avaliação atual da pessoa nesse alvo (para pré-preencher), ou `null` se ainda não avaliou. */\n async mine(target: SpineRatingTarget): Promise<SpineRating | null> {\n const params: Record<string, string> = { scope: target.scope };\n if (target.scope === 'screen') params['screen'] = target.screenPath ?? '';\n const res = await sendWithSession(this.auth, (headers) => this.http!.get<{ rating: SpineRating | null }>(this.url, { headers, params }));\n return res?.rating ?? null;\n }\n\n /** Cria ou atualiza a avaliação (nota 0 a 10); comentário vazio vai como `null`. */\n async save(target: SpineRatingTarget, score: number, comment: string): Promise<SpineRating> {\n const body: Record<string, unknown> = { scope: target.scope, score, comment: comment.trim() || null };\n if (target.scope === 'screen') {\n body['screen_path'] = target.screenPath ?? '';\n body['screen_label'] = target.screenLabel ?? null;\n }\n const res = await sendWithSession(this.auth, (headers) => this.http!.put<{ rating: SpineRating }>(this.url, body, { headers }));\n this.ratedNow.update((set) => new Set(set).add(keyOf(target)));\n if (target.scope === 'app') {\n this.appRated.set(true);\n // A média já mostrada (Configurações › Sobre) passa a contar a nota nova.\n if (this.appAverage()) void this.loadAppAverage().catch(() => undefined);\n }\n return res.rating;\n }\n}\n","import { ChangeDetectionStrategy, Component, ElementRef, computed, inject, input, model, signal } from '@angular/core';\nimport { IconComponent } from '@trismegisto/angular';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\n\n/** Nota máxima: 10 = 5 estrelas cheias (cada estrela vale 2, meia estrela vale 1). */\nexport const SPINE_RATING_SCORE_MAX = 10;\n\nexport type SpineScoreBand = 1 | 2 | 3 | 4 | 5;\nexport type SpineStarFill = 'empty' | 'half' | 'full';\n\n/** Faixa do rótulo qualitativo de uma nota: 0–2 ruim, 3–4 regular, 5–6 bom, 7–8 muito bom, 9–10 excelente. */\nexport function spineScoreBand(score: number): SpineScoreBand {\n return Math.min(5, Math.max(1, Math.ceil(score / 2))) as SpineScoreBand;\n}\n\n/** Preenchimento das 5 estrelas para a nota (uma média vai para a meia estrela mais próxima: 8,4 = 4 estrelas). */\nexport function spineStarFills(score: number | null | undefined): SpineStarFill[] {\n const v = score == null ? 0 : Math.round(Math.min(SPINE_RATING_SCORE_MAX, Math.max(0, score)));\n return [1, 2, 3, 4, 5].map((i) => (v >= i * 2 ? 'full' : v === i * 2 - 1 ? 'half' : 'empty'));\n}\n\n/**\n * Estrelas de uma nota de 0 a 10, com meia estrela: 10 = 5 estrelas, 7 = 3,5, 0 = nenhuma. Ao lado, a nota em número\n * (\"7/10\"; média com uma casa, \"8,4/10\").\n *\n * - `readonly`: só mostra (média do auto-serviço, Configurações › Sobre). Para o leitor é uma imagem com o nome\n * \"8,4 de 10\".\n * - editável (o formulário de avaliação): um `role=\"slider\"` de 0 a 10 com o valor falado \"7 de 10 — Muito bom\". As\n * setas mudam de meia em meia estrela (1 ponto), PageUp/PageDown de estrela em estrela, Home dá 0 e End dá 10. No\n * mouse, a metade inicial da estrela é a meia e a final é a inteira; clicar de novo na primeira metade da primeira\n * estrela (nota 1) deixa em 0. Sem nota escolhida (`null`), o valor falado é \"Sem nota\".\n *\n * Meia estrela sem desenho próprio: a estrela vazia por baixo e a cheia por cima, cortada na metade do lado inicial\n * (em RTL, o lado direito).\n */\n@Component({\n selector: 'spine-rating-stars',\n imports: [IconComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class.spine-stars-host--small]': \"size() === 'small'\",\n '[class.spine-stars-host--large]': \"size() === 'large'\",\n },\n template: `\n @if (readonly()) {\n <span class=\"spine-stars\" role=\"img\" [attr.aria-label]=\"spoken()\">\n <span class=\"spine-stars__row\" aria-hidden=\"true\">\n @for (fill of fills(); track $index) {\n <span class=\"spine-stars__star spine-stars__star--{{ fill }}\">\n <hm-icon shape=\"star\" class=\"spine-stars__base\" />\n <span class=\"spine-stars__fill\"><hm-icon shape=\"star\" [solid]=\"true\" /></span>\n </span>\n }\n </span>\n @if (showValue() && value() != null) {\n <span class=\"spine-stars__value\" aria-hidden=\"true\">{{ short() }}</span>\n }\n </span>\n } @else {\n <span\n class=\"spine-stars spine-stars--input\"\n role=\"slider\"\n tabindex=\"0\"\n aria-valuemin=\"0\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value() ?? null\"\n [attr.aria-valuetext]=\"spoken()\"\n [attr.aria-label]=\"label() || null\"\n [attr.aria-labelledby]=\"labelledBy() || null\"\n [attr.aria-describedby]=\"describedBy() || null\"\n [attr.aria-invalid]=\"invalid() || null\"\n (keydown)=\"onKey($event)\"\n (pointerleave)=\"hovered.set(null)\"\n (blur)=\"hovered.set(null)\"\n >\n <span class=\"spine-stars__row\">\n @for (fill of fills(); track $index; let i = $index) {\n <span class=\"spine-stars__star spine-stars__star--{{ fill }}\">\n <hm-icon shape=\"star\" class=\"spine-stars__base\" />\n <span class=\"spine-stars__fill\"><hm-icon shape=\"star\" [solid]=\"true\" /></span>\n <!-- As duas metades são o alvo do mouse (o teclado é do slider inteiro). -->\n <span class=\"spine-stars__half spine-stars__half--start\" aria-hidden=\"true\"\n (pointerenter)=\"hovered.set(i * 2 + 1)\" (click)=\"pick(i * 2 + 1)\"></span>\n <span class=\"spine-stars__half spine-stars__half--end\" aria-hidden=\"true\"\n (pointerenter)=\"hovered.set(i * 2 + 2)\" (click)=\"pick(i * 2 + 2)\"></span>\n </span>\n }\n </span>\n @if (showValue()) {\n <span class=\"spine-stars__value\" aria-hidden=\"true\">{{ shown() == null ? '' : short() }}</span>\n @if (named()) {\n <span class=\"spine-stars__name\" aria-hidden=\"true\">{{ named() }}</span>\n }\n }\n </span>\n }\n `,\n styles: [`\n :host { --spine-star-size: 18px; display: inline-flex; min-inline-size: 0; }\n :host(.spine-stars-host--small) { --spine-star-size: 14px; }\n :host(.spine-stars-host--large) { --spine-star-size: 28px; }\n .spine-stars { display: inline-flex; align-items: center; gap: var(--hm-space-xs); min-inline-size: 0; }\n .spine-stars__row { display: inline-flex; gap: 1px; font-size: var(--spine-star-size, 18px); line-height: 1; }\n .spine-stars__star { position: relative; display: inline-flex; color: var(--hm-muted); }\n /* A cheia por cima da vazia, cortada no lado inicial: 0, metade ou inteira. */\n .spine-stars__fill {\n position: absolute;\n inset-block: 0;\n inset-inline-start: 0;\n display: inline-flex;\n inline-size: 0;\n overflow: hidden;\n color: var(--hm-warning);\n }\n .spine-stars__star--half .spine-stars__fill { inline-size: 50%; }\n .spine-stars__star--full .spine-stars__fill { inline-size: 100%; }\n .spine-stars__value {\n color: var(--hm-text);\n font-size: var(--hm-font-size-sm, 14px);\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n }\n .spine-stars__name { color: var(--hm-muted); font-size: var(--hm-font-size-sm, 14px); white-space: nowrap; }\n /* Editável: o foco é do slider inteiro; cada metade de estrela é um alvo de clique. */\n .spine-stars--input { border-radius: var(--hm-radius-control); cursor: pointer; outline: none; }\n .spine-stars--input:focus-visible { outline: 2px solid var(--hm-focus-ring, var(--hm-action)); outline-offset: 2px; }\n .spine-stars--input .spine-stars__row { gap: var(--hm-space-micro, 2px); }\n .spine-stars--input .spine-stars__star { padding: var(--hm-space-nano, 2px); transition: transform 120ms ease; }\n .spine-stars--input .spine-stars__star:hover { transform: scale(1.08); }\n .spine-stars--input .spine-stars__fill { inset-block: var(--hm-space-nano, 2px); inset-inline-start: var(--hm-space-nano, 2px); }\n .spine-stars--input .spine-stars__star--half .spine-stars__fill { inline-size: calc(50% - var(--hm-space-nano, 2px)); }\n .spine-stars--input .spine-stars__star--full .spine-stars__fill { inline-size: calc(100% - 2 * var(--hm-space-nano, 2px)); }\n .spine-stars__half { position: absolute; inset-block: 0; inline-size: 50%; }\n .spine-stars__half--start { inset-inline-start: 0; }\n .spine-stars__half--end { inset-inline-end: 0; }\n @media (prefers-reduced-motion: reduce) {\n .spine-stars--input .spine-stars__star { transition: none; }\n .spine-stars--input .spine-stars__star:hover { transform: none; }\n }\n :host-context([data-motion='reduce']) .spine-stars--input .spine-stars__star { transition: none; transform: none; }\n `],\n})\nexport class SpineRatingStarsComponent {\n /** Nota de 0 a 10 (média pode ter casa decimal); `null` = sem nota. Editável: muda com o clique e o teclado. */\n readonly value = model<number | null>(null);\n /** Só mostra (sem foco nem clique). */\n readonly readonly = input(false);\n /** A nota em número ao lado (\"7/10\"). */\n readonly showValue = input(true);\n /** Editável: também o rótulo qualitativo (\"Muito bom\") ao lado da nota. */\n readonly showName = input(false);\n readonly size = input<'small' | 'medium' | 'large'>('medium');\n /** Nome acessível do slider (ou `labelledBy`, o id de um rótulo visível). */\n readonly label = input('');\n readonly labelledBy = input('');\n readonly describedBy = input('');\n readonly invalid = input(false);\n\n private readonly messages = inject(SPINE_MESSAGES);\n private readonly text = this.messages.ratings;\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly numberFormat = new Intl.NumberFormat(this.messages.meta.locale, { maximumFractionDigits: 1 });\n\n protected readonly max = SPINE_RATING_SCORE_MAX;\n /** Prévia do mouse (editável): vence a nota escolhida no desenho, não no valor. */\n protected readonly hovered = signal<number | null>(null);\n\n protected readonly shown = computed(() => (this.readonly() ? this.value() : this.hovered() ?? this.value()));\n protected readonly fills = computed(() => spineStarFills(this.shown()));\n protected readonly short = computed(() => formatMessage(this.text.scoreShort, { value: this.format(this.shown()) }));\n protected readonly named = computed(() => {\n const v = this.shown();\n return this.showName() && v != null ? this.text.scoreNames[spineScoreBand(v)] : '';\n });\n /** O que o leitor fala: \"8,4 de 10\" (imagem) ou \"7 de 10 — Muito bom\" (slider). */\n protected readonly spoken = computed(() => {\n const v = this.value();\n if (v == null) return this.readonly() ? '' : this.text.noScore;\n const value = this.format(v);\n return this.readonly()\n ? formatMessage(this.text.scoreOf, { value })\n : formatMessage(this.text.scoreNamed, { value, name: this.text.scoreNames[spineScoreBand(v)] });\n });\n\n private format(v: number | null): string {\n return v == null ? '' : this.numberFormat.format(v);\n }\n\n /** Clique numa metade: aquela nota; de novo na primeira metade (nota 1), 0 -- o \"nenhuma estrela\" do mouse. */\n protected pick(score: number): void {\n if (this.readonly()) return;\n this.value.set(score === 1 && this.value() === 1 ? 0 : score);\n }\n\n protected onKey(event: KeyboardEvent): void {\n if (this.readonly()) return;\n const rtl = getComputedStyle(this.host.nativeElement).direction === 'rtl';\n const current = this.value();\n const base = current ?? 0;\n // Sem nota: a primeira seta para cima dá 1 (meia estrela), para baixo dá 0.\n const step = (delta: number) => (current == null ? (delta > 0 ? delta : 0) : base + delta);\n const next = (() => {\n switch (event.key) {\n case 'ArrowUp': return step(1);\n case 'ArrowDown': return step(-1);\n case 'ArrowRight': return step(rtl ? -1 : 1);\n case 'ArrowLeft': return step(rtl ? 1 : -1);\n case 'PageUp': return step(2);\n case 'PageDown': return step(-2);\n case 'Home': return 0;\n case 'End': return SPINE_RATING_SCORE_MAX;\n default: return null;\n }\n })();\n if (next == null) return;\n event.preventDefault();\n this.hovered.set(null);\n this.value.set(Math.min(SPINE_RATING_SCORE_MAX, Math.max(0, next)));\n }\n}\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject, input, output, signal } from '@angular/core';\nimport { ButtonComponent, HermesToastService, SkeletonComponent, TextareaComponent } from '@trismegisto/angular';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_CONFIG, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineRatingStarsComponent } from './rating-stars.component';\nimport { SPINE_RATING_COMMENT_MAX, SpineRating, SpineRatingTarget, SpineRatingsService } from './ratings.service';\n\nlet nextId = 0;\n\n/**\n * O formulário de avaliação (o mesmo no popover da tela e no diálogo da ferramenta): a nota de 0 a 10 em 5 estrelas com\n * meia (`spine-rating-stars`, um slider acessível), comentário opcional (até 500, com o contador do `hm-textarea`) e\n * \"Avaliar\". Já avaliou: chega preenchido e o botão vira \"Atualizar\".\n *\n * O rótulo \"Sua nota\" é visível e dá nome ao slider; a dica da escala e o erro de \"sem nota\" o descrevem. Ao lado das\n * estrelas, a nota (\"7/10\") e o rótulo dela (\"Muito bom\"), com a prévia do mouse.\n */\n@Component({\n selector: 'spine-rating-form',\n imports: [ButtonComponent, SkeletonComponent, TextareaComponent, SpineRatingStarsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"spine-rating\">\n <p class=\"spine-rating__lead\">{{ text.subheading }}</p>\n <p class=\"spine-rating__about\">{{ about() }}</p>\n\n @if (loading()) {\n <hm-skeleton shape=\"text\" [count]=\"3\" [label]=\"text.loading\" />\n } @else {\n <div class=\"spine-rating__score\">\n <span class=\"spine-rating__label\" [id]=\"labelId\">{{ text.score }}</span>\n <spine-rating-stars\n size=\"large\"\n [showName]=\"true\"\n [labelledBy]=\"labelId\"\n [describedBy]=\"describedBy()\"\n [invalid]=\"missingScore()\"\n [value]=\"score()\"\n (valueChange)=\"pick($event)\"\n />\n <p class=\"spine-rating__hint\" [id]=\"hintId\">{{ text.scaleHint }}</p>\n @if (missingScore()) {\n <p class=\"spine-rating__error\" [id]=\"errorId\" role=\"alert\">{{ text.scoreRequired }}</p>\n }\n </div>\n\n <hm-textarea\n [label]=\"text.comment\"\n [placeholder]=\"text.commentPlaceholder\"\n [maxLength]=\"max\"\n [rows]=\"3\"\n [(value)]=\"comment\"\n />\n\n @if (previous(); as p) {\n <p class=\"spine-rating__previous\">{{ previousText(p) }}</p>\n }\n\n <div class=\"spine-rating__actions\">\n <hm-button emphasis=\"high\" [loading]=\"saving()\" (clicked)=\"submit()\">\n {{ previous() ? text.update : text.submit }}\n </hm-button>\n </div>\n }\n </div>\n `,\n styles: [`\n :host { display: block; }\n .spine-rating { display: flex; flex-direction: column; gap: var(--hm-space-sm); inline-size: min(22rem, 100%); }\n .spine-rating__lead { margin: 0; color: var(--hm-text); font-size: var(--hm-font-size-sm, 14px); }\n /* O alvo da avaliação (tela ou ferramenta) em texto secundário, cortado numa linha. */\n .spine-rating__about {\n margin: calc(-1 * var(--hm-space-xs)) 0 0;\n overflow: hidden;\n color: var(--hm-muted);\n font-size: var(--hm-font-size-xs, 12px);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .spine-rating__score { display: flex; flex-direction: column; align-items: flex-start; gap: var(--hm-space-xxs, 4px); }\n .spine-rating__label { color: var(--hm-text); font-size: var(--hm-font-size-sm, 14px); font-weight: var(--hm-font-weight-semibold, 600); }\n .spine-rating__hint { margin: 0; color: var(--hm-muted); font-size: var(--hm-font-size-xs, 12px); }\n .spine-rating__error { margin: 0; color: var(--hm-danger); font-size: var(--hm-font-size-xs, 12px); }\n .spine-rating__previous { margin: 0; color: var(--hm-muted); font-size: var(--hm-font-size-xs, 12px); }\n .spine-rating__actions { display: flex; justify-content: flex-end; }\n `],\n})\nexport class SpineRatingFormComponent implements OnInit {\n /** O que se avalia (ferramenta ou tela). Lido na abertura: o formulário é criado a cada vez que abre. */\n readonly target = input.required<SpineRatingTarget>();\n /** Gravou: a avaliação como ficou (quem abriu fecha o popover/diálogo). */\n readonly done = output<SpineRating>();\n\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.ratings;\n private readonly ratings = inject(SpineRatingsService);\n private readonly toast = inject(HermesToastService, { optional: true });\n private readonly appName = inject(SPINE_CONFIG, { optional: true })?.appName ?? 'Hermes';\n\n protected readonly max = SPINE_RATING_COMMENT_MAX;\n private readonly id = nextId++;\n protected readonly labelId = `spine-rating-label-${this.id}`;\n protected readonly hintId = `spine-rating-hint-${this.id}`;\n protected readonly errorId = `spine-rating-error-${this.id}`;\n\n protected readonly loading = signal(true);\n protected readonly saving = signal(false);\n /** 0 a 10; `null` = ainda sem nota (0 é nota: \"nenhuma estrela\"). */\n protected readonly score = signal<number | null>(null);\n protected readonly comment = signal('');\n protected readonly previous = signal<SpineRating | null>(null);\n /** Tentou enviar sem nota. */\n protected readonly missingScore = signal(false);\n\n protected readonly describedBy = computed(() => (this.missingScore() ? `${this.hintId} ${this.errorId}` : this.hintId));\n\n protected readonly about = computed(() => {\n const t = this.target();\n return t.scope === 'screen'\n ? formatMessage(this.text.aboutScreen, { screen: t.screenLabel || t.screenPath || '' })\n : formatMessage(this.text.aboutApp, { app: this.appName });\n });\n\n async ngOnInit(): Promise<void> {\n try {\n const mine = await this.ratings.mine(this.target());\n if (mine) {\n this.previous.set(mine);\n this.score.set(mine.score);\n this.comment.set(mine.comment ?? '');\n }\n } catch {\n /* Sem a avaliação anterior o formulário segue vazio: a pessoa ainda consegue avaliar. */\n } finally {\n this.loading.set(false);\n }\n }\n\n protected previousText(p: SpineRating): string {\n const d = new Date(p.updated_at);\n const date = Number.isNaN(d.getTime()) ? p.updated_at : new Intl.DateTimeFormat(this.messages.meta.locale, { dateStyle: 'short' }).format(d);\n return formatMessage(this.text.previous, { date });\n }\n\n protected pick(value: number | null): void {\n this.score.set(value);\n if (value != null) this.missingScore.set(false);\n }\n\n protected async submit(): Promise<void> {\n if (this.saving()) return;\n const score = this.score();\n if (score == null) {\n this.missingScore.set(true);\n return;\n }\n this.saving.set(true);\n try {\n const saved = await this.ratings.save(this.target(), score, this.comment());\n this.toast?.success(this.previous() ? this.text.updated : this.text.thanks);\n this.previous.set(saved);\n this.done.emit(saved);\n } catch {\n this.toast?.error(this.text.saveError);\n } finally {\n this.saving.set(false);\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { FloatingWindowComponent } from '@trismegisto/angular';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_CONFIG, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineRatingFormComponent } from './rating-form.component';\nimport { SpineRatingsService, ratingTargetKey } from './ratings.service';\n\n/** Tamanho da janela: o formulário (nota, comentário e botões) cabe sem rolar. */\nconst WIDTH = 380;\nconst HEIGHT = 360;\n/** Distância da borda da tela onde a janela nasce (canto inferior direito). */\nconst MARGIN = 24;\n/** Abaixo disto (celular), a janela ocupa a largura e fica presa embaixo, sem arrastar. */\nconst NARROW = 600;\n\n/**\n * A janela de avaliação: flutuante e não modal (`hm-floating-window`), para a pessoa continuar vendo e usando a tela\n * enquanto avalia. Uma só para a ferramenta (\"Avaliar o {app}\", a estrela do cabeçalho e Configurações › Sobre) e para\n * a tela (\"Avaliar esta tela\", a estrela da barra da página): pedir a outra troca o conteúdo da mesma janela.\n *\n * Nasce no canto inferior direito a cada abertura; dá para arrastar e minimizar (sem redimensionar nem maximizar: é um\n * formulário pequeno). Esc fecha. No estreito, ocupa a largura e fica presa embaixo. Só abre quando a pessoa pede\n * (`SpineRatingsService.openApp`/`openScreen`), nunca sozinha. Montada uma vez no cabeçalho; sem o recurso, nada.\n */\n@Component({\n selector: 'spine-rating-window',\n imports: [FloatingWindowComponent, SpineRatingFormComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (ratings.enabled) {\n @if (ratings.windowTarget(); as target) {\n <hm-floating-window\n [heading]=\"heading()\"\n icon=\"star\"\n [open]=\"true\"\n (openChange)=\"$event || ratings.closeWindow()\"\n [width]=\"box().width\"\n [height]=\"box().height\"\n [x]=\"box().x\"\n [y]=\"box().y\"\n [movable]=\"!box().narrow\"\n [resizable]=\"false\"\n [maximizable]=\"false\"\n closeOnEscape\n >\n <!-- Trocar de alvo recria o formulário (ele lê a avaliação anterior daquele alvo ao nascer). -->\n @for (t of [target]; track key(t)) {\n <spine-rating-form [target]=\"t\" (done)=\"ratings.closeWindow()\" />\n }\n </hm-floating-window>\n }\n }\n `,\n})\nexport class SpineRatingWindowComponent {\n protected readonly ratings = inject(SpineRatingsService);\n private readonly text = inject(SPINE_MESSAGES).ratings;\n private readonly appName = inject(SPINE_CONFIG, { optional: true })?.appName ?? 'Hermes';\n protected readonly key = ratingTargetKey;\n\n /** Título: \"Avaliar o {app}\" ou \"Avaliar esta tela\" (segue o idioma ativo). */\n protected readonly heading = computed(() =>\n this.ratings.windowTarget()?.scope === 'screen' ? this.text.rateScreen : formatMessage(this.text.rateApp, { app: this.appName }));\n\n /** Onde nasce: canto inferior direito (ou a largura toda, embaixo, no estreito). Lido de novo a cada abertura. */\n protected readonly box = computed(() => {\n this.ratings.windowTarget();\n const w = typeof window === 'undefined' ? 1280 : window.innerWidth;\n const h = typeof window === 'undefined' ? 800 : window.innerHeight;\n const narrow = w < NARROW;\n const width = narrow ? w - 16 : WIDTH;\n const height = Math.min(HEIGHT, h - 16);\n const margin = narrow ? 8 : MARGIN;\n return { narrow, width, height, x: narrow ? 8 : Math.max(8, w - width - margin), y: Math.max(8, h - height - margin) };\n });\n}\n","import { ChangeDetectionStrategy, Component, OnInit, computed, inject } from '@angular/core';\nimport { IconButtonComponent } from '@trismegisto/angular';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_CONFIG, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineRatingsService } from './ratings.service';\n\n/**\n * \"Avaliar o {app}\" no cabeçalho (no lugar do botão de tela cheia, cujo atalho de teclado continua): a estrela abre a\n * janela de avaliação da ferramenta (flutuante, no canto inferior direito; `spine-rating-window`, montada no cabeçalho). Já avaliou: a estrela fica cheia e\n * o nome diz que é a avaliação dela. Lê uma vez, ao aparecer, se a pessoa já avaliou. Sem o recurso, nada.\n */\n@Component({\n selector: 'spine-rate-app-button',\n imports: [IconButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (ratings.enabled) {\n <hm-icon-button\n emphasis=\"subtle\"\n icon=\"star\"\n [solid]=\"ratings.appRated()\"\n [label]=\"label()\"\n [class.spine-rate-app--rated]=\"ratings.appRated()\"\n (clicked)=\"ratings.openApp()\"\n />\n }\n `,\n styles: [`\n :host { display: contents; }\n .spine-rate-app--rated { color: var(--hm-warning); }\n `],\n})\nexport class SpineRateAppButtonComponent implements OnInit {\n protected readonly ratings = inject(SpineRatingsService);\n private readonly text = inject(SPINE_MESSAGES).ratings;\n private readonly appName = inject(SPINE_CONFIG, { optional: true })?.appName ?? 'Hermes';\n\n protected readonly label = computed(() =>\n formatMessage(this.ratings.appRated() ? this.text.ratedApp : this.text.rateApp, { app: this.appName }));\n\n ngOnInit(): void {\n void this.ratings.checkAppRated();\n }\n}\n","import { InjectionToken, Provider } from '@angular/core';\n\n/** Uma novidade na central de notificações (o sino do cabeçalho). */\nexport interface SpineInboxItem {\n /** Único dentro da fonte. */\n readonly id: string;\n readonly title: string;\n /** A novidade em uma linha (\"Ana: pode mandar um exemplo?\"). */\n readonly body?: string;\n /** Quando aconteceu (a novidade mais recente do item): ordena a lista e vira \"há 5 min\". */\n readonly at: string | Date;\n /** Quantas novidades o item junta (mostra \"+N\" a partir de 2). */\n readonly count?: number;\n /** Quem fez: a foto (ou as iniciais) na linha; sem pessoa, o ícone da fonte. */\n readonly person?: { readonly name: string; readonly picture?: string | null } | null;\n}\n\n/**\n * Uma fonte da central de notificações: o que há de novo PARA a pessoa num recurso (sugestões, aprovações, chamados…).\n * Não são os toasts (`HermesToastService`/`NotificationService`), que passam: aqui fica até a pessoa ver. Registre com\n * `provideSpineInboxSource`; o sino só aparece com alguma fonte.\n */\nexport interface SpineInboxSource {\n readonly id: string;\n /** O nome da fonte (\"Sugestões\"), acima dos itens dela. */\n readonly label: string;\n /** Ícone da fonte (@trismegisto/icons), nos itens sem pessoa. */\n readonly icon?: string;\n /** As novidades (as mais recentes, até umas 20) e o total de itens com novidade (o número do sino). */\n load(): Promise<{ readonly items: readonly SpineInboxItem[]; readonly total: number }>;\n /** A pessoa escolheu o item: marque como visto e abra onde ele está. A central relê depois. */\n open(item: SpineInboxItem): void | Promise<void>;\n}\n\n/** As fontes registradas (multi). Uma fábrica pode devolver `null` (recurso desligado): fica de fora. */\nexport const SPINE_INBOX_SOURCES = new InjectionToken<readonly (SpineInboxSource | null)[]>('SPINE_INBOX_SOURCES');\n\n/**\n * Registra uma fonte na central de notificações. A fábrica roda num contexto de injeção (`inject()` vale) e pode\n * devolver `null` para não registrar nada.\n *\n * ```ts\n * provideSpineInboxSource(() => {\n * const api = inject(AprovacoesApi);\n * const router = inject(Router);\n * return {\n * id: 'aprovacoes', label: 'Aprovações', icon: 'check-circle',\n * load: async () => { const r = await api.pendentes(); return { total: r.total, items: r.itens.map(toItem) }; },\n * open: (item) => void router.navigateByUrl(`/aprovacoes/${item.id}`),\n * };\n * })\n * ```\n */\nexport function provideSpineInboxSource(factory: () => SpineInboxSource | null): Provider {\n return { provide: SPINE_INBOX_SOURCES, multi: true, useFactory: factory };\n}\n","import { DestroyRef, Injectable, PLATFORM_ID, inject, signal } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { SPINE_INBOX_SOURCES, SpineInboxItem, SpineInboxSource } from './inbox';\n\n/** Um item na lista do sino, com a fonte dele. */\nexport interface SpineInboxEntry {\n /** `fonte:item`, único na lista. */\n readonly key: string;\n readonly source: SpineInboxSource;\n readonly item: SpineInboxItem;\n}\n\n/** De quanto em quanto tempo a central relê, com a aba do navegador à vista. */\nexport const SPINE_INBOX_POLL_MS = 60_000;\n\n/**\n * A central de notificações (o sino do cabeçalho): junta as novidades das fontes registradas\n * (`provideSpineInboxSource`), a mais recente primeiro. Relê enquanto alguém acompanha (`watch`): de minuto em minuto\n * com a aba à vista e ao voltar para ela. Quem muda o que conta como novidade (ler uma conversa, por exemplo) chama\n * `refresh()`.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineInboxService {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly sources = (inject(SPINE_INBOX_SOURCES, { optional: true }) ?? []).filter(\n (s): s is SpineInboxSource => !!s,\n );\n\n /** Alguma fonte registrada: sem nenhuma, o sino não aparece. */\n readonly enabled = this.sources.length > 0;\n readonly entries = signal<readonly SpineInboxEntry[]>([]);\n /** Itens com novidade, somando as fontes (o número do sino). */\n readonly total = signal(0);\n readonly loading = signal(false);\n /** Nenhuma fonte respondeu na última leitura. */\n readonly failed = signal(false);\n\n private request = 0;\n private watchers = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private readonly onVisible = () => {\n if (document.visibilityState === 'visible') void this.refresh();\n };\n\n /** Relê todas as fontes. Uma fonte que falha não derruba as outras. */\n async refresh(): Promise<void> {\n if (!this.enabled) return;\n const request = ++this.request;\n this.loading.set(true);\n const results = await Promise.allSettled(this.sources.map((source) => source.load()));\n if (request !== this.request) return;\n const entries: SpineInboxEntry[] = [];\n let total = 0;\n results.forEach((result, i) => {\n if (result.status !== 'fulfilled') return;\n const source = this.sources[i];\n total += result.value.total;\n for (const item of result.value.items) entries.push({ key: `${source.id}:${item.id}`, source, item });\n });\n entries.sort((a, b) => time(b.item.at) - time(a.item.at));\n this.entries.set(entries);\n this.total.set(total);\n this.failed.set(results.every((r) => r.status === 'rejected'));\n this.loading.set(false);\n }\n\n /** A pessoa escolheu um item: a fonte abre (e marca como visto); depois a central relê. */\n async open(entry: SpineInboxEntry): Promise<void> {\n try {\n await entry.source.open(entry.item);\n } finally {\n void this.refresh();\n }\n }\n\n /**\n * Passa a reler sozinha enquanto `destroyRef` viver (o sino no cabeçalho): lê agora, de minuto em minuto com a aba à\n * vista e ao voltar para a aba. Vários acompanhando dividem o mesmo relógio.\n */\n watch(destroyRef: DestroyRef): void {\n if (!this.enabled || !this.browser) return;\n if (this.watchers++ === 0) {\n void this.refresh();\n this.timer = setInterval(() => {\n if (document.visibilityState === 'visible') void this.refresh();\n }, SPINE_INBOX_POLL_MS);\n document.addEventListener('visibilitychange', this.onVisible);\n }\n destroyRef.onDestroy(() => {\n if (--this.watchers > 0) return;\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n document.removeEventListener('visibilitychange', this.onVisible);\n });\n }\n}\n\nfunction time(at: string | Date): number {\n const t = new Date(at).getTime();\n return Number.isNaN(t) ? 0 : t;\n}\n","import { ChangeDetectionStrategy, Component, DestroyRef, computed, inject } from '@angular/core';\nimport {\n AccountAvatarComponent, BadgeComponent, ButtonComponent, IconButtonComponent, IconComponent, PopoverComponent,\n PopoverTriggerDirective,\n} from '@trismegisto/angular';\nimport { pluralMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineInboxEntry, SpineInboxService } from './inbox.service';\n\nconst MINUTE = 60_000;\nconst HOUR = 60 * MINUTE;\nconst DAY = 24 * HOUR;\n\n/**\n * O sino do cabeçalho: a central de notificações (`SpineInboxService`). O número é quantos itens têm novidade; o\n * painel lista as novidades das fontes, a mais recente primeiro, e escolher uma abre onde ela está. Sem fonte\n * registrada, não desenha nada.\n */\n@Component({\n selector: 'spine-inbox-button',\n imports: [AccountAvatarComponent, BadgeComponent, ButtonComponent, IconButtonComponent, IconComponent, PopoverComponent, PopoverTriggerDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (inbox.enabled) {\n <span class=\"spine-inbox\">\n <hm-icon-button emphasis=\"subtle\" icon=\"bell\" [label]=\"buttonLabel()\" [hmPopoverTrigger]=\"panel\" />\n <hm-badge class=\"spine-inbox__badge\" [value]=\"inbox.total()\" />\n </span>\n <hm-popover #panel class=\"spine-inbox__panel\" [heading]=\"text.title\" align=\"end\" [arrow]=\"false\">\n @if (inbox.entries().length) {\n <ul class=\"spine-inbox__list\">\n @for (entry of inbox.entries(); track entry.key) {\n <li>\n <button type=\"button\" class=\"spine-inbox__item\" (click)=\"choose(entry); panel.open.set(false)\">\n @if (entry.item.person; as person) {\n <hm-account-avatar size=\"small\" [name]=\"person.name\" [imageUrl]=\"person.picture ?? null\" />\n } @else {\n <span class=\"spine-inbox__icon\" aria-hidden=\"true\"><hm-icon [shape]=\"entry.source.icon || 'bell'\" /></span>\n }\n <span class=\"spine-inbox__text\">\n <span class=\"spine-inbox__source\">{{ entry.source.label }}</span>\n <span class=\"spine-inbox__title\">{{ entry.item.title }}</span>\n @if (entry.item.body) {\n <span class=\"spine-inbox__body\">{{ entry.item.body }}</span>\n }\n <span class=\"spine-inbox__meta\">\n <time [attr.datetime]=\"iso(entry)\">{{ ago(entry) }}</time>\n @if ((entry.item.count ?? 0) > 1) {\n <span>· {{ newsText(entry.item.count!) }}</span>\n }\n </span>\n </span>\n </button>\n </li>\n }\n </ul>\n } @else if (inbox.failed()) {\n <p class=\"spine-inbox__empty\">{{ text.error }}</p>\n <hm-button size=\"small\" emphasis=\"medium\" (clicked)=\"inbox.refresh()\">{{ text.retry }}</hm-button>\n } @else {\n <p class=\"spine-inbox__empty\">{{ text.empty }}</p>\n }\n </hm-popover>\n }\n `,\n styles: [`\n :host { display: contents; }\n .spine-inbox { position: relative; display: inline-flex; }\n .spine-inbox__badge { position: absolute; inset-block-start: 0; inset-inline-end: 0; pointer-events: none; transform: translate(25%, -15%); }\n /* Cabe no cartão do hm-popover (até 24rem, com o padding dele): só rola na vertical. */\n .spine-inbox__list { display: flex; flex-direction: column; inline-size: min(21rem, calc(100vw - 4rem)); max-block-size: min(28rem, 70dvh);\n margin: 0; padding: 0; overflow-x: hidden; overflow-y: auto; list-style: none; }\n .spine-inbox__item { display: flex; gap: var(--hm-space-sm); inline-size: 100%; padding: var(--hm-space-xs) var(--hm-space-xxxs);\n border: 0; border-radius: var(--hm-radius); background: none; color: var(--hm-text); font: inherit; text-align: start; cursor: pointer; }\n .spine-inbox__item:hover { background: var(--hm-hover); }\n .spine-inbox__item:focus-visible { outline: var(--hm-border-thin) solid var(--hm-focus-color); outline-offset: calc(var(--hm-border-thin) * -1); }\n .spine-inbox__icon { display: inline-flex; flex: none; align-items: center; justify-content: center; inline-size: 2rem; block-size: 2rem;\n border-radius: 50%; background: var(--hm-accent-subtle); color: var(--hm-accent); }\n .spine-inbox__text { display: flex; flex: 1; flex-direction: column; gap: var(--hm-space-micro); min-inline-size: 0; }\n .spine-inbox__source { color: var(--hm-muted); font-size: var(--hm-font-size-xs); }\n .spine-inbox__title { overflow: hidden; font-size: var(--hm-font-size-sm); font-weight: var(--hm-font-weight-semibold); text-overflow: ellipsis; white-space: nowrap; }\n .spine-inbox__body { display: -webkit-box; overflow: hidden; color: var(--hm-text); font-size: var(--hm-font-size-sm); overflow-wrap: anywhere;\n -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }\n .spine-inbox__meta { display: flex; gap: var(--hm-space-micro); color: var(--hm-muted); font-size: var(--hm-font-size-xs); }\n .spine-inbox__empty { margin: 0; padding-block: var(--hm-space-sm); color: var(--hm-muted); font-size: var(--hm-font-size-sm); }\n `],\n})\nexport class SpineInboxButtonComponent {\n protected readonly inbox = inject(SpineInboxService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.inbox;\n\n protected readonly buttonLabel = computed(() => pluralMessage(this.text.button, this.inbox.total(), this.messages.meta.locale));\n\n constructor() {\n this.inbox.watch(inject(DestroyRef));\n }\n\n protected choose(entry: SpineInboxEntry): void {\n void this.inbox.open(entry);\n }\n\n protected newsText(count: number): string {\n return pluralMessage(this.text.news, count, this.messages.meta.locale);\n }\n\n protected iso(entry: SpineInboxEntry): string {\n const at = new Date(entry.item.at);\n return Number.isNaN(at.getTime()) ? '' : at.toISOString();\n }\n\n /** \"há 5 min\", \"ontem\", \"há 3 dias\" (Intl, no idioma do catálogo). */\n protected ago(entry: SpineInboxEntry): string {\n const at = new Date(entry.item.at).getTime();\n if (Number.isNaN(at)) return '';\n const rtf = new Intl.RelativeTimeFormat(this.messages.meta.locale, { numeric: 'auto', style: 'short' });\n const ago = Math.max(0, Date.now() - at);\n if (ago < MINUTE) return rtf.format(0, 'second');\n if (ago < HOUR) return rtf.format(-Math.floor(ago / MINUTE), 'minute');\n if (ago < DAY) return rtf.format(-Math.floor(ago / HOUR), 'hour');\n return rtf.format(-Math.floor(ago / DAY), 'day');\n }\n}\n","import { DestroyRef, Injectable, inject, signal } from '@angular/core';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { SPINE_MESSAGES, SpineUserStorage } from '@trismegisto/spine';\nimport { AlertType, NotificationService } from '@trismegisto/spine/notification';\n\n/** Tempo do aviso de falha na tela (segundos). */\nconst LOGOUT_FAILED_SECONDS = 8;\n\n/** O que o spine usa do `AuthorizationService`, nas duas linhas do `@orfeu/angular`: na 1.0.x `logout()` não\n * devolve nada e não existe `logoutFailed$`; da 1.3.0 em diante devolve `Promise<boolean>` e há `logoutFailed$`. */\ninterface LogoutCapable {\n logout(): unknown;\n logoutFailed$?: { subscribe(next: () => void): { unsubscribe(): void } };\n}\n\n/**\n * Saída da sessão pelo shell: todo botão/atalho de sair do spine passa por aqui (menu do perfil, painel de\n * configurações, tela `/blocked`).\n *\n * - Assina `logoutFailed$` do `@orfeu/angular` (1.3.x) uma vez só: quando o logout no Argos falha (a lib repete uma\n * vez e mantém a sessão), mostra o aviso de erro `session.logoutFailed` (`hm-alert` de erro, `role=\"alert\"`). Vale\n * também para um `logout()` chamado direto pelo app.\n * - `logout()` aguarda o resultado: só apaga os históricos do usuário (`SpineUserStorage.clearHistory()`) quando a\n * saída deu certo. Com falha, nada muda: a pessoa continua na tela, com a sessão e os recentes.\n * - `pending` fica `true` enquanto a saída está em andamento e sempre volta a `false` (os botões não travam).\n *\n * Com `@orfeu/angular` 1.0.x (sem `logoutFailed$`, `logout()` sem retorno) a saída conta como concluída, como antes.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineLogoutService {\n private readonly auth = inject(AuthorizationService) as unknown as LogoutCapable;\n private readonly userStorage = inject(SpineUserStorage);\n private readonly notifications = inject(NotificationService);\n private readonly messages = inject(SPINE_MESSAGES);\n /** `true` quando a lib avisa a falha por `logoutFailed$` (então o aviso sai por lá, uma vez). */\n private readonly failureStream: boolean;\n private inFlight: Promise<boolean> | null = null;\n\n /** Saída em andamento (o botão mostra \"saindo…\" / fica desabilitado). */\n readonly pending = signal(false);\n\n constructor() {\n const failed$ = this.auth.logoutFailed$;\n this.failureStream = typeof failed$?.subscribe === 'function';\n if (!this.failureStream) return;\n const sub = failed$!.subscribe(() => this.notifyFailure());\n inject(DestroyRef).onDestroy(() => sub.unsubscribe());\n }\n\n /**\n * Sai da sessão. Resolve `true` quando saiu (o `@orfeu/angular` já navega para o `/logoff`) e `false` quando o\n * Argos não confirmou: a sessão continua e o aviso de erro aparece. Nunca rejeita. Cliques repetidos durante a\n * saída reaproveitam a mesma tentativa.\n */\n logout(): Promise<boolean> {\n this.inFlight ??= this.run().finally(() => {\n this.inFlight = null;\n this.pending.set(false);\n });\n return this.inFlight;\n }\n\n private async run(): Promise<boolean> {\n this.pending.set(true);\n // Guarda de quem é a sessão antes de sair: depois do logout o token some, e a limpeza precisa do usuário.\n this.userStorage.userId();\n let ok: boolean;\n let rejected = false;\n try {\n // 1.3.x: Promise<boolean>; 1.0.x: void (a saída local sempre acontecia).\n ok = (await this.auth.logout()) !== false;\n } catch {\n ok = false;\n rejected = true;\n }\n if (ok) {\n this.userStorage.clearHistory();\n } else if (rejected || !this.failureStream) {\n // Sem `logoutFailed$` para avisar (ou a chamada nem chegou a resolver): o próprio resultado avisa.\n this.notifyFailure();\n }\n return ok;\n }\n\n private notifyFailure(): void {\n this.notifications.addNotification({\n timer: LOGOUT_FAILED_SECONDS,\n hermesAlertType: AlertType.DANGER,\n message: this.messages.session.logoutFailed,\n hermesAlertClosable: true,\n });\n }\n}\n","import { InjectionToken, Injectable, Provider, Type, signal } from '@angular/core';\n\n/** Seções que o próprio spine já traz. `key` é também o valor de `?settings=` na URL. */\nexport const SPINE_SETTINGS_KEYS = {\n appearance: 'aparencia',\n /** Tamanho do texto e animações. */\n accessibility: 'acessibilidade',\n region: 'regiao',\n shortcuts: 'atalhos',\n /** Novidades, configuração inicial e o essencial. */\n help: 'ajuda',\n /** Tipos de aviso do app e aviso do navegador (`SpineFeatures.notices`). */\n notices: 'notificacoes',\n /** Listas guardadas neste navegador (recentes, buscas, favoritos) e restaurar preferências. */\n data: 'dados',\n account: 'conta',\n /** Verificação em duas etapas e códigos de recuperação (API da conta do Argos). */\n mfa: 'mfa',\n /** Sessão atual, token de acesso, tokens de aplicação e sessões e dispositivos. */\n sessions: 'sessoes',\n /** Grupos desta aplicação em que a pessoa tem função (argos-admin `/me/groups`); só aparece com algum. */\n groups: 'grupos',\n about: 'sobre',\n} as const;\n\n/** Chaves antigas de `?settings=` que continuam abrindo a seção que as substituiu (links já publicados). */\nexport const SPINE_SETTINGS_ALIASES: Readonly<Record<string, string>> = {\n // A antiga seção \"Conta e segurança\" virou \"MFA\" e \"Sessões\"; a chave `security` saiu na 3.3.1.\n seguranca: SPINE_SETTINGS_KEYS.mfa,\n};\n\n/** Chave de seção que vale hoje: troca uma chave antiga pela nova; as demais passam iguais. */\nexport function resolveSettingsSection(section: string): string {\n // hasOwn: `?settings=constructor` não pode devolver o que vem do protótipo.\n return Object.hasOwn(SPINE_SETTINGS_ALIASES, section) ? SPINE_SETTINGS_ALIASES[section] : section;\n}\n\n/** Seção extra do painel, registrada pelo app (ex.: preferências de deploy do hefesto). */\nexport interface SpineSettingsSection {\n /** Identificador estável; também o que `?settings=<key>` abre. Não repetir os do spine. */\n key: string;\n label: string;\n /** Ícone do hermes-icon na navegação. */\n icon?: string;\n description?: string;\n /** Termos extras que acham a seção inteira na busca. */\n keywords?: string;\n /** Conteúdo da seção — de preferência `hm-settings-row`s, para a busca achar cada linha. */\n component: Type<unknown>;\n}\n\nexport const SPINE_SETTINGS_SECTIONS = new InjectionToken<SpineSettingsSection[]>('SPINE_SETTINGS_SECTIONS');\n\n/** Registra uma seção do app no painel de configurações (aparece depois das do spine, antes de\n * \"Sobre\"). Pode ser chamado várias vezes, uma por seção. */\nexport function provideSettingsSection(section: SpineSettingsSection): Provider {\n return { provide: SPINE_SETTINGS_SECTIONS, useValue: section, multi: true };\n}\n\n/** Abre/fecha o painel de configurações de qualquer lugar (menu do perfil, atalho, link). */\n@Injectable({ providedIn: 'root' })\nexport class SpineSettingsService {\n readonly isOpen = signal(false);\n /** Seção pedida na abertura (vazio = a primeira). */\n readonly section = signal('');\n\n /** `section` aceita também as chaves antigas (`seguranca` abre \"MFA\"). */\n open(section = ''): void {\n this.section.set(resolveSettingsSection(section));\n this.isOpen.set(true);\n }\n\n close(): void {\n this.isOpen.set(false);\n }\n\n toggle(): void {\n if (this.isOpen()) this.close();\n else this.open();\n }\n}\n","import { Injectable, OnDestroy, computed, inject } from '@angular/core';\nimport { Subject } from 'rxjs';\nimport { HermesShortcut, HermesShortcutItem, HermesShortcutService } from '@trismegisto/angular';\nimport { SPINE_MESSAGES, SPINE_USER_STORAGE_KEYS, SpineUserStorage } from '@trismegisto/spine';\nimport { detectShortcutPlatform } from '@trismegisto/primitives';\n\n/** Ações concretas que o atalho dispara — ligadas pelo LayoutComponent. */\nexport interface ShortcutActions {\n navigate?: (url: string) => void; // navega para uma rota (ex.: '/home', favorito)\n toggleTheme?: () => void; // alterna claro/escuro\n openSettings?: () => void; // painel de configurações\n toggleSidebar?: () => void; // abre/recolhe o menu lateral\n}\n\n/** `G 1` … `G 9`: um registro só (o dígito sai do evento); a referência identifica o item no painel. */\nconst FAVORITE_KEYS: readonly string[] = Array.from({ length: 9 }, (_, i) => `G ${i + 1}`);\n/** Como os favoritos aparecem no painel: uma linha \"G depois 1…9\" em vez de nove alternativas. */\nconst FAVORITE_DISPLAY_KEYS = 'G 1…9';\n\n/**\n * Atalhos de teclado globais do sistema, sobre o `HermesShortcutService` da lib (um listener só,\n * sequência `G H`, conflito, campo editável, interruptor de tecla única da WCAG 2.1.4).\n *\n * `setActions` registra os atalhos do shell: `G H` (Home), `G 1`…`G 9` (favoritos), `G T` (tema), `Mod+B` (menu\n * lateral), `Mod+,` (configurações) e `?` (painel de atalhos, via `help$`). `Mod+,` vale também com o foco num campo;\n * os demais, não (`Mod+B` num editor continua sendo negrito).\n *\n * Sem atalho de propósito: sair (um deslize perderia o que estava sendo digitado; fica no menu do perfil) e tela cheia\n * (o navegador já tem `F11`, e o botão fica no cabeçalho).\n *\n * O painel (`spine-shortcuts-cheatsheet` e a seção Atalhos das configurações) usa o\n * `hm-shortcut-list` com `panelItems()`: tudo o que está registrado no `HermesShortcutService`\n * (inclusive o que o app liga com `[hmShortcut]`) mais o que o spine só exibe e outra peça dispara\n * (`Mod+K` e `/` do `hm-header`, voltar/avançar do navegador, `Esc` dos diálogos).\n */\n@Injectable({ providedIn: 'root' })\nexport class ShortcutService implements OnDestroy {\n private actions: ShortcutActions = {};\n private removers: (() => void)[] = [];\n private readonly userStorage = inject(SpineUserStorage);\n private readonly hermes = inject(HermesShortcutService);\n private readonly text = inject(SPINE_MESSAGES).shortcuts;\n\n /** Emite quando o usuário pede o painel de atalhos (tecla \"?\" ou menu do perfil). */\n public readonly help$ = new Subject<void>();\n\n /** Teclas (referência) → descrição viva, para o painel acompanhar a troca de idioma. */\n private readonly own = new Map<string | readonly string[], () => string>();\n\n /** Os atalhos do shell. `describe` lê o catálogo na hora (o idioma pode mudar depois do registro). */\n private definitions(): (Omit<HermesShortcut, 'description'> & { describe: () => string })[] {\n const t = this.text;\n return [\n { keys: ['G H'], describe: () => t.goHome, group: 'navigation', handler: () => this.navigate('/home') },\n { keys: FAVORITE_KEYS, describe: () => t.goFavorite, group: 'navigation', handler: (e) => this.goToFavorite(e) },\n { keys: ['Mod+B'], describe: () => t.toggleSidebar, group: 'navigation', handler: () => this.call(this.actions.toggleSidebar) },\n { keys: ['Mod+,'], describe: () => t.openSettings, group: 'actions', allowInInputs: true, handler: () => this.call(this.actions.openSettings) },\n { keys: ['G T'], describe: () => t.toggleTheme, group: 'actions', handler: () => this.call(this.actions.toggleTheme) },\n { keys: ['?'], describe: () => t.showHelp, group: 'general', handler: () => this.help$.next() },\n ];\n }\n\n /** Só exibidos: quem dispara é outra peça (hm-header, navegador, diálogos). */\n private displayOnly(): HermesShortcutItem[] {\n const t = this.text;\n return [\n { keys: ['Mod+K', '/'], description: t.openSearch, group: 'navigation' },\n // O atalho é do navegador, e no Mac ele é outro.\n { keys: detectShortcutPlatform() === 'mac' ? ['Mod+[', 'Mod+]'] : ['Alt+Left', 'Alt+Right'], description: t.history, group: 'navigation' },\n { keys: 'Esc', description: t.closeOverlay, group: 'general' },\n ];\n }\n\n /**\n * O que o painel lista (`<hm-shortcut-list [registered]=\"false\" [items]=\"panelItems()\">`): os\n * atalhos registrados no `HermesShortcutService`, com os favoritos numa linha só, e os só exibidos.\n * Acompanha registro/remoção e a troca de idioma do catálogo da lib.\n */\n public readonly panelItems = computed<readonly HermesShortcutItem[]>(() => {\n const registered = this.hermes.list().map((item) => {\n const describe = this.own.get(item.keys);\n if (!describe) return item;\n return { ...item, description: describe(), keys: item.keys === FAVORITE_KEYS ? FAVORITE_DISPLAY_KEYS : item.keys };\n });\n const display = this.displayOnly();\n // Ordem do painel antigo: busca e histórico abrem a navegação, Esc fecha o geral.\n return [display[0], ...registered, display[1], display[2]];\n });\n\n /** Liga as ações e registra os atalhos no `HermesShortcutService` (idempotente: chamadas seguintes só trocam as ações). */\n setActions(actions: ShortcutActions): void {\n this.actions = { ...this.actions, ...actions };\n if (this.removers.length) return;\n this.removers = this.definitions().map(({ describe, ...definition }) => {\n // Teclas sempre em lista própria: a referência identifica o registro do spine no painel.\n this.own.set(definition.keys, describe);\n const remove = this.hermes.register({ ...definition, description: describe() });\n return () => {\n remove();\n this.own.delete(definition.keys);\n };\n });\n }\n\n ngOnDestroy(): void {\n this.removers.forEach((remove) => remove());\n this.removers = [];\n }\n\n // ── interno ────────────────────────────────────────────────────────────────\n\n /** Ação ausente devolve `false`: o evento segue sem `preventDefault` (o navegador faz o dele). */\n private call(fn?: () => void): boolean {\n if (!fn) return false;\n fn();\n return true;\n }\n\n private navigate(url: string): boolean {\n return this.call(this.actions.navigate && (() => this.actions.navigate!(url)));\n }\n\n /** Navega para o N-ésimo favorito (1-based) lido da store da navegação; N = o dígito do evento. */\n private goToFavorite(event: KeyboardEvent): boolean {\n const digit = /^[1-9]$/.test(event.key) ? event.key : /^Digit([1-9])$/.exec(event.code)?.[1];\n if (!digit) return false;\n let url: string | null = null;\n try {\n const list = JSON.parse(localStorage.getItem(this.userStorage.key(SPINE_USER_STORAGE_KEYS.favorites)) || '[]');\n const fav = Array.isArray(list) ? list[Number(digit) - 1] : null;\n url = fav?.redirect || (typeof fav?.id === 'string' && fav.id.startsWith('/') ? fav.id : null);\n } catch { /* store inválida → ignora */ }\n return url ? this.navigate(url) : false;\n }\n}\n","import { CommonModule } from '@angular/common';\nimport { ChangeDetectorRef, Component, DestroyRef, OnInit, Optional, Inject, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { Router } from '@angular/router';\nimport { filter, take } from 'rxjs';\nimport { AuthorizationService, UserProfile, ViewService } from '@orfeu/angular/core';\nimport {\n AccountAvatarComponent,\n CommandPaletteComponent,\n HeaderComponent as HermesHeaderComponent,\n HermesCommand,\n IconButtonComponent,\n IconComponent,\n MenuButtonComponent,\n MenuItem,\n} from '@trismegisto/angular';\nimport {\n DensityService, QuickAccessItem, Route, SPINE_CONFIG, SPINE_USER_STORAGE_KEYS, SpineConfig, SpineQuickAccessService, SpineUserStorage,\n ThemePresetService, ThemeService, SPINE_MESSAGES, spineRoutesOf,\n} from '@trismegisto/spine';\nimport { AppLauncherComponent } from './app-launcher.component';\nimport { SpineBrandComponent } from './brand.component';\nimport { SpineInitialSetupService } from '../setup/initial-setup.service';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SpineNewsService } from '../news/news.service';\nimport { SpineRatingsService } from '../ratings/ratings.service';\nimport { SpineRatingWindowComponent } from '../ratings/rating-window.component';\nimport { SpineRateAppButtonComponent } from '../ratings/rate-app-button.component';\nimport { SpineInboxButtonComponent } from '../inbox/inbox-button.component';\nimport { ShortcutService } from '../shortcuts/shortcut.service';\nimport { SpineLogoutService } from '../logout/logout.service';\nimport { SpineSettingsService, SPINE_SETTINGS_KEYS } from '../settings/settings.service';\n\n/** Item achatado da árvore de rotas, usado pela busca global (quick-launcher). */\ninterface QuickItem { name: string; icon: string; redirect: string; path: string; }\n\nconst MAX_RECENT_SEARCH = 6;\n\n@Component({\n selector: 'spine-header',\n imports: [\n CommonModule,\n HermesHeaderComponent, IconButtonComponent, IconComponent, MenuButtonComponent, AccountAvatarComponent, CommandPaletteComponent,\n AppLauncherComponent, SpineBrandComponent, SpineRatingWindowComponent, SpineRateAppButtonComponent, SpineInboxButtonComponent,\n ],\n templateUrl: './header.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './header.component.scss',\n})\nexport class HeaderComponent implements OnInit {\n\n public isFullscreen = !!document.fullscreenElement;\n public element = document.documentElement;\n public headerBlocked = false;\n /** route_redirect da primeira rota navegável da view atual — usado pela marca do header.\n * null quando a view não tem nenhuma rota (nesse caso a marca não é link). */\n public homeRoute: string | null = null;\n /** Nome do app (SpineConfig.appName; padrão \"Hermes\") — quem desenha é o `spine-brand`. */\n protected readonly appName: string;\n\n /** OnPush: view, crachá, perfil e histórico mudam fora dos eventos do template (observáveis do Orfeu,\n * outra aba, promessa da tela cheia) — cada um marca a view. Tema/densidade/família são signals. */\n private readonly cdr = inject(ChangeDetectorRef);\n private readonly destroyRef = inject(DestroyRef);\n protected readonly text = inject(SPINE_MESSAGES).header;\n private readonly settings = inject(SpineSettingsService);\n private readonly news = inject(SpineNewsService);\n /** \"Avaliar o {app}\": a estrela do cabeçalho (`spine-rate-app-button`) e a janela de avaliação (`spine-rating-window`). */\n private readonly ratings = inject(SpineRatingsService);\n /**\n * O botão de tela cheia só aparece sem avaliação: com ela, a estrela de avaliar ocupa o lugar dele (o atalho de\n * teclado da tela cheia continua) e o cabeçalho não fica com buraco quando `SpineFeatures.ratings` é `false`.\n */\n readonly showFullscreenButton = !this.ratings.enabled;\n private readonly setup = inject(SpineInitialSetupService);\n private readonly userStorage = inject(SpineUserStorage);\n private readonly logoutService = inject(SpineLogoutService);\n /** Por usuário (`SpineUserStorage`): `<clientId>_header_recent_searches_<sub>`; apagada no logout. */\n private get recentSearchKey(): string {\n return this.userStorage.key(SPINE_USER_STORAGE_KEYS.recentSearches);\n }\n\n constructor(\n private authService: AuthorizationService,\n protected themeService: ThemeService,\n protected themePresetService: ThemePresetService,\n protected densityService: DensityService,\n private viewService: ViewService,\n private router: Router,\n private shortcuts: ShortcutService,\n @Optional() @Inject(SPINE_CONFIG) config: SpineConfig | null,\n ) {\n this.appName = config?.appName ?? 'Hermes';\n // Lista apagada fora daqui (logout, Configurações › Dados do navegador) ou outra conta: relê, para a\n // próxima busca não ressuscitar o que foi apagado.\n const stop = this.userStorage.onChange(() => {\n this.recentSearches = this.loadRecent();\n this.cdr.markForCheck();\n });\n inject(DestroyRef).onDestroy(stop);\n }\n\n async ngOnInit(): Promise<void> {\n this.updateView(this.viewService.currentView);\n this.viewService.currentView$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe((data: any) => {\n this.updateView(data);\n this.cdr.markForCheck();\n });\n // Perfil e crachá (getters sobre o AuthorizationService) mudam com o token: redesenha a cada troca.\n this.authService.isAuth$?.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.cdr.markForCheck());\n\n // Depois de trocar de badge, a view/rotas mudam — sem isso o usuário fica\n // parado numa rota que pode não existir mais pro badge novo. Se o badge novo\n // não tiver nenhuma view disponível, manda pro no-permission em vez de travar.\n //\n // badgeChanged$ dispara ANTES do ViewService.currentView ser atualizado\n // (AuthorizationService.switchBadge emite o evento em applyToken() e só\n // depois faz `await view.update(token)`), então não dá pra usar\n // currentView na hora do evento — ele ainda é a view do badge anterior.\n // Por isso esperamos a próxima emissão *diferente* de currentView$ antes\n // de decidir o redirect.\n this.authService.badgeChanged$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {\n this.cdr.markForCheck();\n const staleView = this.viewService.currentView;\n this.viewService.currentView$\n .pipe(filter((v: any) => v !== staleView), take(1))\n .subscribe((data: any) => {\n const firstRoute = this.findFirstNavigable(spineRoutesOf(data));\n this.router.navigate([firstRoute ?? '/no-permission']);\n });\n });\n\n this.recentSearches = this.loadRecent();\n }\n\n updateView(data: any) {\n const routes = spineRoutesOf(data);\n this.quickIndex = this.flattenRoutes(routes, []);\n this.homeRoute = this.findFirstNavigable(routes);\n }\n\n /** Primeira rota navegável (DFS), atravessando grupos \"transparentes\" sem route_redirect. */\n private findFirstNavigable(routes: Route[]): string | null {\n for (const r of routes || []) {\n if (!r) continue;\n if (r.route_redirect) return r.route_redirect;\n if (r.routes?.length) {\n const found = this.findFirstNavigable(r.routes as Route[]);\n if (found) return found;\n }\n }\n return null;\n }\n\n setTheme(theme: 'light' | 'dark') {\n this.themeService.setTheme(theme);\n }\n\n setDensity() { this.densityService.toggleDensity(); }\n get isCompactDensity(): boolean { return this.densityService.current.name === 'compact'; }\n\n toggleFullscreen() {\n if (!document.fullscreenElement) {\n this.element.requestFullscreen()\n .then(() => { this.isFullscreen = true; this.cdr.markForCheck(); })\n .catch(err => console.error(`Erro ao ativar tela cheia: ${err.message}`));\n } else {\n document.exitFullscreen()\n .then(() => { this.isFullscreen = false; this.cdr.markForCheck(); })\n .catch(err => console.error(`Erro ao sair da tela cheia: ${err.message}`));\n }\n }\n\n get badge() { return this.authService.badge; }\n get badges() { return this.authService.badges; }\n get profile(): UserProfile { return this.authService.profile; }\n\n async switchBadge(badgeTypeId: string): Promise<void> {\n await this.authService.switchBadge(badgeTypeId);\n this.cdr.markForCheck();\n }\n\n /** Sai pelo `SpineLogoutService`: com falha no Argos a pessoa fica aqui, com aviso, e o histórico fica. */\n logout(): Promise<boolean> {\n return this.logoutService.logout();\n }\n\n /** Os cartões do essencial (busca, abas, favoritos, configurações). */\n openEssentials() { this.setup.openEssentials(); }\n\n /** Abre o painel de atalhos de teclado. */\n openShortcuts() { this.shortcuts.help$.next(); }\n\n /** Menu do perfil: achatado (badges, se houver mais de um, + ações), já que `hm-menu`\n * não tem submenu aninhado como o `hermes-dropdown` antigo tinha para a troca de crachá. */\n get profileMenuItems(): MenuItem[] {\n const items: MenuItem[] = [];\n // Vários níveis de acesso: um item que abre um segundo menu (MenuItem.children) em vez de listar\n // todos os níveis direto no menu do perfil.\n if (this.badges.length > 1) {\n items.push({\n id: 'badges',\n label: this.text.accessLevels,\n icon: 'shield-check',\n children: this.badges.map(b => ({ id: `badge:${b.id}`, label: b.name, icon: 'shield-check', disabled: b.id === this.badge?.id })),\n });\n }\n items.push({ id: 'settings', label: this.text.settings, icon: 'cog', separatorAbove: items.length > 0 });\n items.push({ id: 'theme', label: this.text.appearance, icon: 'color-palette' });\n items.push({ id: 'shortcuts', label: this.text.shortcuts, icon: 'keyboard' });\n // Só com alguma novidade para a pessoa (argos-admin /me/news); com as não abertas, a contagem.\n if (this.news.hasAny()) {\n const unseen = this.news.unseenCount();\n items.push({ id: 'news', label: unseen ? formatMessage(this.text.newsUnseen, { label: this.text.news, count: unseen }) : this.text.news, icon: 'star' });\n }\n // Desabilitado só enquanto a saída está em andamento; volta sozinho se ela falhar.\n items.push({ id: 'logout', label: this.text.logout, icon: 'logout', danger: true, separatorAbove: true, disabled: this.logoutService.pending() });\n return items;\n }\n\n onProfileMenuChosen(id: string): void {\n if (id.startsWith('badge:')) { void this.switchBadge(id.slice('badge:'.length)); return; }\n switch (id) {\n case 'news': this.news.showAll(); return;\n case 'shortcuts': this.openShortcuts(); return;\n case 'settings': this.settings.open(); return;\n // \"Aparência\" abre o painel direto na seção (era o modal de tema, que virou parte dela).\n case 'theme': this.settings.open(SPINE_SETTINGS_KEYS.appearance); return;\n case 'logout': void this.logout(); return;\n }\n }\n\n // ─── Busca global (paleta) ──────────────────────────────────────────────────\n private readonly quickAccess = inject(SpineQuickAccessService);\n public quickOpen = false;\n private quickIndex: QuickItem[] = [];\n /** Telas abertas pela busca (Configurações › Dados do navegador conta e apaga esta lista). */\n public recentSearches: QuickItem[] = [];\n /** Montados ao abrir: favoritos, abertos há pouco e módulos (o que aparece com o campo vazio) e as telas. */\n public searchCommands: readonly HermesCommand[] = [];\n protected readonly searchBrowse = [this.text.searchFavorites, this.text.searchRecent, this.text.searchModules];\n protected readonly searchIcons: Readonly<Record<string, string>> = {\n [this.text.searchFavorites]: 'star',\n [this.text.searchRecent]: 'history',\n [this.text.searchModules]: 'grid-layout',\n [this.text.searchScreens]: 'application',\n };\n\n /** Achata a árvore de rotas em itens navegáveis (com trilha de ancestrais). */\n private flattenRoutes(routes: Route[], trail: string[]): QuickItem[] {\n const skip = new Set(['search', 'theme', 'logout']);\n const out: QuickItem[] = [];\n for (const r of routes || []) {\n if (!r) continue;\n const name = r.route_display_name || '';\n if (r.route_redirect && name && !skip.has(r.route_type as string)) {\n out.push({ name, icon: r.route_icon || 'application', redirect: r.route_redirect, path: trail.join(' › ') });\n }\n if (r.routes?.length) out.push(...this.flattenRoutes(r.routes as Route[], name ? [...trail, name] : trail));\n }\n return out;\n }\n\n /** Chamado pelo `(searchRequested)` do `hm-header` (clique no campo, `Ctrl K` ou `/`, já tratados por ele): abre a paleta. */\n onSearchRequested(): void {\n this.searchCommands = this.buildSearchCommands();\n this.quickOpen = true;\n this.cdr.markForCheck();\n }\n\n /**\n * Comandos da paleta. Cada tela aparece uma vez: favoritos primeiro, depois os abertos há pouco que não são\n * favoritos, os módulos (topo do menu) e, só na busca, o resto das telas. Favoritos e recentes valem só se a\n * view atual (o crachá) ainda alcança a tela.\n */\n private buildSearchCommands(): HermesCommand[] {\n const path = (redirect: string) => redirect.split(/[?#]/)[0];\n const byPath = new Map(this.quickIndex.map((item) => [path(item.redirect), item]));\n const used = new Set<string>();\n const command = (group: string, item: QuickItem): HermesCommand => {\n used.add(path(item.redirect));\n return {\n id: `${group}:${path(item.redirect)}`,\n group,\n label: item.name,\n description: item.path || undefined,\n keywords: item.path ? [item.path] : undefined,\n icon: item.icon,\n run: () => this.goTo(item),\n };\n };\n const fromQuick = (entries: readonly QuickAccessItem[]) =>\n entries\n .map((entry) => byPath.get(path(entry.redirect)))\n .filter((item): item is QuickItem => !!item && !used.has(path(item.redirect)));\n\n const out: HermesCommand[] = [];\n for (const item of fromQuick(this.quickAccess.favorites())) out.push(command(this.text.searchFavorites, item));\n for (const item of fromQuick(this.quickAccess.recents()).slice(0, MAX_RECENT_SEARCH)) {\n out.push(command(this.text.searchRecent, item));\n }\n for (const node of spineRoutesOf(this.viewService.currentView)) {\n if (!node?.route_display_name) continue;\n const first = this.flattenRoutes([node], [])[0];\n if (!first || used.has(path(first.redirect))) continue;\n out.push(command(this.text.searchModules, { ...first, name: node.route_display_name, icon: node.route_icon || first.icon, path: '' }));\n }\n for (const item of this.quickIndex) if (!used.has(path(item.redirect))) out.push(command(this.text.searchScreens, item));\n return out;\n }\n\n private goTo(item: QuickItem): void {\n this.pushRecent(item);\n void this.router.navigateByUrl(item.redirect);\n }\n\n // ─── Histórico de buscas ────────────────────────────────────────────────────\n private readJson(key: string): any[] {\n try { const v = JSON.parse(localStorage.getItem(key) || '[]'); return Array.isArray(v) ? v : []; }\n catch { return []; }\n }\n\n private loadRecent(): QuickItem[] {\n return this.readJson(this.recentSearchKey)\n .filter((x) => x?.redirect && x?.name)\n .map((x) => ({ name: x.name, icon: x.icon || 'application', redirect: x.redirect, path: x.path || '' }))\n .slice(0, MAX_RECENT_SEARCH);\n }\n private pushRecent(item: QuickItem) {\n const entry: QuickItem = { name: item.name, icon: item.icon || 'application', redirect: item.redirect, path: item.path || '' };\n const next = [entry, ...this.recentSearches.filter((x) => x.redirect !== entry.redirect)].slice(0, MAX_RECENT_SEARCH);\n this.recentSearches = next;\n try { localStorage.setItem(this.recentSearchKey, JSON.stringify(next)); } catch { /* storage cheio/indisponível */ }\n }\n}\n","<hm-header [class.header-blocked]=\"headerBlocked\" (searchRequested)=\"onSearchRequested()\">\n <div *ngIf=\"headerBlocked\" class=\"header-overlay\"></div>\n\n <spine-app-launcher></spine-app-launcher>\n\n <!-- Marca: logo do app (SpineConfig.logo, padrão assets/images/logo.svg) + SpineConfig.appName,\n levando à primeira rota navegável. Ver SpineBrandComponent. -->\n <spine-brand [homeRoute]=\"homeRoute\" [label]=\"text.home\" />\n\n <div actions class=\"h-right\">\n <!-- central de notificações: o sino, com as novidades das fontes registradas (sem fonte, não aparece) -->\n <spine-inbox-button />\n\n <!-- tema claro/escuro -->\n <hm-icon-button emphasis=\"subtle\" (clicked)=\"setTheme(themeService.current == 'light' ? 'dark' : 'light')\"\n [icon]=\"themeService.current == 'light' ? 'moon' : 'sun'\"\n [label]=\"themeService.current == 'light' ? text.themeDark : text.themeLight\">\n </hm-icon-button>\n\n <!-- densidade -->\n <hm-icon-button emphasis=\"subtle\" (clicked)=\"setDensity()\"\n [icon]=\"isCompactDensity ? 'density-comfortable' : 'density-compact'\"\n [label]=\"isCompactDensity ? text.densityComfortable : text.densityCompact\">\n </hm-icon-button>\n\n <!-- Avaliar o {app} (SpineFeatures.ratings): a estrela abre o diálogo e fica cheia depois de avaliar. Toma o\n lugar do botão de tela cheia (o atalho de teclado continua); sem avaliação, a tela cheia volta aqui. -->\n @if (showFullscreenButton) {\n <hm-icon-button emphasis=\"subtle\" (clicked)=\"toggleFullscreen()\"\n [icon]=\"isFullscreen ? 'shrink' : 'resize'\"\n [label]=\"isFullscreen ? text.exitFullscreen : text.fullscreen\">\n </hm-icon-button>\n } @else {\n <spine-rate-app-button />\n }\n\n <span class=\"h-divider\" aria-hidden=\"true\"></span>\n\n <!-- perfil: crachá, ajuda, tema e sair ficam dentro do menu -->\n <hm-menu-button class=\"h-profile\" [label]=\"profile.name ?? text.user\" align=\"end\" [items]=\"profileMenuItems\" (chosen)=\"onProfileMenuChosen($event)\">\n <hm-account-avatar [name]=\"profile.name ?? text.user\" [imageUrl]=\"profile.picture\"></hm-account-avatar>\n <span class=\"h-profile-info\">\n <span class=\"h-profile-name\">{{ profile.name ?? text.user }}</span>\n <span class=\"h-profile-role\" *ngIf=\"badge\">{{ badge?.name }}</span>\n </span>\n </hm-menu-button>\n </div>\n</hm-header>\n\n<!-- Busca global: paleta ancorada logo abaixo do cabeçalho. Campo vazio = favoritos, abertos há pouco e\n módulos; com texto, busca em todas as telas. Setas/Enter navegam, Esc fecha. -->\n<hm-command-palette\n [(open)]=\"quickOpen\"\n [commands]=\"searchCommands\"\n [browseGroups]=\"searchBrowse\"\n [groupIcons]=\"searchIcons\"\n [label]=\"text.search\"\n [placeholder]=\"text.searchPlaceholder\"\n/>\n\n<!-- A janela de avaliação (flutuante, canto inferior direito): \"Avaliar o {app}\" da estrela do cabeçalho e de\n Configurações › Sobre, e \"Avaliar esta tela\" da barra da página (SpineFeatures.ratings). Só desenha com o recurso\n ligado e aberta. -->\n<spine-rating-window />\n","import { Injectable, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { ViewService } from '@orfeu/angular/core';\nimport {\n HERMES_WORKSPACE_PERSISTENCE_CONFIG,\n TabItem,\n WorkspaceGridLimits,\n WorkspaceState,\n WorkspaceStore,\n canSplitPanel,\n createPersistedWorkspaceStore,\n cyclicPanelNeighbor,\n findPanelTabs,\n panelIdsInOrder,\n} from '@trismegisto/angular';\nimport { tabUrl } from '@trismegisto/primitives';\nimport { Route, SpinePreferencesService, spineRoutesOf } from '@trismegisto/spine';\nimport { resolveEffectiveRouteChain } from '@trismegisto/spine/routing';\nimport { SpineTabParams } from './spine-tab';\n\nconst HOME_PATH = '/home';\n\ntype PanelNode = WorkspaceState['root'];\ntype PanelLeaf = Extract<PanelNode, { kind: 'panel' }>;\n\nfunction leavesOf(node: PanelNode): PanelLeaf[] {\n return node.kind === 'panel' ? [node] : [...leavesOf(node.a), ...leavesOf(node.b)];\n}\n\n/** Limite da grade de painéis do shell: no máximo 2 lado a lado e 2 empilhados (os quatro cantos da tela). */\nexport const SPINE_WORKSPACE_LIMITS: WorkspaceGridLimits = { maxColumns: 2, maxRows: 2 };\n\n/** O painel do outro lado da divisão lado a lado mais próxima de `panelId` (o primeiro dele, na ordem da árvore). */\nfunction besidePanel(node: PanelNode, panelId: string): string | null {\n if (node.kind === 'panel') return null;\n const inA = panelIdsInOrder(node.a).includes(panelId);\n if (!inA && !panelIdsInOrder(node.b).includes(panelId)) return null;\n const deeper = besidePanel(inA ? node.a : node.b, panelId);\n if (deeper) return deeper;\n return node.direction === 'row' ? panelIdsInOrder(inA ? node.b : node.a)[0] : null;\n}\n\n/** O caminho de um endereço (sem query nem fragmento). */\nexport function spinePathOf(url: string): string {\n return url.split(/[?#]/)[0] || HOME_PATH;\n}\n\n/** A query de um endereço, como objeto. */\nexport function spineParamsOf(url: string): SpineTabParams {\n const query = url.split('#')[0].split('?')[1] ?? '';\n const params: Record<string, string> = {};\n new URLSearchParams(query).forEach((value, name) => {\n params[name] = value;\n });\n return params;\n}\n\n/** Caminho + query com os nomes em ordem: o mesmo endereço escrito de dois jeitos vira um só (sem o fragmento). */\nexport function spineNormalizeUrl(url: string): string {\n const path = spinePathOf(url);\n const entries = Object.entries(spineParamsOf(url)).sort(([a], [b]) => a.localeCompare(b));\n return entries.length ? `${path}?${new URLSearchParams(entries).toString()}` : path;\n}\n\n/** Tamanho máximo do nome de aba vindo da tela ou do storage (o nome da rota não passa por aqui). */\nconst LABEL_MAX = 80;\n\n/** Nome de aba vindo de fora da árvore de rotas (a tela, o storage): uma linha, aparado e curto; vazio = não usar. */\nfunction cleanLabel(label: string | undefined): string | undefined {\n const clean = (label ?? '').replace(/\\s+/g, ' ').trim().slice(0, LABEL_MAX);\n return clean || undefined;\n}\n\n/** Os parâmetros da identidade estão todos no endereço, com os mesmos valores? */\nfunction keepsIdentity(id: string, url: string): boolean {\n if (spinePathOf(id) !== spinePathOf(url)) return false;\n const identity = spineParamsOf(id);\n const params = spineParamsOf(url);\n return Object.entries(identity).every(([name, value]) => params[name] === value);\n}\n\n/** Como abrir uma aba pelo app (`openTab`). */\nexport interface SpineOpenTabOptions {\n /** Nome da aba (senão, o da rota). A tela pode trocar depois (`SPINE_TAB.setLabel`). */\n label?: string;\n icon?: string;\n /**\n * Os parâmetros que IDENTIFICAM a aba: com `['dispositivo']`, o mesmo dispositivo em outra seção reaproveita a aba\n * aberta, e trocar a seção dentro dela não abre outra. Sem `match`, todos os parâmetros do endereço identificam.\n */\n match?: readonly string[];\n /**\n * Abre num painel novo ao lado do focado (para comparar), em vez de no próprio painel focado. Só vale com a\n * preferência \"Dividir abas\" ligada (`SpinePreferencesService.splitTabs`); desligada (o padrão), a aba abre no painel\n * focado, como sem `beside`. No limite da grade (`SPINE_WORKSPACE_LIMITS`, 2 colunas), abre no painel que já está\n * ao lado, sem dividir.\n */\n beside?: boolean;\n}\n\n/**\n * Dono do `WorkspaceStore` do shell — mesmo padrão do `WorkspaceNavService` do docs/website\n * (`packages/hermes-ui/docs/website/src/app/workspace-nav.service.ts`), adaptado pra ler a\n * árvore de rotas do BACKEND (`ViewService.currentView`) em vez de um `page-registry.ts`\n * estático. Cada página visitada vira uma aba, pertencente a um painel; a navegação real do\n * `Router` (routerLink, busca, sidebar) sempre atualiza a aba ativa do painel FOCADO.\n *\n * **Dois jeitos de ter aba, que convivem.** A navegação de sempre (menu, links, busca) mantém UMA aba por tela, com o\n * caminho como `id` — como antes; a query que a tela usa fica guardada no `url` da aba e volta junto quando a pessoa\n * retorna a ela. E o app pode abrir **abas com parâmetros** (`openTab`): a mesma tela várias vezes, uma por registro\n * (um pedido, um dispositivo...). Nelas o `id` é a identidade (o caminho com os parâmetros que a identificam) e o `url`\n * é o endereço atual (com a query que a tela vai mudando).\n * O keepAlive do workspace acompanha o `id`, então mudar a query da aba não recria a tela. Uma navegação real cai\n * numa destas, em ordem:\n * 1. o endereço já é o da aba ativa → nada;\n * 2. a mesma tela da aba ativa, mantendo os parâmetros que a identificam → só o `url` da aba muda (mesma aba);\n * 3. outra aba do painel já está nesse endereço → ela é ativada;\n * 4. senão → a aba ativa passa a ser a da tela nova (o comportamento de sempre).\n * `openTab` abre (ou foca, em qualquer painel) a aba de um endereço com parâmetros.\n *\n * **Dividir abas é preferência da pessoa** (`SpinePreferencesService.splitTabs`, desligada por padrão): o shell só\n * deixa dividir a área em painéis com ela ligada (`split`). Desligada — ao carregar ou ao desligar —, um arranjo com\n * vários painéis (salvo no navegador ou feito antes) é fundido num painel só, sem perder aba (`mergePanels`).\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineWorkspaceNavService {\n private readonly router = inject(Router);\n private readonly viewService = inject(ViewService);\n private readonly preferences = inject(SpinePreferencesService);\n\n /** A pessoa pode dividir a área de abas em painéis (a preferência \"Dividir abas\"). */\n readonly split = computed(() => this.preferences.splitTabs());\n /** Até onde dá para dividir (o shell passa para o `hm-workspace`; `openTab` com `beside` respeita). */\n readonly limits = SPINE_WORKSPACE_LIMITS;\n\n readonly store: WorkspaceStore = createPersistedWorkspaceStore(\n { tabs: [this.tabFor(HOME_PATH)], activeId: HOME_PATH },\n (id, saved) => this.restoreTab(id, saved),\n inject(HERMES_WORKSPACE_PERSISTENCE_CONFIG),\n );\n\n private readonly state = signal<WorkspaceState>(this.store.getState());\n readonly root = computed(() => this.state().root);\n readonly focusedPanelId = computed(() => this.state().focusedPanelId);\n\n /** Cadeia resolvida (header→…→page) da aba ativa do painel FOCADO — é o que `spine-sidebar`\n * (menu) e `spine-navigation` (breadcrumb) leem pra saber \"onde estamos\", no lugar do antigo\n * `viewService.logControl$`/`breadCrumb$` globais (que só existiam porque havia uma página\n * \"atual\" só; agora cada painel tem a sua). */\n readonly focusedChain = computed<Route[] | null>(() => {\n const s = this.state();\n const activeId = findPanelTabs(s.root, s.focusedPanelId)?.activeId;\n return activeId ? this.chainFor(activeId) : null;\n });\n\n /** O último endereço que o `Router` mostrou (normalizado, com a query): o `effect` abaixo não navega para ele de novo. */\n private lastKnownUrl = '';\n\n constructor() {\n this.store.subscribe((s) => this.state.set(s));\n // Já antes da primeira tela: o arranjo salvo com vários painéis volta num painel só se a divisão está desligada.\n if (!this.split()) this.mergePanels();\n effect(() => {\n if (!this.split()) untracked(() => this.mergePanels());\n });\n\n this.router.events.subscribe((event) => {\n if (!(event instanceof NavigationEnd)) return;\n const url = spineNormalizeUrl(event.urlAfterRedirects);\n this.lastKnownUrl = url;\n this.followNavigation(this.state().focusedPanelId, url);\n });\n\n // Mesma corrida documentada no WorkspaceNavService do docs/website: pula a 1ª execução, senão\n // o estado inicial (hardcoded ou recém-restaurado do sessionStorage) vence a navegação real\n // (mais lenta, resolve async) e qualquer link direto/F5 cai sempre em HOME_PATH.\n // Compara o endereço INTEIRO (com a query): só o caminho, uma aba com parâmetros navegaria sem parar.\n let first = true;\n effect(() => {\n const active = this.activeTab(this.state(), this.state().focusedPanelId);\n if (first) {\n first = false;\n return;\n }\n if (!active) return;\n const url = spineNormalizeUrl(tabUrl(active));\n if (url === this.lastKnownUrl) return;\n this.lastKnownUrl = url;\n void this.router.navigateByUrl(tabUrl(active));\n });\n\n // Troca de crachá (ou acesso revisto) chega como uma view nova: as abas abertas obedecem a ela.\n this.viewService.currentView$.subscribe(() => this.reconcileWithView());\n }\n\n private activeTab(state: WorkspaceState, panelId: string): TabItem | null {\n const panel = findPanelTabs(state.root, panelId);\n return panel?.tabs.find((tab) => tab.id === panel.activeId) ?? null;\n }\n\n /** Uma navegação real no painel focado: as quatro regras do comentário da classe. */\n private followNavigation(panelId: string, url: string): void {\n const panel = findPanelTabs(this.state().root, panelId);\n const active = panel ? this.activeTab(this.state(), panelId) : null;\n if (active && spineNormalizeUrl(tabUrl(active)) === url) return;\n if (active && keepsIdentity(active.id, url)) {\n this.store.updateTab(panelId, active.id, { url: url === active.id ? undefined : url });\n return;\n }\n const other = panel?.tabs.find((tab) => spineNormalizeUrl(tabUrl(tab)) === url);\n if (other) {\n this.store.activateTab(panelId, other.id);\n return;\n }\n // A tela pode já ter uma aba no painel (só ativada, não trocada): o endereço novo vai junto.\n const tab = this.tabFor(url);\n this.store.navigateActiveTab(panelId, tab);\n this.store.updateTab(panelId, tab.id, { url: tab.url });\n }\n\n /**\n * As abas abertas passam a obedecer à view atual: aba de tela que a pessoa não pode mais abrir fecha (e o\n * conteúdo dela é destruído junto); painel que ficaria sem aba nenhuma mostra o Início no lugar; a aba ativa\n * de cada painel recebe o nome e o ícone da view nova (a aba com parâmetros guarda o nome que a tela deu). View\n * vazia (ainda carregando) não fecha nada.\n */\n reconcileWithView(): void {\n if (spineRoutesOf(this.viewService.currentView).length === 0) return;\n for (const leaf of leavesOf(this.state().root)) {\n const { tabs, activeId } = leaf.tabs;\n const denied = tabs.filter((tab) => tab.id !== HOME_PATH && !this.chainFor(tab.id));\n if (denied.length === tabs.length) {\n // Nada ali vale mais: a aba ativa vira o Início e as outras saem.\n this.store.navigateActiveTab(leaf.id, this.tabFor(HOME_PATH));\n for (const tab of denied) if (tab.id !== activeId) this.store.closeTab(leaf.id, tab.id);\n continue;\n }\n for (const tab of denied) this.store.closeTab(leaf.id, tab.id);\n const active = this.activeTab(this.state(), leaf.id);\n if (!active) continue;\n const fresh = this.tabFor(active.id);\n const custom = active.id.includes('?');\n this.store.updateTab(leaf.id, active.id, {\n ...(custom ? {} : { label: fresh.label }), icon: fresh.icon, description: fresh.description,\n });\n }\n }\n\n /** Resolve a cadeia de rotas pra uma URL, direto na view atual — sem `Router`, sem `async`\n * (o componente da folha só é carregado por quem for de fato desenhar o painel). Desce sozinho\n * por nós organizacionais (com filhos, sem conteúdo próprio) — o rótulo/ícone da aba e o que a\n * sidebar/breadcrumb mostram refletem o destino DE VERDADE, não a rota-container clicada. A query não\n * conta: `ViewService.routePath` a tira. */\n private chainFor(url: string): Route[] | null {\n const currentRoutes = spineRoutesOf(this.viewService.currentView);\n return resolveEffectiveRouteChain(\n currentRoutes,\n (u) => this.viewService.getLevel(u),\n (u, level) => this.viewService.getUrlAtLevel(u, level),\n spinePathOf(url),\n );\n }\n\n /** A aba de uma tela pelo endereço: o `id` é o caminho; com query, o endereço vai no `url` (a mesma aba da tela). */\n tabFor(url: string): TabItem {\n const path = spinePathOf(url);\n const chain = this.chainFor(path);\n const leaf = chain?.at(-1);\n // Segunda linha do cartão de hover da aba: onde a página fica na navegação (a trilha do breadcrumb).\n const trail = (chain ?? []).slice(0, -1).map((route) => route.route_display_name).filter(Boolean).join(' › ');\n const normalized = spineNormalizeUrl(url);\n return {\n id: path,\n label: leaf?.route_display_name ?? path,\n icon: leaf?.route_icon ?? undefined,\n description: trail || undefined,\n ...(normalized !== path ? { url: normalized } : {}),\n };\n }\n\n /**\n * Restaura uma aba salva (F5): a rota precisa continuar valendo para a pessoa. A aba com parâmetros volta com o\n * endereço e o nome que tinha (o nome é o que a tela deu — \"RT-MPLS-3046-0001\" —, a rota não sabe); as outras\n * voltam com o nome da rota (que acompanha o idioma).\n */\n private restoreTab(id: string, saved?: { url?: string; label?: string }): TabItem | null {\n const url = saved?.url ?? id;\n if (!this.chainFor(url)) return null;\n const fresh = this.tabFor(url);\n return {\n ...fresh,\n id,\n ...(saved?.url && saved.url !== id ? { url: saved.url } : { url: undefined }),\n label: (id.includes('?') && cleanLabel(saved?.label)) || fresh.label,\n };\n }\n\n /**\n * Junta todos os painéis no focado, sem perder aba: as abas ficam na ordem dos painéis (da esquerda para a direita,\n * de cima para baixo), uma aba repetida em dois painéis vira uma só (vale a do focado), e a aba ativa do painel focado\n * continua a ativa (`WorkspaceStore.mergePanels`). Com um painel só, não faz nada.\n */\n mergePanels(): void {\n const { root, focusedPanelId } = this.store.getState();\n if (root.kind === 'panel') return;\n const ids = panelIdsInOrder(root);\n this.store.mergePanels(ids.includes(focusedPanelId) ? focusedPanelId : ids[0]);\n }\n\n /** O `+` de um painel: abre a home ali, como um navegador. */\n openNewTab(panelId: string): void {\n this.store.openTab(panelId, this.tabFor(HOME_PATH));\n }\n\n /**\n * Abre (ou foca) a aba de um endereço com parâmetros — um registro por aba na mesma tela:\n * `openTab('/vendas/pedidos?pedido=123&secao=itens', { label: 'Pedido 123', match: ['pedido'] })`.\n * Se alguma aba (em qualquer painel) já tem essa identidade, ela é focada e passa a esse endereço; senão abre uma\n * no painel focado (ou num painel novo ao lado, com `beside` e a divisão ligada). Só abre o que a view da pessoa permite (a mesma\n * regra do menu e do `ViewGuard`); fora dela, não faz nada.\n */\n openTab(url: string, options: SpineOpenTabOptions = {}): void {\n const target = spineNormalizeUrl(url);\n if (!this.chainFor(target)) return;\n const params = spineParamsOf(target);\n const identity = options.match ? Object.fromEntries(options.match.filter((n) => n in params).map((n) => [n, params[n]])) : params;\n const id = spineNormalizeUrl(`${spinePathOf(target)}?${new URLSearchParams(identity).toString()}`);\n const label = cleanLabel(options.label);\n const patch = { url: target === id ? undefined : target, ...(label ? { label } : {}), ...(options.icon ? { icon: options.icon } : {}) };\n\n for (const leaf of leavesOf(this.state().root)) {\n if (!leaf.tabs.tabs.some((tab) => tab.id === id)) continue;\n this.store.updateTab(leaf.id, id, patch);\n this.store.focusPanel(leaf.id);\n this.store.activateTab(leaf.id, id);\n return;\n }\n\n const fresh = this.tabFor(target);\n const tab: TabItem = { ...fresh, id, ...patch, label: label ?? fresh.label, icon: options.icon ?? fresh.icon };\n const { root, focusedPanelId } = this.state();\n if (options.beside && this.split()) {\n if (canSplitPanel(root, focusedPanelId, 'row', this.limits)) {\n this.store.splitPanel(focusedPanelId, 'row', tab);\n return;\n }\n // No limite de colunas: abre no painel que já está ao lado (o do outro lado da divisão), sem dividir.\n const beside = besidePanel(root, focusedPanelId) ?? cyclicPanelNeighbor(panelIdsInOrder(root), focusedPanelId, 1);\n if (beside) {\n this.store.openTab(beside, tab);\n this.store.focusPanel(beside);\n return;\n }\n }\n this.store.openTab(focusedPanelId, tab);\n }\n\n /** O nome (e o ícone) de uma aba, dado pela tela (`SPINE_TAB.setLabel`). */\n setTabLabel(panelId: string, tabId: string, label: string, icon?: string): void {\n const clean = cleanLabel(label);\n if (clean) this.store.updateTab(panelId, tabId, { label: clean, ...(icon ? { icon } : {}) });\n }\n\n /**\n * A tela muda o endereço da própria aba (`SPINE_TAB.navigate`). A mesma tela, mantendo a identidade: só o `url` da\n * aba muda (sem recriar a tela) e, se ela é a visível do painel focado, o endereço do navegador acompanha (sem\n * empilhar histórico). Outra tela: navegação local no painel, como um link dentro dele.\n */\n navigateTab(panelId: string, tabId: string, url: string): void {\n const target = spineNormalizeUrl(url);\n if (!keepsIdentity(tabId, target)) {\n this.navigateLocally(panelId, target);\n return;\n }\n this.store.updateTab(panelId, tabId, { url: target === tabId ? undefined : target });\n const s = this.state();\n if (s.focusedPanelId === panelId && findPanelTabs(s.root, panelId)?.activeId === tabId) {\n this.lastKnownUrl = target;\n void this.router.navigateByUrl(target, { replaceUrl: true });\n }\n }\n\n /** Navegação LOCAL a um painel específico (usada pelo `PanelLocalLinkDirective`) — troca o\n * ASSUNTO da aba ativa daquele painel, não empilha uma aba nova. */\n navigateLocally(panelId: string, href: string): void {\n this.store.navigateActiveTab(panelId, this.tabFor(href));\n }\n}\n","import { CommonModule, Location } from '@angular/common';\nimport { Component, computed, effect, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, NavigationSkipped, Router } from '@angular/router';\nimport { filter } from 'rxjs';\nimport { AppDef, AuthorizationService, RealmAppsService, ViewService } from '@orfeu/angular/core';\nimport { ContextMenuDirective, HermesSidebarService, IconComponent, SidebarComponent as HermesSidebarComponent, SidebarNode, SidebarNodeComponent } from '@trismegisto/angular';\nimport { Route, routerIdOf, SPINE_MESSAGES, spineRoutesOf } from '@trismegisto/spine';\nimport { SpineWorkspaceNavService } from '../workspace/spine-workspace-nav.service';\nimport { formatMessage, MenuItem } from '@trismegisto/primitives';\n\n/**\n * `Route` (árvore do backend) → `SidebarNode` (genérico, o que `hm-sidebar-node` sabe desenhar).\n * Sem filtrar por `route_type`: a árvore real mistura tipos livremente por PAPEL, não por\n * profundidade fixa (achado real, 2026-09-28, com a árvore de verdade em mãos — 'menu'/'item'/\n * 'submenu'/'page' aparecem intercalados; um nó 'item' pode ter filhos 'submenu' que têm filhos\n * 'page', por exemplo \"Sistema\"). `hm-sidebar-node` já decide sozinho link-vs-grupo pela presença\n * de filhos + profundidade restante — não precisa saber o `route_type` pra nada.\n */\nfunction toSidebarNode(route: Route): SidebarNode {\n return {\n // Página: o router (a tela); grupo (sem router próprio): a rota.\n id: routerIdOf(route) ?? route.routed_id,\n label: route.route_display_name ?? '',\n icon: route.route_icon ?? undefined,\n route: route.route_redirect ?? '',\n children: (route.routes ?? []).map(toSidebarNode),\n };\n}\n\n/**\n * Menu lateral fixo — TODA a navegação do shell mora aqui agora, nunca no header (decisão\n * explícita do usuário: \"não deve ter ícones de navegação no menu superior, deve ter um menu\n * lateral de navegação fixa\" — o antigo `h-nav`/`hm-menu-button` de nível 'header'/'menu' do\n * `header.component.html` foi removido, essa navegação virou `modules` abaixo).\n *\n * Dois níveis, um de cada vez — MESMO padrão de back/forward do `docs/website`'s sidebar (achado\n * real, 2026-09-28: a primeira versão mostrava os dois SEMPRE juntos, empilhados, achando que o\n * modelo de rotas do backend não permitia \"sair\" de um módulo — errado; nada impede mostrar só um\n * nível por vez com um botão de voltar, é só um `signal` local):\n * - `modules` (nível 1, 'header', de `ViewService.currentView` direto — não muda com a navegação\n * do painel): a lista pra trocar de módulo.\n * - `menus`: a cadeia resolvida da aba ativa do painel FOCADO\n * (`SpineWorkspaceNavService.focusedChain`) — os itens do módulo ATUAL.\n * `viewingModules` decide qual dos dois aparece; volta pra `false` sozinho sempre que o módulo\n * atual muda (navegação real feita, mesma UX do `leaveModule()` do docs).\n */\n@Component({\n selector: 'spine-sidebar',\n imports: [CommonModule, ContextMenuDirective, HermesSidebarComponent, SidebarNodeComponent, IconComponent],\n templateUrl: './sidebar.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [`\n /* Aplicações (só no mobile): o seletor de apps do header some abaixo de 768px e vem para a sidebar. */\n .spine-sidebar-apps { display: none; }\n @media (max-width: 767px) {\n .spine-sidebar-apps {\n display: flex;\n flex-direction: column;\n gap: var(--hm-space-micro);\n margin-bottom: var(--hm-space-sm);\n padding-bottom: var(--hm-space-sm);\n border-bottom: var(--hm-border-hairline) solid var(--hm-divider);\n }\n .spine-sidebar-apps__title {\n display: flex;\n align-items: center;\n gap: var(--hm-space-nano);\n margin: 0 var(--hm-space-xxxs);\n color: var(--hm-muted);\n font-size: var(--hm-font-size-xs);\n font-weight: var(--hm-font-weight-semibold);\n letter-spacing: 0.04em;\n text-transform: uppercase;\n }\n .spine-sidebar-apps__link {\n display: flex;\n align-items: center;\n gap: var(--hm-space-nano);\n min-height: var(--hm-space-2xl);\n padding: var(--hm-space-nano) var(--hm-space-xxxs);\n border-radius: var(--hm-radius-control);\n color: inherit;\n font-size: var(--hm-font-size-sm);\n text-decoration: none;\n }\n .spine-sidebar-apps__link:hover,\n .spine-sidebar-apps__link:focus-visible { background: var(--hm-hover); }\n }\n\n /* Achado real, 2026-09-28: \\`hm-sidebar\\` (a TAG) é \\`display: contents\\` no @trismegisto/core\n * (repassa os filhos pro pai, sem caixa própria) — \\`height\\` nela não faz NADA, por spec CSS\n * (display:contents não gera caixa principal, propriedade de tamanho é ignorada). Quem\n * realmente precisa da altura é \\`.hm-sidebar\\` (a classe, o <nav> de verdade lá dentro) — e\n * ele só recebe de verdade se ESTE host também tiver altura definida (senão \"100%\" de um pai\n * com altura automática também não é nada). Era isto que sobrava como espaço em branco: o\n * <nav> ficava do tamanho do próprio conteúdo, mas o layout ao redor já reservava a coluna\n * inteira pro sidebar.\n *\n * Segunda rodada do MESMO bug, achada ao vivo 2026-09-28 (barra branca sobrevivia ao fix\n * acima, \\`height:100%\\` sem efeito nenhum medido no DOM real): a regra \\`.hm-sidebar\\` deste\n * bloco NUNCA bateu no \\`<nav class=\"hm-sidebar\">\\` de verdade. Motivo: encapsulamento emulado\n * do Angular tagueia cada seletor com o atributo \\`_ngcontent\\` do componente DONO do template\n * onde o elemento nasce — e o \\`<nav class=\"hm-sidebar\">\\` nasce dentro do template do\n * \\`HermesSidebarComponent\\` (\\`@trismegisto/angular\\`, seletor \\`hm-sidebar\\`), não do template\n * deste \\`SidebarComponent\\` do spine. \\`<hm-sidebar>\\` (a TAG, que É filha direta do template\n * daqui) recebe o atributo certo; o \\`<nav>\\` que \\`display:contents\\` \"promove\" pra cima, não —\n * então \\`.hm-sidebar[_ngcontent-spine-x]\\` vira um seletor que não existe em lugar nenhum do\n * DOM real, silenciosamente inerte. \\`::ng-deep\\` é o jeito suportado de escrever uma regra sem\n * esse atributo, alcançando de fato o DOM interno de um componente filho.\n *\n * E o que essa regra precisa fazer: \\`.hm-sidebar\\` no \\`_sidebar.scss\\` do core tem\n * \\`flex: none\\` — certo pro caso comum (filho de um flex EM LINHA, onde só a LARGURA deve ser\n * travada por \\`width\\`/\\`min-width\\`/\\`max-width\\`, nunca deve \"crescer\"). Mas aqui \\`:host\\` é um\n * flex EM COLUNA — nesse eixo, \\`flex: none\\` também zera \\`flex-grow\\`, então o <nav> (único\n * item do eixo vertical) nunca cresce pra preencher o restante da coluna. \\`flex-grow: 1\\`\n * reforça o preenchimento pelo eixo certo (altura) sem tocar a LARGURA (eixo cruzado, continua\n * só sob controle de width/min-width/max-width do core) — escopado só no spine (\\`:host\\` na\n * frente), o core continua \\`flex: none\\` pra quem usa \\`hm-sidebar\\` direto num flex em linha\n * (docs/website, hefesto sem o wrapper de coluna). */\n :host { display: flex; flex-direction: column; height: 100%; }\n :host ::ng-deep .hm-sidebar { height: 100%; flex-grow: 1; }\n `],\n})\nexport class SidebarComponent {\n protected readonly text = inject(SPINE_MESSAGES).sidebar;\n protected readonly fmt = formatMessage;\n private readonly workspace = inject(SpineWorkspaceNavService);\n private readonly viewService = inject(ViewService);\n private readonly authService = inject(AuthorizationService);\n private readonly realmApps = inject(RealmAppsService);\n private readonly location = inject(Location);\n private readonly column = inject(HermesSidebarService);\n\n protected readonly pageMenu: readonly MenuItem[] = [{ id: 'new-tab', label: this.text.openInNewTab, icon: 'plus' }];\n /** Endereço da página em que o menu de contexto foi aberto. */\n private menuPage = '';\n\n /** Aplicações do realm (o app atual já vem excluído pelo backend) — exibidas só no mobile. */\n protected readonly apps = signal<AppDef[]>([]);\n\n private readonly currentView = toSignal(this.viewService.currentView$, { initialValue: this.viewService.currentView });\n /** Sem nenhum crachá (nenhum grupo do app — ver `ViewGuard`, tela `/blocked`), o menu fica vazio\n * mesmo que a view traga rotas públicas: listar o que leva de volta ao \"Acesso bloqueado\" não\n * ajuda. `badges` não é sinal, mas a view sempre é refeita depois do token (`view.update`), e é\n * ela que recalcula isto. */\n protected readonly modules = computed<SidebarNode[]>(() => {\n // Irmãos de mesmo endereço já fundidos: um \"laboratorio\" só, não um por nível (ver `mergeRouteTree`).\n const routes = spineRoutesOf(this.currentView());\n if (this.authService.authenticated && !this.authService.badges.length) return [];\n return routes.map(toSidebarNode);\n });\n\n protected readonly currentModule = computed<Route | null>(() => this.workspace.focusedChain()?.[0] ?? null);\n\n /** Filhos diretos do módulo atual — sem filtrar por `route_type` (ver `toSidebarNode`). */\n protected readonly menus = computed<SidebarNode[]>(() => (this.currentModule()?.routes ?? []).map(toSidebarNode));\n\n /** Nem todo nível 1 é um \"módulo\" navegável — \"Início\"/\"Monitoração\" na árvore real são\n * `route_type: 'page'` SEM filhos, folhas diretas (achado real, 2026-09-28: mostravam\n * cabeçalho + botão voltar + área de conteúdo vazia, como se fossem módulos de verdade). Só\n * entra no modo \"dentro do módulo\" quando há algo pra mostrar como submenu. */\n protected readonly currentModuleHasChildren = computed(() => (this.currentModule()?.routes?.length ?? 0) > 0);\n\n /** `true` = mostrando a lista de módulos; `false` = mostrando o menu do módulo atual. Cai pra\n * `true` sozinho quando o módulo atual não tem submenu nenhum — nesse caso não existe \"dentro\n * do módulo\" pra mostrar. */\n private readonly wantsModules = signal(false);\n protected readonly viewingModules = computed(() => this.wantsModules() || !this.currentModuleHasChildren());\n\n /** Botão direito (ou Shift+F10/tecla Menu, que o navegador traduz em `contextmenu`) numa página do menu. Grupo e\n * entrada de módulo não são páginas: ali o menu nativo continua valendo. */\n protected onContextMenu(event: MouseEvent, menu: ContextMenuDirective): void {\n const link = (event.target as HTMLElement).closest<HTMLAnchorElement>('a.hm-sidebar-link:not(.hm-sidebar-link--opens-menu)');\n const href = link?.getAttribute('href');\n if (!link || !href) return;\n event.preventDefault();\n this.menuPage = this.location.normalize(href);\n // No modo automático a coluna fecharia: o ponteiro vai para o menu, que fica fora dela.\n this.column.holdOpen(true);\n // Pelo teclado o evento pode vir sem coordenadas: abre colado no link.\n const box = link.getBoundingClientRect();\n menu.openAt(event.clientX || box.left, event.clientY || box.bottom);\n }\n\n protected onPageMenuClosed(): void {\n this.column.holdOpen(false);\n }\n\n protected openPageInNewTab(): void {\n this.workspace.openTab(this.menuPage);\n }\n\n /** Sem teto artificial de nível de grupo — o template não enxerga o global `Infinity`, só\n * membros da classe. Ver comentário no `.html`: o backend já limita a árvore sozinho. */\n protected readonly maxDepth = Infinity;\n\n constructor() {\n void this.realmApps.getApplications(this.authService.getToken()).then(\n list => this.apps.set(list ?? []),\n () => this.apps.set([]), // sem a lista, o bloco de aplicações só não aparece\n );\n\n // Navegou de verdade (clicou num módulo, ou entrou direto por link/F5) -> volta pro menu do\n // módulo novo. Só faz sentido reagir à IDENTIDADE do módulo (router da página ou, num grupo, a\n // rota -- módulo costuma ser grupo, sem router próprio), não ao objeto inteiro\n // (a cadeia inteira muda a cada troca de aba dentro do MESMO módulo também).\n let lastModuleId: string | null | undefined;\n effect(() => {\n const module = this.currentModule();\n const id = module ? routerIdOf(module) ?? module.routed_id : null;\n if (id !== lastModuleId) {\n lastModuleId = id;\n this.wantsModules.set(false);\n }\n });\n\n // O efeito acima não cobre voltar pro MESMO módulo: dentro de \"Sistema\", \"← Módulos\" e\n // clicar em \"Sistema\" de novo navega (a rota muda), mas a identidade do módulo é a mesma — o\n // efeito não dispara e a lista de módulos ficava na tela (achado real, 2026-09-29: só\n // funcionava passando por outro módulo antes). Qualquer navegação concluída é um \"entrar\".\n // NavigationSkipped também: clicar no módulo cuja página já está aberta cai no ViewGuard\n // (`/sys` cancela e redireciona pra `/sys/about/resources`), e o redirect pra URL ATUAL é\n // descartado pelo Router como \"mesma URL\" — não emite NavigationEnd nenhum.\n inject(Router).events.pipe(\n filter(e => e instanceof NavigationEnd || e instanceof NavigationSkipped),\n takeUntilDestroyed(),\n ).subscribe(() => this.wantsModules.set(false));\n }\n\n protected showModules(): void {\n this.wantsModules.set(true);\n }\n}\n","<span hidden [hmContextMenu]=\"pageMenu\" #pageContextMenu=\"hmContextMenu\" (chosen)=\"openPageInNewTab()\" (closed)=\"onPageMenuClosed()\"></span>\n<hm-sidebar\n *ngIf=\"modules().length != 0 || menus().length != 0\"\n [label]=\"!viewingModules() && currentModule() ? fmt(text.moduleNavigation, { module: currentModule()!.route_display_name ?? '' }) : text.modules\"\n [heading]=\"!viewingModules() ? (currentModule()?.route_display_name ?? '') : ''\"\n [headingIcon]=\"currentModule()?.route_icon ?? 'grid'\"\n [backLabel]=\"!viewingModules() && modules().length > 1 ? text.modules : ''\"\n [direction]=\"viewingModules() ? 'back' : 'forward'\"\n (back)=\"showModules()\"\n (contextmenu)=\"onContextMenu($event, pageContextMenu)\"\n>\n <!-- Só no mobile: o seletor de aplicações do header some e vem para cá. -->\n @if (apps().length) {\n <section class=\"spine-sidebar-apps\" [attr.aria-label]=\"text.apps\">\n <p class=\"spine-sidebar-apps__title\"><hm-icon shape=\"grid\" /> {{ text.apps }}</p>\n @for (app of apps(); track app.app_url) {\n <a class=\"spine-sidebar-apps__link\" [href]=\"app.app_url\" target=\"_blank\" rel=\"noopener noreferrer\">\n <hm-icon shape=\"applications\" />\n <span>{{ app.name }}</span>\n </a>\n }\n </section>\n }\n @if (viewingModules()) {\n @for (m of modules(); track m.id) {\n <hm-sidebar-node [node]=\"m\" [depth]=\"0\" />\n }\n } @else {\n @for (menu of menus(); track menu.id) {\n <!-- Infinity, não um número fixo: o backend do spine já usa `route_type` pra limitar a\n árvore a 6 níveis (header→navigation→menu→item→submenu→page — ver `route.model.ts`),\n então não há necessidade de um segundo teto aqui. Um teto baixo (achado ao vivo,\n 2026-09-28: `depth=2`) forçava o penúltimo nível a virar link plano mesmo tendo\n filhos reais (ex.: \"submenu\" com páginas embaixo sumia da árvore visível). -->\n <hm-sidebar-node [node]=\"menu\" [depth]=\"maxDepth\" />\n }\n }\n</hm-sidebar>\n","import { ChangeDetectionStrategy, Component, ElementRef, computed, effect, inject, viewChild } from '@angular/core';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport {\n ButtonComponent, HERMES_THEME_CONFIG, HermesDensity, HermesI18nService, HermesThemeMode, HermesThemeService, IconComponent,\n SegmentedControlComponent, SegmentedOption, ThemePickerComponent,\n} from '@trismegisto/angular';\nimport { DensityService, SPINE_CONFIG, SPINE_MESSAGES, SpinePreferencesService, ThemePresetService, ThemeService } from '@trismegisto/spine';\nimport {\n HERMES_FONTS, HERMES_TEXT_SCALES, HermesFont, HermesMotionPreference, ShortcutDisplay, detectShortcutPlatform, formatMessage, formatShortcut,\n} from '@trismegisto/primitives';\nimport { SpineBrandComponent } from '../header/brand.component';\nimport { SpineInitialSetupService } from './initial-setup.service';\n\n/** Um cartão do essencial: o texto tem `{key}` onde entra a tecla (desenhada como `<kbd>`). */\ninterface EssentialCard {\n readonly id: string;\n readonly icon: string;\n readonly title: string;\n readonly before: string;\n readonly after: string;\n readonly keys: ShortcutDisplay | null;\n}\n\n/**\n * Tela cheia da configuração inicial (ver `SpineInitialSetupService`): sem cabeçalho nem menu, por cima do shell\n * (que fica `inert` enquanto ela está aberta). Cada escolha vale na hora — chama os mesmos serviços do painel de\n * configurações —, e a prévia ao lado é desenhada com os tokens do tema, então acompanha tudo.\n */\n@Component({\n selector: 'spine-initial-setup',\n imports: [ButtonComponent, IconComponent, SegmentedControlComponent, ThemePickerComponent, SpineBrandComponent],\n templateUrl: './initial-setup.component.html',\n styleUrl: './initial-setup.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SpineInitialSetupComponent {\n protected readonly setup = inject(SpineInitialSetupService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly t = this.messages.setup;\n protected readonly s = this.messages.settings;\n protected readonly fmt = formatMessage;\n\n private readonly theme = inject(ThemeService);\n private readonly hermesTheme = inject(HermesThemeService);\n private readonly themeConfig = inject(HERMES_THEME_CONFIG);\n private readonly presets = inject(ThemePresetService);\n private readonly density = inject(DensityService);\n private readonly i18n = inject(HermesI18nService);\n protected readonly preferences = inject(SpinePreferencesService);\n protected readonly appName = inject(SPINE_CONFIG, { optional: true })?.appName ?? 'Hermes';\n\n private readonly heading = viewChild<ElementRef<HTMLElement>>('heading');\n\n /** Primeiro nome do perfil, para a saudação. */\n protected readonly greeting = (() => {\n const name = (inject(AuthorizationService, { optional: true })?.profile?.name ?? '').trim().split(/\\s+/)[0];\n return name ? formatMessage(this.t.greeting, { name }) : this.t.greetingAnonymous;\n })();\n\n protected readonly stepNumber = computed(() => (this.setup.step() === 'appearance' ? 1 : 2));\n protected readonly stepTotal = computed(() => (this.setup.mode() === 'full' ? 2 : 1));\n\n // ── Aparência (as mesmas opções do painel de configurações) ────────────────────────────────\n protected readonly families = this.presets.families;\n protected readonly themeMode = computed(() => this.hermesTheme.mode());\n protected readonly appliedTheme = computed(() => this.hermesTheme.theme());\n protected readonly family = computed(() => this.hermesTheme.family());\n protected readonly densityValue = computed(() => this.hermesTheme.density());\n protected readonly fontValue = computed(() => this.hermesTheme.font());\n protected readonly textSizeValue = computed(() => String(this.preferences.textScale()));\n\n protected readonly themeOptions: readonly SegmentedOption[] = [\n { value: 'light', label: this.s.themeLight, icon: 'sun' },\n { value: 'dark', label: this.s.themeDark, icon: 'moon' },\n { value: 'system', label: this.s.themeSystem, icon: 'computer' },\n ];\n protected readonly densityOptions: readonly SegmentedOption[] = [\n { value: 'comfortable', label: this.s.comfortable },\n { value: 'compact', label: this.s.compact },\n ];\n protected readonly fontOptions: readonly SegmentedOption[] = (this.hermesTheme.fonts ?? HERMES_FONTS).map((f) => ({ value: f.id, label: f.label }));\n protected readonly motionOptions: readonly SegmentedOption[] = [\n { value: 'system', label: this.s.motionSystem },\n { value: 'reduce', label: this.s.motionReduce },\n { value: 'full', label: this.s.motionFull },\n ];\n protected readonly textSizeOptions = computed<readonly SegmentedOption[]>(() => {\n const percent = new Intl.NumberFormat(this.i18n.formatLocale(), { style: 'percent', maximumFractionDigits: 0 });\n return HERMES_TEXT_SCALES.map((scale) => ({ value: String(scale), label: percent.format(scale) }));\n });\n\n // ── O essencial ─────────────────────────────────────────────────────────────────────────────\n private readonly platform = detectShortcutPlatform();\n protected readonly essentials: readonly EssentialCard[] = [\n this.card('search', 'search', this.t.searchTitle, this.t.searchText, 'Mod+K'),\n this.card('tabs', 'view-columns', this.t.tabsTitle, this.t.tabsText),\n this.card('favorites', 'heart', this.t.favoritesTitle, this.t.favoritesText),\n this.card('settings', 'cog', this.t.settingsTitle, this.t.settingsText, 'Mod+,'),\n ];\n\n constructor() {\n // Foco no título a cada etapa: o leitor de tela anuncia onde está, e o Tab segue a ordem da tela.\n effect(() => {\n this.setup.step();\n queueMicrotask(() => this.heading()?.nativeElement.focus());\n });\n }\n\n protected setThemeMode(mode: string): void {\n this.theme.setMode(mode as HermesThemeMode);\n }\n\n protected setFamily(id: string): void {\n const family = this.families.find((f) => f.id === (this.themeConfig.aliases?.[id] ?? id));\n if (family) this.presets.setPreset(family);\n }\n\n protected setDensity(value: string): void {\n this.density.setDensity(value as HermesDensity);\n }\n\n protected setFont(value: string): void {\n this.hermesTheme.setFont(value as HermesFont);\n }\n\n protected setTextSize(value: string): void {\n this.preferences.setTextScale(Number(value));\n }\n\n protected setMotion(value: string): void {\n this.preferences.setMotion(value as HermesMotionPreference);\n }\n\n private card(id: string, icon: string, title: string, text: string, keys?: string): EssentialCard {\n const [before, after = ''] = text.split('{key}');\n return { id, icon, title, before, after, keys: keys ? formatShortcut(keys, this.platform)[0] : null };\n }\n}\n","<div class=\"setup\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"t.label\">\n <div class=\"setup__bar\">\n @if (stepTotal() > 1) {\n <span class=\"setup__step\">{{ fmt(t.step, { current: stepNumber(), total: stepTotal() }) }}</span>\n <span class=\"setup__dots\" aria-hidden=\"true\">\n <span class=\"setup__dot\" [class.setup__dot--on]=\"stepNumber() >= 1\"></span>\n <span class=\"setup__dot\" [class.setup__dot--on]=\"stepNumber() >= 2\"></span>\n </span>\n }\n @if (setup.mode() === 'full') {\n <hm-button class=\"setup__skip\" emphasis=\"minimal\" (clicked)=\"setup.finish()\">{{ t.skip }}</hm-button>\n }\n </div>\n\n @if (setup.step() === 'appearance') {\n <div class=\"setup__body\">\n <section class=\"setup__form\">\n <h1 #heading class=\"setup__title\" tabindex=\"-1\">{{ greeting }}</h1>\n <p class=\"setup__intro\">{{ t.appearanceIntro }}</p>\n\n <div class=\"setup__fields\">\n <div class=\"setup__field\">\n <span class=\"setup__label\">{{ s.theme }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"s.theme\" [options]=\"themeOptions\" [value]=\"themeMode()\" (valueChange)=\"setThemeMode($event)\" />\n </div>\n\n <div class=\"setup__field setup__field--wide\">\n <span class=\"setup__label\">{{ s.accent }}</span>\n <hm-theme-picker\n [families]=\"families\"\n [family]=\"family()\"\n [theme]=\"appliedTheme()\"\n [showMode]=\"false\"\n (familyChosen)=\"setFamily($event)\"\n />\n </div>\n\n <div class=\"setup__field\">\n <span class=\"setup__label\">{{ s.density }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"s.density\" [options]=\"densityOptions\" [value]=\"densityValue()\" (valueChange)=\"setDensity($event)\" />\n </div>\n\n <div class=\"setup__field\">\n <span class=\"setup__label\">{{ s.textSize }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"s.textSize\" [options]=\"textSizeOptions()\" [value]=\"textSizeValue()\" (valueChange)=\"setTextSize($event)\" />\n </div>\n\n @if (fontOptions.length > 1) {\n <div class=\"setup__field\">\n <span class=\"setup__label\">{{ s.font }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"s.font\" [options]=\"fontOptions\" [value]=\"fontValue()\" (valueChange)=\"setFont($event)\" />\n </div>\n }\n\n <div class=\"setup__field\">\n <span class=\"setup__label\">{{ s.motion }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"s.motion\" [options]=\"motionOptions\" [value]=\"preferences.motion()\" (valueChange)=\"setMotion($event)\" />\n </div>\n </div>\n\n <div class=\"setup__actions\">\n <hm-button emphasis=\"high\" iconEnd=\"arrow-right\" (clicked)=\"setup.next()\">{{ t.next }}</hm-button>\n </div>\n </section>\n\n <!-- Prévia: um shell em miniatura pintado com os tokens do tema, então acompanha cada escolha. Decorativa. -->\n <figure class=\"setup__preview\">\n <figcaption class=\"setup__preview-label\">{{ t.preview }}</figcaption>\n <div class=\"pv\" aria-hidden=\"true\">\n <div class=\"pv__header\">\n <spine-brand class=\"pv__brand\" [label]=\"appName\" />\n <span class=\"pv__search\"></span>\n <span class=\"pv__avatar\"></span>\n </div>\n <div class=\"pv__body\">\n <div class=\"pv__side\">\n <span class=\"pv__item pv__item--on\"></span>\n <span class=\"pv__item\"></span>\n <span class=\"pv__item\"></span>\n <span class=\"pv__item\"></span>\n <span class=\"pv__item pv__item--short\"></span>\n </div>\n <div class=\"pv__main\">\n <div class=\"pv__tabs\">\n <span class=\"pv__tab pv__tab--on\">{{ t.previewPage }}</span>\n <span class=\"pv__tab\"><span class=\"pv__line\"></span></span>\n <span class=\"pv__tab\"><span class=\"pv__line\"></span></span>\n </div>\n <div class=\"pv__page\">\n <span class=\"pv__title\"></span>\n <div class=\"pv__cards\">\n @for (n of [1, 2, 3]; track n) {\n <span class=\"pv__card\"><span class=\"pv__num\"></span><span class=\"pv__line\"></span></span>\n }\n </div>\n <div class=\"pv__table\">\n <span class=\"pv__row pv__row--head\"></span>\n @for (n of [1, 2, 3, 4]; track n) {\n <span class=\"pv__row\"><span class=\"pv__line\"></span><span class=\"pv__line pv__line--short\"></span></span>\n }\n </div>\n <div class=\"pv__buttons\">\n <span class=\"pv__btn pv__btn--ghost\"></span>\n <span class=\"pv__btn\"></span>\n </div>\n </div>\n </div>\n </div>\n </div>\n </figure>\n </div>\n } @else {\n <div class=\"setup__body setup__body--essentials\">\n <section class=\"setup__essentials\">\n <h1 #heading class=\"setup__title\" tabindex=\"-1\">{{ t.essentialsTitle }}</h1>\n <p class=\"setup__intro\">{{ t.essentialsIntro }}</p>\n\n <ul class=\"setup__cards\">\n @for (card of essentials; track card.id) {\n <li class=\"setup__card\">\n <span class=\"setup__card-icon\"><hm-icon [shape]=\"card.icon\" /></span>\n <h2 class=\"setup__card-title\">{{ card.title }}</h2>\n <p class=\"setup__card-text\">\n {{ card.before }}@if (card.keys) {<span class=\"setup__keys\">@for (step of card.keys; track $index) {@for (key of step; track $index) {<kbd>{{ key.label }}</kbd>}}</span>}{{ card.after }}\n </p>\n </li>\n }\n </ul>\n\n <div class=\"setup__actions\">\n @if (setup.mode() === 'full') {\n <hm-button emphasis=\"medium\" icon=\"arrow-left\" (clicked)=\"setup.back()\">{{ t.back }}</hm-button>\n <hm-button emphasis=\"high\" (clicked)=\"setup.finish()\">{{ t.finish }}</hm-button>\n } @else {\n <hm-button emphasis=\"high\" (clicked)=\"setup.finish()\">{{ t.close }}</hm-button>\n }\n </div>\n </section>\n </div>\n }\n</div>\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef, computed, effect, inject, signal, untracked, viewChild,\n} from '@angular/core';\nimport {\n AccountAvatarComponent, AlertComponent, BreadcrumbComponent, BreadcrumbItem, ButtonComponent, DrawerComponent, IconComponent,\n ModalComponent, PaginatorComponent, RichTextComponent, SearchFieldComponent,\n} from '@trismegisto/angular';\nimport type { PaginationState } from '@trismegisto/primitives';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineNewsDetail, SpineNewsKind, SpineNewsService, SpineNewsSummary } from './news.service';\n\n/** Novidades por chamada ao servidor: o painel lê as páginas em sequência até ter tudo (ou o teto). */\nconst PAGE_LIMIT = 50;\n/** Teto do que o painel carrega (as mais recentes): a busca e os filtros rodam sobre isto, no navegador. */\nconst MAX_ITEMS = 200;\n/** Novidades por página antes de medir o painel (e o mínimo depois de medir). */\nconst DEFAULT_PAGE_SIZE = 6;\nconst MIN_PAGE_SIZE = 3;\n/** Altura de um item antes de haver um na tela para medir (data, título, resumo em 2 linhas e autor). */\nconst FALLBACK_ROW_PX = 104;\n\n/** Filtro em pílula do topo do painel. */\nexport type SpineNewsFilter = 'all' | 'unread' | 'favorites';\n\n/** Ícone de cada tipo (na linha de meta do modal). */\nconst KIND_ICONS: Record<SpineNewsKind, string> = {\n informativo: 'file-text',\n implementacao: 'rocket-diagonal',\n alteracao: 'two-way-arrows',\n};\n\n/** Minúsculo e sem acento, para a busca achar \"relatorio\" em \"Relatório\". */\nconst fold = (value: string) => value.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();\n\n/** HTML de rich text com texto de verdade (não só tags vazias). */\nconst hasText = (html: string | undefined) => !!html && html.replace(/<[^>]*>/g, '').replace(/&nbsp;|&#160;/g, ' ').trim() !== '';\n\nlet sequence = 0;\n\ninterface MonthGroup {\n readonly key: string;\n readonly label: string;\n readonly items: readonly SpineNewsSummary[];\n}\n\n/**\n * Painel lateral de novidades e o modal de leitura. Montado uma vez no layout; quem abre é o `SpineNewsService` (aviso\n * da entrada, menu do perfil, Início, configurações).\n *\n * Painel: sem cards — itens de texto separados por divisor, agrupados por mês (data, selo \"Nova\", título, resumo em\n * duas linhas e o autor com foto), com busca (\"Buscar novidades…\") e filtros em pílula (Todas, Não lidas, Favoritas,\n * cada um com a contagem). Favoritar é o marcador à direita de cada item. O item aberto ganha a barra de destaque.\n *\n * Busca e filtros rodam no navegador: \"não lida\" e \"favorita\" só existem nele (por id, no localStorage), então o\n * painel lê as mais recentes de `/me/news` em páginas de 50, em sequência, até ter todas (teto de 200) e filtra a\n * lista carregada — as contagens das pílulas batem com o que aparece.\n *\n * Modal: trilha \"Início › Novidades › título\", título grande (com \"Nova\" se ainda não tinha sido aberta), a linha de\n * meta (data, autor, tipo), o resumo como texto de abertura e o conteúdo do tipo — o texto (informativo), \"O que\n * mudou\" com os checks (implementação) ou o antes e o agora lado a lado (alteração). Rodapé: \"Marcar como não lida\" e\n * \"Entendi\".\n *\n * O HTML vem de rich text, saneado pelo servidor ao gravar, e é mostrado pelo próprio `hm-rich-text` em `readonly`\n * (que passa pela lista branca dele de novo) — nunca por `[innerHTML]`. Os itens da implementação são texto puro.\n */\n@Component({\n selector: 'spine-news',\n imports: [\n AccountAvatarComponent, AlertComponent, BreadcrumbComponent, ButtonComponent, DrawerComponent, IconComponent, ModalComponent,\n PaginatorComponent, RichTextComponent, SearchFieldComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (news.isOpen()) {\n <hm-drawer [heading]=\"text.heading\" size=\"large\" [open]=\"true\" [closeLabel]=\"text.close\" (closed)=\"news.close()\">\n <div #tools class=\"news-tools\">\n <hm-search-field [label]=\"text.search\" labelHidden [placeholder]=\"text.searchPlaceholder\" [landmark]=\"false\"\n [value]=\"query()\" (valueChange)=\"query.set($event)\" />\n <div class=\"news-filters\" role=\"group\" [attr.aria-label]=\"text.filters\">\n @for (f of filters; track f) {\n <button type=\"button\" class=\"news-filter\" [class.news-filter--on]=\"filter() === f\" [attr.aria-pressed]=\"filter() === f\"\n (click)=\"filter.set(f)\">\n <span>{{ filterLabel(f) }}</span><span class=\"news-filter__count\">{{ counts()[f] }}</span>\n </button>\n }\n </div>\n </div>\n\n @if (error()) {\n <div class=\"news-state\">\n <hm-alert variant=\"error\">{{ text.loadError }}</hm-alert>\n <hm-button emphasis=\"medium\" (clicked)=\"load()\">{{ text.retry }}</hm-button>\n </div>\n } @else if (loading() && !items().length) {\n <p class=\"news-state news-state--muted\" role=\"status\">{{ text.loading }}</p>\n } @else if (!items().length) {\n <p class=\"news-state news-state--muted\">{{ text.empty }}</p>\n } @else if (!groups().length) {\n <p class=\"news-state news-state--muted\" role=\"status\">{{ text.noResults }}</p>\n } @else {\n <div #list class=\"news-groups\" role=\"region\" [attr.aria-label]=\"text.pages\" [attr.aria-busy]=\"loading()\">\n @for (group of groups(); track group.key) {\n <section class=\"news-month\" [attr.aria-labelledby]=\"uid + '-' + group.key\">\n <h3 class=\"news-month__title\" [id]=\"uid + '-' + group.key\">{{ group.label }}</h3>\n <ol class=\"news-list\">\n @for (item of group.items; track item.id) {\n <li class=\"news-row\" [class.news-row--selected]=\"opened()?.id === item.id\">\n <button type=\"button\" class=\"news-item\" (click)=\"open(item)\">\n <span class=\"news-item__meta\">\n <span class=\"news-item__date\">{{ dayOf(item) }}</span>\n @if (unseen(item.id)) { <span class=\"news-item__badge\">{{ text.unseen }}</span> }\n </span>\n <span class=\"news-item__title\">{{ item.title }}</span>\n @if (item.summary) { <span class=\"news-item__summary\">{{ item.summary }}</span> }\n @if (item.author; as author) {\n <span class=\"news-item__author\">\n <hm-account-avatar size=\"small\" [name]=\"author.name\" [imageUrl]=\"author.picture\" />\n <span>{{ author.name }}</span>\n </span>\n }\n </button>\n <button type=\"button\" class=\"news-fav\" [class.news-fav--on]=\"favorite(item.id)\" [attr.aria-pressed]=\"favorite(item.id)\"\n [attr.aria-label]=\"favoriteLabel(item)\" [title]=\"favoriteLabel(item)\" (click)=\"news.toggleFavorite(item.id)\">\n <hm-icon shape=\"bookmark\" size=\"sm\" [solid]=\"favorite(item.id)\" />\n </button>\n </li>\n }\n </ol>\n </section>\n }\n </div>\n }\n <ng-container footer>\n @if (filtered().length > pageSize()) {\n <hm-paginator class=\"news-pages\" variant=\"simple\" [label]=\"text.pages\" [state]=\"pageState()\" [totalItems]=\"filtered().length\"\n (stateChanged)=\"changePage($event)\" />\n }\n <hm-button (clicked)=\"news.close()\">{{ text.close }}</hm-button>\n </ng-container>\n </hm-drawer>\n\n <!-- O h2 do hm-modal fica como nome do diálogo (fora da vista, ver os estilos); o cabeçalho visível é o nosso. -->\n <hm-modal [open]=\"!!opened()\" (openChange)=\"$event || closeItem()\" [heading]=\"opened()?.title ?? text.heading\" size=\"large\"\n [closeLabel]=\"text.close\" (closed)=\"closeItem()\">\n @if (opened(); as item) {\n <div class=\"news-read\">\n <header class=\"news-read__head\">\n <hm-breadcrumb [items]=\"crumbs(item)\" (itemClick)=\"onCrumb($event)\" />\n <div class=\"news-read__title-row\">\n <span class=\"news-read__title\" aria-hidden=\"true\">{{ item.title }}</span>\n @if (openedUnseen()) { <span class=\"news-item__badge news-read__badge\">{{ text.unseen }}</span> }\n </div>\n <div class=\"news-read__meta\">\n <span class=\"news-read__meta-part\"><hm-icon shape=\"calendar\" size=\"xs\" />{{ publishedOn(item) }}</span>\n @if (item.author; as author) {\n <span class=\"news-read__meta-part\">\n <hm-account-avatar size=\"small\" [name]=\"author.name\" [imageUrl]=\"author.picture\" />\n <span>{{ author.name }}</span>\n </span>\n }\n <span class=\"news-read__tag\"><hm-icon [shape]=\"kindIcon(item)\" size=\"xs\" />{{ kindLabel(item) }}</span>\n </div>\n </header>\n\n @if (item.summary) { <p class=\"news-read__lead\">{{ item.summary }}</p> }\n\n @if (detailError()) {\n <hm-alert variant=\"error\">{{ text.detailError }}</hm-alert>\n } @else if (detail(); as d) {\n @switch (kindOf(d)) {\n @case ('implementacao') {\n @if (hasText(d.body_html)) {\n <hm-rich-text class=\"news-read__body\" readonly [label]=\"text.body\" labelHidden [value]=\"d.body_html\" />\n }\n <section class=\"news-read__section\" [attr.aria-labelledby]=\"uid + '-changes'\">\n <h3 class=\"news-read__section-title\" [id]=\"uid + '-changes'\">{{ text.changes }}</h3>\n <ul class=\"news-changes\">\n @for (change of d.items ?? []; track $index) {\n <li class=\"news-changes__item\"><hm-icon class=\"news-changes__icon\" shape=\"check-circle\" size=\"sm\" /><span>{{ change }}</span></li>\n }\n </ul>\n </section>\n }\n @case ('alteracao') {\n @if (hasText(d.body_html)) {\n <hm-rich-text class=\"news-read__body\" readonly [label]=\"text.body\" labelHidden [value]=\"d.body_html\" />\n }\n <div class=\"news-compare\">\n <section class=\"news-compare__side news-compare__side--before\" [attr.aria-labelledby]=\"uid + '-before'\">\n <h3 class=\"news-compare__title\" [id]=\"uid + '-before'\">{{ text.before }}</h3>\n <hm-rich-text class=\"news-read__body\" readonly [label]=\"text.before\" labelHidden [value]=\"d.before_html ?? ''\" />\n </section>\n <section class=\"news-compare__side news-compare__side--after\" [attr.aria-labelledby]=\"uid + '-after'\">\n <h3 class=\"news-compare__title\" [id]=\"uid + '-after'\">{{ text.after }}</h3>\n <hm-rich-text class=\"news-read__body\" readonly [label]=\"text.after\" labelHidden [value]=\"d.after_html ?? ''\" />\n </section>\n </div>\n }\n @default {\n <hm-rich-text class=\"news-read__body\" readonly [label]=\"text.body\" labelHidden [value]=\"d.body_html\" />\n }\n }\n @if (d.edited; as edited) {\n <p class=\"news-read__edited\">\n <span>{{ editedOn(edited.at) }}</span>\n <hm-account-avatar size=\"small\" [name]=\"edited.name\" [imageUrl]=\"edited.picture\" />\n <span>{{ edited.name }}</span>\n </p>\n }\n } @else {\n <hm-rich-text class=\"news-read__body\" readonly loading [label]=\"text.body\" labelHidden [value]=\"''\" />\n }\n </div>\n }\n <ng-container footer>\n <hm-button class=\"news-read__unread\" emphasis=\"medium\" (clicked)=\"markUnread()\">{{ text.markUnread }}</hm-button>\n <hm-button (clicked)=\"closeItem()\">{{ text.gotIt }}</hm-button>\n </ng-container>\n </hm-modal>\n }\n `,\n styles: [`\n .news-state { display: flex; flex-direction: column; align-items: flex-start; gap: var(--hm-space-sm); margin: 0; }\n .news-state--muted { color: var(--hm-muted); font-size: var(--hm-font-size-sm); }\n\n .news-tools { display: flex; flex-direction: column; gap: var(--hm-space-sm); margin-block-end: var(--hm-space-md); }\n .news-filters { display: flex; flex-wrap: wrap; gap: var(--hm-space-xs); }\n .news-filter {\n display: inline-flex; align-items: center; gap: var(--hm-space-xs); padding: var(--hm-space-micro) var(--hm-space-sm);\n border: var(--hm-border-hairline) solid var(--hm-border); border-radius: var(--hm-radius-pill); background: transparent;\n color: var(--hm-text); font: inherit; font-size: var(--hm-font-size-sm); cursor: pointer;\n }\n .news-filter:hover { background: var(--hm-hover); }\n .news-filter:focus-visible, .news-item:focus-visible, .news-fav:focus-visible {\n outline: var(--hm-border-thin) solid var(--hm-accent); outline-offset: 2px;\n }\n .news-filter--on { border-color: var(--hm-accent); background: var(--hm-accent-subtle); color: var(--hm-accent); font-weight: var(--hm-font-weight-semibold); }\n .news-filter__count { font-size: var(--hm-font-size-xs); opacity: 0.8; }\n\n .news-groups { display: flex; flex-direction: column; gap: var(--hm-space-md); }\n .news-groups[aria-busy='true'] { opacity: 0.8; }\n .news-month { display: flex; flex-direction: column; gap: var(--hm-space-xs); }\n .news-month .news-list { border-block-start: var(--hm-border-hairline) solid var(--hm-border); }\n .news-pages { margin-inline-end: auto; }\n .news-month__title {\n margin: 0; color: var(--hm-muted); font-size: var(--hm-font-size-xs); font-weight: var(--hm-font-weight-semibold);\n letter-spacing: 0.06em; text-transform: uppercase;\n }\n .news-list { display: flex; flex-direction: column; margin: 0; padding: 0; list-style: none; }\n /* Sem cards: itens de texto separados por divisor; o aberto ganha a barra à esquerda. */\n .news-row {\n position: relative; display: flex; align-items: flex-start; gap: var(--hm-space-xs);\n border-block-end: var(--hm-border-hairline) solid var(--hm-border);\n }\n .news-row:last-child { border-block-end: 0; }\n .news-row--selected { background: var(--hm-accent-subtle); }\n .news-row--selected::before {\n content: ''; position: absolute; inset-block: var(--hm-space-xs); inset-inline-start: 0; inline-size: 3px;\n border-radius: var(--hm-radius-pill); background: var(--hm-accent);\n }\n .news-item {\n display: flex; flex: 1 1 auto; flex-direction: column; gap: var(--hm-space-micro); min-inline-size: 0;\n padding: var(--hm-space-sm) var(--hm-space-xs) var(--hm-space-sm) var(--hm-space-sm);\n border: 0; border-radius: 0; background: transparent; color: inherit; font: inherit; text-align: start; cursor: pointer;\n }\n .news-item:hover { background: var(--hm-hover); }\n .news-item__meta { display: flex; align-items: center; gap: var(--hm-space-xs); }\n .news-item__date { color: var(--hm-muted); font-size: var(--hm-font-size-xs); }\n .news-item__badge {\n padding: var(--hm-space-nano) var(--hm-space-xs); border-radius: var(--hm-radius-pill); background: var(--hm-accent-subtle);\n color: var(--hm-accent); font-size: var(--hm-font-size-3xs); font-weight: var(--hm-font-weight-semibold); letter-spacing: 0.04em;\n text-transform: uppercase;\n }\n .news-item__title {\n color: var(--hm-text); font-size: var(--hm-font-size-md); font-weight: var(--hm-font-weight-bold); line-height: var(--hm-line-height-tight);\n }\n .news-item__summary {\n display: -webkit-box; overflow: hidden; color: var(--hm-muted); font-size: var(--hm-font-size-sm); line-height: var(--hm-line-height-normal);\n -webkit-box-orient: vertical; -webkit-line-clamp: 2;\n }\n .news-item__author { display: inline-flex; align-items: center; gap: var(--hm-space-xs); color: var(--hm-muted); font-size: var(--hm-font-size-xs); }\n .news-fav {\n display: grid; flex: none; place-items: center; inline-size: var(--hm-control-height); block-size: var(--hm-control-height);\n margin-block-start: var(--hm-space-sm); border: 0; border-radius: var(--hm-radius-control); background: transparent; color: var(--hm-muted);\n cursor: pointer;\n }\n .news-fav:hover { background: var(--hm-hover); color: var(--hm-text); }\n .news-fav--on { color: var(--hm-accent); }\n\n /* Modal de leitura: o cabeçalho do hm-modal some da vista (o h2 segue como nome do diálogo) e só o X fica. */\n :host ::ng-deep .hm-modal__window:has(> .hm-modal__body > .news-read) > .hm-modal__header {\n position: absolute; z-index: 1; inset-block-start: 0; inset-inline-end: 0; border: 0; padding: var(--hm-space-sm);\n }\n :host ::ng-deep .hm-modal__window:has(> .hm-modal__body > .news-read) .hm-modal__heading {\n position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;\n }\n .news-read { display: flex; flex-direction: column; gap: var(--hm-space-sm); padding-block-start: var(--hm-space-xs); }\n .news-read__head {\n display: flex; flex-direction: column; gap: var(--hm-space-xs);\n padding-inline-end: calc(var(--hm-control-height) + var(--hm-space-sm)); padding-block-end: var(--hm-space-md);\n border-block-end: var(--hm-border-hairline) solid var(--hm-divider);\n }\n .news-read__title-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--hm-space-xs) var(--hm-space-sm); }\n .news-read__title {\n color: var(--hm-text); font-size: var(--hm-font-size-xxl); font-weight: var(--hm-font-weight-bold); line-height: var(--hm-line-height-tight);\n }\n .news-read__meta {\n display: flex; flex-wrap: wrap; align-items: center; gap: var(--hm-space-xs) var(--hm-space-md); color: var(--hm-muted);\n font-size: var(--hm-font-size-sm);\n }\n .news-read__meta-part { display: inline-flex; align-items: center; gap: var(--hm-space-xs); }\n .news-read__tag {\n display: inline-flex; align-items: center; gap: var(--hm-space-micro); padding: var(--hm-space-nano) var(--hm-space-xs);\n border: var(--hm-border-hairline) solid var(--hm-divider); border-radius: var(--hm-radius-pill); background: var(--hm-surface-muted);\n color: var(--hm-text); font-size: var(--hm-font-size-xs);\n }\n .news-read__lead { margin: 0; color: var(--hm-text); font-size: var(--hm-font-size-lg); line-height: var(--hm-line-height-snug); }\n .news-read__section { display: flex; flex-direction: column; gap: var(--hm-space-sm); }\n .news-read__section-title, .news-compare__title {\n margin: 0; color: var(--hm-text); font-size: var(--hm-font-size-lg); font-weight: var(--hm-font-weight-bold);\n }\n .news-changes { display: flex; flex-direction: column; gap: var(--hm-space-xs); margin: 0; padding: 0; list-style: none; }\n .news-changes__item {\n display: flex; align-items: flex-start; gap: var(--hm-space-xs); color: var(--hm-text); font-size: var(--hm-font-size-sm);\n line-height: var(--hm-line-height-normal);\n }\n .news-changes__icon { flex: none; margin-block-start: 2px; color: var(--hm-success); }\n /* Antes x agora: lado a lado (empilham no estreito); o antes em tom neutro, o agora no tom de sucesso. */\n .news-compare { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); gap: var(--hm-space-md); }\n .news-compare__side {\n display: flex; flex-direction: column; gap: var(--hm-space-xs); min-inline-size: 0; padding: var(--hm-space-md);\n border: var(--hm-border-hairline) solid var(--hm-divider); border-inline-start-width: var(--hm-border-thin); border-radius: var(--hm-radius);\n }\n .news-compare__side--before { border-inline-start-color: var(--hm-muted); background: var(--hm-surface-muted); }\n .news-compare__side--after { border-inline-start-color: var(--hm-success); background: var(--hm-surface-raised); }\n .news-compare__side--after .news-compare__title { color: var(--hm-success); }\n .news-read__edited {\n display: flex; flex-wrap: wrap; align-items: center; gap: var(--hm-space-xs); margin: 0; color: var(--hm-muted); font-size: var(--hm-font-size-xs);\n }\n .news-read__unread { margin-inline-end: auto; }\n /* Leitura, não campo: o rich text sem moldura, sem fundo e sem o recuo interno; títulos internos chamativos. */\n .news-read__body ::ng-deep .hm-rich-text__frame { border: 0; background: transparent; }\n .news-read__body ::ng-deep .hm-rich-text__area { padding: 0; min-block-size: 0; }\n .news-read__body ::ng-deep .hm-prose > :last-child { margin-block-end: 0; }\n .news-read__body ::ng-deep :is(h2, h3) { color: var(--hm-text); font-weight: var(--hm-font-weight-bold); }\n `],\n})\nexport class SpineNewsComponent {\n protected readonly news = inject(SpineNewsService);\n protected readonly text = inject(SPINE_MESSAGES).news;\n private readonly locale = inject(SPINE_MESSAGES).meta.locale;\n private readonly dateFormat = new Intl.DateTimeFormat(this.locale, { dateStyle: 'long' });\n private readonly dayFormat = new Intl.DateTimeFormat(this.locale, { dateStyle: 'medium' });\n private readonly monthFormat = new Intl.DateTimeFormat(this.locale, { month: 'long', year: 'numeric' });\n protected readonly uid = `spine-news-${++sequence}`;\n protected readonly filters: readonly SpineNewsFilter[] = ['all', 'unread', 'favorites'];\n protected readonly hasText = hasText;\n\n /** Tudo o que foi carregado (as mais recentes, até o teto). */\n protected readonly items = signal<readonly SpineNewsSummary[]>([]);\n protected readonly loading = signal(false);\n protected readonly error = signal(false);\n readonly query = signal('');\n readonly filter = signal<SpineNewsFilter>('all');\n /** Página atual e quantas novidades cabem no painel (medido pela altura dele; refeito ao redimensionar). */\n readonly page = signal(1);\n readonly pageSize = signal(DEFAULT_PAGE_SIZE);\n protected readonly pageState = computed<PaginationState>(() => ({ page: this.currentPage(), size: this.pageSize() }));\n private readonly toolsRef = viewChild<ElementRef<HTMLElement>>('tools');\n private readonly listRef = viewChild<ElementRef<HTMLElement>>('list');\n /** Altura de um item, medida no primeiro que aparece (estável: não muda a cada página). */\n private rowPx = 0;\n /** A novidade aberta no modal (o resumo, já na mão) e o conteúdo dela quando chega. */\n protected readonly opened = signal<SpineNewsSummary | null>(null);\n /** Estava \"Nova\" quando abriu (abrir já marca como vista; o selo do modal lembra que era). */\n protected readonly openedUnseen = signal(false);\n protected readonly detail = signal<SpineNewsDetail | null>(null);\n protected readonly detailError = signal(false);\n /** Respostas fora de ordem (reabriu o painel, abriu outra) não sobrescrevem a atual. */\n private loadSeq = 0;\n private detailSeq = 0;\n\n /** Contagem de cada pílula, sobre o que foi carregado (a busca não muda as contagens). */\n protected readonly counts = computed<Record<SpineNewsFilter, number>>(() => {\n const all = this.items();\n return {\n all: all.length,\n unread: all.filter((n) => this.news.isUnseen(n.id)).length,\n favorites: all.filter((n) => this.news.isFavorite(n.id)).length,\n };\n });\n\n /** O que passa no filtro e na busca (na ordem da lista: da mais recente). */\n protected readonly filtered = computed<readonly SpineNewsSummary[]>(() => {\n const filter = this.filter();\n const terms = fold(this.query().trim()).split(/\\s+/).filter(Boolean);\n return this.items().filter((n) => {\n if (filter === 'unread' && !this.news.isUnseen(n.id)) return false;\n if (filter === 'favorites' && !this.news.isFavorite(n.id)) return false;\n if (!terms.length) return true;\n const hay = fold(`${n.title} ${n.summary} ${n.author?.name ?? ''}`);\n return terms.every((t) => hay.includes(t));\n });\n });\n\n /** A página dentro do total (trocar o filtro ou o tamanho da página não deixa numa página que não existe). */\n protected readonly currentPage = computed(() =>\n Math.min(this.page(), Math.max(1, Math.ceil(this.filtered().length / this.pageSize()))));\n\n /** A página atual, agrupada por mês. */\n protected readonly groups = computed<readonly MonthGroup[]>(() => {\n const size = this.pageSize();\n const start = (this.currentPage() - 1) * size;\n const out: { key: string; label: string; items: SpineNewsSummary[] }[] = [];\n for (const n of this.filtered().slice(start, start + size)) {\n const date = new Date(n.published_at);\n const valid = !Number.isNaN(date.getTime());\n const key = valid ? `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}` : 'sem-data';\n const last = out[out.length - 1];\n if (last?.key === key) last.items.push(n);\n else out.push({ key, label: valid ? this.monthFormat.format(date) : '', items: [n] });\n }\n return out;\n });\n\n /** \"Nova\" = ainda não aberta neste navegador (reage a `markSeen`/`markUnseen`). */\n protected readonly unseen = (id: string) => this.news.isUnseen(id);\n protected readonly favorite = (id: string) => this.news.isFavorite(id);\n\n constructor() {\n // Buscar ou trocar o filtro volta para a primeira página.\n effect(() => {\n this.query();\n this.filter();\n untracked(() => this.page.set(1));\n });\n\n // Quantas cabem: a altura do corpo do painel menos a busca e os filtros, dividida pela altura de um item (com folga\n // para dois títulos de mês). Refeito quando o painel muda de tamanho.\n let observer: ResizeObserver | null = null;\n inject(DestroyRef).onDestroy(() => observer?.disconnect());\n effect(() => {\n const list = this.listRef()?.nativeElement;\n const body = list?.closest<HTMLElement>('.hm-drawer__body');\n observer?.disconnect();\n observer = null;\n if (!list || !body || typeof ResizeObserver === 'undefined') return;\n observer = new ResizeObserver(() => this.measure(body, list));\n observer.observe(body);\n });\n\n // Abriu o painel: lê a lista; o Início pode ter pedido uma novidade específica.\n effect(() => {\n if (!this.news.isOpen()) return;\n untracked(() => {\n void this.load();\n const id = this.news.requested();\n if (id) {\n this.news.requested.set(null);\n const known = this.news.latest().find((n) => n.id === id);\n if (known) this.open(known);\n }\n });\n });\n }\n\n private measure(body: HTMLElement, list: HTMLElement): void {\n const style = getComputedStyle(body);\n const tools = this.toolsRef()?.nativeElement;\n const toolsPx = tools ? tools.getBoundingClientRect().height + (parseFloat(getComputedStyle(tools).marginBlockEnd) || 0) : 0;\n const available = body.clientHeight - (parseFloat(style.paddingBlockStart) || 0) - (parseFloat(style.paddingBlockEnd) || 0) - toolsPx;\n if (!this.rowPx) {\n const rows = Array.from(list.querySelectorAll<HTMLElement>('.news-row'));\n if (rows.length) this.rowPx = Math.max(...rows.map((r) => r.getBoundingClientRect().height));\n }\n const month = list.querySelector<HTMLElement>('.news-month__title');\n const monthPx = (month?.getBoundingClientRect().height ?? 16) + 24;\n const size = Math.max(MIN_PAGE_SIZE, Math.floor((available - 2 * monthPx) / (this.rowPx || FALLBACK_ROW_PX)));\n if (size !== this.pageSize()) this.pageSize.set(size);\n }\n\n protected changePage(next: PaginationState): void {\n this.page.set(next.page);\n this.listRef()?.nativeElement.closest('.hm-drawer__body')?.scrollTo?.({ top: 0 });\n }\n\n protected filterLabel(f: SpineNewsFilter): string {\n return f === 'unread' ? this.text.filterUnread : f === 'favorites' ? this.text.filterFavorites : this.text.filterAll;\n }\n\n protected favoriteLabel(item: SpineNewsSummary): string {\n return formatMessage(this.favorite(item.id) ? this.text.unfavorite : this.text.favorite, { title: item.title });\n }\n\n protected kindOf(item: SpineNewsSummary): SpineNewsKind {\n return item.kind && item.kind in KIND_ICONS ? item.kind : 'informativo';\n }\n\n protected kindIcon(item: SpineNewsSummary): string {\n return KIND_ICONS[this.kindOf(item)];\n }\n\n protected kindLabel(item: SpineNewsSummary): string {\n const kind = this.kindOf(item);\n return kind === 'implementacao' ? this.text.kindImplementacao : kind === 'alteracao' ? this.text.kindAlteracao : this.text.kindInformativo;\n }\n\n protected crumbs(item: SpineNewsSummary): BreadcrumbItem[] {\n return [{ label: this.text.home, icon: 'home', routerLink: '/' }, { label: this.text.heading }, { label: item.title }];\n }\n\n /** \"Início\" da trilha leva à tela inicial: fecha o modal e o painel. */\n protected onCrumb(crumb: BreadcrumbItem): void {\n if (crumb.routerLink === undefined) return;\n this.closeItem();\n this.news.close();\n }\n\n protected dayOf(item: SpineNewsSummary): string {\n const date = new Date(item.published_at);\n return Number.isNaN(date.getTime()) ? '' : this.dayFormat.format(date);\n }\n\n protected publishedOn(item: SpineNewsSummary): string {\n const date = new Date(item.published_at);\n return Number.isNaN(date.getTime()) ? '' : formatMessage(this.text.publishedOn, { date: this.dateFormat.format(date) });\n }\n\n protected editedOn(at: string): string {\n const date = new Date(at);\n return Number.isNaN(date.getTime()) ? '' : formatMessage(this.text.editedOn, { date: this.dateFormat.format(date) });\n }\n\n /** Lê as páginas em sequência (50 por vez) até ter todas ou o teto; a lista aparece já com a primeira. */\n async load(): Promise<void> {\n if (!this.news.available) return;\n const seq = ++this.loadSeq;\n this.loading.set(true);\n this.error.set(false);\n const loaded: SpineNewsSummary[] = [];\n try {\n for (let page = 1; ; page++) {\n const res = await this.news.page(page, PAGE_LIMIT);\n if (seq !== this.loadSeq) return;\n const batch = res.news ?? [];\n loaded.push(...batch);\n this.items.set(loaded.slice(0, MAX_ITEMS));\n if (!batch.length || loaded.length >= (res.total ?? 0) || loaded.length >= MAX_ITEMS) break;\n }\n } catch {\n // Falhou já na primeira: o erro com \"Tentar de novo\". Depois dela: fica o que veio.\n if (seq === this.loadSeq) this.error.set(!loaded.length);\n } finally {\n if (seq === this.loadSeq) this.loading.set(false);\n }\n }\n\n /** Abre no modal e marca como vista; o conteúdo chega em seguida. */\n open(item: SpineNewsSummary): void {\n const seq = ++this.detailSeq;\n this.openedUnseen.set(this.news.isUnseen(item.id));\n this.opened.set(item);\n this.detail.set(null);\n this.detailError.set(false);\n this.news.markSeen(item.id);\n this.news.detail(item.id).then(\n (d) => { if (seq === this.detailSeq) this.detail.set(d); },\n () => { if (seq === this.detailSeq) this.detailError.set(true); },\n );\n }\n\n /** \"Marcar como não lida\": volta o selo \"Nova\" e fecha. */\n protected markUnread(): void {\n const item = this.opened();\n if (item) this.news.markUnseen(item.id);\n this.closeItem();\n }\n\n protected closeItem(): void {\n this.detailSeq++;\n this.opened.set(null);\n this.openedUnseen.set(false);\n this.detail.set(null);\n this.detailError.set(false);\n }\n}\n","import { ChangeDetectorRef, Component, OnDestroy, OnInit, ChangeDetectionStrategy, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { ButtonComponent, HermesShortcutService, ModalComponent, ShortcutListComponent } from '@trismegisto/angular';\nimport { ShortcutService } from './shortcut.service';\nimport { SpineInitialSetupService } from '../setup/initial-setup.service';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\n\n/**\n * Painel de atalhos (cheatsheet). Abre com \"?\" (via `ShortcutService.help$`) e lista, com o\n * `hm-shortcut-list` da lib, os atalhos agrupados — com busca e o interruptor dos atalhos de tecla\n * única (WCAG 2.1.4; a escolha persiste no `SpinePreferencesService`). Leva também ao essencial.\n */\n@Component({\n selector: 'spine-shortcuts-cheatsheet',\n imports: [ModalComponent, ButtonComponent, ShortcutListComponent],\n templateUrl: './shortcuts-cheatsheet.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n styleUrl: './shortcuts-cheatsheet.component.scss',\n})\nexport class ShortcutsCheatsheetComponent implements OnInit, OnDestroy {\n public open = false;\n protected readonly text = inject(SPINE_MESSAGES).shortcuts;\n private readonly shortcuts = inject(ShortcutService);\n private readonly setup = inject(SpineInitialSetupService);\n /** OnPush: o \"?\" e o menu do perfil abrem o painel por `help$`, fora dos eventos deste template. */\n private readonly cdr = inject(ChangeDetectorRef);\n /** Atalhos do painel: registrados (favoritos numa linha só) + os que outra peça dispara. */\n protected readonly items = this.shortcuts.panelItems;\n /** Atalhos de tecla única ligados — sem eles o \"?\" da dica não funciona. */\n protected readonly characterKeys = inject(HermesShortcutService).characterKeys;\n /** Dica com a tecla no meio: o texto do catálogo partido em volta de `{key}`. */\n protected get hintParts(): string[] {\n return this.text.hint.split('{key}');\n }\n\n private sub?: Subscription;\n\n /** Abre os cartões do essencial e fecha este painel. */\n openEssentials(): void {\n this.open = false;\n this.setup.openEssentials();\n }\n\n ngOnInit(): void {\n this.sub = this.shortcuts.help$.subscribe(() => {\n this.open = !this.open;\n this.cdr.markForCheck();\n });\n }\n\n ngOnDestroy(): void {\n this.sub?.unsubscribe();\n }\n}\n","<hm-modal [open]=\"open\" (openChange)=\"open = $event\" [heading]=\"text.heading\" size=\"large\">\n <!-- Com a tecla única desligada (WCAG 2.1.4) o \"?\" não abre o painel: a dica some junto. -->\n @if (characterKeys()) {\n <p class=\"sc-hint\">\n {{ hintParts[0] }}<kbd class=\"sc-chip\">?</kbd>{{ hintParts[1] }}\n </p>\n }\n\n <hm-shortcut-list searchable characterKeysToggle [registered]=\"false\" [items]=\"items()\" />\n\n <ng-container footer>\n <hm-button emphasis=\"medium\" icon=\"help\" (clicked)=\"openEssentials()\">{{ text.essentials }}</hm-button>\n <hm-button (clicked)=\"open = false\">{{ text.dismiss }}</hm-button>\n </ng-container>\n</hm-modal>\n","import { SPINE_IDLE_OPTIONS, SpineFeatures } from '@trismegisto/spine';\n\n/** Limites de \"Encerrar por inatividade\" já resolvidos a partir de `SpineFeatures.idleTimeout`. */\nexport interface SpineIdleLimits {\n enabled: boolean;\n /** Minutos mínimos (0 = sem mínimo). */\n min: number;\n /** Minutos máximos (0 = sem máximo; com máximo a opção \"Nunca\" some). */\n max: number;\n /** Opções oferecidas (0 = nunca), já filtradas pelos limites. */\n options: readonly number[];\n}\n\nconst positive = (value: unknown): number => {\n const n = Number(value);\n return Number.isFinite(n) && n > 0 ? Math.round(n) : 0;\n};\n\n/** Opções e limites de inatividade do app. Sem o recurso, `enabled` é falso e não há opções. */\nexport function idleLimits(features: SpineFeatures | undefined): SpineIdleLimits {\n const config = features?.idleTimeout;\n if (!config) return { enabled: false, min: 0, max: 0, options: [] };\n const min = typeof config === 'object' ? positive(config.min) : 0;\n let max = typeof config === 'object' ? positive(config.max) : 0;\n if (max && min && max < min) max = min;\n const options = SPINE_IDLE_OPTIONS.filter((m) => (m === 0 ? !max : m >= min && (!max || m <= max)));\n // Um limite fora das opções padrão (ex.: máximo de 10 min) entra como opção própria.\n const extra = [min, max].filter((m) => m > 0 && !options.includes(m));\n return { enabled: true, min, max, options: [...options, ...extra].sort((a, b) => a - b) };\n}\n\n/** Minutos que valem de fato: a escolha da pessoa dentro dos limites do app (0 = não encerra). */\nexport function effectiveIdleMinutes(chosen: number, limits: SpineIdleLimits): number {\n if (!limits.enabled) return 0;\n let minutes = chosen > 0 ? chosen : 0;\n if (limits.max && (minutes === 0 || minutes > limits.max)) minutes = limits.max;\n if (limits.min && minutes > 0 && minutes < limits.min) minutes = limits.min;\n return minutes;\n}\n","import { DestroyRef, Injectable, NgZone, PLATFORM_ID, computed, effect, inject, signal } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { SPINE_CONFIG, SpinePreferencesService } from '@trismegisto/spine';\nimport { effectiveIdleMinutes, idleLimits } from '../features/spine-features';\nimport { SpineLogoutService } from '../logout/logout.service';\n\n/** Segundos de aviso antes de encerrar. */\nexport const SPINE_IDLE_WARNING_SECONDS = 60;\n/** Intervalo entre gravações da última atividade no `localStorage` (as outras abas leem de lá). */\nconst WRITE_EVERY_MS = 5_000;\nconst ACTIVITY_EVENTS = ['pointerdown', 'pointermove', 'keydown', 'wheel', 'touchstart', 'scroll'] as const;\n\n/**\n * Encerrar por inatividade (`SpineFeatures.idleTimeout`): conta o tempo sem uso (ponteiro, teclado, rolagem) em\n * TODAS as abas do app — a última atividade vai para o `localStorage` (`hermes_<clientId>_last_activity`) e cada aba\n * confere a mais recente —, abre o aviso com contagem regressiva `SPINE_IDLE_WARNING_SECONDS` antes do fim e, se\n * ninguém responder, sai pelo `SpineLogoutService` (o mesmo \"Sair\" do menu). Com o aviso aberto, só \"Continuar\n * conectado\" (ou atividade em outra aba) mantém a sessão: mexer o ponteiro sobre o aviso não conta.\n *\n * Os minutos vêm do `SpinePreferencesService.idleMinutes`, limitados pelo app (`effectiveIdleMinutes`). Ligado pelo\n * `LayoutComponent` (só existe com sessão); não faz nada fora do navegador.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineIdleService {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly zone = inject(NgZone);\n private readonly preferences = inject(SpinePreferencesService);\n private readonly logoutService = inject(SpineLogoutService);\n private readonly config = inject(SPINE_CONFIG, { optional: true });\n private readonly storageKey = `hermes_${this.config?.clientId || 'app'}_last_activity`;\n\n readonly limits = idleLimits(this.config?.features);\n /** Minutos que valem agora (0 = não encerra). */\n readonly minutes = computed(() => effectiveIdleMinutes(this.preferences.idleMinutes(), this.limits));\n /** Aviso aberto. */\n readonly warning = signal(false);\n /** Segundos que faltam, enquanto o aviso está aberto. */\n readonly secondsLeft = signal(SPINE_IDLE_WARNING_SECONDS);\n\n private lastActivity = Date.now();\n private lastWrite = 0;\n private timer: ReturnType<typeof setInterval> | null = null;\n private expiring = false;\n /** Ligado por `start()` (o layout, que só existe com sessão). */\n private readonly active = signal(false);\n private readonly onActivity = () => {\n if (this.warning()) return;\n this.touch();\n };\n\n constructor() {\n if (!this.browser) return;\n effect(() => {\n if (this.active() && this.minutes() > 0) this.run();\n else this.stop();\n });\n inject(DestroyRef).onDestroy(() => this.stop());\n }\n\n /** Liga a contagem (idempotente). Para sozinha quando a escolha vira \"Nunca\". */\n start(): void {\n this.active.set(true);\n }\n\n /** \"Continuar conectado\": fecha o aviso e recomeça a contagem. */\n stay(): void {\n this.warning.set(false);\n this.touch(true);\n }\n\n /** \"Sair agora\". */\n logoutNow(): void {\n void this.expire();\n }\n\n /** Conta uma atividade agora (e a grava para as outras abas no máximo a cada 5 s, ou já, com `force`). */\n touch(force = false): void {\n const now = Date.now();\n this.lastActivity = now;\n if (!force && now - this.lastWrite < WRITE_EVERY_MS) return;\n this.lastWrite = now;\n try { localStorage.setItem(this.storageKey, String(now)); } catch { /* storage indisponível */ }\n }\n\n /** Confere o tempo sem uso: abre o aviso, atualiza a contagem ou encerra. Exposto para os testes. */\n check(now = Date.now()): void {\n const minutes = this.minutes();\n if (!minutes || this.expiring) return;\n const idle = now - Math.max(this.lastActivity, this.storedActivity());\n const total = minutes * 60_000;\n const warnAt = Math.max(0, total - SPINE_IDLE_WARNING_SECONDS * 1000);\n if (idle >= total) {\n void this.expire();\n } else if (idle >= warnAt) {\n this.zone.run(() => {\n this.secondsLeft.set(Math.max(1, Math.ceil((total - idle) / 1000)));\n this.warning.set(true);\n });\n } else if (this.warning()) {\n // Atividade em outra aba: o aviso some sozinho.\n this.zone.run(() => this.warning.set(false));\n }\n }\n\n private storedActivity(): number {\n try {\n const value = Number(localStorage.getItem(this.storageKey));\n return Number.isFinite(value) ? value : 0;\n } catch {\n return 0;\n }\n }\n\n private run(): void {\n if (this.timer) return;\n this.touch(true);\n this.zone.runOutsideAngular(() => {\n for (const name of ACTIVITY_EVENTS) document.addEventListener(name, this.onActivity, { passive: true, capture: true });\n this.timer = setInterval(() => this.check(), 1000);\n });\n }\n\n private stop(): void {\n if (this.timer) clearInterval(this.timer);\n this.timer = null;\n if (this.browser) for (const name of ACTIVITY_EVENTS) document.removeEventListener(name, this.onActivity, { capture: true });\n this.warning.set(false);\n }\n\n private async expire(): Promise<void> {\n if (this.expiring) return;\n this.expiring = true;\n this.zone.run(() => this.warning.set(false));\n try {\n const ok = await this.logoutService.logout();\n // Saída recusada pelo Argos: a sessão continua (o aviso de falha já apareceu); recomeça a contagem.\n if (!ok) this.touch(true);\n } finally {\n this.expiring = false;\n }\n }\n}\n","import { Injectable, Injector, NgZone, PLATFORM_ID, computed, inject, isDevMode, signal } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { HermesToastService } from '@trismegisto/angular';\nimport { SPINE_CONFIG, SPINE_MESSAGES, SpineNoticeType, SpinePreferencesService } from '@trismegisto/spine';\nimport type { AlertVariant } from '@trismegisto/primitives';\n\n/** Um aviso do app (`SpineNoticesService.notify`). */\nexport interface SpineNotice {\n title: string;\n /** Detalhe (segunda linha do aviso do navegador; no aviso da tela é o texto, com `title` no título). */\n body?: string;\n /** Caminho interno (`/solicitacoes/42`) aberto pelo \"Abrir\" do aviso e pelo clique no aviso do navegador. */\n url?: string;\n /** Cor do aviso na tela. Padrão: `info`. */\n intent?: AlertVariant;\n}\n\n/** Permissão do navegador para avisos, ou `unsupported` (sem Notification API, ou fora do navegador). */\nexport type SpineNoticePermission = NotificationPermission | 'unsupported';\n\n/**\n * Avisos do app (`SpineFeatures.notices`): o app declara os tipos que emite (`{ id, label }`) e chama\n * `notify(tipo, aviso)` de onde já sabe do acontecimento (subscription, polling). Cada tipo pode ser desligado em\n * Configurações › Notificações; tipo desligado não aparece. O aviso ligado:\n *\n * - aparece na tela (`HermesToastService`, com \"Abrir\" quando tem `url`);\n * - com a aba em segundo plano, o aviso do navegador ligado e a permissão concedida, vira também um aviso do sistema\n * (Notification API); clicar nele traz a aba para a frente e abre a `url`.\n *\n * Tipo não declarado em `SpineFeatures.notices.types` aparece sempre (em desenvolvimento, com um aviso no console).\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineNoticesService {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly zone = inject(NgZone);\n private readonly injector = inject(Injector);\n private readonly toast = inject(HermesToastService);\n private readonly preferences = inject(SpinePreferencesService);\n private readonly messages = inject(SPINE_MESSAGES);\n private readonly config = inject(SPINE_CONFIG, { optional: true })?.features?.notices;\n private readonly warned = new Set<string>();\n\n /** Recurso ligado pelo app. */\n readonly enabled = !!this.config;\n /** Tipos declarados pelo app. */\n readonly types: readonly SpineNoticeType[] = this.config?.types ?? [];\n /** Permissão atual do navegador. */\n readonly permission = signal<SpineNoticePermission>(this.readPermission());\n /** Aviso do navegador valendo de fato: ligado nas configurações e permitido pelo navegador. */\n readonly browserActive = computed(() => this.preferences.browserNotices() && this.permission() === 'granted');\n\n /** O tipo está ligado (escolha da pessoa ou, sem escolha, o `defaultEnabled` dele). */\n isEnabled(typeId: string): boolean {\n const chosen = this.preferences.noticeTypes()[typeId];\n if (typeof chosen === 'boolean') return chosen;\n return this.types.find((t) => t.id === typeId)?.defaultEnabled ?? true;\n }\n\n setEnabled(typeId: string, enabled: boolean): void {\n this.preferences.setNoticeType(typeId, enabled);\n }\n\n /**\n * Liga o aviso do navegador: pede a permissão quando ainda não foi pedida. Devolve se ficou ligado (permissão\n * negada ou navegador sem suporte: continua desligado).\n */\n async enableBrowser(): Promise<boolean> {\n if (this.readPermission() === 'unsupported') {\n this.permission.set('unsupported');\n return false;\n }\n let permission = Notification.permission;\n if (permission === 'default') {\n try { permission = await Notification.requestPermission(); } catch { permission = 'denied'; }\n }\n this.permission.set(permission);\n const granted = permission === 'granted';\n this.preferences.setBrowserNotices(granted);\n return granted;\n }\n\n disableBrowser(): void {\n this.preferences.setBrowserNotices(false);\n }\n\n /** Relê a permissão (a pessoa pode ter mudado nas configurações do navegador). */\n refreshPermission(): void {\n this.permission.set(this.readPermission());\n }\n\n /** Mostra o aviso, se o tipo estiver ligado. Devolve se mostrou. */\n notify(typeId: string, notice: SpineNotice): boolean {\n if (this.types.length && !this.types.some((t) => t.id === typeId) && isDevMode() && !this.warned.has(typeId)) {\n this.warned.add(typeId);\n console.warn(`[hermes-spine] aviso de tipo não declarado em SpineFeatures.notices.types: ${typeId}`);\n }\n if (!this.isEnabled(typeId)) return false;\n const url = notice.url && notice.url.startsWith('/') && !notice.url.startsWith('//') ? notice.url : undefined;\n // Com detalhe, o tipo do aviso vira o título do toast (\"Deploy concluído\") e o detalhe, o texto; sem detalhe, o\n // título é o texto e o toast usa o título padrão da variante.\n const action = url ? { label: this.messages.accountFeatures.noticeOpen, run: () => this.open(url) } : undefined;\n const options = notice.body ? { title: notice.title, ...(action ? { action } : {}) } : action ? { action } : undefined;\n this.toast.push(notice.intent ?? 'info', notice.body || notice.title, options);\n if (this.browser && document.visibilityState === 'hidden' && this.preferences.browserNotices()) this.system(typeId, notice, url);\n return true;\n }\n\n private system(typeId: string, notice: SpineNotice, url: string | undefined): void {\n this.refreshPermission();\n if (this.permission() !== 'granted') return;\n try {\n const shown = new Notification(notice.title, { body: notice.body, tag: url ? `${typeId}:${url}` : typeId });\n shown.onclick = () => {\n window.focus();\n shown.close();\n if (url) this.open(url);\n };\n } catch {\n // Alguns navegadores (Chrome no Android) só aceitam aviso por service worker: fica só o da tela.\n }\n }\n\n private open(url: string): void {\n this.zone.run(() => void this.injector.get(Router).navigateByUrl(url));\n }\n\n private readPermission(): SpineNoticePermission {\n if (!this.browser || typeof Notification === 'undefined') return 'unsupported';\n return Notification.permission;\n }\n}\n","import { DestroyRef, Injectable, Injector, PLATFORM_ID, inject } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { NavigationEnd, Router } from '@angular/router';\nimport { filter } from 'rxjs';\nimport { SPINE_CONFIG, SPINE_USER_STORAGE_KEYS, SpinePreferencesService, SpineQuickAccessService, SpineUserStorage } from '@trismegisto/spine';\n\n/** Rotas do shell que nunca viram \"última tela\". */\nconst IGNORED = /^\\/(callback|logoff|loggedout|login|no-permission|blocked)(\\/|$)/;\n\n/** Caminho interno seguro (`/x`, nunca `//host` nem `http:`). */\nexport function isInternalPath(url: unknown): url is string {\n return typeof url === 'string' && url.startsWith('/') && !url.startsWith('//') && !url.includes('\\\\');\n}\n\n/**\n * Tela inicial (`SpineFeatures.startPage`): para onde o app vai depois do login quando a pessoa não pediu uma URL\n * (`/callback` sem URL de retorno, ou com `/` ou `/home`) — o início do app, um favorito ou a última tela visitada.\n *\n * A última tela fica no `SpineUserStorage` (`lastPage`, por usuário) e só é gravada enquanto a escolha for\n * \"Última tela visitada\" (`track()`, ligado pelo `LayoutComponent`); ao contrário dos recentes, ela fica no logout.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineStartPageService {\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n private readonly preferences = inject(SpinePreferencesService);\n private readonly storage = inject(SpineUserStorage);\n readonly enabled = !!inject(SPINE_CONFIG, { optional: true })?.features?.startPage;\n private tracking = false;\n\n /** Grava a URL de cada navegação enquanto a escolha for \"Última tela visitada\" (idempotente). */\n track(): void {\n if (!this.enabled || !this.browser || this.tracking) return;\n this.tracking = true;\n const router = this.injector.get(Router);\n const sub = router.events\n .pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd))\n .subscribe((e) => this.remember(e.urlAfterRedirects));\n this.destroyRef.onDestroy(() => sub.unsubscribe());\n }\n\n /** Guarda `url` como última tela (só com a escolha \"Última tela visitada\"). */\n remember(url: string): void {\n if (!this.enabled || this.preferences.startPage() !== 'last' || !isInternalPath(url) || IGNORED.test(url)) return;\n try { localStorage.setItem(this.storage.key(SPINE_USER_STORAGE_KEYS.lastPage), url); } catch { /* storage indisponível */ }\n }\n\n /** Destino da tela inicial escolhida, ou `null` (início do app, recurso desligado ou favorito que sumiu). */\n target(): string | null {\n if (!this.enabled || !this.browser) return null;\n const choice = this.preferences.startPage();\n if (choice === 'last') {\n let url: string | null = null;\n try { url = localStorage.getItem(this.storage.key(SPINE_USER_STORAGE_KEYS.lastPage)); } catch { url = null; }\n return isInternalPath(url) && !IGNORED.test(url) ? url : null;\n }\n if (choice.startsWith('fav:')) {\n const id = choice.slice(4);\n const favorite = this.injector.get(SpineQuickAccessService).favorites().find((f) => f.id === id);\n return favorite && isInternalPath(favorite.redirect) ? favorite.redirect : null;\n }\n return null;\n }\n\n /** `true` quando o login não pediu uma URL própria (aí a tela inicial manda). */\n static isDefaultReturn(returnUrl: string | null): boolean {\n return !returnUrl || returnUrl === '/' || returnUrl === '/home';\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { AlertComponent, ButtonComponent, IconComponent, SegmentedControlComponent, SegmentedOption, TagComponent, TagColor } from '@trismegisto/angular';\nimport { SPINE_MESSAGES, SpinePreferencesService } from '@trismegisto/spine';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { AccountActivityEntry, SpineAccountSecurityService, accountErrorCode } from './account-security.service';\n\n/** Itens por página. */\nconst PAGE = 10;\n\n/**\n * Atividade da conta (MFA › \"Atividade da conta\", `SpineFeatures.accountActivity`): as entradas e as tentativas que\n * falharam desta conta nos últimos 90 dias (`GET {api}/activity` do Argos) — quando, de onde (IP e navegador), em qual\n * aplicativo, por qual método e, na falha, o motivo. \"Só falhas\" filtra; \"Carregar mais\" traz a página seguinte.\n */\n@Component({\n selector: 'spine-account-activity',\n imports: [AlertComponent, ButtonComponent, IconComponent, SegmentedControlComponent, TagComponent],\n template: `\n <div class=\"sp-account__toolbar\">\n <hm-segmented-control size=\"small\" emphasis=\"action\" [label]=\"t.activityFilter\" [options]=\"filterOptions()\" [value]=\"filter()\" (valueChange)=\"setFilter($event)\" />\n </div>\n @if (loading() && !entries().length) {\n <p class=\"sp-account__note\" role=\"status\">{{ messages.accountSecurity.loading }}</p>\n } @else if (loadError()) {\n <hm-alert variant=\"error\">{{ errorText() }}</hm-alert>\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"refresh\" (clicked)=\"reload()\">{{ messages.accountSecurity.retry }}</hm-button>\n </div>\n } @else {\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\">\n @for (a of entries(); track a.id) {\n <li class=\"sp-account__item\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"a.result === 'success'\"><hm-icon [shape]=\"a.device.mobile ? 'mobile' : 'computer'\" /></span>\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\">\n <strong>{{ a.device.label }}</strong>\n <hm-tag [name]=\"resultLabel(a)\" [color]=\"resultColor(a)\" />\n </span>\n <span class=\"sp-account__meta\">{{ detail(a) }}</span>\n <span class=\"sp-account__meta\">{{ method(a) }}@if (a.reason) { · {{ reason(a) }} }@if (a.client) { · {{ app(a) }} }</span>\n </span>\n </li>\n } @empty {\n <li class=\"sp-account__item sp-account__item--empty\">{{ t.activityEmpty }}</li>\n }\n </ul>\n @if (entries().length) {\n <div class=\"sp-account__list-footer\">\n <span class=\"sp-account__note\">{{ showing() }}</span>\n @if (entries().length < total()) {\n <hm-button size=\"small\" emphasis=\"medium\" [loading]=\"loading()\" (clicked)=\"more()\">{{ t.activityMore }}</hm-button>\n }\n </div>\n }\n </div>\n }\n `,\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AccountActivityComponent {\n private readonly api = inject(SpineAccountSecurityService);\n protected readonly messages = inject(SPINE_MESSAGES);\n protected readonly t = this.messages.accountFeatures;\n private readonly attempts = this.messages.loginAttempts;\n private readonly preferences = inject(SpinePreferencesService);\n\n protected readonly filter = signal<'' | 'failure'>('');\n protected readonly entries = signal<AccountActivityEntry[]>([]);\n protected readonly total = signal(0);\n protected readonly loading = signal(true);\n protected readonly loadError = signal('');\n\n protected readonly filterOptions = computed<readonly SegmentedOption[]>(() => [\n { value: '', label: this.t.activityAll },\n { value: 'failure', label: this.t.activityFailures },\n ]);\n protected readonly showing = computed(() => formatMessage(this.t.activityShowing, { shown: this.entries().length, total: this.total() }));\n\n constructor() {\n if (this.api.available) void this.load(0);\n else this.loading.set(false);\n }\n\n protected setFilter(value: string): void {\n this.filter.set(value === 'failure' ? 'failure' : '');\n this.reload();\n }\n\n protected reload(): void {\n this.entries.set([]);\n void this.load(0);\n }\n\n protected more(): void {\n void this.load(this.entries().length);\n }\n\n private async load(offset: number): Promise<void> {\n this.loading.set(true);\n try {\n const page = await this.api.activity({ limit: PAGE, offset, result: this.filter() || undefined });\n const attempts = page?.attempts ?? [];\n this.entries.update((list) => (offset ? [...list, ...attempts] : attempts));\n this.total.set(page?.total ?? attempts.length);\n this.loadError.set('');\n } catch (err) {\n this.loadError.set(accountErrorCode(err) || 'generic');\n } finally {\n this.loading.set(false);\n }\n }\n\n protected errorText(): string {\n const errors = this.messages.accountSecurity.errors as Record<string, string>;\n const code = this.loadError();\n return code === 'generic' || !errors[code] ? this.t.activityLoadError : errors[code];\n }\n\n protected resultLabel(a: AccountActivityEntry): string {\n return this.attempts.results[a.result] ?? a.result;\n }\n\n protected resultColor(a: AccountActivityEntry): TagColor {\n return a.result === 'success' ? 'success' : a.result === 'failure' ? 'danger' : 'neutral';\n }\n\n protected method(a: AccountActivityEntry): string {\n return (this.attempts.methods as Record<string, string>)[a.method] ?? a.method;\n }\n\n protected reason(a: AccountActivityEntry): string {\n return (this.attempts.reasons as Record<string, string>)[a.reason ?? ''] ?? a.reason ?? '';\n }\n\n protected app(a: AccountActivityEntry): string {\n return formatMessage(this.t.activityApp, { app: a.client?.name || this.t.unknownApp });\n }\n\n protected detail(a: AccountActivityEntry): string {\n const date = new Intl.DateTimeFormat(this.messages.meta.locale, { dateStyle: 'short', timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() })\n .format(new Date(a.at));\n return formatMessage(this.t.activityDetail, { date, ip: a.ip || this.t.unknownIp });\n }\n}\n","import { Directive, Injectable, computed, inject, signal } from '@angular/core';\nimport { AccountMethod, AccountOverview, AccountReauth, SpineAccountSecurityService, accountErrorCode } from './account-security.service';\n\n/** O que a pessoa pediu: adicionar/trocar/remover um método ou gerar códigos de recuperação. */\nexport type AccountAction =\n | { kind: 'add' | 'replace' | 'remove'; method: AccountMethod }\n | { kind: 'codes' };\n\nexport type AccountStep = 'idle' | 'reauth' | 'confirm-remove' | 'enroll-totp' | 'enroll-email' | 'enroll-email-code' | 'codes';\n\n/** Avisos de sucesso (chaves de `SpineMessages.accountSecurity`). */\nexport type AccountNotice = 'methodAdded' | 'deviceReplaced' | 'methodRemoved' | 'codesRegenerated' | 'reauthCodeSent';\n\n/** Métodos que o painel trata (o Argos só tem fluxo para estes; o SMS aparece como indisponível). */\nconst SUPPORTED = ['totp', 'email', 'sms'];\nconst nameOf = (m: AccountMethod | null | undefined) => m?.method_name?.toLowerCase() ?? '';\nexport const isTotp = (m: AccountMethod | null | undefined) => nameOf(m) === 'totp';\nexport const isEmail = (m: AccountMethod | null | undefined) => nameOf(m) === 'email';\nexport const isSms = (m: AccountMethod | null | undefined) => nameOf(m) === 'sms';\n\n/**\n * Estado da seção \"MFA\" do painel de configurações: visão geral do Argos e o fluxo de uma\n * alteração (reautenticação → cadastro/remoção/códigos). Mesmo roteiro da tela \"Segurança da conta\" do\n * Argos: toda alteração pede antes a prova de identidade recente (senha ou um fator ativo, 5 minutos no\n * servidor); a recusa `reauthentication_required` no meio volta para a prova e a ação segue depois dela.\n *\n * Uma instância por abertura do painel (`spineAccountSecurity` no `hm-settings-section`): os códigos de\n * recuperação e o QR Code somem quando o painel fecha.\n */\n@Injectable()\nexport class SpineAccountSecurityState {\n private readonly api = inject(SpineAccountSecurityService);\n\n readonly available = this.api.available;\n readonly loading = signal(false);\n /** Código do erro ao carregar (`login_required`, `network`...); `''` = carregou. */\n readonly loadError = signal('');\n readonly overview = signal<AccountOverview | null>(null);\n\n readonly step = signal<AccountStep>('idle');\n readonly action = signal<AccountAction | null>(null);\n readonly busy = signal(false);\n /** Código do último erro de uma ação (`invalid_code`...). */\n readonly error = signal('');\n readonly notice = signal<AccountNotice | null>(null);\n\n /** Como provar a identidade: `password`, o id de um método ativo ou o id do código de recuperação. */\n readonly reauthMode = signal('password');\n readonly reauthCodeSent = signal(false);\n /** Até quando (epoch ms) a reautenticação vale, pelo que o servidor informou. */\n private reauthUntil = 0;\n\n readonly totpSetup = signal<{ secret: string; qrcode: string } | null>(null);\n readonly enrollEmail = signal('');\n /** Códigos de recuperação recém-gerados: só existem aqui, até a pessoa dizer que guardou. */\n readonly issuedCodes = signal<string[] | null>(null);\n\n readonly methods = computed(() => (this.overview()?.methods ?? []).filter((m) => SUPPORTED.includes(nameOf(m))));\n readonly activeMethods = computed(() => this.methods().filter((m) => m.active));\n readonly remainingCodes = computed(() => this.overview()?.recovery_codes.remaining ?? 0);\n readonly recoveryMethodId = computed(() => this.overview()?.recovery_method_id ?? '');\n /** Linha da última ação (métodos ou códigos): é ela que mostra o fluxo, o erro e o aviso. */\n readonly owner = signal<'methods' | 'codes'>('methods');\n\n constructor() {\n if (this.available) void this.load();\n }\n\n async load(): Promise<void> {\n this.loading.set(true);\n try {\n this.apply(await this.api.overview());\n this.loadError.set('');\n } catch (err) {\n this.loadError.set(accountErrorCode(err) || 'generic');\n } finally {\n this.loading.set(false);\n }\n }\n\n /** Com MFA obrigatório, o último método ativo não sai (o servidor também recusa: `mfa_last_method`). */\n canRemove(method: AccountMethod): boolean {\n return !(this.overview()?.policy.required && this.activeMethods().length <= 1 && method.active);\n }\n\n // ── Início de uma ação: reautentica se preciso, depois segue ───────────────\n start(action: AccountAction): void {\n this.error.set('');\n this.notice.set(null);\n this.issuedCodes.set(null);\n this.action.set(action);\n this.owner.set(action.kind === 'codes' ? 'codes' : 'methods');\n if (Date.now() < this.reauthUntil) void this.run(() => this.proceed());\n else this.openReauth();\n }\n\n cancel(): void {\n this.action.set(null);\n this.step.set('idle');\n this.error.set('');\n this.totpSetup.set(null);\n // Códigos de recuperação não ficam na memória da tela depois que o fluxo é abandonado.\n this.issuedCodes.set(null);\n }\n\n private openReauth(): void {\n this.reauthCodeSent.set(false);\n this.reauthMode.set('password');\n this.step.set('reauth');\n }\n\n chooseReauth(mode: string): void {\n this.error.set('');\n this.notice.set(null);\n this.reauthCodeSent.set(false);\n this.reauthMode.set(mode);\n }\n\n sendReauthCode(): Promise<void> {\n return this.run(async () => {\n await this.api.requestReauthCode(this.reauthMode());\n this.reauthCodeSent.set(true);\n this.notice.set('reauthCodeSent');\n });\n }\n\n confirmReauth(proof: AccountReauth): Promise<void> {\n return this.run(async () => {\n const response = await this.api.reauthenticate(proof);\n this.reauthUntil = Date.now() + (response?.reauth_expires_in ?? 0) * 1000;\n this.notice.set(null);\n await this.proceed();\n });\n }\n\n // ── Depois da reautenticação (sempre de dentro de run()) ───────────────────\n private async proceed(): Promise<void> {\n const action = this.action();\n if (!action) return;\n if (action.kind === 'remove') {\n this.step.set('confirm-remove');\n return;\n }\n if (action.kind === 'codes') {\n const result = await this.api.regenerateRecoveryCodes();\n this.issuedCodes.set(result.recovery_codes);\n this.step.set('codes');\n await this.refresh();\n return;\n }\n if (isTotp(action.method)) {\n const setup = await this.api.configure(action.method.method_id);\n this.totpSetup.set({ secret: setup.secret ?? '', qrcode: setup.qrcode ?? '' });\n this.step.set('enroll-totp');\n return;\n }\n this.step.set('enroll-email');\n }\n\n sendEnrollEmail(email: string): Promise<void> {\n const action = this.action();\n if (!action || action.kind === 'codes') return Promise.resolve();\n return this.run(async () => {\n await this.api.configure(action.method.method_id, email);\n this.enrollEmail.set(email);\n this.step.set('enroll-email-code');\n });\n }\n\n confirmEnroll(code: string): Promise<void> {\n const action = this.action();\n if (!action || action.kind === 'codes' || action.kind === 'remove' || !/^\\d{6}$/.test(code)) return Promise.resolve();\n return this.run(async () => {\n const overview = await this.api.register(action.method.method_id, code);\n this.apply(overview);\n this.totpSetup.set(null);\n if (overview.recovery_codes_issued?.length) {\n // Primeiro método: os códigos aparecem uma vez, na linha deles.\n this.action.set({ kind: 'codes' });\n this.owner.set('codes');\n this.issuedCodes.set(overview.recovery_codes_issued);\n this.step.set('codes');\n return;\n }\n this.finish(action.kind === 'replace' ? 'deviceReplaced' : 'methodAdded');\n });\n }\n\n confirmRemove(): Promise<void> {\n const action = this.action();\n if (!action || action.kind !== 'remove') return Promise.resolve();\n return this.run(async () => {\n this.apply(await this.api.remove(action.method.method_id));\n this.finish('methodRemoved');\n });\n }\n\n codesSaved(): void {\n this.issuedCodes.set(null);\n this.finish('codesRegenerated');\n }\n\n private finish(notice: AccountNotice): void {\n this.action.set(null);\n this.step.set('idle');\n this.notice.set(notice);\n }\n\n private apply(overview: AccountOverview): void {\n this.overview.set(overview);\n if (overview.reauthenticated) this.reauthUntil = Date.now() + overview.reauth_expires_in * 1000;\n }\n\n private async refresh(): Promise<void> {\n try {\n this.apply(await this.api.overview());\n } catch {\n // A ação já foi feita; a contagem volta certa na próxima abertura do painel.\n }\n }\n\n /** Executa uma chamada com o estado de ocupado e o erro na tela. A reautenticação vencida no meio volta\n * para a prova de identidade (e a ação continua depois dela). */\n private async run(fn: () => Promise<void>): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n this.error.set('');\n try {\n await fn();\n } catch (err) {\n const code = accountErrorCode(err) || 'generic';\n if (code === 'reauthentication_required') {\n this.reauthUntil = 0;\n this.openReauth();\n }\n this.error.set(code);\n } finally {\n this.busy.set(false);\n }\n }\n}\n\n/**\n * Escopo do estado da conta: no `hm-settings-section` da seção \"MFA\", para as linhas da seção\n * (métodos e códigos de recuperação) dividirem o mesmo estado e ele morrer junto com o painel.\n */\n@Directive({\n selector: '[spineAccountSecurity]',\n providers: [SpineAccountSecurityState],\n})\nexport class SpineAccountSecurityScopeDirective {}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { ButtonComponent, CodeInputComponent, IconComponent, InputComponent, RadioComponent, RadioOption } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineAccountSecurityState, isEmail, isSms, isTotp } from './account-security.state';\n\nlet sequence = 0;\n\n/**\n * Prova de identidade antes de uma alteração na conta (senha, código do autenticador, código enviado ao\n * e-mail cadastrado ou código de recuperação). Vale 5 minutos no Argos, presa à sessão do login; depois\n * dela a ação pedida continua sozinha (`SpineAccountSecurityState.confirmReauth`).\n */\n@Component({\n selector: 'spine-account-reauth',\n imports: [ReactiveFormsModule, ButtonComponent, CodeInputComponent, IconComponent, InputComponent, RadioComponent],\n template: `\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"titleId\" [attr.aria-describedby]=\"hintId\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"shield-check\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"titleId\">{{ t.reauthTitle }}</h4>\n <p class=\"sp-account__note\" [id]=\"hintId\">{{ t.reauthHint }}</p>\n </div>\n </div>\n\n @if (choices().length > 1) {\n <hm-radio layout=\"inline\" [label]=\"t.reauthHow\" [options]=\"choices()\" [value]=\"state.reauthMode()\" (valueChange)=\"choose($event)\" />\n }\n\n @switch (kind()) {\n @case ('password') {\n <form class=\"sp-account__form\" (submit)=\"$event.preventDefault(); submitPassword()\">\n <hm-input type=\"password\" autocomplete=\"current-password\" [label]=\"t.currentPassword\" [formControl]=\"password\" [messages]=\"{ required: t.passwordRequired }\" />\n <div class=\"sp-account__actions\">\n <hm-button type=\"submit\" emphasis=\"high\" [loading]=\"state.busy()\">{{ t.confirm }}</hm-button>\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </form>\n }\n @case ('recovery') {\n <form class=\"sp-account__form\" (submit)=\"$event.preventDefault(); submitRecovery()\">\n <hm-input autocomplete=\"off\" [label]=\"t.recoveryCode\" [placeholder]=\"t.recoveryCodePlaceholder\" [formControl]=\"recoveryCode\"\n [messages]=\"{ required: t.recoveryCodeRequired, minlength: t.recoveryCodeLength }\" />\n <div class=\"sp-account__actions\">\n <hm-button type=\"submit\" emphasis=\"high\" [loading]=\"state.busy()\">{{ t.confirm }}</hm-button>\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </form>\n }\n @case ('email-request') {\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"high\" icon=\"mail\" [loading]=\"state.busy()\" (clicked)=\"state.sendReauthCode()\">{{ t.sendEmailCode }}</hm-button>\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n }\n @default {\n <div class=\"sp-account__code\" role=\"group\" [attr.aria-labelledby]=\"codeLabelId\">\n <span class=\"sp-account__label\" [id]=\"codeLabelId\">{{ t.sixDigitCode }}</span>\n <hm-code-input (completed)=\"submitCode($event)\" />\n </div>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n }\n }\n </section>\n `,\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AccountReauthComponent {\n protected readonly state = inject(SpineAccountSecurityState);\n protected readonly t = inject(SPINE_MESSAGES).accountSecurity;\n protected readonly titleId = `sp-account-reauth-${++sequence}`;\n protected readonly codeLabelId = `${this.titleId}-code`;\n protected readonly hintId = `${this.titleId}-hint`;\n\n protected readonly password = new FormControl('', { nonNullable: true, validators: [Validators.required] });\n protected readonly recoveryCode = new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.minLength(10)] });\n\n /** Senha, os métodos ativos que servem de prova (o SMS não tem envio) e, com códigos restantes, um código de recuperação. */\n protected readonly choices = computed<RadioOption[]>(() => {\n const options: RadioOption[] = [{ value: 'password', label: this.t.reauthPassword }];\n for (const m of this.state.activeMethods()) {\n if (isSms(m)) continue;\n options.push({ value: m.method_id, label: isTotp(m) ? this.t.methodTotp : isEmail(m) ? this.t.methodEmail : m.method_name });\n }\n if (this.state.activeMethods().length && this.state.remainingCodes() > 0) {\n options.push({ value: this.state.recoveryMethodId(), label: this.t.reauthRecoveryCode });\n }\n return options;\n });\n\n protected readonly kind = computed<'password' | 'recovery' | 'email-request' | 'code'>(() => {\n const mode = this.state.reauthMode();\n if (mode === 'password') return 'password';\n if (mode === this.state.recoveryMethodId()) return 'recovery';\n const method = this.state.activeMethods().find((m) => m.method_id === mode);\n return isEmail(method) && !this.state.reauthCodeSent() ? 'email-request' : 'code';\n });\n\n protected choose(mode: string | null): void {\n if (mode) this.state.chooseReauth(mode);\n }\n\n protected submitPassword(): void {\n this.password.markAsTouched();\n if (this.password.invalid) return;\n void this.state.confirmReauth({ password: this.password.value });\n }\n\n protected submitRecovery(): void {\n this.recoveryCode.markAsTouched();\n if (this.recoveryCode.invalid) return;\n void this.state.confirmReauth({ method_id: this.state.reauthMode(), code: this.recoveryCode.value.trim() });\n }\n\n protected submitCode(code: string): void {\n void this.state.confirmReauth({ method_id: this.state.reauthMode(), code });\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { FormControl, ReactiveFormsModule, Validators } from '@angular/forms';\nimport { AlertComponent, ButtonComponent, CodeInputComponent, IconComponent, InputComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { AccountMethod } from './account-security.service';\nimport { SpineAccountSecurityState, isEmail, isSms, isTotp } from './account-security.state';\nimport { AccountReauthComponent } from './account-reauth.component';\n\nlet sequence = 0;\n\n/**\n * Verificação em duas etapas da conta no Argos, dentro do painel de configurações: os métodos (ativo ou não\n * cadastrado; o SMS, sem fluxo no Argos, só aparece se já estiver ativo) e as ações — adicionar (TOTP com QR Code\n * e confirmação pelo código; e-mail com código no endereço informado), trocar o aparelho do autenticador e remover. Cada ação passa antes pela\n * reautenticação (`spine-account-reauth`).\n */\n@Component({\n selector: 'spine-account-mfa',\n imports: [ReactiveFormsModule, AlertComponent, ButtonComponent, CodeInputComponent, IconComponent, InputComponent, AccountReauthComponent],\n templateUrl: './account-mfa.component.html',\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AccountMfaComponent {\n protected readonly state = inject(SpineAccountSecurityState);\n protected readonly t = inject(SPINE_MESSAGES).accountSecurity;\n protected readonly fmt = formatMessage;\n protected readonly isTotp = isTotp;\n protected readonly isSms = isSms;\n protected readonly ids = `sp-account-mfa-${++sequence}`;\n\n protected readonly email = new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.email] });\n\n /** Métodos da lista: o SMS não cadastrado fica de fora (não há como cadastrar daqui). */\n protected readonly shown = computed(() => this.state.methods().filter((m) => !isSms(m) || m.active));\n\n protected label(method: AccountMethod | null | undefined): string {\n if (!method) return '';\n if (isTotp(method)) return this.t.methodTotp;\n if (isEmail(method)) return this.t.methodEmail;\n if (isSms(method)) return this.t.methodSms;\n return method.method_name;\n }\n\n protected icon(method: AccountMethod): string {\n return isTotp(method) ? 'authenticator' : isEmail(method) ? 'mail' : 'sms';\n }\n\n protected status(method: AccountMethod): string {\n if (!method.active) return this.t.notRegistered;\n return method.secret ? formatMessage(this.t.activeWithDetail, { detail: method.secret }) : this.t.active;\n }\n\n /** Método da ação em andamento (para o título \"Remover ...?\"). */\n protected actionMethod(): AccountMethod | null {\n const action = this.state.action();\n return action && action.kind !== 'codes' ? action.method : null;\n }\n\n protected errorText(code: string): string {\n return (this.t.errors as Record<string, string>)[code] ?? this.t.errors.generic;\n }\n\n protected startAdd(method: AccountMethod): void {\n this.email.reset('');\n this.state.start({ kind: 'add', method });\n }\n\n protected sendEmail(): void {\n this.email.markAsTouched();\n if (this.email.invalid) return;\n void this.state.sendEnrollEmail(this.email.value.trim());\n }\n}\n","@if (state.loading() && !state.overview()) {\n <p class=\"sp-account__note\" role=\"status\">{{ t.loading }}</p>\n} @else if (state.loadError()) {\n <hm-alert variant=\"error\">{{ errorText(state.loadError()) }}</hm-alert>\n @if (state.loadError() !== 'login_required' && state.loadError() !== 'invalid_token') {\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"refresh\" (clicked)=\"state.load()\">{{ t.retry }}</hm-button>\n </div>\n }\n} @else if (state.overview(); as data) {\n @if (state.owner() === 'methods') {\n @if (state.notice(); as notice) {\n <hm-alert variant=\"success\">{{ t.notices[notice] }}</hm-alert>\n }\n @if (state.error(); as error) {\n <hm-alert variant=\"error\">{{ errorText(error) }}</hm-alert>\n }\n }\n\n @if (state.owner() === 'methods' && state.step() !== 'idle') {\n @switch (state.step()) {\n @case ('reauth') {\n <spine-account-reauth />\n }\n\n @case ('confirm-remove') {\n <section class=\"sp-account__panel sp-account__panel--danger\" [attr.aria-labelledby]=\"ids + '-remove'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"trash\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-remove'\">{{ fmt(t.removeTitle, { method: label(actionMethod()) }) }}</h4>\n <p class=\"sp-account__note\">\n {{ t.removeHint }}\n @if (state.activeMethods().length <= 1) { {{ t.removeLastHint }} }\n </p>\n </div>\n </div>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"high\" intent=\"danger\" [loading]=\"state.busy()\" (clicked)=\"state.confirmRemove()\">{{ t.remove }}</hm-button>\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </section>\n }\n\n @case ('enroll-totp') {\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"ids + '-totp'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"authenticator\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-totp'\">{{ t.totpTitle }}</h4>\n @if (state.totpSetup(); as setup) {\n <p class=\"sp-account__note\">{{ t.manualKey }} <code class=\"sp-account__secret\">{{ setup.secret }}</code></p>\n }\n </div>\n </div>\n @if (state.totpSetup()?.qrcode; as qrcode) {\n <div class=\"sp-account__qr\"><img [src]=\"qrcode\" [alt]=\"t.qrAlt\" /></div>\n }\n <div class=\"sp-account__code\" role=\"group\" [attr.aria-labelledby]=\"ids + '-totp-code'\">\n <span class=\"sp-account__label\" [id]=\"ids + '-totp-code'\">{{ t.appCode }}</span>\n <hm-code-input (completed)=\"state.confirmEnroll($event)\" />\n </div>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </section>\n }\n\n @case ('enroll-email') {\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"ids + '-email'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"mail\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-email'\">{{ t.emailTitle }}</h4>\n </div>\n </div>\n <form class=\"sp-account__form\" (submit)=\"$event.preventDefault(); sendEmail()\">\n <hm-input type=\"email\" autocomplete=\"email\" [label]=\"t.email\" [placeholder]=\"t.emailPlaceholder\" [formControl]=\"email\"\n [messages]=\"{ required: t.emailRequired, email: t.emailInvalid }\" />\n <div class=\"sp-account__actions\">\n <hm-button type=\"submit\" emphasis=\"high\" icon=\"mail\" [loading]=\"state.busy()\">{{ t.sendCode }}</hm-button>\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </form>\n </section>\n }\n\n @case ('enroll-email-code') {\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"ids + '-email-code'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"mail\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-email-code'\">{{ t.emailCodeTitle }}</h4>\n <p class=\"sp-account__note\" [id]=\"ids + '-email-code-hint'\">{{ fmt(t.emailCodeHint, { email: state.enrollEmail() }) }}</p>\n </div>\n </div>\n <div class=\"sp-account__code\" role=\"group\" [attr.aria-labelledby]=\"ids + '-email-code-label'\" [attr.aria-describedby]=\"ids + '-email-code-hint'\">\n <span class=\"sp-account__label\" [id]=\"ids + '-email-code-label'\">{{ t.sixDigitCode }}</span>\n <hm-code-input (completed)=\"state.confirmEnroll($event)\" />\n </div>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"medium\" [disabled]=\"state.busy()\" (clicked)=\"state.cancel()\">{{ t.cancel }}</hm-button>\n </div>\n </section>\n }\n }\n } @else {\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\">\n @for (m of shown(); track m.method_id) {\n <li class=\"sp-account__item\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"m.active\"><hm-icon [shape]=\"icon(m)\" /></span>\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\"><strong>{{ label(m) }}</strong></span>\n <span class=\"sp-account__meta\">{{ status(m) }}</span>\n </span>\n @if (!isSms(m)) {\n <span class=\"sp-account__item-actions\">\n @if (!m.active) {\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"plus\" [disabled]=\"state.busy() || state.step() !== 'idle'\" (clicked)=\"startAdd(m)\">{{ t.add }}</hm-button>\n } @else {\n @if (isTotp(m)) {\n <hm-button size=\"small\" emphasis=\"medium\" [disabled]=\"state.busy() || state.step() !== 'idle'\" (clicked)=\"state.start({ kind: 'replace', method: m })\">{{ t.replaceDevice }}</hm-button>\n }\n <hm-button size=\"small\" emphasis=\"medium\" intent=\"danger\" [disabled]=\"state.busy() || state.step() !== 'idle' || !state.canRemove(m)\" (clicked)=\"state.start({ kind: 'remove', method: m })\">{{ t.remove }}</hm-button>\n }\n </span>\n }\n </li>\n }\n </ul>\n @if (data.policy.required) {\n <div class=\"sp-account__list-footer\">\n <span class=\"sp-account__note\">{{ t.requiredHint }}</span>\n </div>\n }\n </div>\n }\n}\n","import { HttpClient, HttpHeaders } from '@angular/common/http';\nimport { Injectable, inject, signal } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { SPINE_ADMIN_API } from '@trismegisto/spine';\nimport { urlPath } from '@trismegisto/primitives';\n\n/** Um token de aplicação do usuário, como o argos-admin devolve (nunca o valor, só o prefixo). */\nexport interface AppToken {\n id: string;\n name: string;\n description: string | null;\n prefix: string;\n badge_id: string;\n badge_name: string;\n expires_at: string;\n created_at: string;\n last_used_at: string | null;\n expired: boolean;\n}\n\nexport interface AppTokenList {\n tokens: AppToken[];\n max_active: number;\n max_days: number;\n}\n\n/** A aplicação logada e os níveis de acesso que o usuário pode escolher nela ao criar um token. */\nexport interface AppTokenOptions {\n client: { id: string; name: string | null };\n badges: { id: string; name: string }[];\n max_days: number;\n}\n\nexport interface CreatedAppToken {\n id: string;\n /** Valor bruto — só existe nesta resposta. */\n token: string;\n expires_at: string;\n}\n\n/**\n * Tokens de aplicação pessoais (`x-app-token`) do usuário logado — `argos-admin /me/app-tokens`.\n * Sempre da aplicação LOGADA: o servidor tira o client do próprio access-token da sessão, então\n * aqui não existe escolha de aplicação.\n * Autentica com o access-token da sessão (o servidor recusa um app-token aqui: token não cria\n * token). `available` é falso quando o app não tem a URL do argos-admin (`SPINE_ADMIN_API`).\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineAppTokensService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly adminApi = inject(SPINE_ADMIN_API, { optional: true });\n\n readonly available = !!this.adminApi;\n /** Sobe a cada token criado por aqui (o \"Conectar um agente de IA\" cria um; a lista de tokens relê). */\n readonly changes = signal(0);\n\n private get baseUrl(): string {\n return `${this.adminApi}/me/app-tokens`;\n }\n\n private get headers(): HttpHeaders {\n return new HttpHeaders({ 'x-access-token': this.auth.getToken() ?? '' });\n }\n\n list(): Promise<AppTokenList> {\n return firstValueFrom(this.http.get<AppTokenList>(this.baseUrl, { headers: this.headers }));\n }\n\n options(): Promise<AppTokenOptions> {\n return firstValueFrom(this.http.get<AppTokenOptions>(`${this.baseUrl}/options`, { headers: this.headers }));\n }\n\n async create(body: { badge_id: string; name: string; validity_days: number }): Promise<CreatedAppToken> {\n const created = await firstValueFrom(this.http.post<CreatedAppToken>(this.baseUrl, body, { headers: this.headers }));\n this.changes.update((n) => n + 1);\n return created;\n }\n\n revoke(id: string): Promise<void> {\n return firstValueFrom(this.http.delete<void>(`${this.baseUrl}${urlPath`/${id}`}`, { headers: this.headers }));\n }\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport {\n ButtonComponent, CheckboxComponent, CodeViewerComponent, HermesToastService, IconComponent, SegmentedControlComponent, SegmentedOption,\n} from '@trismegisto/angular';\nimport { SPINE_CONFIG, SPINE_MESSAGES, SpineMcpServer, SpinePreferencesService } from '@trismegisto/spine';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SpineAppTokensService } from './app-tokens.service';\n\n/** Monta o `.mcp.json` do Claude Code: uma entrada por servidor, todas com o mesmo token. Com `write`, cada servidor\n * que tem `writeScopes` pede esses escopos; os demais (e todos sem `write`) vão com `readScopes`, ou sem o header\n * (o MCP já é só leitura sem ele). URL relativa é resolvida contra `origin`. */\nexport function buildMcpConfig(servers: readonly SpineMcpServer[], token: string, write: boolean, origin: string): string {\n const mcpServers: Record<string, { type: 'http'; url: string; headers: Record<string, string> }> = {};\n for (const server of servers) {\n const headers: Record<string, string> = { 'x-app-token': token };\n const scopes = write && server.writeScopes ? server.writeScopes : server.readScopes;\n if (scopes) headers['x-mcp-scopes'] = scopes;\n mcpServers[server.name] = { type: 'http', url: new URL(server.url, origin).href, headers };\n }\n return JSON.stringify({ mcpServers }, null, 2);\n}\n\n/**\n * Sessões › \"Conectar um agente de IA\" (`SpineFeatures.aiAgent`): em um passo, cria um token de aplicação pessoal\n * (`x-app-token`, a mesma API de \"Tokens de aplicação\") e monta a configuração MCP pronta para o Claude Code, com os\n * servidores que o app declarou e os escopos do acesso escolhido (só leitura ou leitura e escrita). O token aparece\n * uma única vez, dentro da configuração; nunca vai para o console nem para o armazenamento do navegador, e some ao\n * concluir ou fechar o painel.\n */\n@Component({\n selector: 'spine-ai-agent',\n imports: [ButtonComponent, CheckboxComponent, CodeViewerComponent, IconComponent, SegmentedControlComponent],\n template: `\n @if (!available) {\n <p class=\"sp-account__note\">{{ t.aiAgentUnavailable }}</p>\n } @else if (result(); as r) {\n <div class=\"sp-account__panel sp-account__panel--success\" role=\"status\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"check-circle\" />\n <div class=\"sp-account__panel-text\">\n <p class=\"sp-account__title\">{{ t.aiAgentResult }}</p>\n <p class=\"sp-account__note\">{{ fmt(t.aiAgentResultHint, { date: r.expires }) }}</p>\n </div>\n </div>\n <hm-code-viewer [code]=\"r.config\" language=\"json\" filename=\".mcp.json\" [label]=\"t.aiAgentResult\" />\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"high\" icon=\"copy\" (clicked)=\"copy()\">{{ t.aiAgentCopy }}</hm-button>\n <hm-button size=\"small\" emphasis=\"medium\" (clicked)=\"done()\">{{ t.aiAgentDone }}</hm-button>\n </div>\n </div>\n } @else if (open()) {\n <div class=\"sp-account__panel\">\n <div class=\"sp-account__form\">\n @if (servers.length > 1) {\n <fieldset class=\"sp-account__choices\">\n <legend class=\"sp-account__label\">{{ t.aiAgentServers }}</legend>\n @for (s of servers; track s.name) {\n <hm-checkbox [label]=\"serverLabel(s)\" [checked]=\"selected().has(s.name)\" (checkedChange)=\"toggleServer(s.name, $event)\" />\n }\n </fieldset>\n }\n @if (canWrite()) {\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ t.aiAgentAccess }}</span>\n <hm-segmented-control size=\"small\" emphasis=\"action\" [label]=\"t.aiAgentAccess\" [options]=\"accessOptions()\" [value]=\"access()\" (valueChange)=\"access.set($event === 'write' ? 'write' : 'read')\" />\n @if (access() === 'write') { <p class=\"sp-account__note\">{{ t.aiAgentWriteHint }}</p> }\n </div>\n }\n @if (badgeOptions().length > 1) {\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ tokens.accessLevel }}</span>\n <hm-segmented-control size=\"small\" emphasis=\"action\" [label]=\"tokens.accessLevel\" [options]=\"badgeOptions()\" [value]=\"badgeId()\" (valueChange)=\"badgeId.set($event)\" />\n </div>\n }\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ tokens.validity }}</span>\n <hm-segmented-control size=\"small\" emphasis=\"action\" [label]=\"tokens.validity\" [options]=\"validityOptions()\" [value]=\"validity()\" (valueChange)=\"validity.set($event)\" />\n </div>\n @if (!selected().size) { <p class=\"sp-account__note sp-account__note--error\">{{ t.aiAgentSelectServer }}</p> }\n @if (noBadges()) { <p class=\"sp-account__note sp-account__note--error\">{{ tokens.noBadges }}</p> }\n </div>\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" [disabled]=\"submitting()\" (clicked)=\"cancel()\">{{ tokens.cancel }}</hm-button>\n <hm-button size=\"small\" emphasis=\"high\" icon=\"plugin\" [loading]=\"submitting()\" [disabled]=\"!canSubmit()\" (clicked)=\"generate()\">{{ t.aiAgentGenerate }}</hm-button>\n </div>\n </div>\n } @else {\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"medium\" icon=\"plugin\" [loading]=\"starting()\" (clicked)=\"start()\">{{ t.aiAgentStart }}</hm-button>\n </div>\n }\n `,\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AiAgentComponent {\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly t = this.messages.accountFeatures;\n protected readonly tokens = this.messages.appTokens;\n protected readonly fmt = formatMessage;\n private readonly service = inject(SpineAppTokensService);\n private readonly toast = inject(HermesToastService);\n private readonly preferences = inject(SpinePreferencesService);\n\n protected readonly available = this.service.available;\n protected readonly servers: readonly SpineMcpServer[] = inject(SPINE_CONFIG, { optional: true })?.features?.aiAgent?.servers ?? [];\n\n protected readonly open = signal(false);\n protected readonly starting = signal(false);\n protected readonly submitting = signal(false);\n protected readonly selected = signal<ReadonlySet<string>>(new Set(this.servers.map((s) => s.name)));\n protected readonly access = signal<'read' | 'write'>('read');\n protected readonly badges = signal<{ id: string; name: string }[]>([]);\n protected readonly badgeId = signal('');\n protected readonly validity = signal('90');\n /** Configuração gerada (com o token), mostrada uma única vez. */\n protected readonly result = signal<{ config: string; expires: string } | null>(null);\n\n protected readonly canWrite = computed(() => this.servers.some((s) => s.writeScopes && this.selected().has(s.name)));\n protected readonly noBadges = computed(() => !this.badges().length);\n protected readonly canSubmit = computed(() => !!this.selected().size && !!this.badgeId() && !this.submitting());\n protected readonly accessOptions = computed<readonly SegmentedOption[]>(() => [\n { value: 'read', label: this.t.aiAgentReadOnly },\n { value: 'write', label: this.t.aiAgentReadWrite },\n ]);\n protected readonly badgeOptions = computed<readonly SegmentedOption[]>(() => this.badges().map((b) => ({ value: b.id, label: b.name })));\n protected readonly validityOptions = computed<readonly SegmentedOption[]>(() => [\n { value: '30', label: this.tokens.days30 },\n { value: '90', label: this.tokens.days90 },\n { value: '180', label: this.tokens.months6 },\n { value: '365', label: this.tokens.year1 },\n ]);\n\n protected serverLabel(server: SpineMcpServer): string {\n const label = server.label ?? server.name;\n return server.writeScopes ? label : formatMessage(this.t.aiAgentReadOnlyServer, { name: label });\n }\n\n protected toggleServer(name: string, checked: boolean): void {\n const next = new Set(this.selected());\n if (checked) next.add(name);\n else next.delete(name);\n this.selected.set(next);\n }\n\n protected async start(): Promise<void> {\n this.starting.set(true);\n try {\n const { badges } = await this.service.options();\n this.badges.set(badges);\n this.badgeId.set(badges[0]?.id ?? '');\n this.access.set('read');\n this.validity.set('90');\n this.open.set(true);\n } catch (err) {\n this.toast.error(errorDetail(err) || this.tokens.badgesError);\n } finally {\n this.starting.set(false);\n }\n }\n\n protected cancel(): void {\n this.open.set(false);\n }\n\n protected async generate(): Promise<void> {\n if (!this.canSubmit()) return;\n this.submitting.set(true);\n try {\n const date = new Intl.DateTimeFormat(this.messages.meta.locale, { dateStyle: 'short', timeZone: this.preferences.effectiveTimeZone() }).format(new Date());\n const created = await this.service.create({\n badge_id: this.badgeId(),\n name: formatMessage(this.t.aiAgentTokenName, { date }).slice(0, 80),\n validity_days: Number(this.validity()),\n });\n const servers = this.servers.filter((s) => this.selected().has(s.name));\n const write = this.access() === 'write' && this.canWrite();\n this.result.set({\n config: buildMcpConfig(servers, created.token, write, location.origin),\n expires: new Intl.DateTimeFormat(this.messages.meta.locale, { dateStyle: 'short', timeZone: this.preferences.effectiveTimeZone() })\n .format(new Date(created.expires_at)),\n });\n this.open.set(false);\n } catch (err) {\n this.toast.error(errorDetail(err) || this.t.aiAgentCreateError);\n } finally {\n this.submitting.set(false);\n }\n }\n\n protected async copy(): Promise<void> {\n const config = this.result()?.config;\n if (!config) return;\n try {\n await navigator.clipboard.writeText(config);\n this.toast.success(this.t.aiAgentCopied);\n } catch {\n this.toast.error(this.tokens.copyFailed);\n }\n }\n\n protected done(): void {\n this.result.set(null);\n }\n}\n\nfunction errorDetail(err: unknown): string {\n return err instanceof HttpErrorResponse ? ((err.error?.detail as string | undefined) ?? '') : '';\n}\n","import { ChangeDetectionStrategy, Component, inject, signal, viewChild } from '@angular/core';\nimport { AlertComponent, HermesToastService, SelectComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineAccountSecurityService } from './account-security.service';\n\n/**\n * Crachá padrão (Conta › \"Crachá padrão\", `SpineFeatures.defaultBadge`): o nível de acesso com que o login entra\n * nesta aplicação, guardado no Argos por usuário e aplicação (`GET/PUT {api}/badges`) — vale em qualquer navegador.\n * \"Automático\" volta à regra do Argos (o crachá de menor nível). A troca no menu do perfil continua valendo só para a\n * sessão.\n */\n@Component({\n selector: 'spine-default-badge',\n imports: [AlertComponent, SelectComponent],\n template: `\n @if (loadError()) {\n <hm-alert variant=\"error\">{{ t.defaultBadgeLoadError }}</hm-alert>\n } @else {\n <hm-select\n class=\"sp-settings__badge\"\n [label]=\"t.defaultBadge\"\n [labelHidden]=\"true\"\n [value]=\"value()\"\n [disabled]=\"loading() || saving()\"\n (valueChange)=\"save($event ?? '')\"\n >\n <option value=\"\">{{ t.defaultBadgeAuto }}</option>\n @for (b of badges(); track b.id) {\n <option [value]=\"b.id\">{{ b.name }}</option>\n }\n </hm-select>\n }\n `,\n styles: [`:host { display: block; min-width: 0; } .sp-settings__badge { min-inline-size: 14rem; max-inline-size: 100%; }`],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class DefaultBadgeComponent {\n private readonly api = inject(SpineAccountSecurityService);\n private readonly toast = inject(HermesToastService);\n protected readonly t = inject(SPINE_MESSAGES).accountFeatures;\n\n protected readonly badges = signal<{ id: string; name: string }[]>([]);\n protected readonly value = signal('');\n protected readonly loading = signal(true);\n protected readonly saving = signal(false);\n protected readonly loadError = signal(false);\n private readonly select = viewChild(SelectComponent);\n\n constructor() {\n void this.load();\n }\n\n private async load(): Promise<void> {\n try {\n const result = await this.api.badges();\n this.badges.set(result.badges ?? []);\n this.value.set(result.default_badge_id ?? '');\n } catch {\n this.loadError.set(true);\n } finally {\n this.loading.set(false);\n }\n }\n\n protected async save(value: string): Promise<void> {\n const previous = this.value();\n if (value === previous) return;\n this.value.set(value);\n this.saving.set(true);\n try {\n const result = await this.api.setDefaultBadge(value || null);\n this.value.set(result.default_badge_id ?? '');\n this.toast.success(this.t.defaultBadgeSaved);\n } catch {\n this.value.set(previous);\n // O <select> já mostra a escolha recusada: volta ao valor salvo.\n this.select()?.value.set(previous);\n this.toast.error(this.t.defaultBadgeError);\n } finally {\n this.saving.set(false);\n }\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { AlertComponent, ButtonComponent, HermesToastService, IconComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { pluralMessage } from '@trismegisto/primitives';\nimport { SpineAccountSecurityState } from './account-security.state';\nimport { AccountReauthComponent } from './account-reauth.component';\n\nlet sequence = 0;\n\n/**\n * Códigos de recuperação da conta no Argos: quantos restam e \"gerar novos\" (com reautenticação). O lote\n * novo aparece UMA vez (o Argos só guarda o hash), com copiar e baixar em .txt, até a pessoa dizer que\n * guardou — e some quando o painel fecha.\n */\n@Component({\n selector: 'spine-account-recovery-codes',\n imports: [AlertComponent, ButtonComponent, IconComponent, AccountReauthComponent],\n template: `\n @if (state.overview()) {\n @if (state.owner() === 'codes') {\n @if (state.notice(); as notice) {\n <hm-alert variant=\"success\">{{ t.notices[notice] }}</hm-alert>\n }\n @if (state.error(); as error) {\n <hm-alert variant=\"error\">{{ errorText(error) }}</hm-alert>\n }\n }\n\n @if (state.owner() === 'codes' && state.step() === 'reauth') {\n <spine-account-reauth />\n } @else if (state.owner() === 'codes' && state.step() === 'codes' && state.issuedCodes(); as codes) {\n <section class=\"sp-account__panel sp-account__panel--success\" [attr.aria-labelledby]=\"titleId\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"key\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"titleId\">{{ t.codesTitle }}</h4>\n <p class=\"sp-account__note\">{{ t.codesShownOnce }}</p>\n </div>\n </div>\n <ol class=\"sp-account__codes\">\n @for (code of codes; track code) {\n <li><code>{{ code }}</code></li>\n }\n </ol>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"high\" (clicked)=\"state.codesSaved()\">{{ t.codesSaved }}</hm-button>\n <hm-button emphasis=\"medium\" icon=\"copy\" (clicked)=\"copy(codes)\">{{ t.copyCodes }}</hm-button>\n <hm-button emphasis=\"medium\" icon=\"download\" (clicked)=\"download(codes)\">{{ t.downloadCodes }}</hm-button>\n </div>\n </section>\n } @else {\n <ul class=\"sp-account__list\">\n <li class=\"sp-account__item\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"state.remainingCodes() > 0\"><hm-icon shape=\"key\" /></span>\n <span class=\"sp-account__item-main\">\n @if (state.activeMethods().length) {\n <span class=\"sp-account__item-title\"><strong>{{ remaining() }}</strong></span>\n <span class=\"sp-account__meta\">{{ t.codesHint }}</span>\n } @else {\n <span class=\"sp-account__meta\">{{ t.codesNeedMethod }}</span>\n }\n </span>\n @if (state.activeMethods().length) {\n <span class=\"sp-account__item-actions\">\n <hm-button size=\"small\" emphasis=\"medium\" [disabled]=\"state.busy() || state.step() !== 'idle'\" (clicked)=\"state.start({ kind: 'codes' })\">\n {{ state.remainingCodes() ? t.regenerateCodes : t.generateCodes }}\n </hm-button>\n </span>\n }\n </li>\n </ul>\n }\n }\n `,\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AccountRecoveryCodesComponent {\n protected readonly state = inject(SpineAccountSecurityState);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly t = this.messages.accountSecurity;\n private readonly toast = inject(HermesToastService);\n protected readonly titleId = `sp-account-codes-${++sequence}`;\n\n protected readonly remaining = computed(() =>\n pluralMessage(this.t.codesRemaining, this.state.remainingCodes(), this.messages.meta.locale));\n\n protected errorText(code: string): string {\n return (this.t.errors as Record<string, string>)[code] ?? this.t.errors.generic;\n }\n\n private asText(codes: readonly string[]): string {\n return `${this.t.codesFileHeader}\\n\\n${codes.join('\\n')}\\n`;\n }\n\n protected async copy(codes: readonly string[]): Promise<void> {\n try {\n await navigator.clipboard.writeText(this.asText(codes));\n this.toast.success(this.t.codesCopied);\n } catch {\n this.toast.error(this.t.copyFailed);\n }\n }\n\n protected download(codes: readonly string[]): void {\n const url = URL.createObjectURL(new Blob([this.asText(codes)], { type: 'text/plain;charset=utf-8' }));\n const a = document.createElement('a');\n a.href = url;\n a.download = this.t.codesFileName;\n a.click();\n // Revogar no mesmo tick pode cancelar o download em alguns navegadores (o clique só agenda a navegação).\n setTimeout(() => URL.revokeObjectURL(url), 1000);\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport { AlertComponent, ButtonComponent, IconComponent, TagComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES, SpinePreferencesService } from '@trismegisto/spine';\nimport { formatMessage, pluralMessage } from '@trismegisto/primitives';\nimport { AccountSession, SpineAccountSecurityService, accountErrorCode } from './account-security.service';\n\n/**\n * Sessões e dispositivos da conta no Argos, dentro do painel de configurações: onde a conta está\n * conectada (navegador, IP, aplicativos, último uso), com a sessão deste login marcada. Encerra uma\n * sessão (segundo clique confirma) ou todas as outras. A sessão atual não tem \"Encerrar\" aqui: sair dela é\n * o \"Sair\" da seção Conta, que também encerra o app.\n */\n@Component({\n selector: 'spine-account-sessions',\n imports: [AlertComponent, ButtonComponent, IconComponent, TagComponent],\n templateUrl: './account-sessions.component.html',\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AccountSessionsComponent {\n private readonly api = inject(SpineAccountSecurityService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly t = this.messages.accountSecurity;\n private readonly preferences = inject(SpinePreferencesService);\n\n protected readonly loading = signal(true);\n protected readonly loadError = signal('');\n protected readonly sessions = signal<AccountSession[]>([]);\n protected readonly notice = signal('');\n protected readonly error = signal('');\n /** Encerramento aguardando o segundo clique: id da sessão, `others` ou null. */\n protected readonly confirming = signal<string | null>(null);\n protected readonly busy = signal(false);\n\n /** A deste login primeiro; depois as outras, da usada mais recentemente. */\n protected readonly ordered = computed(() =>\n [...this.sessions()].sort((a, b) => Number(b.current) - Number(a.current) || b.last_seen_at.localeCompare(a.last_seen_at)));\n protected readonly others = computed(() => this.sessions().filter((s) => !s.current).length);\n protected readonly othersConfirm = computed(() =>\n pluralMessage(this.t.endOthersConfirm, this.others(), this.messages.meta.locale));\n\n constructor() {\n if (this.api.available) void this.load();\n else this.loading.set(false);\n }\n\n protected async load(): Promise<void> {\n this.loading.set(true);\n try {\n const { sessions } = await this.api.sessions();\n this.sessions.set(sessions ?? []);\n this.loadError.set('');\n } catch (err) {\n this.loadError.set(accountErrorCode(err) || 'generic');\n } finally {\n this.loading.set(false);\n }\n }\n\n protected ask(target: string): void {\n this.notice.set('');\n this.error.set('');\n this.confirming.set(target);\n }\n\n protected cancel(): void {\n this.confirming.set(null);\n }\n\n protected async end(session: AccountSession): Promise<void> {\n if (this.confirming() !== session.id) {\n this.ask(session.id);\n return;\n }\n await this.run(async () => {\n await this.api.endSession(session.id);\n this.notice.set(this.t.sessionEndedNotice);\n });\n }\n\n protected async endOthers(): Promise<void> {\n await this.run(async () => {\n const { ended } = await this.api.endOtherSessions();\n this.notice.set(pluralMessage(this.t.othersEndedNotice, ended, this.messages.meta.locale));\n });\n }\n\n private async run(fn: () => Promise<void>): Promise<void> {\n if (this.busy()) return;\n this.busy.set(true);\n this.error.set('');\n try {\n await fn();\n } catch (err) {\n const code = accountErrorCode(err) || 'generic';\n if (code === 'login_required' || code === 'invalid_token') {\n this.loadError.set(code);\n } else {\n this.error.set(this.errorText(code));\n }\n } finally {\n this.confirming.set(null);\n this.busy.set(false);\n }\n if (!this.loadError()) await this.load();\n }\n\n protected errorText(code: string): string {\n return (this.t.errors as Record<string, string>)[code] ?? this.t.errors.generic;\n }\n\n protected detail(session: AccountSession): string {\n return formatMessage(this.t.sessionDetail, { ip: session.ip || this.t.unknownIp, date: this.date(session.last_seen_at) });\n }\n\n protected since(session: AccountSession): string {\n return formatMessage(this.t.sessionSince, { date: this.date(session.created_at) });\n }\n\n protected apps(session: AccountSession): string {\n return formatMessage(this.t.sessionApps, { apps: session.clients.map((c) => c.name ?? this.t.unnamedApp).join(', ') });\n }\n\n private date(value: string): string {\n return new Intl.DateTimeFormat(this.messages.meta.locale, { dateStyle: 'short', timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() })\n .format(new Date(value));\n }\n}\n","@if (loading() && !sessions().length) {\n <p class=\"sp-account__note\" role=\"status\">{{ t.loading }}</p>\n} @else if (loadError()) {\n <hm-alert variant=\"error\">{{ errorText(loadError()) }}</hm-alert>\n @if (loadError() !== 'login_required' && loadError() !== 'invalid_token') {\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"refresh\" (clicked)=\"load()\">{{ t.retry }}</hm-button>\n </div>\n }\n} @else {\n @if (notice()) {\n <hm-alert variant=\"success\">{{ notice() }}</hm-alert>\n }\n @if (error()) {\n <hm-alert variant=\"error\">{{ error() }}</hm-alert>\n }\n\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\">\n @for (s of ordered(); track s.id) {\n <li class=\"sp-account__item\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"s.current\"><hm-icon [shape]=\"s.device.mobile ? 'mobile' : 'computer'\" /></span>\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\">\n <strong>{{ s.device.label }}</strong>\n @if (s.current) {\n <hm-tag [name]=\"t.thisSession\" color=\"success\" />\n } @else if (s.this_device) {\n <hm-tag [name]=\"t.thisBrowser\" color=\"info\" />\n }\n @if (!s.sso_active) {\n <hm-tag [name]=\"t.appsOnly\" color=\"warning\" />\n }\n </span>\n <span class=\"sp-account__meta\">{{ detail(s) }}</span>\n <span class=\"sp-account__meta\">{{ since(s) }}@if (s.clients.length) { · {{ apps(s) }} }</span>\n </span>\n @if (!s.current) {\n <span class=\"sp-account__item-actions\">\n @if (confirming() === s.id) {\n <hm-button size=\"small\" emphasis=\"medium\" [disabled]=\"busy()\" (clicked)=\"cancel()\">{{ t.cancel }}</hm-button>\n }\n <hm-button size=\"small\" [emphasis]=\"confirming() === s.id ? 'high' : 'medium'\" intent=\"danger\" [loading]=\"busy() && confirming() === s.id\" [disabled]=\"busy() && confirming() !== s.id\" (clicked)=\"end(s)\">\n {{ confirming() === s.id ? t.confirmEndSession : t.endSession }}\n </hm-button>\n </span>\n }\n </li>\n } @empty {\n <li class=\"sp-account__item sp-account__item--empty\">{{ t.sessionsEmpty }}</li>\n }\n </ul>\n\n @if (others() > 0) {\n <div class=\"sp-account__list-footer\">\n @if (confirming() === 'others') {\n <span class=\"sp-account__note\">{{ othersConfirm() }}</span>\n <span class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" [disabled]=\"busy()\" (clicked)=\"cancel()\">{{ t.cancel }}</hm-button>\n <hm-button size=\"small\" emphasis=\"high\" intent=\"danger\" icon=\"logout\" [loading]=\"busy()\" (clicked)=\"endOthers()\">{{ t.endOthers }}</hm-button>\n </span>\n } @else {\n <hm-button size=\"small\" emphasis=\"medium\" intent=\"danger\" icon=\"logout\" [disabled]=\"busy()\" (clicked)=\"ask('others')\">{{ t.endOthers }}</hm-button>\n }\n </div>\n }\n </div>\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, signal, untracked } from '@angular/core';\nimport { FormControl, Validators, ReactiveFormsModule } from '@angular/forms';\nimport {\n ButtonComponent,\n InputComponent,\n HermesToastService,\n IconComponent,\n SegmentedControlComponent,\n SegmentedOption,\n} from '@trismegisto/angular';\nimport { SpinePreferencesService, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { AppToken, SpineAppTokensService } from './app-tokens.service';\nimport { formatMessage, formatMessageHtml } from '@trismegisto/primitives';\n\nlet sequence = 0;\n\n/** Validades oferecidas (dias). O servidor recusa acima de 365 — o CHECK no banco também. */\n\n/**\n * Tokens de aplicação do usuário (seção Conta do painel de configurações): lista, criação e\n * revogação. O valor do token só aparece uma vez, logo depois de criado, e some quando o painel\n * fecha (o componente vive dentro do `@if` do painel).\n */\n@Component({\n selector: 'spine-app-tokens',\n imports: [ReactiveFormsModule, ButtonComponent, InputComponent, IconComponent, SegmentedControlComponent],\n templateUrl: './app-tokens.component.html',\n styleUrl: './settings-blocks.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class AppTokensComponent {\n protected readonly text = inject(SPINE_MESSAGES).appTokens;\n protected readonly fmt = formatMessage;\n /** Para `[innerHTML]`: escapa os parâmetros (o nome da aplicação vem do servidor). */\n protected readonly fmtHtml = formatMessageHtml;\n private readonly locale = inject(SPINE_MESSAGES);\n private readonly service = inject(SpineAppTokensService);\n private readonly toast = inject(HermesToastService);\n private readonly preferences = inject(SpinePreferencesService);\n\n protected readonly available = this.service.available;\n protected readonly ids = `sp-tokens-${++sequence}`;\n protected readonly loading = signal(true);\n protected readonly loadError = signal('');\n protected readonly tokens = signal<AppToken[]>([]);\n protected readonly maxActive = signal(10);\n\n protected readonly validCount = computed(() => this.tokens().filter((t) => !t.expired).length);\n protected readonly atLimit = computed(() => this.validCount() >= this.maxActive());\n\n // ── criação ─────────────────────────────────────────────────────────────────\n protected readonly creating = signal(false);\n protected readonly submitting = signal(false);\n /** Nome da aplicação logada (a única para a qual dá pra criar token aqui). */\n protected readonly clientName = signal('');\n protected readonly badges = signal<{ id: string; name: string }[]>([]);\n protected readonly badgeId = signal('');\n protected readonly validity = signal('90');\n protected readonly nameControl = new FormControl('', { nonNullable: true, validators: [Validators.required, Validators.maxLength(80)] });\n protected readonly validityOptions = computed<readonly SegmentedOption[]>(() => [\n { value: '30', label: this.text.days30 },\n { value: '90', label: this.text.days90 },\n { value: '180', label: this.text.months6 },\n { value: '365', label: this.text.year1 },\n ]);\n\n protected readonly badgeOptions = computed<SegmentedOption[]>(() =>\n this.badges().map((b) => ({ value: b.id, label: b.name })),\n );\n\n /** Token recém-criado, mostrado uma única vez. */\n protected readonly created = signal<{ name: string; token: string; expiresAt: string } | null>(null);\n /** Token com a revogação aguardando confirmação (segundo clique). */\n protected readonly confirmingRevoke = signal<string | null>(null);\n\n constructor() {\n if (this.available) void this.load();\n else this.loading.set(false);\n // Token criado em outro lugar do painel (\"Conectar um agente de IA\"): relê a lista. O que esta lista cria já relê.\n let seen = this.service.changes();\n effect(() => {\n const changes = this.service.changes();\n if (changes === seen) return;\n seen = changes;\n if (!untracked(this.submitting)) void untracked(() => this.load());\n });\n }\n\n private async load(): Promise<void> {\n this.loading.set(true);\n this.loadError.set('');\n try {\n const list = await this.service.list();\n this.tokens.set(list.tokens);\n this.maxActive.set(list.max_active);\n } catch (err) {\n this.loadError.set(this.errorText(err, this.text.loadError));\n } finally {\n this.loading.set(false);\n }\n }\n\n protected async startCreate(): Promise<void> {\n this.created.set(null);\n this.nameControl.reset('');\n this.validity.set('90');\n this.creating.set(true);\n try {\n const { client, badges } = await this.service.options();\n this.clientName.set(client.name ?? '');\n this.badges.set(badges);\n // Um nível só: já vem escolhido. Vários: o de maior nível vem primeiro (ordem do servidor).\n this.badgeId.set(badges[0]?.id ?? '');\n } catch (err) {\n this.toast.error(this.errorText(err, this.text.badgesError));\n this.creating.set(false);\n }\n }\n\n protected cancelCreate(): void {\n this.creating.set(false);\n }\n\n protected readonly canSubmit = computed(() => !!this.badgeId() && !this.submitting());\n\n protected async submit(): Promise<void> {\n this.nameControl.markAsTouched();\n if (!this.canSubmit() || this.nameControl.invalid) return;\n this.submitting.set(true);\n try {\n const name = this.nameControl.value.trim();\n const result = await this.service.create({\n badge_id: this.badgeId(),\n name,\n validity_days: Number(this.validity()),\n });\n this.created.set({ name, token: result.token, expiresAt: result.expires_at });\n this.creating.set(false);\n await this.load();\n } catch (err) {\n this.toast.error(this.errorText(err, this.text.createError));\n } finally {\n this.submitting.set(false);\n }\n }\n\n protected async copyCreated(): Promise<void> {\n const token = this.created()?.token;\n if (!token) return;\n try {\n await navigator.clipboard.writeText(token);\n this.toast.success(this.text.copied);\n } catch {\n this.toast.error(this.text.copyFailed);\n }\n }\n\n protected dismissCreated(): void {\n this.created.set(null);\n }\n\n protected async revoke(token: AppToken): Promise<void> {\n if (this.confirmingRevoke() !== token.id) {\n this.confirmingRevoke.set(token.id);\n return;\n }\n this.confirmingRevoke.set(null);\n try {\n await this.service.revoke(token.id);\n this.tokens.update((list) => list.filter((t) => t.id !== token.id));\n this.toast.success(formatMessage(this.text.revoked, { name: token.name }));\n } catch (err) {\n this.toast.error(this.errorText(err, this.text.revokeError));\n }\n }\n\n protected cancelRevoke(): void {\n this.confirmingRevoke.set(null);\n }\n\n protected formatDate(value: string | null): string {\n if (!value) return this.text.never;\n return new Intl.DateTimeFormat(this.locale.meta.locale, { dateStyle: 'short', timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() })\n .format(new Date(value));\n }\n\n private errorText(err: unknown, fallback: string): string {\n const detail = err instanceof HttpErrorResponse ? (err.error?.detail as string | undefined) : undefined;\n return detail || fallback;\n }\n}\n","@if (!available) {\n <p class=\"sp-account__note\">{{ text.unavailable }}</p>\n} @else {\n <!-- Token recém-criado: única vez em que o valor aparece. -->\n @if (created(); as c) {\n <section class=\"sp-account__panel sp-account__panel--success\" role=\"status\" [attr.aria-labelledby]=\"ids + '-created'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"check-circle\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-created'\">{{ fmt(text.created, { name: c.name }) }}</h4>\n <p class=\"sp-account__note\" [innerHTML]=\"fmtHtml(text.sendHeader, { date: formatDate(c.expiresAt) })\"></p>\n </div>\n </div>\n <code class=\"sp-account__secret sp-account__secret--block\">{{ c.token }}</code>\n <div class=\"sp-account__actions\">\n <hm-button emphasis=\"high\" icon=\"copy\" (clicked)=\"copyCreated()\">{{ text.copyToken }}</hm-button>\n <hm-button emphasis=\"medium\" (clicked)=\"dismissCreated()\">{{ text.saved }}</hm-button>\n </div>\n </section>\n }\n\n @if (loading()) {\n <p class=\"sp-account__note\" role=\"status\">{{ text.loading }}</p>\n } @else if (loadError()) {\n <p class=\"sp-account__note sp-account__note--error\">{{ loadError() }}</p>\n } @else {\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\">\n @for (t of tokens(); track t.id) {\n <li class=\"sp-account__item\" [class.sp-account__item--muted]=\"t.expired\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"!t.expired\"><hm-icon shape=\"key\" /></span>\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\"><strong>{{ t.name }}</strong></span>\n <span class=\"sp-account__meta\">{{ t.badge_name }} · <code>{{ t.prefix }}</code></span>\n <span class=\"sp-account__meta\">\n @if (t.expired) { <span class=\"sp-account__meta--danger\">{{ fmt(text.expiredOn, { date: formatDate(t.expires_at) }) }}</span> }\n @else { {{ fmt(text.expiresOn, { date: formatDate(t.expires_at) }) }} }\n · {{ fmt(text.lastUsed, { date: formatDate(t.last_used_at) }) }}\n </span>\n </span>\n <span class=\"sp-account__item-actions\">\n @if (confirmingRevoke() === t.id) {\n <hm-button size=\"small\" emphasis=\"medium\" (clicked)=\"cancelRevoke()\">{{ text.cancel }}</hm-button>\n }\n <hm-button size=\"small\" [emphasis]=\"confirmingRevoke() === t.id ? 'high' : 'medium'\" intent=\"danger\" (clicked)=\"revoke(t)\">\n {{ confirmingRevoke() === t.id ? text.confirmRevoke : text.revoke }}\n </hm-button>\n </span>\n </li>\n } @empty {\n <li class=\"sp-account__item sp-account__item--empty\">{{ text.empty }}</li>\n }\n </ul>\n\n @if (!creating()) {\n <div class=\"sp-account__list-footer\">\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"plus\" [disabled]=\"atLimit()\" (clicked)=\"startCreate()\">{{ text.newToken }}</hm-button>\n <span class=\"sp-account__note\">{{ atLimit() ? text.limit : fmt(text.validCount, { valid: validCount(), max: maxActive() }) }}</span>\n </div>\n }\n </div>\n\n @if (creating()) {\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"ids + '-new'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"key\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-new'\">{{ text.newToken }}</h4>\n @if (clientName()) {\n <p class=\"sp-account__note\" [innerHTML]=\"fmtHtml(text.appOnly, { name: clientName() })\"></p>\n }\n </div>\n </div>\n <form class=\"sp-account__form\" (submit)=\"$event.preventDefault(); submit()\">\n @if (!badges().length) {\n <p class=\"sp-account__note\">{{ text.noBadges }}</p>\n } @else {\n @if (badgeOptions().length > 1) {\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ text.accessLevel }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"text.accessLevel\" [options]=\"badgeOptions()\" [value]=\"badgeId()\" (valueChange)=\"badgeId.set($event)\" />\n </div>\n }\n <hm-input [label]=\"text.name\" [placeholder]=\"text.namePlaceholder\" [formControl]=\"nameControl\" [messages]=\"{ required: text.nameRequired, maxlength: text.nameMax }\" />\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ text.validity }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"text.validity\" [options]=\"validityOptions()\" [value]=\"validity()\" (valueChange)=\"validity.set($event)\" />\n </div>\n }\n <div class=\"sp-account__actions\">\n @if (badges().length) {\n <hm-button type=\"submit\" emphasis=\"high\" icon=\"key\" [disabled]=\"!canSubmit()\" [loading]=\"submitting()\">{{ text.create }}</hm-button>\n }\n <hm-button emphasis=\"medium\" (clicked)=\"cancelCreate()\">{{ text.cancel }}</hm-button>\n </div>\n </form>\n </section>\n }\n }\n}\n","// Mesma peça de argos admin/ui src/shared/members-loader.ts (o painel central usa a dele). Interna deste ponto de\n// entrada: não vai no public-api.\nimport { computed, signal } from '@angular/core';\nimport { Observable, Subscription } from 'rxjs';\n\n/** Membros por página pedidos ao servidor: o teto das rotas `GET …/members` do argos-admin. */\nexport const MEMBERS_PAGE_LIMIT = 200;\n\n/** Uma página como as rotas `GET …/members` devolvem. */\nexport interface MembersPageLike<T> {\n members?: T[];\n total?: number;\n}\n\n/** Pede a página `page` (1..) ao servidor. */\nexport interface MembersPageFetcher<T> {\n (page: number): Observable<MembersPageLike<T>>;\n}\n\n/**\n * Lista inteira de membros carregada aos poucos: o servidor pagina (nunca monta o grupo inteiro em memória) e a tela\n * pede as páginas uma depois da outra, acrescentando conforme chegam, até ter o `total` (ou vir uma página vazia). A\n * lista já aparece e funciona com a primeira página; `loading` diz que ainda há páginas a caminho.\n *\n * `cancel()` desfaz a inscrição da requisição pendente (o HttpClient a cancela); chame ao fechar a tela ou trocar de\n * grupo. Falha numa página para em `error`, com o que já chegou intacto; `retry()` continua da página que falhou.\n */\nexport class MembersLoader<T> {\n readonly items = signal<readonly T[]>([]);\n /** Total do servidor (o grupo inteiro). */\n readonly total = signal(0);\n /** Ainda pedindo páginas. */\n readonly loading = signal(false);\n /** A primeira página já chegou (antes dela a tela mostra o estado de carregando). */\n readonly ready = signal(false);\n readonly error = signal<unknown>(null);\n readonly loaded = computed(() => this.items().length);\n\n private current: Subscription | null = null;\n private nextPage = 1;\n private readonly ids = new Set<string>();\n\n constructor(\n private readonly fetchPage: MembersPageFetcher<T>,\n private readonly idOf: (item: T) => string,\n ) {}\n\n /** Recomeça do zero (cancela o que estava a caminho). */\n start(): void {\n this.cancel();\n this.items.set([]);\n this.ids.clear();\n this.total.set(0);\n this.ready.set(false);\n this.error.set(null);\n this.nextPage = 1;\n this.fetchNext();\n }\n\n /** Depois de uma falha: continua da página que falhou, sem perder o que já chegou. */\n retry(): void {\n if (this.loading()) return;\n this.error.set(null);\n this.fetchNext();\n }\n\n cancel(): void {\n this.current?.unsubscribe();\n this.current = null;\n this.loading.set(false);\n }\n\n /**\n * Mudança feita pela própria tela depois de gravar (incluir, remover, trocar função), sem reler: `totalDelta` mantém o\n * total coerente com a lista.\n */\n patch(change: (items: readonly T[]) => readonly T[], totalDelta = 0): void {\n const next = change(this.items());\n this.ids.clear();\n for (const item of next) this.ids.add(this.idOf(item));\n this.items.set(next);\n this.total.update((n) => Math.max(next.length, n + totalDelta));\n }\n\n private fetchNext(): void {\n this.loading.set(true);\n // A continuação (próxima página) roda no `complete`; com uma resposta síncrona ela começa antes do `subscribe`\n // devolver, por isso a inscrição vai num contêiner criado antes.\n const holder = new Subscription();\n this.current = holder;\n let more = false;\n holder.add(this.fetchPage(this.nextPage).subscribe({\n next: (res) => {\n const page = res.members ?? [];\n const fresh = page.filter((item) => !this.ids.has(this.idOf(item)));\n for (const item of fresh) this.ids.add(this.idOf(item));\n if (fresh.length) this.items.update((list) => [...list, ...fresh]);\n this.total.set(Math.max(res.total ?? 0, this.items().length));\n this.ready.set(true);\n this.nextPage += 1;\n // Página vazia, ou só com quem já chegou (o servidor mudou no meio), encerra: sem isso a carga não teria fim.\n more = fresh.length > 0 && this.items().length < this.total();\n },\n error: (err) => {\n if (this.current !== holder) return;\n this.current = null;\n this.error.set(err);\n this.ready.set(true);\n this.loading.set(false);\n },\n complete: () => {\n if (this.current !== holder) return;\n if (more) {\n this.fetchNext();\n } else {\n this.current = null;\n this.loading.set(false);\n }\n },\n }));\n }\n}\n","import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';\nimport { Injectable, inject, signal } from '@angular/core';\nimport { Observable, firstValueFrom } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { SPINE_ADMIN_API } from '@trismegisto/spine';\nimport { urlPath } from '@trismegisto/primitives';\n\n/** Função da pessoa no grupo, como o Argos guarda. Sem função (null) é o membro comum, que só vê os outros. */\nexport type GroupRole = 'Administrador' | 'Editor';\n\n/** Um grupo desta aplicação de que a pessoa é membro, com o que a função dela permite (decidido pelo servidor). */\nexport interface ManagedGroup {\n id: string;\n name: string;\n description: string | null;\n enabled: boolean;\n type: { id: string; name: string; level: number };\n my_role: GroupRole | null;\n /** Inclui pessoas (Administrador e Editor). */\n can_add: boolean;\n /** Funções que a pessoa pode dar a quem inclui, além de \"sem função\" (Administrador: as duas; Editor: nenhuma). */\n assignable_roles: GroupRole[];\n /** Só Administrador troca a função dos outros membros. */\n can_change_roles: boolean;\n /** Resumo dos membros (servidor que já manda): total e os primeiros, com foto. */\n members_count?: number;\n members_preview?: { user_id: string; username: string; name: string | null; picture: string | null }[];\n}\n\nexport interface GroupMember {\n user_id: string;\n username: string;\n email: string | null;\n name: string | null;\n enabled: boolean;\n role: GroupRole | null;\n picture: string | null;\n joined_at: string | null;\n added_by_username: string | null;\n}\n\n/** Página e filtros da lista de membros (o servidor pagina: padrão 50, até 200 por página). */\nexport interface GroupMembersQuery {\n page?: number;\n limit?: number;\n /** Trecho do nome, do login ou do e-mail. */\n search?: string;\n}\n\n/** Uma página de membros, com a função de quem pede e o que ela permite (como em `ManagedGroup`). */\nexport interface GroupMembersPage {\n my_role: GroupRole | null;\n can_add: boolean;\n assignable_roles: GroupRole[];\n can_change_roles: boolean;\n members: GroupMember[];\n /** Quantos passam pela busca (sem busca, o grupo inteiro). */\n total: number;\n page: number;\n limit: number;\n}\n\nexport interface RealmUser {\n id: string;\n username: string;\n email: string | null;\n name: string | null;\n enabled: boolean;\n /** Foto (o argos-admin já manda com a busca): a pessoa incluída entra na lista com ela. */\n picture?: string | null;\n}\n\n/**\n * Grupos de que a pessoa é membro e o que a função dela permite — `argos-admin /me/groups`. Sempre da aplicação LOGADA (o\n * servidor tira o client do access-token da sessão) e sempre com o token da sessão (o servidor recusa x-app-token).\n * A regra de quem faz o quê é do servidor; aqui só se mostra o que ele diz (`can_add`, `assignable_roles`,\n * `can_change_roles`).\n *\n * `groups` é a lista que decide se a seção \"Grupos\" aparece: lida a cada abertura do painel (`refresh`). Sem\n * `SPINE_ADMIN_API`, ou com um argos-admin que ainda não tem a rota, fica vazia e a seção não aparece.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineMyGroupsService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly adminApi = inject(SPINE_ADMIN_API, { optional: true });\n\n readonly available = !!this.adminApi;\n readonly groups = signal<ManagedGroup[]>([]);\n\n private get baseUrl(): string {\n return `${this.adminApi}/me/groups`;\n }\n\n private get headers(): HttpHeaders {\n return new HttpHeaders({ 'x-access-token': this.auth.getToken() ?? '' });\n }\n\n /** Relê os grupos; qualquer falha deixa a lista vazia (a seção some em vez de mostrar um erro sem contexto). */\n async refresh(): Promise<void> {\n if (!this.available) return;\n try {\n const res = await firstValueFrom(this.http.get<{ groups: ManagedGroup[] }>(this.baseUrl, { headers: this.headers }));\n this.groups.set(res.groups ?? []);\n } catch {\n this.groups.set([]);\n }\n }\n\n /**\n * Uma página dos membros, pela ordem do login. Observable (não Promise): a tela pede as páginas até o fim e cancela a\n * pendente ao sair.\n */\n members(groupId: string, query: GroupMembersQuery = {}): Observable<GroupMembersPage> {\n let params = new HttpParams();\n if (query.page) params = params.set('page', query.page);\n if (query.limit) params = params.set('limit', query.limit);\n if (query.search?.trim()) params = params.set('search', query.search.trim());\n return this.http.get<GroupMembersPage>(`${this.baseUrl}${urlPath`/${groupId}/members`}`, { headers: this.headers, params });\n }\n\n searchUsers(search: string, limit = 10): Promise<{ users: RealmUser[] }> {\n return firstValueFrom(this.http.get<{ users: RealmUser[] }>(`${this.baseUrl}/users`, {\n headers: this.headers,\n params: { search, limit },\n }));\n }\n\n /** `role` ausente ou null: entra sem função (o único jeito de o Editor incluir). */\n addMember(groupId: string, userId: string, role: GroupRole | null = null): Promise<void> {\n const body = role === null ? { user_id: userId } : { user_id: userId, role };\n return firstValueFrom(this.http.post<void>(`${this.baseUrl}${urlPath`/${groupId}/members`}`, body, { headers: this.headers }));\n }\n\n updateRole(groupId: string, userId: string, role: GroupRole | null): Promise<void> {\n return firstValueFrom(this.http.put<void>(`${this.baseUrl}${urlPath`/${groupId}/members/${userId}`}`, { role }, { headers: this.headers }));\n }\n\n removeMember(groupId: string, userId: string): Promise<void> {\n return firstValueFrom(this.http.delete<void>(`${this.baseUrl}${urlPath`/${groupId}/members/${userId}`}`, { headers: this.headers }));\n }\n}\n","import { HttpErrorResponse } from '@angular/common/http';\nimport { ChangeDetectionStrategy, Component, DestroyRef, OnInit, computed, inject, input, signal } from '@angular/core';\nimport { takeUntilDestroyed, toSignal } from '@angular/core/rxjs-interop';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\nimport { debounceTime, distinctUntilChanged } from 'rxjs';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport {\n AccountAvatarComponent,\n ButtonComponent,\n HermesI18nService,\n HermesToastService,\n IconComponent,\n InputComponent,\n SegmentedControlComponent,\n SegmentedOption,\n SelectComponent,\n TagComponent,\n} from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { formatMessage, pluralMessage } from '@trismegisto/primitives';\nimport { MEMBERS_PAGE_LIMIT, MembersLoader } from './members-loader';\nimport { GroupMember, GroupRole, ManagedGroup, RealmUser, SpineMyGroupsService } from './my-groups.service';\n\nlet sequence = 0;\n\n/** Valor do seletor de função para o membro sem função (o `<option>` não carrega null). */\nconst MEMBER = '';\n\n/** Nome da função na tela: sem função é \"Membro\". */\nexport function groupRoleLabel(text: { roleAdministrator: string; roleEditor: string; roleMember: string }, role: GroupRole | null): string {\n if (role === 'Administrador') return text.roleAdministrator;\n if (role === 'Editor') return text.roleEditor;\n return text.roleMember;\n}\n\n/**\n * Membros de um grupo (tela de membros da seção \"Grupos\"), com o que a função da pessoa permite: Administrador inclui\n * com qualquer função, troca funções e remove qualquer um menos a si mesmo; Editor inclui como Membro e remove só\n * Membros; Membro só vê. \"Incluir membro\" fica acima da lista. Cada ação vale na hora (como os tokens e as sessões do\n * painel); remover pede confirmação. A regra é do servidor: os botões só aparecem onde ele aceitaria, e um 403/409 que\n * venha mesmo assim vira aviso.\n *\n * A lista inteira vem do servidor em páginas, uma depois da outra (`MembersLoader`), e já funciona com a primeira; a\n * busca é local e instantânea sobre o que já chegou.\n */\n@Component({\n selector: 'spine-my-group',\n imports: [\n ReactiveFormsModule, AccountAvatarComponent, ButtonComponent, IconComponent, InputComponent, SegmentedControlComponent,\n SelectComponent, TagComponent,\n ],\n templateUrl: './my-group.component.html',\n styleUrls: ['./settings-blocks.scss', './my-group.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MyGroupComponent implements OnInit {\n readonly group = input.required<ManagedGroup>();\n\n protected readonly text = inject(SPINE_MESSAGES).myGroups;\n protected readonly fmt = formatMessage;\n private readonly service = inject(SpineMyGroupsService);\n private readonly toast = inject(HermesToastService);\n private readonly i18n = inject(HermesI18nService);\n private readonly auth = inject(AuthorizationService);\n\n protected readonly ids = `sp-group-${++sequence}`;\n /** Todos os membros, carregados aos poucos (o servidor pagina; aqui se pede até o fim). */\n protected readonly loader = new MembersLoader<GroupMember>(\n (page) => this.service.members(this.group().id, { page, limit: MEMBERS_PAGE_LIMIT }),\n (m) => m.user_id.toLowerCase(),\n );\n /** Busca na lista: local e instantânea (nome, login, e-mail). */\n protected readonly filterControl = new FormControl('', { nonNullable: true });\n protected readonly filter = toSignal(this.filterControl.valueChanges, { initialValue: '' });\n /** Membro com a remoção aguardando confirmação (segundo clique). */\n protected readonly confirmingRemove = signal<string | null>(null);\n /** Membro com uma troca de função ou remoção em andamento. */\n protected readonly busy = signal<string | null>(null);\n\n /** `sub` da sessão, para marcar \"você\" e não oferecer ações sobre si mesmo. */\n private readonly me = (tokenSub(this.auth.getToken()) ?? '').toLowerCase();\n\n protected readonly members = computed(() => {\n const term = this.filter().trim().toLowerCase();\n const all = this.loader.items();\n if (!term) return all;\n return all.filter((m) => [m.name, m.username, m.email].some((v) => (v ?? '').toLowerCase().includes(term)));\n });\n\n protected readonly countLabel = computed(() => {\n const locale = this.i18n.formatLocale();\n return this.filter().trim()\n ? pluralMessage(this.text.matchesCount, this.members().length, locale)\n : pluralMessage(this.text.membersCount, this.loader.total(), locale);\n });\n\n /** \"Carregando membros… 400 de 1.250\". */\n protected readonly progressLabel = computed(() => {\n const number = new Intl.NumberFormat(this.i18n.formatLocale());\n return formatMessage(this.text.loadingProgress, { loaded: number.format(this.loader.loaded()), total: number.format(this.loader.total()) });\n });\n\n protected readonly incompleteLabel = computed(() => {\n const number = new Intl.NumberFormat(this.i18n.formatLocale());\n return formatMessage(this.text.loadIncomplete, { loaded: number.format(this.loader.loaded()), total: number.format(this.loader.total()) });\n });\n\n /** Funções que o Administrador escolhe (seletor de cada membro e inclusão): Membro, Editor, Administrador. */\n protected readonly roleOptions = computed<readonly SegmentedOption[]>(() => [\n { value: MEMBER, label: this.text.roleMember },\n ...[...this.group().assignable_roles].reverse().map((r) => ({ value: r as string, label: this.roleLabel(r) })),\n ]);\n\n // ── inclusão ────────────────────────────────────────────────────────────────\n protected readonly adding = signal(false);\n protected readonly searchControl = new FormControl('', { nonNullable: true });\n protected readonly searching = signal(false);\n protected readonly searchError = signal('');\n protected readonly results = signal<RealmUser[] | null>(null);\n protected readonly selected = signal<RealmUser | null>(null);\n protected readonly newRole = signal<string>(MEMBER);\n protected readonly submitting = signal(false);\n private readonly memberIds = computed(() => new Set(this.loader.items().map((m) => m.user_id.toLowerCase())));\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n this.searchControl.valueChanges\n .pipe(debounceTime(300), distinctUntilChanged(), takeUntilDestroyed(destroyRef))\n .subscribe((value) => void this.search(value));\n // Sair da tela (voltar aos grupos, fechar o painel) cancela a página que estiver a caminho.\n destroyRef.onDestroy(() => this.loader.cancel());\n }\n\n ngOnInit(): void {\n this.loader.start();\n }\n\n protected roleLabel(role: GroupRole | null): string {\n return groupRoleLabel(this.text, role);\n }\n\n protected isMe(member: GroupMember): boolean {\n return member.user_id.toLowerCase() === this.me;\n }\n\n /** Já é membro? Com a lista ainda carregando, quem não chegou passa (e o servidor responde \"já é membro\"). */\n protected isMember(user: RealmUser): boolean {\n return this.memberIds().has(user.id.toLowerCase());\n }\n\n /** Mesma regra do servidor: Administrador remove qualquer um menos a si mesmo; Editor, só Membros. */\n protected canRemove(member: GroupMember): boolean {\n if (this.isMe(member)) return false;\n const role = this.group().my_role;\n return role === 'Administrador' || (role === 'Editor' && member.role === null);\n }\n\n protected canChangeRole(member: GroupMember): boolean {\n return this.group().can_change_roles && !this.isMe(member);\n }\n\n /**\n * Depois de gravar: muda a lista na tela, sem reler. Inclusão e remoção deslocam as páginas do servidor, então com a\n * carga ainda em andamento ela recomeça do zero (senão alguém ficaria de fora ou repetido).\n */\n private afterWrite(change: (items: readonly GroupMember[]) => readonly GroupMember[], totalDelta: number): void {\n if (totalDelta !== 0 && this.loader.loading()) this.loader.start();\n else this.loader.patch(change, totalDelta);\n }\n\n protected async changeRole(member: GroupMember, value: string | null): Promise<void> {\n const role = (value || null) as GroupRole | null;\n if (role === member.role) return;\n this.busy.set(member.user_id);\n try {\n await this.service.updateRole(this.group().id, member.user_id, role);\n this.afterWrite((list) => list.map((m) => (m.user_id === member.user_id ? { ...m, role } : m)), 0);\n this.toast.success(formatMessage(this.text.roleChanged, { name: displayName(member), role: this.roleLabel(role) }));\n } catch (err) {\n this.toast.error(errorText(err, this.text.roleError));\n this.loader.start();\n } finally {\n this.busy.set(null);\n }\n }\n\n protected async remove(member: GroupMember): Promise<void> {\n if (this.confirmingRemove() !== member.user_id) {\n this.confirmingRemove.set(member.user_id);\n return;\n }\n this.confirmingRemove.set(null);\n this.busy.set(member.user_id);\n try {\n await this.service.removeMember(this.group().id, member.user_id);\n this.afterWrite((list) => list.filter((m) => m.user_id !== member.user_id), -1);\n this.toast.success(formatMessage(this.text.removed, { name: displayName(member) }));\n } catch (err) {\n this.toast.error(errorText(err, this.text.removeError));\n this.loader.start();\n } finally {\n this.busy.set(null);\n }\n }\n\n protected cancelRemove(): void {\n this.confirmingRemove.set(null);\n }\n\n protected startAdd(): void {\n this.searchControl.setValue('', { emitEvent: false });\n this.results.set(null);\n this.selected.set(null);\n this.searchError.set('');\n this.newRole.set(MEMBER);\n this.adding.set(true);\n }\n\n protected cancelAdd(): void {\n this.adding.set(false);\n }\n\n private async search(value: string): Promise<void> {\n const term = value.trim();\n this.selected.set(null);\n this.searchError.set('');\n if (term.length < 2) {\n this.results.set(null);\n return;\n }\n this.searching.set(true);\n try {\n const res = await this.service.searchUsers(term);\n // Resposta de uma busca antiga (a pessoa continuou digitando): descarta.\n if (this.searchControl.value.trim() === term) this.results.set(res.users ?? []);\n } catch (err) {\n this.results.set(null);\n this.searchError.set(errorText(err, this.text.searchError));\n } finally {\n this.searching.set(false);\n }\n }\n\n protected pick(user: RealmUser): void {\n if (!this.isMember(user)) this.selected.set(user);\n }\n\n protected async submitAdd(): Promise<void> {\n const user = this.selected();\n if (!user || this.submitting()) return;\n this.submitting.set(true);\n try {\n // Editor não escolhe: entra como Membro (sem função).\n const role = this.group().can_change_roles ? ((this.newRole() || null) as GroupRole | null) : null;\n await this.service.addMember(this.group().id, user.id, role);\n this.toast.success(formatMessage(this.text.added, { name: user.name || user.username }));\n this.adding.set(false);\n const added: GroupMember = {\n user_id: user.id, username: user.username, email: user.email, name: user.name, enabled: user.enabled, role,\n picture: user.picture ?? null, joined_at: new Date().toISOString(), added_by_username: null,\n };\n // Entra na posição do login, como o servidor ordena.\n this.afterWrite((list) => [...list, added].sort((a, b) => a.username.localeCompare(b.username)), 1);\n } catch (err) {\n this.toast.error(errorText(err, this.text.addError));\n } finally {\n this.submitting.set(false);\n }\n }\n}\n\nfunction displayName(member: { name: string | null; username: string }): string {\n return member.name || member.username;\n}\n\nfunction errorText(err: unknown, fallback: string): string {\n const detail = err instanceof HttpErrorResponse ? (err.error?.detail as string | undefined) : undefined;\n return detail || fallback;\n}\n\n/** `sub` do payload do token da sessão (só leitura, sem validar: serve para marcar \"você\" na lista). */\nfunction tokenSub(token: string | null): string | null {\n const payload = token?.split('.')[1];\n if (!payload) return null;\n try {\n const json = atob(payload.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(payload.length / 4) * 4, '='));\n const sub = (JSON.parse(json) as Record<string, unknown>)['sub'];\n return typeof sub === 'string' ? sub : null;\n } catch {\n return null;\n }\n}\n","<!-- Incluir membro fica acima da lista: o botão, ou o painel de inclusão aberto no lugar dele. -->\n@if (group().can_add) {\n @if (adding()) {\n <section class=\"sp-account__panel\" [attr.aria-labelledby]=\"ids + '-add'\">\n <div class=\"sp-account__panel-head\">\n <hm-icon shape=\"assign-user\" />\n <div class=\"sp-account__panel-text\">\n <h4 class=\"sp-account__title\" [id]=\"ids + '-add'\">{{ fmt(text.addHeading, { group: group().name }) }}</h4>\n @if (!group().can_change_roles) {\n <p class=\"sp-account__note\">{{ text.editorAddsMembers }}</p>\n }\n </div>\n </div>\n <form class=\"sp-account__form\" (submit)=\"$event.preventDefault(); submitAdd()\">\n <hm-input\n icon=\"search\"\n autocomplete=\"off\"\n [label]=\"text.search\"\n [placeholder]=\"text.searchPlaceholder\"\n [hint]=\"text.searchHint\"\n [formControl]=\"searchControl\"\n />\n\n @if (searching()) {\n <p class=\"sp-account__note\" role=\"status\">{{ text.searching }}</p>\n } @else if (searchError()) {\n <p class=\"sp-account__note sp-account__note--error\">{{ searchError() }}</p>\n } @else if (results(); as list) {\n @if (list.length) {\n <ul class=\"sp-account__list sp-group__results\" [attr.aria-label]=\"text.search\">\n @for (u of list; track u.id) {\n <li>\n <button\n type=\"button\"\n class=\"sp-group__result\"\n [class.sp-group__result--selected]=\"selected()?.id === u.id\"\n [attr.aria-pressed]=\"selected()?.id === u.id\"\n [disabled]=\"isMember(u)\"\n (click)=\"pick(u)\"\n >\n <strong>{{ u.name || u.username }}</strong>\n <span class=\"sp-account__meta\">{{ u.username }}@if (u.email) { · {{ u.email }} }@if (isMember(u)) { · {{ text.alreadyMember }} }</span>\n </button>\n </li>\n }\n </ul>\n } @else {\n <p class=\"sp-account__note\" role=\"status\">{{ text.noResults }}</p>\n }\n }\n\n @if (group().can_change_roles) {\n <div class=\"sp-account__field\">\n <span class=\"sp-account__label\">{{ text.role }}</span>\n <hm-segmented-control emphasis=\"action\" [label]=\"text.role\" [options]=\"roleOptions()\" [value]=\"newRole()\" (valueChange)=\"newRole.set($event)\" />\n </div>\n }\n\n <div class=\"sp-account__actions\">\n <hm-button type=\"submit\" emphasis=\"high\" icon=\"plus\" [disabled]=\"!selected()\" [loading]=\"submitting()\">{{ text.add }}</hm-button>\n <hm-button emphasis=\"medium\" (clicked)=\"cancelAdd()\">{{ text.cancel }}</hm-button>\n </div>\n </form>\n </section>\n } @else {\n <div class=\"sp-account__actions\">\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"plus\" (clicked)=\"startAdd()\">{{ text.addMember }}</hm-button>\n </div>\n }\n} @else {\n <p class=\"sp-account__note\">{{ text.readOnly }}</p>\n}\n\n<!-- Busca na lista: local e instantânea sobre o que já chegou. Fica fora do \"carregando\" para não perder o foco. -->\n<hm-input\n class=\"sp-group__filter\"\n icon=\"search\"\n type=\"search\"\n autocomplete=\"off\"\n [label]=\"text.filterMembers\"\n [placeholder]=\"text.searchPlaceholder\"\n [formControl]=\"filterControl\"\n/>\n\n@if (loader.error()) {\n <!-- Falha numa página: o que já chegou continua na lista; \"Tentar de novo\" segue de onde parou. -->\n <div class=\"sp-group__status\">\n <p class=\"sp-account__note sp-account__note--error\">{{ loader.loaded() ? incompleteLabel() : text.loadError }}</p>\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"refresh\" (clicked)=\"loader.retry()\">{{ text.retry }}</hm-button>\n </div>\n} @else if (loader.loading() && loader.ready()) {\n <p class=\"sp-account__note sp-group__status\" role=\"status\">\n {{ progressLabel() }}@if (filter().trim()) { · {{ text.partialResults }} }\n </p>\n}\n\n@if (!loader.ready()) {\n <p class=\"sp-account__note\" role=\"status\">{{ text.loading }}</p>\n} @else if (loader.loaded() || !loader.error()) {\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\" [attr.aria-label]=\"group().name\">\n @for (m of members(); track m.user_id) {\n <li class=\"sp-account__item\" [class.sp-account__item--muted]=\"!m.enabled\">\n <hm-account-avatar class=\"sp-group__avatar\" [name]=\"m.name || m.username\" [imageUrl]=\"m.picture\" />\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\">\n <strong>{{ m.name || m.username }}</strong>\n @if (isMe(m)) { <hm-tag color=\"info\" [name]=\"text.you\" /> }\n </span>\n <span class=\"sp-account__meta\">{{ m.username }}@if (m.email) { · {{ m.email }} }</span>\n @if (!canChangeRole(m)) {\n <span class=\"sp-account__meta\">{{ roleLabel(m.role) }}</span>\n }\n </span>\n @if (canChangeRole(m) || canRemove(m)) {\n <span class=\"sp-account__item-actions\">\n <!-- Confirmando a remoção, a linha mostra só Cancelar e Confirmar (a função não importa mais). -->\n @if (canChangeRole(m) && confirmingRemove() !== m.user_id) {\n <hm-select\n class=\"sp-group__role\"\n [label]=\"fmt(text.roleOf, { name: m.name || m.username })\"\n [labelHidden]=\"true\"\n [value]=\"m.role ?? ''\"\n [disabled]=\"busy() === m.user_id\"\n (valueChange)=\"changeRole(m, $event)\"\n >\n @for (option of roleOptions(); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </hm-select>\n }\n @if (canRemove(m)) {\n @if (confirmingRemove() === m.user_id) {\n <hm-button emphasis=\"medium\" (clicked)=\"cancelRemove()\">{{ text.cancel }}</hm-button>\n }\n <hm-button\n intent=\"danger\"\n [emphasis]=\"confirmingRemove() === m.user_id ? 'high' : 'medium'\"\n [loading]=\"busy() === m.user_id\"\n (clicked)=\"remove(m)\"\n >{{ confirmingRemove() === m.user_id ? text.confirmRemove : text.remove }}</hm-button>\n }\n </span>\n }\n </li>\n } @empty {\n <li class=\"sp-account__item sp-account__item--empty\">{{ filter().trim() ? text.noMatches : text.empty }}</li>\n }\n </ul>\n <div class=\"sp-account__list-footer\">\n <span class=\"sp-account__note\">{{ countLabel() }}</span>\n </div>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, inject, input, output, signal, untracked } from '@angular/core';\nimport { AvatarGroupComponent, AvatarGroupPerson, ButtonComponent, HermesI18nService, IconComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { formatMessage, pluralMessage } from '@trismegisto/primitives';\nimport { MyGroupComponent, groupRoleLabel } from './my-group.component';\nimport { ManagedGroup } from './my-groups.service';\n\n/**\n * Seção \"Grupos\" do painel de configurações: primeiro a lista dos grupos desta aplicação de que a pessoa é membro (com\n * a função dela e o crachá); escolher um abre a tela de membros dele, com \"Voltar aos grupos\" no topo. A tela escolhida\n * vive só enquanto o painel está aberto (o painel desmonta ao fechar). Se o grupo aberto some da lista (a pessoa saiu\n * dele, ou a lista foi relida sem ele), volta para a lista.\n */\n@Component({\n selector: 'spine-my-groups',\n imports: [AvatarGroupComponent, ButtonComponent, IconComponent, MyGroupComponent],\n templateUrl: './my-groups.component.html',\n styleUrls: ['./settings-blocks.scss', './my-group.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class MyGroupsComponent {\n readonly groups = input.required<readonly ManagedGroup[]>();\n\n private readonly messages = inject(SPINE_MESSAGES);\n private readonly i18n = inject(HermesI18nService);\n protected readonly text = this.messages.myGroups;\n\n private readonly openId = signal<string | null>(null);\n /** Grupo aberto (tela de membros); null = a lista. */\n protected readonly open = computed(() => this.groups().find((g) => g.id === this.openId()) ?? null);\n /** Um grupo aberto (tela de membros) ou a lista: o painel some com o cabeçalho da seção enquanto há grupo aberto. */\n readonly openChange = output<boolean>();\n\n constructor() {\n // Grupo aberto que não está mais na lista: volta para a lista.\n effect(() => {\n const id = this.openId();\n if (id && !this.groups().some((g) => g.id === id)) untracked(() => this.openId.set(null));\n });\n }\n\n private readonly emitOpen = effect(() => {\n const isOpen = !!this.open();\n untracked(() => this.openChange.emit(isOpen));\n });\n\n protected openGroup(group: ManagedGroup): void {\n this.openId.set(group.id);\n }\n\n protected back(): void {\n this.openId.set(null);\n }\n\n /** Rostos dos primeiros membros (o resto no \"+N\" do `hm-avatar-group`). */\n protected peopleOf(group: ManagedGroup): AvatarGroupPerson[] {\n return (group.members_preview ?? []).map((m) => ({ name: m.name || m.username, imageUrl: m.picture }));\n }\n\n /** \"4 membros\": nome acessível do grupo de rostos. */\n protected membersLabel(group: ManagedGroup): string {\n return pluralMessage(this.text.membersCount, group.members_count ?? 0, this.i18n.formatLocale());\n }\n\n /** \"Sua função: Editor · Crachá: Operador\" (ou \"Grupo desativado\" no lugar do crachá). */\n protected summary(group: ManagedGroup): string {\n const role = groupRoleLabel(this.text, group.my_role);\n const settings = this.messages.settings;\n return group.enabled\n ? formatMessage(settings.groupRole, { role, badge: group.type.name })\n : formatMessage(settings.groupRoleDisabled, { role });\n }\n}\n","@if (open(); as group) {\n <!-- Tela de membros de um grupo: voltar no topo, depois o grupo e os membros (com \"Incluir membro\" acima da lista). -->\n <div class=\"sp-groups__back\">\n <hm-button size=\"small\" emphasis=\"minimal\" icon=\"arrow-left\" (clicked)=\"back()\">{{ text.back }}</hm-button>\n </div>\n <div class=\"sp-account__panel-text sp-groups__heading\">\n <h4 class=\"sp-account__title\">{{ group.name }}</h4>\n <p class=\"sp-account__note\">{{ summary(group) }}</p>\n </div>\n <spine-my-group [group]=\"group\" />\n} @else {\n <!-- Lista dos grupos: cada um abre a tela de membros. -->\n <div class=\"sp-account__list\">\n <ul class=\"sp-account__items\" [attr.aria-label]=\"text.listLabel\">\n @for (g of groups(); track g.id) {\n <li>\n <button type=\"button\" class=\"sp-groups__item\" (click)=\"openGroup(g)\">\n <span class=\"sp-account__icon\" [class.sp-account__icon--accent]=\"g.enabled\"><hm-icon shape=\"employee-group\" /></span>\n <span class=\"sp-account__item-main\">\n <span class=\"sp-account__item-title\"><strong>{{ g.name }}</strong></span>\n <span class=\"sp-account__meta\">{{ summary(g) }}</span>\n </span>\n @if (g.members_count) {\n <hm-avatar-group class=\"sp-groups__faces\" size=\"small\" [max]=\"4\" [people]=\"peopleOf(g)\" [total]=\"g.members_count\" [label]=\"membersLabel(g)\" />\n }\n <hm-icon class=\"sp-groups__chevron\" shape=\"angle-right\" />\n </button>\n </li>\n }\n </ul>\n </div>\n}\n","import { ChangeDetectionStrategy, Component, OnInit, inject, signal } from '@angular/core';\nimport { ButtonComponent, SkeletonComponent } from '@trismegisto/angular';\nimport { pluralMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineRatingStarsComponent } from './rating-stars.component';\nimport { SpineRatingsService } from './ratings.service';\n\n/**\n * A média da ferramenta para qualquer pessoa logada (Configurações › Sobre): estrelas com meia, \"8,4/10 · 12\n * avaliações\" e \"Avaliar\", que abre o diálogo de avaliar a ferramenta. Lê `GET /me/ratings/summary` ao aparecer (o\n * painel só desenha aberto); avaliar a ferramenta atualiza a média sozinho (`SpineRatingsService.save`).\n */\n@Component({\n selector: 'spine-app-rating-summary',\n imports: [ButtonComponent, SkeletonComponent, SpineRatingStarsComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <span class=\"spine-app-rating\">\n @if (loading()) {\n <hm-skeleton shape=\"text\" [count]=\"1\" [label]=\"text.loadingAverage\" />\n } @else if (failed()) {\n <span class=\"spine-app-rating__muted\">{{ text.averageError }}</span>\n } @else if (ratings.appAverage(); as a) {\n @if (a.total) {\n <spine-rating-stars [readonly]=\"true\" size=\"small\" [value]=\"a.average\" />\n <span class=\"spine-app-rating__muted\">· {{ total(a.total) }}</span>\n } @else {\n <span class=\"spine-app-rating__muted\">{{ text.noRatingsYet }}</span>\n }\n }\n <hm-button emphasis=\"medium\" size=\"small\" icon=\"star\" (clicked)=\"ratings.openApp()\">{{ text.rateAction }}</hm-button>\n </span>\n `,\n styles: [`\n :host { display: block; }\n .spine-app-rating { display: inline-flex; flex-wrap: wrap; align-items: center; gap: var(--hm-space-xs); }\n .spine-app-rating__muted { color: var(--hm-muted); font-size: var(--hm-font-size-sm, 14px); }\n `],\n})\nexport class SpineAppRatingSummaryComponent implements OnInit {\n protected readonly ratings = inject(SpineRatingsService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.ratings;\n\n protected readonly loading = signal(true);\n protected readonly failed = signal(false);\n\n async ngOnInit(): Promise<void> {\n try {\n await this.ratings.loadAppAverage();\n } catch {\n this.failed.set(true);\n } finally {\n this.loading.set(false);\n }\n }\n\n protected total(count: number): string {\n return pluralMessage(this.text.total, count, this.messages.meta.locale);\n }\n}\n","import { NgComponentOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, isDevMode, signal, untracked } from '@angular/core';\nimport { AUTH_CONFIG, AuthorizationService } from '@orfeu/angular/core';\nimport { AccountAvatarComponent, ButtonComponent, ComboboxComponent, CheckboxComponent, ComboboxOption, HERMES_SIDEBAR_CONFIG, HERMES_THEME_CONFIG, HermesDensity, HermesI18nService, HermesSidebarService, HermesThemeMode, HermesThemeService, HermesToastService, SegmentedControlComponent, SegmentedOption, SettingsDialogComponent, SettingsRowComponent, SettingsSectionComponent, ShortcutListComponent, ThemePickerComponent, SelectComponent, ToggletipComponent } from '@trismegisto/angular';\nimport { APP_PACKAGE_INFO, DensityService, SPINE_CONFIG, SPINE_USER_STORAGE_KEYS, SpineHourCyclePreference, SpinePreferencesService, SpineStartPagePreference, SpineQuickAccessService, SpineUserStorage, SpineUserStorageKey, ThemePresetService, ThemeService, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { FALLBACK_FAMILY, HERMES_FONTS, HERMES_TEXT_SCALES, HermesFont, HermesMotionPreference, Weekday, formatMessage, pluralMessage, weekdayNames } from '@trismegisto/primitives';\nimport { SpineNewsService } from '../news/news.service';\nimport { SpineInitialSetupService } from '../setup/initial-setup.service';\nimport { Router } from '@angular/router';\nimport { SpineAccountPreferencesService } from '../account-preferences/account-preferences.service';\nimport { SpineIdleService } from '../idle/idle.service';\nimport { SpineNoticesService } from '../notices/notices.service';\nimport { SpineStartPageService } from '../start-page/start-page.service';\nimport { AccountActivityComponent } from './account-activity.component';\nimport { AccountMfaComponent } from './account-mfa.component';\nimport { AiAgentComponent } from './ai-agent.component';\nimport { DefaultBadgeComponent } from './default-badge.component';\nimport { AccountRecoveryCodesComponent } from './account-recovery-codes.component';\nimport { SpineAccountSecurityService } from './account-security.service';\nimport { SpineAccountSecurityScopeDirective } from './account-security.state';\nimport { AccountSessionsComponent } from './account-sessions.component';\nimport { AppTokensComponent } from './app-tokens.component';\nimport { MyGroupsComponent } from './my-groups.component';\nimport { SpineMyGroupsService } from './my-groups.service';\nimport { ShortcutService } from '../shortcuts/shortcut.service';\nimport { SpineLogoutService } from '../logout/logout.service';\nimport { SPINE_SETTINGS_KEYS, SPINE_SETTINGS_SECTIONS, SpineSettingsService, resolveSettingsSection } from './settings.service';\nimport { SpineAppRatingSummaryComponent } from '../ratings/app-rating-summary.component';\nimport { SpineRatingsService } from '../ratings/ratings.service';\n\n/** Dependências que valem mostrar em \"Sobre\" (as demais são detalhe de build). */\n// check-strings: off — nomes de produto, não se traduzem.\nconst KEY_DEPENDENCIES: readonly { name: string; label: string }[] = [\n { name: '@angular/core', label: 'Angular' },\n { name: '@trismegisto/angular', label: 'Hermes DS' },\n { name: '@trismegisto/spine', label: 'Hermes Spine' },\n { name: '@orfeu/angular', label: 'Orfeu' },\n { name: 'apollo-angular', label: 'Apollo' },\n { name: 'graphql', label: 'GraphQL' },\n { name: 'rxjs', label: 'RxJS' },\n // check-strings: on\n];\n\n/** Uma lista guardada neste navegador que a seção \"Dados do navegador\" limpa. */\ntype BrowserList = 'recents' | 'searches' | 'favorites';\n\n/** Lista → chave do `SpineUserStorage` (por usuário). */\nconst BROWSER_LISTS: Readonly<Record<BrowserList, SpineUserStorageKey>> = {\n recents: SPINE_USER_STORAGE_KEYS.recents,\n searches: SPINE_USER_STORAGE_KEYS.recentSearches,\n favorites: SPINE_USER_STORAGE_KEYS.favorites,\n};\n\n/**\n * Painel de configurações do shell (substitui as telas do antigo módulo \"Sistema\"): Conta (perfil, nível,\n * sessão, sair), MFA (verificação em duas etapas e códigos de recuperação do Argos), Sessões (token de\n * acesso, tokens de aplicação e sessões e dispositivos do Argos), Aparência, Acessibilidade (tamanho do texto,\n * animações), Região (idioma, fuso, formato de hora, primeiro dia da semana), Atalhos, Dados do navegador\n * (limpar listas, restaurar preferências), Ajuda (novidades, configuração inicial, o essencial) e Sobre, mais as seções que o app registrar\n * com `provideSettingsSection`. Tudo vale na hora — cada controle chama o serviço que já persiste aquela\n * preferência (tema, densidade, menu lateral, fuso, tamanho do texto…).\n *\n * Aberto por `SpineSettingsService.open()` — menu do perfil, `Ctrl+,` ou `?settings=<seção>`.\n */\n@Component({\n selector: 'spine-settings-panel',\n imports: [\n NgComponentOutlet, AppTokensComponent, MyGroupsComponent, AiAgentComponent, AccountActivityComponent, DefaultBadgeComponent, CheckboxComponent,\n AccountMfaComponent, AccountRecoveryCodesComponent, AccountSessionsComponent, SpineAccountSecurityScopeDirective,\n AccountAvatarComponent, ButtonComponent, ComboboxComponent,\n SegmentedControlComponent, SettingsDialogComponent, SettingsRowComponent, SettingsSectionComponent,\n SelectComponent, ShortcutListComponent, ThemePickerComponent, ToggletipComponent, SpineAppRatingSummaryComponent,\n ],\n templateUrl: './settings-panel.component.html',\n styleUrl: './settings-panel.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class SettingsPanelComponent {\n protected readonly settings = inject(SpineSettingsService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.settings;\n protected readonly fmt = formatMessage;\n protected readonly keys = SPINE_SETTINGS_KEYS;\n /** Seção aberta, com a chave antiga já trocada pela nova (`seguranca` → `mfa`). */\n protected readonly activeSection = computed(() => resolveSettingsSection(this.settings.section()));\n\n private readonly theme = inject(ThemeService);\n private readonly hermesTheme = inject(HermesThemeService);\n private readonly themeConfig = inject(HERMES_THEME_CONFIG);\n private readonly sidebarConfig = inject(HERMES_SIDEBAR_CONFIG);\n private readonly i18n = inject(HermesI18nService);\n private readonly news = inject(SpineNewsService);\n private readonly quickAccess = inject(SpineQuickAccessService);\n private readonly userStorage = inject(SpineUserStorage);\n private readonly presets = inject(ThemePresetService);\n private readonly density = inject(DensityService);\n protected readonly sidebar = inject(HermesSidebarService);\n protected readonly preferences = inject(SpinePreferencesService);\n private readonly shortcutService = inject(ShortcutService);\n private readonly setup = inject(SpineInitialSetupService);\n private readonly auth = inject(AuthorizationService);\n private readonly authConfig = inject(AUTH_CONFIG, { optional: true });\n private readonly toast = inject(HermesToastService);\n protected readonly packageInfo = inject(APP_PACKAGE_INFO, { optional: true }) ?? {};\n private readonly config = inject(SPINE_CONFIG, { optional: true });\n protected readonly appSections = inject(SPINE_SETTINGS_SECTIONS, { optional: true }) ?? [];\n\n protected readonly appName = this.config?.appName ?? 'Hermes';\n /** Recursos opcionais ligados pelo app (`SpineConfig.features`). */\n protected readonly features = this.config?.features ?? {};\n protected readonly featureText = this.messages.accountFeatures;\n /** Sobre › Avaliação: a média da ferramenta e \"Avaliar\" (`SpineFeatures.ratings` com `SPINE_ADMIN_API`). */\n protected readonly ratingsEnabled = inject(SpineRatingsService).enabled;\n protected readonly ratingText = this.messages.ratings;\n\n /**\n * \"Copiar token de acesso\" é ferramenta de desenvolvimento: põe o token da sessão (Bearer de tudo que a\n * pessoa pode fazer) na área de transferência, ao alcance de qualquer app/extensão que leia o clipboard.\n * Só aparece com `SpineConfig.technicalDocs` (sem configuração, só em `isDevMode()`), como a visão técnica.\n */\n protected readonly showAccessToken = this.config?.technicalDocs ?? isDevMode();\n\n // ── Aparência ───────────────────────────────────────────────────────────────\n protected readonly themeOptions = computed<readonly SegmentedOption[]>(() => [\n { value: 'light', label: this.text.themeLight, icon: 'sun' },\n { value: 'dark', label: this.text.themeDark, icon: 'moon' },\n { value: 'system', label: this.text.themeSystem, icon: 'computer' },\n ]);\n protected readonly densityOptions = computed<readonly SegmentedOption[]>(() => [\n { value: 'comfortable', label: this.text.comfortable },\n { value: 'compact', label: this.text.compact },\n ]);\n // As fontes da lib, com as sobrescritas do app (`provideUi({ theme: { replaceFonts } })`) no lugar.\n protected readonly fontOptions: readonly SegmentedOption[] = (this.hermesTheme.fonts ?? HERMES_FONTS).map((f) => ({ value: f.id, label: f.label }));\n protected readonly sidebarOptions = computed<readonly SegmentedOption[]>(() => [\n { value: 'auto', label: this.text.sidebarAuto },\n { value: 'fixed', label: this.text.sidebarFixed },\n { value: 'compact', label: this.text.sidebarCompact },\n ]);\n\n protected readonly themeMode = computed(() => this.hermesTheme.mode());\n protected readonly appliedTheme = computed(() => this.hermesTheme.theme());\n protected readonly family = computed(() => this.hermesTheme.family());\n protected readonly densityValue = computed(() => this.hermesTheme.density());\n protected readonly fontValue = computed(() => this.hermesTheme.font());\n protected readonly families = this.presets.families;\n\n protected setThemeMode(mode: string): void {\n this.theme.setMode(mode as HermesThemeMode);\n }\n\n protected setFamily(id: string): void {\n const family = this.families.find((f) => f.id === id);\n if (family) this.presets.setPreset(family);\n }\n\n protected setDensity(value: string): void {\n this.density.setDensity(value as HermesDensity);\n }\n\n protected setFont(value: string): void {\n this.hermesTheme.setFont(value as HermesFont);\n }\n\n protected setSidebarMode(value: string): void {\n this.sidebar.setMode(value as 'auto' | 'fixed' | 'compact');\n }\n\n // ── Acessibilidade ──────────────────────────────────────────────────────────\n /** 100%, 110%, 125%, 150% — no formato de porcentagem do idioma. */\n protected readonly textSizeOptions = computed<readonly SegmentedOption[]>(() => {\n const percent = new Intl.NumberFormat(this.i18n.formatLocale(), { style: 'percent', maximumFractionDigits: 0 });\n return HERMES_TEXT_SCALES.map((scale) => ({ value: String(scale), label: percent.format(scale) }));\n });\n protected readonly textSizeValue = computed(() => String(this.preferences.textScale()));\n\n protected readonly motionOptions = computed<readonly SegmentedOption[]>(() => [\n { value: 'system', label: this.text.motionSystem },\n { value: 'reduce', label: this.text.motionReduce },\n { value: 'full', label: this.text.motionFull },\n ]);\n\n protected setTextSize(value: string): void {\n this.preferences.setTextScale(Number(value));\n }\n\n protected setMotion(value: string): void {\n this.preferences.setMotion(value as HermesMotionPreference);\n }\n\n // ── Região ──────────────────────────────────────────────────────────────────\n protected readonly languageOptions = computed(() => {\n const appLanguage = this.preferences.languages.find((l) => l.value === this.preferences.appLanguage)?.label ?? this.preferences.appLanguage;\n return [\n { value: '', label: formatMessage(this.text.languageAuto, { language: appLanguage }) },\n ...this.preferences.languages,\n ];\n });\n\n /** ~400 fusos, cada um com o deslocamento calculado: só monta quando o painel abre pela\n * primeira vez, não no carregamento de toda página (o painel vive no layout desde o início). */\n private timeZoneCache: readonly ComboboxOption[] | null = null;\n protected readonly timeZoneOptions = computed<readonly ComboboxOption[]>(() => [\n { value: '', label: formatMessage(this.text.timeZoneAuto, { zone: this.preferences.browserTimeZone }) },\n ...(this.timeZoneCache ??= this.preferences\n .supportedTimeZones()\n .map((tz) => ({ value: tz, label: `${tz.replace(/_/g, ' ')} (${offsetOf(tz)})` }))),\n ]);\n\n /** Hora agora no fuso efetivo — prévia de como as datas vão aparecer. */\n protected readonly timeZonePreview = computed(() => {\n const zone = this.preferences.effectiveTimeZone();\n try {\n return new Intl.DateTimeFormat(this.i18n.formatLocale(), { dateStyle: 'short', timeStyle: 'short', timeZone: zone }).format(new Date())\n + ` (${offsetOf(zone)})`;\n } catch {\n return zone;\n }\n });\n\n protected readonly hourCycleOptions = computed<readonly SegmentedOption[]>(() => [\n { value: '', label: this.text.hourCycleAuto },\n { value: 'h23', label: this.text.hourCycle24 },\n { value: 'h12', label: this.text.hourCycle12 },\n ]);\n\n /** Hora agora, no relógio escolhido — prévia do formato. */\n protected readonly hourCyclePreview = computed(() => {\n try {\n return new Intl.DateTimeFormat(this.i18n.formatLocale(), { timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() }).format(new Date());\n } catch {\n return '';\n }\n });\n\n /** Automático, domingo e segunda — os nomes dos dias saem do `Intl`, no idioma. */\n protected readonly weekStartOptions = computed<readonly SegmentedOption[]>(() => {\n const names = weekdayNames(this.i18n.locale(), 'long', 0);\n return [\n { value: '', label: this.text.weekStartAuto },\n { value: '0', label: names[0] },\n { value: '1', label: names[1] },\n ];\n });\n protected readonly weekStartValue = computed(() => {\n const day = this.preferences.weekStart();\n return day === null ? '' : String(day);\n });\n\n protected setHourCycle(value: string): void {\n this.preferences.setHourCycle(value as SpineHourCyclePreference);\n }\n\n protected setWeekStart(value: string): void {\n this.preferences.setWeekStart(value === '' ? null : (Number(value) as Weekday));\n }\n\n // ── Atalhos ─────────────────────────────────────────────────────────────────\n /** Atalhos registrados (favoritos numa linha só) + os que outra peça dispara — os mesmos do painel \"?\". */\n protected readonly shortcutItems = this.shortcutService.panelItems;\n\n // ── Ajuda ───────────────────────────────────────────────────────────────────\n /** \"Ver novidades\" só com alguma novidade para a pessoa (argos-admin `/me/news`). */\n protected readonly hasNews = this.news.hasAny;\n /** \"Refazer\" a configuração inicial só quando o app não a desligou. */\n protected readonly setupEnabled = this.setup.enabled;\n\n /** Fecha o painel antes: novidades, configuração inicial e o essencial ocupam a tela. */\n protected showNews(): void {\n this.settings.close();\n this.news.showAll();\n }\n\n protected redoSetup(): void {\n this.settings.close();\n this.setup.open();\n }\n\n protected showEssentials(): void {\n this.settings.close();\n this.setup.openEssentials();\n }\n\n // ── Dados do navegador ──────────────────────────────────────────────────────\n /** Relida quando o painel abre e depois de limpar (as buscas recentes não têm sinal próprio). */\n private readonly dataVersion = signal(0);\n protected readonly counts = computed<Readonly<Record<BrowserList, number>>>(() => {\n this.dataVersion();\n this.settings.isOpen();\n return {\n recents: this.quickAccess.recents().length,\n searches: this.userStorage.count(BROWSER_LISTS.searches),\n favorites: this.quickAccess.favorites().length,\n };\n });\n /** As três listas, com a contagem já no texto da linha. */\n protected readonly browserLists = computed(() => {\n const counts = this.counts();\n const locale = this.i18n.formatLocale();\n const row = (id: BrowserList, label: string, keywords: string, count: string) => ({ id, label, keywords, count, empty: counts[id] === 0 });\n return [\n row('recents', this.text.recentPages, this.text.recentPagesKeywords, pluralMessage(this.text.pagesCount, counts.recents, locale)),\n row('searches', this.text.recentSearches, this.text.recentSearchesKeywords, pluralMessage(this.text.searchesCount, counts.searches, locale)),\n row('favorites', this.text.favorites, this.text.favoritesKeywords, pluralMessage(this.text.pagesCount, counts.favorites, locale)),\n ];\n });\n\n /** Ação destrutiva esperando confirmação (uma por vez, como nas listas do painel). */\n protected readonly confirming = signal<BrowserList | 'preferences' | null>(null);\n\n constructor() {\n // Painel fechado por qualquer caminho: a confirmação pendente não reaparece na próxima abertura.\n effect(() => {\n if (!this.settings.isOpen()) this.confirming.set(null);\n });\n // A cada abertura, relê os grupos da pessoa (alguém pode tê-la incluído, removido ou trocado a função dela).\n effect(() => {\n if (this.settings.isOpen()) untracked(() => void this.myGroupsService.refresh());\n });\n }\n\n protected cancelConfirm(): void {\n this.confirming.set(null);\n }\n\n /** 1º clique pede confirmação; o 2º apaga a lista do usuário atual e avisa. */\n protected clearList(list: BrowserList): void {\n if (this.confirming() !== list) {\n this.confirming.set(list);\n return;\n }\n this.confirming.set(null);\n this.userStorage.clear(BROWSER_LISTS[list]);\n this.dataVersion.update((v) => v + 1);\n const done = { recents: this.text.recentPagesCleared, searches: this.text.recentSearchesCleared, favorites: this.text.favoritesCleared };\n this.toast.success(done[list]);\n }\n\n /**\n * Restaurar preferências (com confirmação): tema (sistema), cor principal (a padrão do app), densidade\n * (confortável), fonte (a padrão do app), menu lateral (o modo padrão do app), dividir abas (desligado), tamanho do\n * texto (100%), animações (sistema), formato de hora e primeiro dia da semana (automáticos). Idioma, fuso horário e\n * atalhos de tecla única ficam: mudam como a pessoa lê e digita, e não são \"aparência\".\n */\n protected restorePreferences(): void {\n if (this.confirming() !== 'preferences') {\n this.confirming.set('preferences');\n return;\n }\n this.confirming.set(null);\n const config = this.themeConfig;\n this.theme.setMode('system');\n const families = this.families;\n const knownFamily = (id: string | undefined) => !!id && families.some((f) => f.id === (config.aliases?.[id] ?? id));\n const family = [config.defaultFamily, FALLBACK_FAMILY, families[0]?.id].find(knownFamily);\n if (family) this.hermesTheme.setFamily(family);\n this.density.setDensity('comfortable');\n const fonts = this.hermesTheme.fonts ?? HERMES_FONTS;\n const knownFont = (id: string | undefined) => !!id && fonts.some((f) => f.id === (config.fontAliases?.[id] ?? id));\n const font = [config.defaultFont, 'geist', fonts[0]?.id].find(knownFont);\n if (font) this.hermesTheme.setFont(font as HermesFont);\n this.sidebar.setMode(this.sidebarConfig.defaultMode ?? 'auto');\n this.preferences.setSplitTabs(false);\n this.preferences.setTextScale(1);\n this.preferences.setMotion('system');\n this.preferences.setHourCycle('');\n this.preferences.setWeekStart(null);\n this.toast.success(this.text.preferencesRestored);\n }\n\n // ── Conta ───────────────────────────────────────────────────────────────────\n protected get profile() { return this.auth.profile; }\n protected get badge() { return this.auth.badge; }\n\n /** Validade da sessão lida do `exp` do próprio token (só leitura do payload, sem validar). */\n protected get sessionExpiry(): string {\n const exp = decodeTokenPayload(this.auth.getToken())?.['exp'];\n if (typeof exp !== 'number') return this.text.sessionUnknown;\n const at = new Date(exp * 1000);\n const minutes = Math.round((at.getTime() - Date.now()) / 60000);\n const when = new Intl.DateTimeFormat(this.i18n.formatLocale(), { timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() }).format(at);\n if (minutes <= 0) return formatMessage(this.text.sessionExpired, { time: when });\n return minutes < 60\n ? formatMessage(this.text.sessionExpiresIn, { minutes, time: when })\n : formatMessage(this.text.sessionExpiresAt, { time: when });\n }\n\n protected async copyToken(): Promise<void> {\n if (!this.showAccessToken) return;\n const token = this.auth.getToken();\n if (!token) { this.toast.warning(this.text.noSessionToken); return; }\n await this.copy(token, this.text.tokenCopied);\n }\n\n private readonly logoutService = inject(SpineLogoutService);\n /** \"Saindo…\" no botão; volta a `false` também quando a saída falha. */\n protected readonly logoutPending = this.logoutService.pending;\n\n /** O painel fica aberto até a saída dar certo: com falha, a pessoa continua aqui, com o aviso de erro. */\n protected async logout(): Promise<void> {\n if (await this.logoutService.logout()) this.settings.close();\n }\n\n // ── MFA ─────────────────────────────────────────────────────────────────────\n /** API da conta no Argos (Bearer com o token da sessão), a partir do `AUTH_CONFIG`. Sem ela (sem\n * `authority`/`realmId`, ou com `CHANGE_ME`) a seção MFA e a linha \"Sessões e dispositivos\" não aparecem. */\n protected readonly accountSecurity = inject(SpineAccountSecurityService).available;\n\n /** Login da pessoa (`preferred_username` do token, ou o e-mail), para dizer QUAL conta do Argos. */\n protected get accountLogin(): string {\n const payload = decodeTokenPayload(this.auth.getToken());\n const login = payload?.['preferred_username'] ?? payload?.['email'];\n return typeof login === 'string' ? login : '';\n }\n\n /** Realm pelo nome (`master`, `Minha Empresa`); um id (UUID) não diz nada a quem lê e fica de fora. */\n protected get accountRealm(): string {\n const realm = this.authConfig?.realmId?.trim() ?? '';\n return UUID.test(realm) ? '' : realm;\n }\n\n // ── Sessões ─────────────────────────────────────────────────────────────────\n /** Linhas da seção Sessões, cada uma com a própria condição. \"Tokens de aplicação\" sempre aparece (sem\n * `SPINE_ADMIN_API` os tokens explicam que não estão disponíveis); o token de acesso só com\n * `technicalDocs`; sessões e dispositivos só com a API da conta. A \"Sessão\" (validade) fica em Conta. */\n protected readonly sessionsItems = {\n accessToken: this.showAccessToken,\n appTokens: true,\n aiAgent: !!this.config?.features?.aiAgent?.servers?.length,\n devices: this.accountSecurity,\n } as const;\n /** Sem nenhuma linha visível a seção não aparece. */\n protected readonly hasSessionsSection = Object.values(this.sessionsItems).some(Boolean);\n\n // ── Grupos ──────────────────────────────────────────────────────────────────\n /** Grupos desta aplicação de que a pessoa é membro (relidos a cada abertura); sem nenhum, a seção some. */\n private readonly myGroupsService = inject(SpineMyGroupsService);\n protected readonly myGroups = this.myGroupsService.groups;\n /** Grupo aberto na seção Grupos (tela de membros): o cabeçalho da seção sai de vista. */\n protected readonly groupOpen = signal(false);\n\n // ── Recursos opcionais (SpineConfig.features) ──────────────────────────────\n private readonly idle = inject(SpineIdleService);\n private readonly startPageService = inject(SpineStartPageService);\n private readonly router = inject(Router);\n protected readonly notices = inject(SpineNoticesService);\n protected readonly accountPreferences = inject(SpineAccountPreferencesService);\n\n /** Conta › \"Encerrar por inatividade\": opções dentro dos limites do app. */\n protected readonly idleOptions = computed<readonly SegmentedOption[]>(() =>\n this.idle.limits.options.map((m) => ({ value: String(m), label: m ? formatMessage(this.featureText.idleOption, { minutes: m }) : this.featureText.idleNever })));\n protected readonly idleValue = computed(() => String(this.idle.minutes()));\n protected readonly idleHint = this.idle.limits.max ? formatMessage(this.featureText.idleLimitHint, { minutes: this.idle.limits.max }) : '';\n\n protected setIdle(value: string): void {\n this.preferences.setIdleMinutes(Number(value));\n }\n\n /** Conta › \"Tela inicial\": início, última tela e cada favorito. */\n protected readonly startPageOptions = computed(() => [\n { value: 'home', label: this.featureText.startHome },\n { value: 'last', label: this.featureText.startLast },\n ...this.quickAccess.favorites().map((f) => ({ value: `fav:${f.id}`, label: formatMessage(this.featureText.startFavorite, { name: f.displayName || f.redirect }) })),\n ]);\n /** Favorito escolhido que deixou de ser favorito: mostra \"Início\" (é para onde o login vai). */\n protected readonly startPageValue = computed(() => {\n const value = this.preferences.startPage();\n return this.startPageOptions().some((o) => o.value === value) ? value : 'home';\n });\n\n protected readonly quickAccessHasFavorites = computed(() => this.quickAccess.favorites().length > 0);\n\n protected setStartPage(value: string): void {\n this.preferences.setStartPage(value as SpineStartPagePreference);\n // \"Última tela visitada\" começa a valer já com a tela de agora.\n if (value === 'last') this.startPageService.remember(this.router.url);\n }\n\n /** Conta › \"Crachá padrão\": só com mais de um crachá nesta aplicação (claim `badges` do token). */\n protected get showDefaultBadge(): boolean {\n return !!this.features.defaultBadge && this.accountSecurity && (this.auth.badges?.length ?? 0) > 1;\n }\n\n /** Notificações: aviso do navegador ligado (escolha + permissão). */\n protected async setBrowserNotices(enabled: boolean): Promise<void> {\n if (!enabled) {\n this.notices.disableBrowser();\n return;\n }\n const ok = await this.notices.enableBrowser();\n if (!ok) this.toast.warning(this.notices.permission() === 'unsupported' ? this.featureText.browserNoticesUnsupported : this.featureText.browserNoticesDenied);\n }\n\n /** \"Preferências na conta\": situação da sincronização. */\n protected readonly syncStatus = computed(() => {\n const status = this.accountPreferences.status();\n const at = this.accountPreferences.syncedAt();\n if (status === 'local') return this.featureText.syncLocal;\n if (status === 'error') return this.featureText.syncError;\n if (status === 'saving' || status === 'loading') return this.featureText.syncSaving;\n if (!at) return '';\n const time = new Intl.DateTimeFormat(this.i18n.formatLocale(), { timeStyle: 'short', timeZone: this.preferences.effectiveTimeZone() }).format(at);\n return formatMessage(this.featureText.syncSynced, { time });\n });\n\n protected syncNow(): void {\n void this.accountPreferences.syncNow();\n }\n\n // ── Sobre ───────────────────────────────────────────────────────────────────\n protected readonly dependencies = KEY_DEPENDENCIES\n .map((d) => ({ ...d, version: this.packageInfo.dependencies?.[d.name] }))\n .filter((d) => !!d.version);\n\n protected get buildDate(): string {\n const date = this.packageInfo.buildDate;\n return date ? new Intl.DateTimeFormat(this.i18n.formatLocale(), { dateStyle: 'short', timeStyle: 'short' }).format(new Date(date)) : '';\n }\n\n /** Texto pronto pra colar num chamado: app, versão, ambiente, navegador, tela, fuso e página. */\n protected async copySupportInfo(): Promise<void> {\n const info = this.packageInfo;\n const s = this.messages.support;\n const theme = formatMessage(s.themeValue, {\n theme: this.appliedTheme(), mode: this.themeMode(), family: this.family(), density: this.densityValue(), font: this.fontValue(),\n });\n const lines = [\n `${s.application}: ${this.appName}${info.name ? ` (${info.name})` : ''}`,\n `${s.version}: ${info.version ?? '—'}`,\n info.buildDate ? `${s.build}: ${this.buildDate}` : '',\n info.environment ? `${s.environment}: ${info.environment}` : '',\n `${s.page}: ${location.href}`,\n `${s.browser}: ${navigator.userAgent}`,\n `${s.screen}: ${window.innerWidth}×${window.innerHeight} @${window.devicePixelRatio}x`,\n `${s.theme}: ${theme}`,\n `${s.timeZone}: ${this.preferences.effectiveTimeZone()}`,\n `${s.accessLevel}: ${this.badge?.name ?? '—'}`,\n `${s.date}: ${new Date().toISOString()}`,\n ].filter(Boolean);\n await this.copy(lines.join('\\n'), this.text.supportCopied);\n }\n\n private async copy(text: string, success: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n this.toast.success(success);\n } catch {\n this.toast.error(this.text.copyBlocked);\n }\n }\n\n protected onOpenChange(open: boolean): void {\n if (!open) this.settings.close();\n }\n}\n\nconst UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\n/** \"UTC−03:00\" para um fuso IANA. */\nfunction offsetOf(timeZone: string): string {\n try {\n const part = new Intl.DateTimeFormat('en-US', { timeZone, timeZoneName: 'longOffset' })\n .formatToParts(new Date())\n .find((p) => p.type === 'timeZoneName')?.value;\n return (part ?? 'GMT').replace('GMT', 'UTC').replace('-', '−') || 'UTC';\n } catch {\n return 'UTC';\n }\n}\n\nfunction decodeTokenPayload(token: string | null): Record<string, unknown> | null {\n const payload = token?.split('.')[1];\n if (!payload) return null;\n try {\n const json = atob(payload.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(payload.length / 4) * 4, '='));\n return JSON.parse(json) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n","<!-- Montado só enquanto aberto: nada disto (lista de fusos, leitura do token...) custa no\n carregamento de toda página. -->\n@if (settings.isOpen()) {\n <hm-settings-dialog\n [heading]=\"text.heading\"\n [open]=\"true\"\n (openChange)=\"onOpenChange($event)\"\n [activeSection]=\"activeSection()\"\n (activeSectionChange)=\"settings.section.set($event)\"\n >\n <!-- ── Conta ─────────────────────────────────────────────────────────── -->\n <hm-settings-section [key]=\"keys.account\" [label]=\"text.account\" icon=\"user\" [keywords]=\"text.accountKeywords\">\n <div class=\"sp-settings__profile\">\n <hm-account-avatar [name]=\"profile.name ?? text.user\" [imageUrl]=\"profile.picture\" />\n <span class=\"sp-settings__profile-text\">\n <strong>{{ profile.name ?? text.user }}</strong>\n @if (profile.role) { <span>{{ profile.role }}</span> }\n </span>\n </div>\n\n <!-- Só informativo: a troca de nível fica no menu do perfil, perto de onde se trabalha. -->\n @if (badge) {\n <hm-settings-row [label]=\"text.accessLevel\" [keywords]=\"text.accessLevelKeywords\">\n <span class=\"sp-settings__value\">{{ badge.name }}</span>\n </hm-settings-row>\n }\n\n <hm-settings-row [label]=\"text.session\" [description]=\"text.sessionDescription\" [keywords]=\"text.sessionKeywords\">\n <span class=\"sp-settings__value\">{{ sessionExpiry }}</span>\n </hm-settings-row>\n\n <!-- Recursos opcionais (SpineConfig.features): crachá padrão (Argos), inatividade e tela inicial. -->\n @if (showDefaultBadge) {\n <hm-settings-row [label]=\"featureText.defaultBadge\" [description]=\"featureText.defaultBadgeDescription\" [keywords]=\"featureText.defaultBadgeKeywords\">\n <spine-default-badge />\n </hm-settings-row>\n }\n\n @if (idleOptions().length) {\n <hm-settings-row [label]=\"featureText.idle\" [description]=\"idleHint || featureText.idleDescription\" [keywords]=\"featureText.idleKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"featureText.idle\" [options]=\"idleOptions()\" [value]=\"idleValue()\" (valueChange)=\"setIdle($event)\" />\n </hm-settings-row>\n }\n\n @if (features.startPage) {\n <hm-settings-row [label]=\"featureText.startPage\" [description]=\"quickAccessHasFavorites() ? featureText.startPageDescription : featureText.startPageHint\" [keywords]=\"featureText.startPageKeywords\">\n <hm-select class=\"sp-settings__language\" [label]=\"featureText.startPage\" [labelHidden]=\"true\" [value]=\"startPageValue()\" (valueChange)=\"setStartPage($event ?? 'home')\">\n @for (option of startPageOptions(); track option.value) {\n <option [value]=\"option.value\">{{ option.label }}</option>\n }\n </hm-select>\n </hm-settings-row>\n }\n\n <hm-settings-row [label]=\"text.logout\" [description]=\"text.logoutDescription\" [keywords]=\"text.logoutKeywords\">\n <hm-button emphasis=\"medium\" intent=\"danger\" icon=\"logout\" [loading]=\"logoutPending()\" (clicked)=\"logout()\">{{ text.logout }}</hm-button>\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── MFA ───────────────────────────────────────────────────────────── -->\n <!-- API da conta do Argos com o token da sessão (Bearer): MFA e códigos de recuperação aqui mesmo, sem\n abrir o Argos. O spineAccountSecurity dá às linhas o mesmo estado (reautenticação, cadastro em\n andamento), que morre quando o painel fecha. `?settings=seguranca` (chave antiga) abre esta seção. -->\n @if (accountSecurity) {\n <hm-settings-section spineAccountSecurity [key]=\"keys.mfa\" [label]=\"text.mfa\" icon=\"shield-check\" [description]=\"text.mfaDescription\" [keywords]=\"text.mfaKeywords\">\n <!-- Realm só pelo nome: o id (UUID) não diz nada a quem lê, então some. -->\n @if (accountLogin || accountRealm) {\n <hm-settings-row [label]=\"text.signedInAccount\" [description]=\"accountRealm ? fmt(text.signedInRealm, { realm: accountRealm }) : ''\">\n <span class=\"sp-settings__value\">{{ profile.name ?? text.user }}@if (accountLogin) { <span class=\"sp-settings__muted\"> · {{ accountLogin }}</span> }</span>\n </hm-settings-row>\n }\n\n <hm-settings-row [label]=\"text.twoFactor\" [description]=\"text.twoFactorDescription\" [keywords]=\"text.twoFactorKeywords\" [stacked]=\"true\">\n <spine-account-mfa />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.recoveryCodes\" [description]=\"text.recoveryCodesDescription\" [keywords]=\"text.recoveryCodesKeywords\" [stacked]=\"true\">\n <spine-account-recovery-codes />\n </hm-settings-row>\n\n <!-- Entradas e tentativas desta conta (SpineFeatures.accountActivity), últimos 90 dias. -->\n @if (features.accountActivity) {\n <hm-settings-row [label]=\"featureText.activity\" [description]=\"featureText.activityDescription\" [keywords]=\"featureText.activityKeywords\" [stacked]=\"true\">\n <spine-account-activity />\n </hm-settings-row>\n }\n </hm-settings-section>\n }\n\n <!-- ── Sessões ───────────────────────────────────────────────────────── -->\n <!-- Os tokens e onde a conta está conectada (a validade desta sessão fica em Conta). Cada linha tem a\n própria condição; a seção some se nenhuma sobrar (hasSessionsSection). -->\n @if (hasSessionsSection) {\n <hm-settings-section [key]=\"keys.sessions\" [label]=\"text.sessionsSection\" icon=\"devices\" [description]=\"text.sessionsSectionDescription\" [keywords]=\"text.sessionsSectionKeywords\">\n <!-- Só com SpineConfig.technicalDocs (padrão: isDevMode()): token da sessão no clipboard é ferramenta de dev. -->\n @if (sessionsItems.accessToken) {\n <hm-settings-row [label]=\"text.accessToken\" [description]=\"text.accessTokenDescription\" [keywords]=\"text.accessTokenKeywords\">\n <hm-button emphasis=\"medium\" icon=\"copy\" (clicked)=\"copyToken()\">{{ text.copy }}</hm-button>\n </hm-settings-row>\n }\n\n @if (sessionsItems.appTokens) {\n <hm-settings-row [label]=\"text.appTokens\" [stacked]=\"true\"\n [description]=\"text.appTokensDescription\"\n [keywords]=\"text.appTokensKeywords\">\n <hm-toggletip rowHelp [label]=\"fmt(text.moreAbout, { label: text.appTokens })\" [text]=\"text.appTokensHelp\" />\n <spine-app-tokens />\n </hm-settings-row>\n }\n\n <!-- Token + .mcp.json prontos para um agente de IA (SpineFeatures.aiAgent). -->\n @if (sessionsItems.aiAgent) {\n <hm-settings-row [label]=\"featureText.aiAgent\" [description]=\"featureText.aiAgentDescription\" [keywords]=\"featureText.aiAgentKeywords\" [stacked]=\"true\">\n <hm-toggletip rowHelp [label]=\"fmt(text.moreAbout, { label: featureText.aiAgent })\" [text]=\"featureText.aiAgentHelp\" />\n <spine-ai-agent />\n </hm-settings-row>\n }\n\n <!-- Sessões e dispositivos: API da conta do Argos, mesma condição da seção MFA. -->\n @if (sessionsItems.devices) {\n <hm-settings-row [label]=\"text.sessions\" [description]=\"text.sessionsDescription\" [keywords]=\"text.sessionsKeywords\" [stacked]=\"true\">\n <spine-account-sessions />\n </hm-settings-row>\n }\n </hm-settings-section>\n }\n\n <!-- ── Grupos ────────────────────────────────────────────────────────── -->\n <!-- Os grupos desta aplicação de que a pessoa é membro (argos-admin /me/groups, relidos a cada abertura): a lista,\n e escolhendo um, a tela de membros dele. Sem grupo nenhum, a seção não aparece. -->\n @if (myGroups().length) {\n <hm-settings-section [key]=\"keys.groups\" [label]=\"text.groups\" icon=\"employee-group\" [keywords]=\"text.groupsKeywords\"\n [class.sp-settings__section--group-open]=\"groupOpen()\" [description]=\"groupOpen() ? '' : text.groupsDescription\">\n <spine-my-groups [groups]=\"myGroups()\" (openChange)=\"groupOpen.set($event)\" />\n </hm-settings-section>\n }\n\n <!-- ── Aparência ─────────────────────────────────────────────────────── -->\n <hm-settings-section [key]=\"keys.appearance\" [label]=\"text.appearance\" icon=\"color-palette\" [keywords]=\"text.appearanceKeywords\">\n <hm-settings-row [label]=\"text.theme\" [description]=\"text.themeDescription\" [keywords]=\"text.themeKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.theme\" [options]=\"themeOptions()\" [value]=\"themeMode()\" (valueChange)=\"setThemeMode($event)\" />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.accent\" [description]=\"text.accentDescription\" [keywords]=\"text.accentKeywords\" [stacked]=\"true\">\n <hm-theme-picker\n class=\"sp-settings__picker\"\n [families]=\"families\"\n [family]=\"family()\"\n [theme]=\"appliedTheme()\"\n [showMode]=\"false\"\n (familyChosen)=\"setFamily($event)\"\n />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.density\" [description]=\"text.densityDescription\" [keywords]=\"text.densityKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.density\" [options]=\"densityOptions()\" [value]=\"densityValue()\" (valueChange)=\"setDensity($event)\" />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.font\" [description]=\"text.fontDescription\" [keywords]=\"text.fontKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.font\" [options]=\"fontOptions\" [value]=\"fontValue()\" (valueChange)=\"setFont($event)\" />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.sidebar\" [description]=\"text.sidebarDescription\" [keywords]=\"text.sidebarKeywords\">\n <hm-toggletip rowHelp [label]=\"fmt(text.moreAbout, { label: text.sidebar })\" [text]=\"text.sidebarHelp\" />\n <hm-segmented-control emphasis=\"action\" [label]=\"text.sidebar\" [options]=\"sidebarOptions()\" [value]=\"sidebar.mode()\" (valueChange)=\"setSidebarMode($event)\" />\n </hm-settings-row>\n\n <!-- Dividir abas: com ela desligada (o padrão) a área de abas fica num painel só (SpineWorkspaceNavService). -->\n <hm-settings-row [label]=\"text.splitTabs\" [description]=\"text.splitTabsDescription\" [keywords]=\"text.splitTabsKeywords\">\n <hm-checkbox [label]=\"text.splitTabs\" [labelHidden]=\"true\" [checked]=\"preferences.splitTabs()\" (checkedChange)=\"preferences.setSplitTabs($event)\" />\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── Acessibilidade ────────────────────────────────────────────────── -->\n <!-- Tamanho do texto (--hm-text-scale no <html>, HermesZoomService) e movimento (data-motion no <html>,\n HermesMotionService), guardados pelo SpinePreferencesService. -->\n <hm-settings-section [key]=\"keys.accessibility\" [label]=\"text.accessibility\" icon=\"accessibility-1\" [keywords]=\"text.accessibilityKeywords\">\n <hm-settings-row [label]=\"text.textSize\" [description]=\"text.textSizeDescription\" [keywords]=\"text.textSizeKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.textSize\" [options]=\"textSizeOptions()\" [value]=\"textSizeValue()\" (valueChange)=\"setTextSize($event)\" />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.motion\" [description]=\"text.motionDescription\" [keywords]=\"text.motionKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.motion\" [options]=\"motionOptions()\" [value]=\"preferences.motion()\" (valueChange)=\"setMotion($event)\" />\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── Região ────────────────────────────────────────────────────────── -->\n <hm-settings-section [key]=\"keys.region\" [label]=\"text.region\" icon=\"clock\" [keywords]=\"text.regionKeywords\">\n <hm-settings-row [label]=\"text.language\" [description]=\"text.languageDescription\" [keywords]=\"text.languageKeywords\">\n <hm-select\n class=\"sp-settings__language\"\n [label]=\"text.language\"\n [labelHidden]=\"true\"\n [value]=\"preferences.language()\"\n (valueChange)=\"preferences.setLanguage($event ?? '')\"\n >\n @for (option of languageOptions(); track option.value) {\n <option [value]=\"option.value\" [attr.lang]=\"option.value || null\">{{ option.label }}</option>\n }\n </hm-select>\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.timeZone\" [description]=\"fmt(text.timeZoneHint, { now: timeZonePreview() })\" [keywords]=\"text.timeZoneKeywords\">\n <hm-combobox\n class=\"sp-settings__timezone\"\n [label]=\"text.timeZone\"\n [labelHidden]=\"true\"\n icon=\"world\"\n [options]=\"timeZoneOptions()\"\n [value]=\"preferences.timeZone()\"\n (valueChange)=\"preferences.setTimeZone($event)\"\n />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.hourCycle\" [description]=\"fmt(text.hourCycleHint, { now: hourCyclePreview() })\" [keywords]=\"text.hourCycleKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.hourCycle\" [options]=\"hourCycleOptions()\" [value]=\"preferences.hourCycle()\" (valueChange)=\"setHourCycle($event)\" />\n </hm-settings-row>\n\n <hm-settings-row [label]=\"text.weekStart\" [description]=\"text.weekStartDescription\" [keywords]=\"text.weekStartKeywords\">\n <hm-segmented-control emphasis=\"action\" [label]=\"text.weekStart\" [options]=\"weekStartOptions()\" [value]=\"weekStartValue()\" (valueChange)=\"setWeekStart($event)\" />\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── Notificações (SpineFeatures.notices) ──────────────────────────── -->\n <!-- Os tipos de aviso que o app declarou (SpineNoticesService) e o aviso do navegador com a aba em segundo plano. -->\n @if (notices.enabled) {\n <hm-settings-section [key]=\"keys.notices\" [label]=\"featureText.notices\" icon=\"bell\" [description]=\"featureText.noticesDescription\" [keywords]=\"featureText.noticesKeywords\">\n @for (type of notices.types; track type.id) {\n <hm-settings-row [label]=\"type.label\" [description]=\"type.description ?? ''\">\n <hm-checkbox [label]=\"type.label\" [labelHidden]=\"true\" [checked]=\"notices.isEnabled(type.id)\" (checkedChange)=\"notices.setEnabled(type.id, $event)\" />\n </hm-settings-row>\n }\n <hm-settings-row [label]=\"featureText.browserNotices\" [description]=\"notices.permission() === 'denied' ? featureText.browserNoticesDenied : notices.permission() === 'unsupported' ? featureText.browserNoticesUnsupported : featureText.browserNoticesDescription\">\n <hm-checkbox [label]=\"featureText.browserNotices\" [labelHidden]=\"true\" [checked]=\"notices.browserActive()\" (checkedChange)=\"setBrowserNotices($event)\" />\n </hm-settings-row>\n </hm-settings-section>\n }\n\n <!-- ── Atalhos ───────────────────────────────────────────────────────── -->\n <hm-settings-section [key]=\"keys.shortcuts\" [label]=\"text.shortcuts\" icon=\"keyboard\" [description]=\"text.shortcutsDescription\" [keywords]=\"text.shortcutsKeywords\">\n <!-- Mesma lista do painel \"?\", sem busca (a do diálogo de configurações já cobre a seção);\n o interruptor de tecla única (WCAG 2.1.4) persiste no SpinePreferencesService. -->\n <hm-shortcut-list class=\"sp-settings__shortcuts\" characterKeysToggle [registered]=\"false\" [items]=\"shortcutItems()\" [headingLevel]=\"4\" />\n </hm-settings-section>\n\n <!-- ── Dados do navegador ────────────────────────────────────────────── -->\n <!-- Listas por usuário do SpineUserStorage e as preferências deste painel. Destrutivo: o 1º clique pede\n confirmação (botão vira \"Confirmar\" + Cancelar), como nas listas de tokens e sessões. -->\n <hm-settings-section [key]=\"keys.data\" [label]=\"text.browserData\" icon=\"browser-setting\" [description]=\"text.browserDataDescription\" [keywords]=\"text.browserDataKeywords\">\n <!-- SpineFeatures.accountPreferences: as preferências também na conta do Argos (as telas acima não mudam). -->\n @if (features.accountPreferences) {\n <hm-settings-row [label]=\"featureText.sync\" [description]=\"syncStatus() || featureText.syncDescription\" [keywords]=\"featureText.syncKeywords\">\n <hm-toggletip rowHelp [label]=\"fmt(text.moreAbout, { label: featureText.sync })\" [text]=\"featureText.syncDescription\" />\n <hm-button emphasis=\"medium\" icon=\"refresh\" [disabled]=\"accountPreferences.status() === 'local'\" [loading]=\"accountPreferences.status() === 'saving' || accountPreferences.status() === 'loading'\" (clicked)=\"syncNow()\">{{ featureText.syncNow }}</hm-button>\n </hm-settings-row>\n }\n @for (list of browserLists(); track list.id) {\n <hm-settings-row [label]=\"list.label\" [description]=\"list.count\" [keywords]=\"list.keywords\">\n <span class=\"sp-settings__actions\">\n @if (confirming() === list.id) {\n <hm-button emphasis=\"medium\" (clicked)=\"cancelConfirm()\">{{ text.cancel }}</hm-button>\n }\n <hm-button\n [emphasis]=\"confirming() === list.id ? 'high' : 'medium'\"\n intent=\"danger\"\n [disabled]=\"list.empty && confirming() !== list.id\"\n (clicked)=\"clearList(list.id)\"\n >{{ confirming() === list.id ? text.confirmClear : text.clear }}</hm-button>\n </span>\n </hm-settings-row>\n }\n\n <hm-settings-row [label]=\"text.restorePreferences\" [description]=\"text.restorePreferencesDescription\" [keywords]=\"text.restorePreferencesKeywords\">\n <hm-toggletip rowHelp [label]=\"fmt(text.moreAbout, { label: text.restorePreferences })\" [text]=\"text.restorePreferencesHelp\" />\n <span class=\"sp-settings__actions\">\n @if (confirming() === 'preferences') {\n <hm-button emphasis=\"medium\" (clicked)=\"cancelConfirm()\">{{ text.cancel }}</hm-button>\n }\n <hm-button [emphasis]=\"confirming() === 'preferences' ? 'high' : 'medium'\" intent=\"danger\" (clicked)=\"restorePreferences()\">\n {{ confirming() === 'preferences' ? text.confirmRestore : text.restore }}\n </hm-button>\n </span>\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── Ajuda ─────────────────────────────────────────────────────────── -->\n <!-- Novidades (só com alguma vigente), configuração inicial e o essencial: fecham o painel antes de abrir. -->\n <hm-settings-section [key]=\"keys.help\" [label]=\"text.help\" icon=\"help\" [keywords]=\"text.helpKeywords\">\n @if (hasNews()) {\n <hm-settings-row [label]=\"text.news\" [description]=\"text.newsDescription\" [keywords]=\"text.newsKeywords\">\n <hm-button emphasis=\"medium\" icon=\"star\" (clicked)=\"showNews()\">{{ text.showNews }}</hm-button>\n </hm-settings-row>\n }\n @if (setupEnabled) {\n <hm-settings-row [label]=\"text.setup\" [description]=\"text.setupDescription\" [keywords]=\"text.setupKeywords\">\n <hm-button emphasis=\"medium\" icon=\"color-palette\" (clicked)=\"redoSetup()\">{{ text.redoSetup }}</hm-button>\n </hm-settings-row>\n }\n <hm-settings-row [label]=\"text.essentials\" [description]=\"text.essentialsDescription\" [keywords]=\"text.essentialsKeywords\">\n <hm-button emphasis=\"medium\" icon=\"help\" (clicked)=\"showEssentials()\">{{ text.showEssentials }}</hm-button>\n </hm-settings-row>\n </hm-settings-section>\n\n <!-- ── Seções do app (provideSettingsSection) ────────────────────────── -->\n @for (s of appSections; track s.key) {\n <hm-settings-section [key]=\"s.key\" [label]=\"s.label\" [icon]=\"s.icon ?? 'cog'\" [description]=\"s.description ?? ''\" [keywords]=\"s.keywords ?? ''\">\n <ng-container *ngComponentOutlet=\"s.component\" />\n </hm-settings-section>\n }\n\n <!-- ── Sobre ─────────────────────────────────────────────────────────── -->\n <hm-settings-section [key]=\"keys.about\" [label]=\"text.about\" icon=\"info-circle\" [keywords]=\"text.aboutKeywords\">\n <hm-settings-row [label]=\"text.application\">\n <span class=\"sp-settings__value\">{{ appName }}@if (packageInfo.name) { <span class=\"sp-settings__muted\"> · {{ packageInfo.name }}</span> }</span>\n </hm-settings-row>\n <!-- Média da ferramenta (SpineFeatures.ratings) e \"Avaliar\", que abre o diálogo da estrela do cabeçalho. -->\n @if (ratingsEnabled) {\n <hm-settings-row [label]=\"ratingText.aboutRating\" [keywords]=\"ratingText.aboutRatingKeywords\">\n <spine-app-rating-summary />\n </hm-settings-row>\n }\n <hm-settings-row [label]=\"text.version\" [keywords]=\"text.versionKeywords\">\n <span class=\"sp-settings__value sp-settings__mono\">{{ packageInfo.version ?? '—' }}</span>\n </hm-settings-row>\n @if (buildDate) {\n <hm-settings-row [label]=\"text.buildDate\">\n <span class=\"sp-settings__value\">{{ buildDate }}</span>\n </hm-settings-row>\n }\n @if (packageInfo.environment) {\n <hm-settings-row [label]=\"text.environment\" [keywords]=\"text.environmentKeywords\">\n <span class=\"sp-settings__value\">{{ packageInfo.environment }}</span>\n </hm-settings-row>\n }\n @if (packageInfo.repository?.url || packageInfo.docs || packageInfo.issues) {\n <hm-settings-row [label]=\"text.links\" [keywords]=\"text.linksKeywords\">\n <span class=\"sp-settings__links\">\n @if (packageInfo.docs) { <hm-button emphasis=\"medium\" icon=\"book\" [link]=\"packageInfo.docs\" [newTab]=\"true\">{{ text.docs }}</hm-button> }\n @if (packageInfo.issues) { <hm-button emphasis=\"medium\" icon=\"bug\" [link]=\"packageInfo.issues\" [newTab]=\"true\">{{ text.reportIssue }}</hm-button> }\n @if (packageInfo.repository?.url) { <hm-button emphasis=\"medium\" icon=\"link\" [link]=\"packageInfo.repository!.url!\" [newTab]=\"true\">{{ text.repository }}</hm-button> }\n </span>\n </hm-settings-row>\n }\n @if (dependencies.length) {\n <hm-settings-row [label]=\"text.dependencies\" [description]=\"text.dependenciesDescription\" [keywords]=\"text.dependenciesKeywords\" [stacked]=\"true\">\n <dl class=\"sp-settings__deps\">\n @for (d of dependencies; track d.name) {\n <div><dt>{{ d.label }}</dt><dd class=\"sp-settings__mono\">{{ d.version }}</dd></div>\n }\n </dl>\n </hm-settings-row>\n }\n <hm-settings-row [label]=\"text.supportInfo\" [description]=\"text.supportInfoDescription\" [keywords]=\"text.supportInfoKeywords\">\n <hm-button emphasis=\"medium\" icon=\"clipboard\" (clicked)=\"copySupportInfo()\">{{ text.copy }}</hm-button>\n </hm-settings-row>\n </hm-settings-section>\n </hm-settings-dialog>\n}\n","import { DestroyRef, Injectable, computed, inject, isDevMode, signal } from '@angular/core';\nimport { ViewService } from '@orfeu/angular/core';\nimport { Route, SPINE_CONFIG, SPINE_MESSAGES, routerIdOf, spineRoutesOf } from '@trismegisto/spine';\nimport { ComponentDistributorService, RouteDocument, componentRouterId } from '@trismegisto/spine/routing';\n\n/** Documento de uma tela que a pessoa logada pode abrir. */\nexport interface DocsEntry extends RouteDocument {\n /** Chave da tela (router_id ou, sem ele, o do template), sempre em minúsculas. */\n readonly id: string;\n readonly title: string;\n readonly group: string;\n}\n\nexport interface DocsGroup {\n readonly title: string;\n readonly entries: readonly DocsEntry[];\n}\n\nexport type DocsView = 'usage' | 'technical';\n\ninterface ScreenInfo {\n readonly label: string;\n readonly module: string;\n}\n\n/**\n * Estado da documentação das telas: o que está registrado em `COMPONENT_ROUTES` com `document`,\n * filtrado pelas telas que existem na árvore da pessoa (documento de tela sem acesso nunca é oferecido),\n * e a leitura em andamento no modal `spine-docs`.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineDocsService {\n readonly #distributor = inject(ComponentDistributorService);\n readonly #views = inject(ViewService);\n readonly #messages = inject(SPINE_MESSAGES);\n\n /** Visão técnica liberada (`SpineConfig.technicalDocs`; sem configuração, só em desenvolvimento). */\n readonly technicalAvailable: boolean = inject(SPINE_CONFIG, { optional: true })?.technicalDocs ?? isDevMode();\n\n readonly #isOpen = signal(false);\n readonly #current = signal<DocsEntry | null>(null);\n readonly #view = signal<DocsView>('usage');\n readonly #content = signal('');\n readonly #loading = signal(false);\n readonly #failed = signal(false);\n /** Identifica a leitura vigente; respostas de leituras anteriores são ignoradas. */\n #ticket = 0;\n /** A view do Orfeu não é um signal: este contador força a releitura da árvore. */\n readonly #treeRevision = signal(0);\n\n readonly isOpen = this.#isOpen.asReadonly();\n readonly current = this.#current.asReadonly();\n readonly view = this.#view.asReadonly();\n readonly content = this.#content.asReadonly();\n readonly loading = this.#loading.asReadonly();\n readonly error = computed(() => (this.#failed() ? this.#messages.docs.loadError : ''));\n readonly showTechnical = computed(\n () => this.technicalAvailable && !!this.#current()?.loadTechnical,\n );\n\n readonly #offered = computed<ReadonlyMap<string, DocsEntry>>(() => {\n this.#treeRevision();\n const screens = this.#screens();\n const offered = new Map<string, DocsEntry>();\n for (const registered of this.#distributor.entries) {\n const document = registered.document;\n if (!document) continue;\n const key = (componentRouterId(registered) ?? registered.source_template_router_id)?.toLowerCase();\n if (!key || offered.has(key)) continue;\n const screen = screens.get(key);\n if (!screen) continue;\n offered.set(key, {\n ...document,\n id: key,\n title: document.title ?? screen.label,\n group: document.group ?? screen.module,\n });\n }\n return offered;\n });\n\n readonly index = computed<DocsGroup[]>(() => {\n const locale = this.#messages.meta.locale;\n const compare = (a: string, b: string) => a.localeCompare(b, locale);\n const byGroup = new Map<string, DocsEntry[]>();\n for (const entry of this.#offered().values()) {\n const list = byGroup.get(entry.group);\n if (list) list.push(entry);\n else byGroup.set(entry.group, [entry]);\n }\n return [...byGroup]\n .map(([title, entries]) => ({ title, entries: entries.sort((a, b) => compare(a.title, b.title)) }))\n .sort((a, b) => compare(a.title, b.title));\n });\n\n constructor() {\n // Quando a view muda (login, troca de crachá), o botão da barra da página acompanha sem esperar\n // a próxima abertura.\n const changes = (this.#views as Partial<Pick<ViewService, 'currentView$'>>).currentView$;\n // A emissão síncrona da inscrição é a view que o `#offered` já lê; só as seguintes importam.\n let subscribed = false;\n const subscription = changes?.subscribe?.(() => {\n if (subscribed) this.#refreshTree();\n });\n subscribed = true;\n if (subscription) inject(DestroyRef).onDestroy(() => subscription.unsubscribe());\n }\n\n documentFor(routerId: string | null | undefined, sourceTemplateRouterId?: string | null): DocsEntry | null {\n const offered = this.#offered();\n for (const candidate of [routerId, sourceTemplateRouterId]) {\n if (!candidate) continue;\n const entry = offered.get(candidate.toLowerCase());\n if (entry) return entry;\n }\n return null;\n }\n\n openForRoute(routerId: string | null | undefined, sourceTemplateRouterId?: string | null): void {\n this.#refreshTree();\n this.#isOpen.set(true);\n const entry = this.documentFor(routerId, sourceTemplateRouterId);\n if (entry) void this.open(entry);\n }\n\n openIndex(): void {\n this.#refreshTree();\n this.#isOpen.set(true);\n }\n\n close(): void {\n this.#isOpen.set(false);\n }\n\n open(entry: DocsEntry, view: DocsView = 'usage'): Promise<void> {\n this.#current.set(entry);\n return this.show(view);\n }\n\n async show(view: DocsView): Promise<void> {\n const entry = this.#current();\n if (!entry) return;\n const technical = view === 'technical' && this.technicalAvailable ? entry.loadTechnical : undefined;\n const ticket = ++this.#ticket;\n\n this.#view.set(technical ? 'technical' : 'usage');\n this.#loading.set(true);\n this.#failed.set(false);\n\n let text = '';\n let failed = false;\n try {\n text = await (technical ?? entry.load)();\n } catch {\n failed = true;\n }\n if (ticket !== this.#ticket) return;\n\n this.#content.set(failed ? '' : text);\n this.#failed.set(failed);\n this.#loading.set(false);\n }\n\n #refreshTree(): void {\n this.#treeRevision.update((n) => n + 1);\n }\n\n /** Telas da árvore da pessoa, por router_id e por template, com rótulo e módulo de topo. */\n #screens(): Map<string, ScreenInfo> {\n const screens = new Map<string, ScreenInfo>();\n const visit = (node: Route, module: string) => {\n const info: ScreenInfo = { label: node.route_display_name ?? '', module };\n for (const key of [routerIdOf(node), node.source_template_router_id]) {\n if (key && !screens.has(key.toLowerCase())) screens.set(key.toLowerCase(), info);\n }\n for (const child of node.routes ?? []) visit(child, module);\n };\n for (const root of spineRoutesOf(this.#views.currentView)) visit(root, root.route_display_name ?? '');\n return screens;\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';\nimport { IconButtonComponent, TooltipDirective } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineRatingTarget, SpineRatingsService } from './ratings.service';\n\n/**\n * \"Avaliar esta tela\" na barra da página (`spine-page-bar`): a estrela abre a janela de avaliação (flutuante, no canto\n * inferior direito; `spine-rating-window`) para esta tela — a pessoa avalia vendo a tela. A barra só passa a rota e o\n * caminho legível; o resto mora aqui. Sem `SpineFeatures.ratings` ou sem `SPINE_ADMIN_API`, não desenha nada.\n *\n * O formulário só existe com a janela aberta: é ao abrir que ele lê a avaliação anterior, nunca a cada tela visitada.\n * A estrela fica cheia depois que a pessoa avalia (nesta sessão do app).\n */\n@Component({\n selector: 'spine-rate-screen-button',\n imports: [IconButtonComponent, TooltipDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (enabled && screenPath()) {\n <hm-icon-button\n emphasis=\"subtle\"\n icon=\"star\"\n [solid]=\"rated()\"\n [label]=\"text.rateScreen\"\n [hmTooltip]=\"text.rateScreen\"\n [class.spine-rate-screen--rated]=\"rated()\"\n (clicked)=\"ratings.openScreen(target())\"\n />\n }\n `,\n styles: [`\n :host { display: contents; }\n .spine-rate-screen--rated { color: var(--hm-warning); }\n `],\n})\nexport class SpineRateScreenButtonComponent {\n /** Rota da tela (chave da avaliação); vazia = sem botão. */\n readonly screenPath = input<string | null>(null);\n /** Caminho legível (\"Módulo › Tela\"), guardado junto para o auto-serviço mostrar. */\n readonly screenLabel = input<string | null>(null);\n\n protected readonly text = inject(SPINE_MESSAGES).ratings;\n protected readonly ratings = inject(SpineRatingsService);\n protected readonly enabled = this.ratings.enabled;\n\n protected readonly target = computed<SpineRatingTarget>(() => ({\n scope: 'screen', screenPath: this.screenPath(), screenLabel: this.screenLabel(),\n }));\n protected readonly rated = computed(() => this.ratings.isRated(this.target()));\n}\n","import type { Route } from '@trismegisto/spine';\n\n/** Uma tela que dá para escolher no \"Sugerir melhoria\": a rota, o `router_id` e o caminho legível (\"Módulo › Tela\"). */\nexport interface SuggestionScreenOption {\n path: string;\n routerId: string | null;\n /** O nome da tela (o último nível). */\n name: string;\n /** O caminho inteiro, como a barra da página mostra (\"Vendas › Pedidos › Consulta\"): é o que vai para o `screen.label`. */\n label: string;\n icon: string;\n}\n\n/** Valor da opção \"Nova tela\" no seletor (não é rota: nenhuma rota começa sem \"/\"). */\nexport const NEW_SCREEN_VALUE = 'nova-tela';\n\n/** Itens do menu que não são telas (ações da barra lateral). */\nconst NOT_SCREENS = new Set(['search', 'theme', 'logout']);\n\n/**\n * As telas que a pessoa alcança, da árvore de rotas que ela já recebe (`spineRoutesOf(view)`), na ordem do menu: cada\n * nó com endereço e nome, com o caminho dos ancestrais com endereço (o mesmo \"Módulo › … › Tela\" da barra da página).\n * Um endereço aparece uma vez só (o primeiro). Nó com endereço e filhos (módulo que também é página) entra.\n */\nexport function suggestionScreens(routes: readonly Route[] | null | undefined): SuggestionScreenOption[] {\n const out: SuggestionScreenOption[] = [];\n const seen = new Set<string>();\n const walk = (list: readonly Route[], trail: string[], icon: string | null) => {\n for (const r of list) {\n if (!r) continue;\n const name = r.route_display_name?.trim() || '';\n const ownIcon = r.route_icon || icon;\n const path = r.route_redirect || '';\n if (path && name && !NOT_SCREENS.has(r.route_type ?? '') && !seen.has(path)) {\n seen.add(path);\n out.push({\n path, routerId: r.router_id ?? null, name, label: [...trail, name].join(' › '), icon: ownIcon || 'application',\n });\n }\n // Grupo sem endereço não entra no caminho: a barra da página (de onde vinha o rótulo até aqui) também o pula.\n if (r.routes?.length) walk(r.routes, name && path ? [...trail, name] : trail, ownIcon);\n }\n };\n walk(routes ?? [], [], null);\n return out;\n}\n\n/** O módulo (primeiro nível) de um caminho legível: \"Vendas › Pedidos\" → \"Vendas\". */\nexport function screenModule(label: string | null | undefined): string {\n return (label ?? '').split(' › ')[0]?.trim() ?? '';\n}\n\n/** O nome da tela (último nível) de um caminho legível: \"Vendas › Pedidos › Consulta\" → \"Consulta\". */\nexport function screenName(label: string | null | undefined): string {\n return (label ?? '').split(' › ').at(-1)?.trim() ?? '';\n}\n","import { HttpClient, HttpParams } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { SPINE_ADMIN_API } from '@trismegisto/spine';\nimport { urlPath } from '@trismegisto/primitives';\nimport type { TagColor } from '@trismegisto/angular';\nimport { sendWithSession } from '../session-token';\n\n/** Tipos de sugestão, como o Argos guarda (`web.app_suggestions.kind`). */\nexport const SPINE_SUGGESTION_KINDS = ['melhoria', 'nova_funcionalidade', 'problema', 'outro'] as const;\nexport type SpineSuggestionKind = (typeof SPINE_SUGGESTION_KINDS)[number];\n\n/**\n * Os status, na ordem das colunas. Toda sugestão nasce `em_analise` (o antigo \"Nova\" saiu; ainda aparece no histórico,\n * pelo `legacyStatuses` do catálogo). `concluida` e `recusada` encerram: recusada sai do quadro na hora, concluída\n * depois de alguns dias (o servidor decide; ver `done_days` do quadro), e as duas ficam no arquivo.\n */\nexport const SPINE_SUGGESTION_STATUSES = ['em_analise', 'planejada', 'em_desenvolvimento', 'concluida', 'recusada'] as const;\nexport type SpineSuggestionStatus = (typeof SPINE_SUGGESTION_STATUSES)[number];\n\n/** Os status que aparecem em \"Sugestões do app\" (as de todo mundo): a recusada não entra (nem a arquivada pela equipe). */\nexport const SPINE_SUGGESTION_PUBLIC_STATUSES = ['em_analise', 'planejada', 'em_desenvolvimento', 'concluida'] as const;\nexport type SpineSuggestionPublicStatus = (typeof SPINE_SUGGESTION_PUBLIC_STATUSES)[number];\n\n/** Ordem de \"Sugestões do app\": as mais apoiadas (padrão do servidor) ou as mais novas. */\nexport const SPINE_SUGGESTION_PUBLIC_SORTS = ['votes', 'recent'] as const;\nexport type SpineSuggestionPublicSort = (typeof SPINE_SUGGESTION_PUBLIC_SORTS)[number];\n\n/** Cor da etiqueta de status (a mesma em \"Minhas sugestões\" e no kanban do auto-serviço). */\nexport const SPINE_SUGGESTION_STATUS_COLORS: Record<SpineSuggestionStatus, TagColor> = {\n em_analise: 'info', planejada: 'primary', em_desenvolvimento: 'warning', concluida: 'success', recusada: 'neutral',\n};\n\n/** Ícone de cada status (coluna do kanban, etiqueta do arquivo). */\nexport const SPINE_SUGGESTION_STATUS_ICONS: Record<SpineSuggestionStatus, string> = {\n em_analise: 'magnifying-glass', planejada: 'calendar-check', em_desenvolvimento: 'code', concluida: 'check-circle', recusada: 'ban',\n};\n\n/** Ícone e cor de cada tipo (o modal de nova sugestão e o cartão do kanban). */\nexport const SPINE_SUGGESTION_KIND_ICONS: Record<SpineSuggestionKind, string> = {\n melhoria: 'lightbulb', nova_funcionalidade: 'rocket-diagonal', problema: 'bug', outro: 'ballon-question',\n};\nexport const SPINE_SUGGESTION_KIND_COLORS: Record<SpineSuggestionKind, TagColor> = {\n melhoria: 'primary', nova_funcionalidade: 'info', problema: 'danger', outro: 'neutral',\n};\n\n/** Limites do servidor (colunas da migration): o formulário corta antes. */\nexport const SPINE_SUGGESTION_LIMITS = { title: 140, description: 4000, screen: 512 } as const;\n\nexport interface SpineSuggestionPerson { user_id: string; username: string | null; name: string | null; picture: string | null }\n\n/** Uma sugestão como o argos-admin devolve (`/me/suggestions` e `/auto-service/:clientId/suggestions`). */\nexport interface SpineSuggestion {\n id: string;\n /** A chave da sugestão no app (\"SUG-12\"), a mesma que a equipe usa no quadro. */\n key?: string;\n kind: SpineSuggestionKind;\n title: string;\n description: string;\n screen: SpineSuggestionScreen;\n status: SpineSuggestionStatus;\n position: number;\n votes: number;\n /** Quem consulta também apoia (só nas leituras da pessoa). */\n voted: boolean;\n comments_count: number;\n last_comment: { comment: string; created_at: string } | null;\n /** Desde quando está no status atual (o último evento para ele; sem evento, a criação). */\n status_at?: string;\n /** Com quem está a vez na conversa (null = em dia). */\n waiting_on?: SpineSuggestionWaiting | null;\n waiting_since?: string | null;\n created_at: string;\n updated_at: string;\n /** Só no auto-serviço: quem pediu, com a foto (null = pessoa removida). */\n author?: SpineSuggestionPerson | null;\n /** Só em \"já pediram nesta tela\": a sugestão é de quem consulta (autora ou relatora). */\n mine?: boolean;\n /** Só em \"Minhas\": quem consulta é relatora (a sugestão dela foi agrupada nesta), não a autora. */\n reporter?: boolean;\n /** Só em \"Minhas\": as sugestões de quem consulta agrupadas nesta (\"SUG-30 agrupada em SUG-12\"). */\n merged_from?: Array<{ id: string; key: string; title: string }>;\n}\n\n/**\n * Uma sugestão em \"Sugestões do app\" (`/me/suggestions/all`): só o que é público do pedido, de quem quer que seja —\n * nada do quadro de trabalho da equipe, e os comentários contados e o último são só os públicos.\n */\nexport interface SpineAppSuggestion {\n id: string;\n key: string;\n kind: SpineSuggestionKind;\n title: string;\n /** Texto puro (a descrição inteira, até 4000). */\n description: string;\n screen: SpineSuggestionScreen;\n status: SpineSuggestionStatus;\n votes: number;\n /** Quem consulta apoia. */\n voted: boolean;\n /** É de quem consulta: não dá para apoiar (o servidor responde `409 own_suggestion`). */\n mine: boolean;\n comments_count: number;\n last_comment: { comment: string; created_at: string } | null;\n created_at: string;\n /** Quem pediu, com a foto (null = pessoa removida). */\n author: SpineSuggestionPerson | null;\n}\n\n/** Comentário público de uma sugestão (`/me/suggestions/:id/comments`); `status` = a mudança que ele acompanha. */\nexport interface SpineSuggestionComment {\n id: string;\n comment: string;\n status: SpineSuggestionStatus | null;\n created_at: string;\n author: SpineSuggestionPerson | null;\n}\n\nexport interface SpineAppSuggestionsQuery {\n limit: number;\n offset: number;\n status?: SpineSuggestionPublicStatus | '';\n /** Título, descrição, tela ou a chave (\"SUG-12\"). */\n q?: string;\n /** Só as pedidas nesta rota. */\n screen?: string;\n sort?: SpineSuggestionPublicSort;\n}\n\nexport interface SpineSuggestionDraft {\n kind: SpineSuggestionKind;\n title: string;\n /** Texto puro (o formato antigo; o servidor ainda aceita). */\n description?: string;\n /** A descrição em rich text (o editor do modal); o servidor saneia e deriva o texto puro. */\n description_html?: string;\n /** Tela do menu (`router_id` e a rota) ou `new: true` com o nome da tela que ainda não existe em `label`. */\n screen: { path: string | null; label: string | null; router_id?: string | null; new?: boolean };\n}\n\n/** Por que a pessoa vê a sugestão (o servidor decide; uma sugestão pode ter vários). */\nexport const SPINE_SUGGESTION_REASONS = ['autor', 'relator', 'envolvido', 'responsavel', 'grupo'] as const;\nexport type SpineSuggestionReason = (typeof SPINE_SUGGESTION_REASONS)[number];\n\n/** Com quem está a vez na conversa: quem pediu (a equipe respondeu) ou a equipe (quem pediu escreveu). */\nexport const SPINE_SUGGESTION_WAITING = ['solicitante', 'responsaveis'] as const;\nexport type SpineSuggestionWaiting = (typeof SPINE_SUGGESTION_WAITING)[number];\n\n/** Cor do selo \"Aguardando…\": a vez de quem pede chama atenção; a da equipe, não. */\nexport const SPINE_SUGGESTION_WAITING_COLORS: Record<SpineSuggestionWaiting, TagColor> = { solicitante: 'warning', responsaveis: 'info' };\n\nexport const SPINE_SUGGESTION_VISIBLE_SORTS = ['activity', 'recent', 'votes'] as const;\nexport type SpineSuggestionVisibleSort = (typeof SPINE_SUGGESTION_VISIBLE_SORTS)[number];\n\n/** A tela de uma sugestão: a do menu (`router_id`, rota e o caminho legível) ou uma nova (`new`, o nome no `label`). */\nexport interface SpineSuggestionScreen { path: string | null; label: string | null; router_id?: string | null; new?: boolean }\n\n/**\n * Uma sugestão que a pessoa VÊ (`/me/suggestions/visible` e o detalhe): as dela, as do grupo dela e as em que ela está\n * envolvida, com os motivos (`reasons`), se ela pode conversar (`can_comment`, quem tem motivo pessoal) e com quem está\n * a vez (`waiting_on`).\n */\nexport interface SpineVisibleSuggestion {\n id: string;\n key: string;\n kind: SpineSuggestionKind;\n title: string;\n description: string;\n /** A descrição em rich text (saneada pelo servidor); vazia sem descrição. */\n description_html?: string;\n screen: SpineSuggestionScreen;\n status: SpineSuggestionStatus;\n status_at?: string;\n votes: number;\n voted: boolean;\n mine: boolean;\n reasons: SpineSuggestionReason[];\n can_comment: boolean;\n waiting_on: SpineSuggestionWaiting | null;\n waiting_since: string | null;\n comments_count: number;\n last_comment: { comment: string; created_at: string } | null;\n /** Mensagens de outras pessoas que quem consulta ainda não leu. */\n unread: number;\n archived: boolean;\n merged_from: Array<{ id: string; key: string; title: string }>;\n groups: Array<{ id: string; name: string }>;\n author: SpineSuggestionPerson | null;\n assignees: SpineSuggestionPerson[];\n created_at: string;\n updated_at: string;\n last_activity_at?: string;\n}\n\n/** Contagens do conjunto visível inteiro (sem os filtros), para os filtros rápidos da página. */\nexport type SpineVisibleCounts = Record<SpineSuggestionReason, number> & { waiting_me: number; unread: number };\n\nexport interface SpineVisibleQuery {\n limit: number;\n offset: number;\n reason?: SpineSuggestionReason | '';\n status?: SpineSuggestionStatus | '';\n kind?: SpineSuggestionKind | '';\n waiting?: SpineSuggestionWaiting | '';\n screen?: string;\n newScreen?: boolean;\n q?: string;\n sort?: SpineSuggestionVisibleSort;\n}\n\n/** Mensagem da conversa (comentário público): `from_requester` = escrita por quem pediu ou um envolvido. */\nexport interface SpineSuggestionMessage extends SpineSuggestionComment {\n from_requester?: boolean;\n}\n\n/**\n * Sugestões de melhoria da pessoa — `argos-admin /me/suggestions`. Sempre da aplicação LOGADA (o servidor tira o client\n * do access-token da sessão) e com o token da sessão (o servidor recusa x-app-token). Sem `SPINE_ADMIN_API` não há\n * para onde mandar: o botão da barra da página nem aparece (`SpineSuggestButtonComponent`).\n */\n/** Uma sugestão acompanhada com novidade (`/me/suggestions/updates`): a central de notificações. */\nexport interface SpineSuggestionUpdate {\n id: string;\n key: string;\n title: string;\n status: SpineSuggestionStatus;\n /** Quantas novidades desde a última leitura (comentários públicos e mudanças de status de outras pessoas). */\n count: number;\n /** A mais recente: o comentário (até 200) ou o status novo, e quem fez. */\n last: { kind: 'comment' | 'status'; status: SpineSuggestionStatus | null; comment: string | null; at: string; author: SpineSuggestionPerson | null };\n}\n\n@Injectable({ providedIn: 'root' })\nexport class SpineSuggestionsService {\n private readonly http = inject(HttpClient);\n private readonly auth = inject(AuthorizationService);\n private readonly adminApi = inject(SPINE_ADMIN_API, { optional: true });\n\n private url(strings: TemplateStringsArray, ...ids: readonly string[]): string {\n return `${this.adminApi}/me/suggestions${urlPath(strings, ...ids)}`;\n }\n\n create(draft: SpineSuggestionDraft): Promise<SpineSuggestion> {\n return sendWithSession(this.auth, (headers) => this.http.post<SpineSuggestion>(this.url``, draft, { headers }));\n }\n\n /** As minhas, da mais nova; `status` filtra uma coluna. */\n async mine(opts: { limit: number; offset: number; status?: SpineSuggestionStatus | '' }): Promise<{ suggestions: SpineSuggestion[]; total: number }> {\n let params = new HttpParams().set('limit', opts.limit).set('offset', opts.offset);\n if (opts.status) params = params.set('status', opts.status);\n return sendWithSession(this.auth, (headers) => this.http.get<{ suggestions: SpineSuggestion[]; total: number }>(this.url``, { headers, params }));\n }\n\n /** \"Sugestões do app\": as de todas as pessoas no app (menos recusadas e arquivadas), com filtros e paginação. */\n async all(query: SpineAppSuggestionsQuery): Promise<{ suggestions: SpineAppSuggestion[]; total: number }> {\n let params = new HttpParams().set('limit', query.limit).set('offset', query.offset);\n if (query.status) params = params.set('status', query.status);\n if (query.q?.trim()) params = params.set('q', query.q.trim());\n if (query.screen) params = params.set('screen', query.screen);\n if (query.sort) params = params.set('sort', query.sort);\n return sendWithSession(this.auth, (headers) => this.http.get<{ suggestions: SpineAppSuggestion[]; total: number }>(this.url`/all`, { headers, params }));\n }\n\n /** Os comentários públicos de uma sugestão (a conversa), do mais novo. */\n async comments(id: string, page: { limit: number; offset: number }): Promise<{ comments: SpineSuggestionMessage[]; total: number }> {\n const params = new HttpParams().set('limit', page.limit).set('offset', page.offset);\n return sendWithSession(this.auth, (headers) => this.http.get<{ comments: SpineSuggestionMessage[]; total: number }>(this.url`/${id}/comments`, { headers, params }));\n }\n\n /**\n * As que a pessoa vê (página \"Sugestões do app\"): as dela, as agrupadas, as em que está envolvida e as do grupo dela,\n * com filtros e paginação no servidor; `counts` é do conjunto inteiro (os números dos filtros rápidos).\n */\n async visible(query: SpineVisibleQuery): Promise<{ suggestions: SpineVisibleSuggestion[]; total: number; counts: SpineVisibleCounts | null }> {\n let params = new HttpParams().set('limit', query.limit).set('offset', query.offset);\n if (query.reason) params = params.set('reason', query.reason);\n if (query.status) params = params.set('status', query.status);\n if (query.kind) params = params.set('kind', query.kind);\n if (query.waiting) params = params.set('waiting', query.waiting);\n if (query.screen) params = params.set('screen', query.screen);\n if (query.newScreen) params = params.set('new_screen', 'true');\n if (query.q?.trim()) params = params.set('q', query.q.trim());\n if (query.sort) params = params.set('sort', query.sort);\n const res = await sendWithSession(this.auth, (headers) => this.http.get<{ suggestions: SpineVisibleSuggestion[]; total: number; counts?: SpineVisibleCounts }>(this.url`/visible`, { headers, params }));\n return { suggestions: res.suggestions ?? [], total: res.total ?? 0, counts: res.counts ?? null };\n }\n\n /** Uma que a pessoa vê, pelo id (404 se não vê). */\n get(id: string): Promise<SpineVisibleSuggestion> {\n return sendWithSession(this.auth, (headers) => this.http.get<SpineVisibleSuggestion>(this.url`/${id}`, { headers }));\n }\n\n /** Pela chave (\"SUG-12\"): o link \"?sugestao=SUG-12\" abre a sugestão na página. */\n lookup(key: string): Promise<SpineVisibleSuggestion> {\n const params = new HttpParams().set('key', key);\n return sendWithSession(this.auth, (headers) => this.http.get<SpineVisibleSuggestion>(this.url`/lookup`, { headers, params }));\n }\n\n /** Escreve na conversa (quem pediu ou um envolvido): a vez passa para os responsáveis. */\n reply(id: string, comment: string): Promise<SpineSuggestionMessage> {\n return sendWithSession(this.auth, (headers) => this.http.post<SpineSuggestionMessage>(this.url`/${id}/comments`, { comment }, { headers }));\n }\n\n /** As que a pessoa acompanha com novidade, a mais recente primeiro; `total` = quantas têm novidade. */\n updates(limit = 20): Promise<{ updates: SpineSuggestionUpdate[]; total: number }> {\n const params = new HttpParams().set('limit', limit);\n return sendWithSession(this.auth, (headers) => this.http.get<{ updates: SpineSuggestionUpdate[]; total: number }>(this.url`/updates`, { headers, params }));\n }\n\n /** Marca a conversa como lida por quem consulta (zera o `unread`). */\n markRead(id: string): Promise<void> {\n return sendWithSession(this.auth, (headers) => this.http.post<void>(this.url`/${id}/read`, {}, { headers }));\n }\n\n /** As ainda abertas da tela, de qualquer pessoa: o modal oferece apoiar em vez de repetir. */\n async byScreen(path: string): Promise<SpineSuggestion[]> {\n const params = new HttpParams().set('path', path);\n const res = await sendWithSession(this.auth, (headers) => this.http.get<{ suggestions: SpineSuggestion[] }>(this.url`/screen`, { headers, params }));\n return res.suggestions ?? [];\n }\n\n vote(id: string): Promise<void> {\n return sendWithSession(this.auth, (headers) => this.http.post<void>(this.url`/${id}/vote`, {}, { headers }));\n }\n\n unvote(id: string): Promise<void> {\n return sendWithSession(this.auth, (headers) => this.http.delete<void>(this.url`/${id}/vote`, { headers }));\n }\n}\n","import { EnvironmentProviders, inject, makeEnvironmentProviders, provideEnvironmentInitializer } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_ADMIN_API, SPINE_CONFIG, SPINE_MESSAGES, registerSpineBuiltinPage } from '@trismegisto/spine';\nimport { SpineInboxItem, SpineInboxSource, provideSpineInboxSource } from '../inbox/inbox';\nimport { SpineWorkspaceNavService } from '../workspace/spine-workspace-nav.service';\nimport { SpineSuggestionUpdate, SpineSuggestionsService } from './suggestions.service';\n\n/**\n * A página \"Sugestões do app\" de quem pede: uma página do PRÓPRIO spine (ver `registerSpineBuiltinPage`), em todo app\n * com sugestões ligadas, sem cadastro de rota por client. Abre como qualquer tela do workspace (aba, painel, F5, link).\n */\nexport const SPINE_SUGGESTIONS_PAGE_PATH = '/sugestoes';\n/** Chave sintética da página no distribuidor de telas (não é UUID: não colide com router do banco). */\nexport const SPINE_SUGGESTIONS_PAGE_ID = 'spine:sugestoes';\n/** \"?sugestao=SUG-12\": abrir a página com ela abre a sugestão no painel (o mesmo parâmetro do quadro da equipe). */\nexport const SPINE_SUGGESTION_PAGE_PARAM = 'sugestao';\n/** \"&aba=conversa\": junto com `sugestao`, abre a gaveta na Conversa (sem ele, em Detalhes). */\nexport const SPINE_SUGGESTION_TAB_PARAM = 'aba';\nexport const SPINE_SUGGESTION_TAB_CONVERSATION = 'conversa';\n/** Quantas a central de notificações mostra. */\nconst INBOX_LIMIT = 20;\n\n/** Sugestões ligadas: o recurso não foi desligado (`SpineFeatures.suggestions`) e há para onde mandar (`SPINE_ADMIN_API`). */\nexport function spineSuggestionsEnabled(): boolean {\n return !!inject(SPINE_ADMIN_API, { optional: true })\n && inject(SPINE_CONFIG, { optional: true })?.features?.suggestions !== false;\n}\n\n/**\n * Registra a página no bootstrap (antes da primeira navegação: o F5 em /sugestoes passa pelo `ViewGuard`). Vai no\n * `provideShell`; com as sugestões desligadas, não registra nada e o endereço cai no fallback de sempre.\n */\nexport function provideSpineSuggestionsPage(): EnvironmentProviders {\n return makeEnvironmentProviders([registerPage(), provideSpineInboxSource(suggestionsInboxSource)]);\n}\n\nfunction registerPage(): EnvironmentProviders {\n return provideEnvironmentInitializer(() => {\n if (!spineSuggestionsEnabled()) return;\n const text = inject(SPINE_MESSAGES).suggestions.page;\n registerSpineBuiltinPage({\n route: {\n routed_id: '',\n router_id: SPINE_SUGGESTIONS_PAGE_ID,\n route_type: 'page',\n route_display_name: text.title,\n route_icon: 'lightbulb',\n route_redirect: SPINE_SUGGESTIONS_PAGE_PATH,\n description: text.description,\n },\n load: () => import('./suggestions-page.component').then((m) => m.SpineSuggestionsPageComponent),\n });\n });\n}\n\n/**\n * A fonte \"Sugestões\" da central de notificações: as que a pessoa acompanha (pediu, foi agrupada, é envolvida ou\n * responsável) com novidade de outra pessoa. Escolher marca como lida e abre a página com a sugestão na gaveta: na\n * Conversa quando a novidade é um comentário, em Detalhes quando é o status. A aba da página, se já estiver aberta em\n * algum painel, é reaproveitada.\n */\nfunction suggestionsInboxSource(): SpineInboxSource | null {\n if (!spineSuggestionsEnabled()) return null;\n const service = inject(SpineSuggestionsService);\n const nav = inject(SpineWorkspaceNavService, { optional: true });\n const router = inject(Router, { optional: true });\n const text = inject(SPINE_MESSAGES).suggestions;\n const loaded = new Map<string, SpineSuggestionUpdate>();\n\n const body = (u: SpineSuggestionUpdate): string => {\n const name = u.last.author?.name || u.last.author?.username || text.page.team;\n if (u.last.kind === 'status' && u.last.status) return formatMessage(text.inbox.status, { name, status: text.statuses[u.last.status] });\n return formatMessage(text.inbox.comment, { name, comment: (u.last.comment ?? '').replace(/\\s+/g, ' ').trim() });\n };\n const toItem = (u: SpineSuggestionUpdate): SpineInboxItem => ({\n id: u.id,\n title: `${u.key} · ${u.title}`,\n body: body(u),\n at: u.last.at,\n count: u.count,\n person: u.last.author ? { name: u.last.author.name || u.last.author.username || text.page.team, picture: u.last.author.picture } : null,\n });\n\n return {\n id: 'suggestions',\n label: text.inbox.label,\n icon: 'lightbulb',\n async load() {\n const res = await service.updates(INBOX_LIMIT);\n loaded.clear();\n for (const u of res.updates) loaded.set(u.id, u);\n return { total: res.total, items: res.updates.map(toItem) };\n },\n async open(item) {\n const u = loaded.get(item.id);\n if (!u) return;\n await service.markRead(u.id).catch(() => undefined);\n const params = new URLSearchParams({ [SPINE_SUGGESTION_PAGE_PARAM]: u.key });\n if (u.last.kind === 'comment') params.set(SPINE_SUGGESTION_TAB_PARAM, SPINE_SUGGESTION_TAB_CONVERSATION);\n const url = `${SPINE_SUGGESTIONS_PAGE_PATH}?${params.toString()}`;\n // A aba da página é uma só (a identidade é o caminho): reaproveita a que estiver aberta, em qualquer painel.\n if (nav) nav.openTab(url, { match: [] });\n else void router?.navigateByUrl(url);\n },\n };\n}\n","import { ChangeDetectionStrategy, Component, computed, effect, inject, input, model, output, signal, untracked } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { ViewService } from '@orfeu/angular/core';\nimport {\n AlertComponent, ButtonComponent, ComboboxComponent, ComboboxOption, HermesToastService, InputComponent, ModalComponent,\n RichTextComponent, SegmentedControlComponent, SegmentedOption, TagComponent,\n} from '@trismegisto/angular';\nimport { pluralMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES, spineRoutesOf } from '@trismegisto/spine';\nimport { NEW_SCREEN_VALUE, suggestionScreens } from './suggestion-screens';\nimport { SPINE_SUGGESTIONS_PAGE_PATH, SPINE_SUGGESTION_PAGE_PARAM } from './suggestions-page';\nimport {\n SPINE_SUGGESTION_KIND_ICONS, SPINE_SUGGESTION_KINDS, SPINE_SUGGESTION_LIMITS, SPINE_SUGGESTION_STATUS_COLORS,\n SpineSuggestion, SpineSuggestionKind, SpineSuggestionsService,\n} from './suggestions.service';\n\n/** O que está aberto: o modal de nova sugestão ou nada. (A lista virou a página \"Sugestões do app\".) */\nexport type SpineSuggestionsView = 'new' | null;\n\n/**\n * O modal \"Sugerir melhoria\" (montado pelo `spine-suggest-button` no primeiro uso e pela página \"Sugestões do app\").\n *\n * - Tipo, título, descrição (rich text, o mesmo editor da descrição da tarefa) e a **tela**: uma do menu do app (as que a pessoa alcança, da árvore de rotas que ela já\n * recebe, com o caminho \"Módulo › Tela\"), já escolhida quando o modal vem da barra da página, ou **Nova tela** — aí\n * o nome da tela que ainda não existe é obrigatório. Sem texto livre para a tela: o quadro da equipe agrupa e filtra\n * pela rota, e um rótulo digitado à mão não casava com nada.\n * - Antes do formulário, as ainda abertas da tela escolhida (as que a pessoa vê) com \"Também quero\": apoiar evita o\n * mesmo pedido em dobro. Trocar a tela relê.\n * - Enviar fecha, avisa no canto com \"Abrir\" (a página, já na sugestão nova) e emite `created`. O rodapé abre a página.\n */\n@Component({\n selector: 'spine-suggestions-dialog',\n imports: [\n AlertComponent, ButtonComponent, ComboboxComponent, InputComponent, ModalComponent, RichTextComponent,\n SegmentedControlComponent, TagComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './suggestions-dialog.component.html',\n styleUrl: './suggestions-dialog.component.scss',\n})\nexport class SpineSuggestionsDialogComponent {\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.suggestions;\n private readonly service = inject(SpineSuggestionsService);\n private readonly toast = inject(HermesToastService);\n private readonly views = inject(ViewService, { optional: true });\n private readonly router = inject(Router, { optional: true });\n\n readonly view = model<SpineSuggestionsView>(null);\n /** A rota da tela de onde a pessoa veio ('' = de nenhuma: a página \"Sugestões do app\"). */\n readonly screenPath = input('');\n readonly screenLabel = input('');\n /** A página \"Sugestões do app\" já está aberta: o rodapé não oferece abri-la. */\n readonly onPage = input(false);\n /** A sugestão acabou de ser criada (a página relê e a abre). */\n readonly created = output<SpineSuggestion>();\n\n protected readonly limits = SPINE_SUGGESTION_LIMITS;\n protected readonly statusColors = SPINE_SUGGESTION_STATUS_COLORS;\n protected readonly newScreenValue = NEW_SCREEN_VALUE;\n protected readonly kindOptions: readonly SegmentedOption[] = SPINE_SUGGESTION_KINDS.map((k) => ({\n value: k, label: this.text.kinds[k], icon: SPINE_SUGGESTION_KIND_ICONS[k],\n }));\n\n /** As telas do menu, relidas a cada abertura (a view muda com troca de perfil/grupo). */\n protected readonly screens = signal(suggestionScreens([]));\n protected readonly screenOptions = computed<ComboboxOption[]>(() => [\n ...this.screens().map((s) => ({ value: s.path, label: s.label, icon: s.icon })),\n { value: NEW_SCREEN_VALUE, label: this.text.newScreenOption, icon: 'plus' },\n ]);\n\n protected readonly kind = signal<string>('melhoria');\n protected readonly title = signal('');\n /** A descrição em HTML (o `hm-rich-text`); o servidor saneia e tira dela o texto puro. */\n protected readonly description = signal('');\n /** A rota escolhida, `NEW_SCREEN_VALUE` ou '' (nenhuma). */\n protected readonly screen = signal('');\n protected readonly newScreenName = signal('');\n protected readonly isNewScreen = computed(() => this.screen() === NEW_SCREEN_VALUE);\n protected readonly titleError = signal('');\n protected readonly newScreenError = signal('');\n protected readonly sendError = signal('');\n protected readonly sending = signal(false);\n protected readonly similar = signal<SpineSuggestion[]>([]);\n protected readonly voting = signal<string | null>(null);\n private similarRequest = 0;\n\n constructor() {\n // Cada abertura parte da tela de onde a pessoa veio.\n effect(() => {\n if (this.view() === 'new') untracked(() => this.prepareNew());\n });\n // O que já pediram na tela escolhida (trocar a tela relê; nova tela não tem o que mostrar).\n effect(() => {\n const path = this.screen();\n if (this.view() !== 'new') return;\n untracked(() => this.loadSimilar(path));\n });\n }\n\n protected setOpen(open: boolean): void {\n if (!open && this.view() === 'new') this.view.set(null);\n }\n\n private prepareNew(): void {\n this.screens.set(suggestionScreens(spineRoutesOf(this.views?.currentView)));\n const from = this.screenPath();\n this.screen.set(from && this.screens().some((s) => s.path === from) ? from : '');\n this.newScreenName.set('');\n this.titleError.set('');\n this.newScreenError.set('');\n this.sendError.set('');\n }\n\n private loadSimilar(path: string): void {\n const request = ++this.similarRequest;\n this.similar.set([]);\n if (!path || path === NEW_SCREEN_VALUE) return;\n this.service.byScreen(path).then(\n (list) => { if (request === this.similarRequest) this.similar.set(list); },\n () => { if (request === this.similarRequest) this.similar.set([]); },\n );\n }\n\n /** O `screen` do pedido: a tela do menu (rota, router e o caminho), a nova (só o nome) ou nenhuma. */\n private draftScreen() {\n if (this.isNewScreen()) return { path: null, label: this.newScreenName().trim(), router_id: null, new: true };\n const chosen = this.screens().find((s) => s.path === this.screen());\n if (chosen) return { path: chosen.path, label: chosen.label, router_id: chosen.routerId, new: false };\n return { path: null, label: null, router_id: null, new: false };\n }\n\n protected async send(): Promise<void> {\n if (this.sending()) return;\n const title = this.title().trim();\n this.titleError.set(title ? '' : this.text.titleRequired);\n const missingName = this.isNewScreen() && !this.newScreenName().trim();\n this.newScreenError.set(missingName ? this.text.newScreenRequired : '');\n if (!title || missingName) return;\n this.sending.set(true);\n this.sendError.set('');\n try {\n const created = await this.service.create({\n kind: this.kind() as SpineSuggestionKind, title, description_html: this.description(), screen: this.draftScreen(),\n });\n this.title.set('');\n this.description.set('');\n this.kind.set('melhoria');\n this.view.set(null);\n this.created.emit(created);\n this.toast.success(this.text.sent, this.onPage() ? {} : { action: { label: this.text.openPage, run: () => this.openPage(created.key) } });\n } catch {\n this.sendError.set(this.text.sendError);\n } finally {\n this.sending.set(false);\n }\n }\n\n /** Abre a página \"Sugestões do app\" (já numa sugestão, com a chave). */\n protected openPage(key?: string): void {\n this.view.set(null);\n const query = key ? `?${SPINE_SUGGESTION_PAGE_PARAM}=${encodeURIComponent(key)}` : '';\n void this.router?.navigateByUrl(`${SPINE_SUGGESTIONS_PAGE_PATH}${query}`);\n }\n\n /** \"Também quero\": liga ou desliga o apoio e ajusta a contagem sem reler a lista. */\n protected async toggleVote(s: SpineSuggestion): Promise<void> {\n if (this.voting()) return;\n this.voting.set(s.id);\n try {\n if (s.voted) await this.service.unvote(s.id);\n else await this.service.vote(s.id);\n this.similar.update((list) => list.map((x) => (x.id === s.id\n ? { ...x, voted: !s.voted, votes: Math.max(0, x.votes + (s.voted ? -1 : 1)) } : x)));\n } catch {\n this.toast.error(this.text.voteError);\n } finally {\n this.voting.set(null);\n }\n }\n\n protected votesText(count: number): string {\n return pluralMessage(this.text.votes, count, this.messages.meta.locale);\n }\n}\n","<hm-modal [heading]=\"text.modalTitle\" [open]=\"view() === 'new'\" (openChange)=\"setOpen($event)\">\n <div class=\"spine-suggest\">\n <p class=\"spine-suggest__intro\">{{ text.intro }}</p>\n\n <div class=\"spine-suggest__form\">\n <hm-segmented-control [label]=\"text.kind\" [options]=\"kindOptions\" [(value)]=\"kind\" />\n <hm-input [label]=\"text.title\" [placeholder]=\"text.titlePlaceholder\" [maxLength]=\"limits.title\" required\n [error]=\"titleError()\" [(value)]=\"title\" />\n <hm-rich-text [label]=\"text.description\" [hint]=\"text.descriptionHint\" [maxLength]=\"limits.description\"\n [rows]=\"5\" [maxRows]=\"14\" [(value)]=\"description\" />\n <!-- A tela: uma do menu (já escolhida quando vem da barra da página) ou \"Nova tela\", com o nome. -->\n <hm-combobox [label]=\"text.screenPick\" [hint]=\"text.screenPickHint\" [placeholder]=\"text.screenPickPlaceholder\"\n icon=\"application\" clearable [options]=\"screenOptions()\" [(value)]=\"screen\" />\n @if (isNewScreen()) {\n <hm-input [label]=\"text.newScreenName\" [hint]=\"text.newScreenHint\" [maxLength]=\"limits.screen\" required\n [error]=\"newScreenError()\" [(value)]=\"newScreenName\" />\n }\n </div>\n\n <!-- O que já pediram na tela escolhida (as abertas que a pessoa vê): apoiar em vez de repetir. -->\n @if (similar().length) {\n <section class=\"spine-suggest__similar\" aria-labelledby=\"spine-suggest-similar\">\n <h3 id=\"spine-suggest-similar\" class=\"spine-suggest__heading\">{{ text.similarHeading }}</h3>\n <p class=\"spine-suggest__hint\">{{ text.similarHint }}</p>\n <ul class=\"spine-suggest__list\">\n @for (s of similar(); track s.id) {\n <li class=\"spine-suggest__similar-item\">\n <div class=\"spine-suggest__similar-text\">\n <span class=\"spine-suggest__similar-title\">{{ s.title }}</span>\n <span class=\"spine-suggest__meta\">\n <hm-tag [name]=\"text.statuses[s.status]\" [color]=\"statusColors[s.status]\" />\n {{ votesText(s.votes) }}\n </span>\n </div>\n @if (s.mine) {\n <hm-tag [name]=\"text.yours\" />\n } @else {\n <hm-button size=\"small\" emphasis=\"medium\" icon=\"thumbs-up\" toggle [pressed]=\"s.voted\"\n [loading]=\"voting() === s.id\" (clicked)=\"toggleVote(s)\">\n {{ s.voted ? text.voted : text.vote }}\n </hm-button>\n }\n </li>\n }\n </ul>\n </section>\n }\n\n @if (sendError()) {\n <hm-alert variant=\"error\">{{ sendError() }}</hm-alert>\n }\n </div>\n\n <div footer class=\"spine-suggest__footer\">\n @if (!onPage()) {\n <hm-button emphasis=\"minimal\" icon=\"list\" (clicked)=\"openPage()\">{{ text.openPage }}</hm-button>\n }\n <span class=\"spine-suggest__spacer\"></span>\n <hm-button emphasis=\"medium\" (clicked)=\"view.set(null)\">{{ text.cancel }}</hm-button>\n <hm-button [loading]=\"sending()\" (clicked)=\"send()\">{{ text.send }}</hm-button>\n </div>\n</hm-modal>\n","import { ChangeDetectionStrategy, Component, inject, input, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { MenuButtonComponent } from '@trismegisto/angular';\nimport { MenuItem } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineSuggestionsDialogComponent, SpineSuggestionsView } from './suggestions-dialog.component';\nimport { SPINE_SUGGESTIONS_PAGE_PATH, spineSuggestionsEnabled } from './suggestions-page';\n\n/**\n * \"Sugestões\" na barra da página (`spine-page-bar`, contêiner `.spine-page-bar__feedback`): um menu com **Sugerir\n * melhoria** (o modal, com a tela já escolhida: a rota e o caminho legível \"Módulo › … › Tela\", os mesmos da avaliação)\n * e **Ver sugestões do app** (a página de quem pede — as dela, as do grupo e as em que está envolvida, com a conversa),\n * sem precisar passar pelo formulário.\n *\n * Leve de propósito: só decide se aparece (`SpineFeatures.suggestions` ligado por padrão + `SPINE_ADMIN_API`) e\n * guarda o que está aberto. O diálogo (que fala com o servidor) só nasce no primeiro \"Sugerir melhoria\", então a\n * barra não puxa nada do servidor enquanto ninguém sugere. Na barra estreita, só o ícone (o nome fica no menu).\n */\n@Component({\n selector: 'spine-suggest-button',\n imports: [MenuButtonComponent, SpineSuggestionsDialogComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (enabled) {\n <hm-menu-button class=\"spine-suggest-button__wide\" size=\"small\" icon=\"lightbulb\" align=\"end\"\n [label]=\"text.buttonMenu\" [items]=\"items\" (chosen)=\"choose($event)\">{{ text.buttonMenu }}</hm-menu-button>\n <hm-menu-button class=\"spine-suggest-button__narrow\" size=\"small\" icon=\"lightbulb\" shape=\"circle\" align=\"end\"\n [showArrow]=\"false\" [label]=\"text.buttonMenu\" [items]=\"items\" (chosen)=\"choose($event)\" />\n @if (opened()) {\n <spine-suggestions-dialog [(view)]=\"view\" [screenPath]=\"screenPath() ?? ''\" [screenLabel]=\"screenLabel()\"\n [onPage]=\"onPage()\" />\n }\n }\n `,\n styles: [`\n :host { display: contents; }\n .spine-suggest-button__narrow { display: none; }\n @media (max-width: 40rem) {\n .spine-suggest-button__wide { display: none; }\n .spine-suggest-button__narrow { display: inline-flex; }\n }\n `],\n})\nexport class SpineSuggestButtonComponent {\n protected readonly text = inject(SPINE_MESSAGES).suggestions;\n private readonly router = inject(Router, { optional: true });\n /** A rota da tela (o endereço da página na barra); null enquanto a página não tem endereço. */\n readonly screenPath = input<string | null>(null);\n /** O caminho legível (\"Módulo › … › Tela\"), que quem administra lê no cartão. */\n readonly screenLabel = input('');\n\n protected readonly enabled = spineSuggestionsEnabled();\n\n protected readonly items: readonly MenuItem[] = [\n { id: 'new', label: this.text.button, icon: 'lightbulb' },\n { id: 'page', label: this.text.openPage, icon: 'list' },\n ];\n\n protected readonly view = signal<SpineSuggestionsView>(null);\n /** O diálogo fica montado depois do primeiro uso (fechar não o destrói: mantém o rascunho). */\n protected readonly opened = signal(false);\n\n /** Na própria página \"Sugestões do app\" o modal não oferece abri-la de novo. */\n protected onPage(): boolean {\n return (this.screenPath() ?? '').split('?')[0] === SPINE_SUGGESTIONS_PAGE_PATH;\n }\n\n protected choose(id: string): void {\n if (id === 'page') {\n void this.router?.navigateByUrl(SPINE_SUGGESTIONS_PAGE_PATH);\n return;\n }\n this.opened.set(true);\n this.view.set('new');\n }\n}\n","import { Directive, Injectable, OnDestroy, TemplateRef, ViewContainerRef, afterNextRender, inject, signal } from '@angular/core';\n\n/**\n * Lugar das ações da tela na barra da página (`spine-page-bar`): um por painel do workspace, fornecido pelo\n * `spine-page-panel`. A tela não fala com ele direto: usa `<ng-template spinePageActions>`.\n */\n@Injectable()\nexport class SpinePageActionsSlot {\n readonly template = signal<TemplateRef<unknown> | null>(null);\n}\n\n/**\n * Ações que valem para a tela inteira (período, \"Atualizar\", \"Atualizado em…\") na barra da página, à direita do título:\n *\n * ```html\n * <ng-template spinePageActions>\n * <hm-segmented-control … />\n * <hm-button icon=\"refresh\" (clicked)=\"reload()\">Atualizar</hm-button>\n * </ng-template>\n * ```\n *\n * O conteúdo continua sendo da tela (bindings e eventos no componente dela); só aparece na barra do painel em que a tela\n * está. Fora de um painel (tela montada sozinha, teste), aparece no próprio lugar do `ng-template`. Uma tela por painel:\n * a última que registrar vale, e sair da tela tira as ações da barra.\n */\n@Directive({ selector: 'ng-template[spinePageActions]' })\nexport class SpinePageActionsDirective implements OnDestroy {\n private readonly slot = inject(SpinePageActionsSlot, { optional: true });\n private readonly template = inject<TemplateRef<unknown>>(TemplateRef);\n\n constructor() {\n if (!this.slot) {\n inject(ViewContainerRef).createEmbeddedView(this.template);\n return;\n }\n // Depois da primeira renderização: a barra já foi verificada nesta passada, e o sinal a marca para a próxima.\n const slot = this.slot;\n afterNextRender(() => slot.template.set(this.template));\n }\n\n ngOnDestroy(): void {\n if (this.slot?.template() === this.template) this.slot.template.set(null);\n }\n}\n","import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, computed, effect, inject, input, signal } from '@angular/core';\nimport { BreadcrumbComponent, BreadcrumbItem, IconButtonComponent, IconComponent, TooltipDirective } from '@trismegisto/angular';\nimport { QuickAccessItem, Route, routerIdOf, SpineQuickAccessService, SPINE_MESSAGES } from '@trismegisto/spine';\nimport { SpineDocsService } from '../docs/docs.service';\nimport { SpineRateScreenButtonComponent } from '../ratings/rate-screen-button.component';\nimport { SpineSuggestButtonComponent } from '../suggestions/suggest-button.component';\nimport { SpinePageActionsSlot } from './spine-page-actions.directive';\n\n/**\n * Barra de contexto do topo de CADA painel do workspace: título e ícone da página e as\n * ações que valem pra página inteira (favoritar, copiar link, documentação) em cima; a descrição da\n * tela logo abaixo do título; a trilha (breadcrumb) embaixo.\n *\n * A descrição é do ROUTER (`web.router.description`, editada no Argos), não da tela: é aqui que todo\n * app mostra \"o que esta página faz\", então as telas NÃO repetem título+descrição internos.\n * Tela identificada pelo `router_id` do nó 'page' (`routerIdOf`), nunca pelo `web.routes.route_id`.\n *\n * Mora dentro do painel (não num shell global) porque cada painel do `hm-workspace` resolve a\n * própria aba: dois painéis lado a lado mostram duas trilhas diferentes ao mesmo tempo. Por isso\n * recebe a `chain` (header→…→page) do painel em vez de ler a \"página atual\" de algum serviço global.\n *\n * Só o painel focado alimenta os \"recentes\" (`recordRecent`) — os outros apenas exibem.\n *\n * Favoritos e recentes moram no `SpineQuickAccessService` (compartilhado com a tela inicial): o\n * coração daqui e a seção \"Favoritos\" do Início mudam juntos.\n */\n@Component({\n selector: 'spine-page-bar',\n imports: [NgTemplateOutlet, BreadcrumbComponent, IconComponent, IconButtonComponent, TooltipDirective, SpineRateScreenButtonComponent, SpineSuggestButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (title(); as pageTitle) {\n <header class=\"spine-page-bar\">\n <div class=\"spine-page-bar__identity\">\n <div class=\"spine-page-bar__title-row\">\n @if (icon(); as ic) {\n <hm-icon class=\"spine-page-bar__icon\" [shape]=\"ic\" />\n }\n <h1 class=\"spine-page-bar__title\">{{ pageTitle }}</h1>\n\n <span class=\"spine-page-bar__actions\">\n <!-- O estado vai no nome (\"Favoritar\" / \"Remover dos favoritos\"). Sem aria-pressed: no host\n <hm-icon-button> ele caía num elemento sem papel, e não no <button> (o leitor não lia).\n A dica (hmTooltip) repete o nome para quem enxerga: só ícone, sem texto, o botão não diz\n o que faz até ser clicado. -->\n <hm-icon-button\n emphasis=\"subtle\"\n icon=\"heart\" [solid]=\"isFavorite()\"\n [label]=\"isFavorite() ? text.unfavorite : text.favorite\"\n [hmTooltip]=\"isFavorite() ? text.unfavorite : text.favorite\"\n [class.spine-page-bar__fav--on]=\"isFavorite()\"\n (clicked)=\"toggleFavorite()\"\n />\n <hm-icon-button\n emphasis=\"subtle\"\n [icon]=\"linkCopied() ? 'check' : 'copy'\"\n [label]=\"linkCopied() ? text.linkCopied : text.copyLink\"\n [hmTooltip]=\"linkCopied() ? text.linkCopied : text.copyLink\"\n (clicked)=\"copyLink()\"\n />\n <!-- Só quando a tela tem documento registrado (\\`document\\` no mapa de componentes). -->\n @if (hasDoc()) {\n <hm-icon-button emphasis=\"subtle\" icon=\"doc-list\" [label]=\"text.docs\" [hmTooltip]=\"text.docs\" (clicked)=\"openDocs()\" />\n }\n </span>\n </div>\n\n @if (description(); as desc) {\n <p class=\"spine-page-bar__description\">{{ desc }}</p>\n }\n\n <!-- Trilha: o hm-breadcrumb da lib (nav nomeado, lista ordenada, aria-current no último degrau,\n recolhe o meio de trilha longa). Só com mais de um nível — numa página de nível 1 a trilha\n repetiria o título. -->\n @if (crumbs().length > 1) {\n <hm-breadcrumb class=\"spine-page-bar__trail\" [items]=\"trail()\" [label]=\"text.trail\" />\n }\n </div>\n\n <!-- Ações da própria tela (ng-template spinePageActions: período, Atualizar…) e o conteúdo projetado. -->\n <div class=\"spine-page-bar__extra\"><ng-content />@if (actions?.template(); as tpl) {<ng-container [ngTemplateOutlet]=\"tpl\" />}</div>\n\n <!-- Retorno da pessoa sobre a tela (avaliar, sugerir melhoria), à direita: cada botão é um componente próprio,\n que some sozinho quando o recurso dele está desligado. -->\n <div class=\"spine-page-bar__feedback\">\n <spine-rate-screen-button [screenPath]=\"screenPath()\" [screenLabel]=\"screenTrail()\" />\n <spine-suggest-button [screenPath]=\"screenPath()\" [screenLabel]=\"screenTrail()\" />\n </div>\n </header>\n }\n `,\n styles: [`\n :host { display: block; }\n .spine-page-bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--hm-space-sm);\n padding: var(--hm-space-sm) var(--hm-space-md);\n margin: 0;\n /* Faixa própria: fundo elevado e uma linha embaixo separam a barra do conteúdo da página. */\n background: var(--hm-surface-raised);\n border-block-end: var(--hm-border-hairline, 1px) solid var(--hm-divider);\n }\n /* Cresce para a trilha ter a largura da barra (e recolher/truncar nela), sem empurrar as ações extras.\n Entre o nome da página e a trilha: --hm-space-md até o TEXTO da trilha (com menos as linhas liam como um bloco\n só) — o respiro interno de cada degrau do hm-breadcrumb (--hm-space-micro) já conta nessa distância. */\n .spine-page-bar__identity {\n display: flex;\n flex: 1 1 auto;\n min-inline-size: 0;\n flex-direction: column;\n gap: calc(var(--hm-space-md) - var(--hm-space-micro));\n }\n .spine-page-bar__title-row { display: flex; align-items: center; gap: var(--hm-space-xs); min-inline-size: 0; }\n .spine-page-bar__icon { flex: none; color: var(--hm-accent); font-size: var(--hm-font-size-xxl, 28px); }\n .spine-page-bar__title {\n min-inline-size: 0;\n margin: 0;\n overflow: hidden;\n color: var(--hm-text);\n font-size: var(--hm-font-size-xl, 22px);\n font-weight: var(--hm-font-weight-bold, 700);\n line-height: var(--hm-line-height-tight, 1.2);\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n /* Colada no título (desconta o gap da coluna, que é o respiro título→trilha): fica --hm-space-nano\n abaixo dele. Texto secundário, quebra em mais linhas sem truncar. */\n .spine-page-bar__description {\n max-inline-size: 80ch;\n margin: calc(var(--hm-space-nano) - (var(--hm-space-md) - var(--hm-space-micro))) 0 0;\n color: var(--hm-muted);\n font-size: var(--hm-font-size-sm, 14px);\n line-height: var(--hm-line-height-normal, 1.5);\n }\n .spine-page-bar__actions { display: inline-flex; flex: none; align-items: center; gap: var(--hm-space-micro); margin-inline-start: var(--hm-space-nano); }\n /* Favorito ativo: ícone preenchido em --hm-danger (o mesmo tratamento da tela inicial). */\n .spine-page-bar__fav--on { color: var(--hm-danger); }\n /* Trilha = hm-breadcrumb (visual do @trismegisto/core: degrau clicável na cor de ação, o atual em texto\n secundário, separador em ângulo). Cada degrau tem um respiro interno (alvo de foco/hover); a margem\n negativa do mesmo tamanho alinha o texto do primeiro degrau com o título, em qualquer densidade. */\n .spine-page-bar__trail { margin-inline-start: calc(-1 * var(--hm-space-micro)); margin-block-end: calc(-1 * var(--hm-space-micro)); }\n .spine-page-bar__extra { display: flex; flex: 0 1 auto; flex-wrap: wrap; align-items: center; gap: var(--hm-space-xs); min-inline-size: 0; }\n .spine-page-bar__extra:empty { display: none; }\n .spine-page-bar__feedback { display: flex; flex: none; align-items: center; gap: var(--hm-space-micro); }\n `],\n})\nexport class SpinePageBarComponent {\n protected readonly text = inject(SPINE_MESSAGES).pageBar;\n /** Cadeia resolvida (header→…→page) do painel; `null` enquanto a URL não resolve. */\n readonly chain = input<Route[] | null>(null);\n /** Só o painel focado registra a página em \"recentes\". */\n readonly recordRecent = input(false);\n\n protected readonly linkCopied = signal(false);\n /** Ações da tela do painel (`SpinePageActionsDirective`); fora de um `spine-page-panel`, nenhuma. */\n protected readonly actions = inject(SpinePageActionsSlot, { optional: true });\n private readonly docs = inject(SpineDocsService);\n\n /** A página (último nó da cadeia). */\n private readonly page = computed(() => this.chain()?.at(-1) ?? null);\n /** router_id da página -- chave do documento dela (o router do template entra como alternativa). */\n private readonly routerId = computed(() => routerIdOf(this.page()));\n private readonly sourceTemplateRouterId = computed(() => this.page()?.source_template_router_id ?? null);\n protected readonly hasDoc = computed(() => !!this.docs.documentFor(this.routerId(), this.sourceTemplateRouterId()));\n\n /** Descrição do router da página (`web.router.description`); vazia = sem a linha. */\n protected readonly description = computed(() => this.page()?.description?.trim() || '');\n\n protected openDocs(): void {\n this.docs.openForRoute(this.routerId(), this.sourceTemplateRouterId());\n }\n\n private readonly quickAccess = inject(SpineQuickAccessService);\n\n constructor() {\n effect(() => {\n const item = this.currentItem();\n if (this.recordRecent() && item) this.quickAccess.recordVisit(item);\n });\n }\n\n protected readonly crumbs = computed<{ label: string; link: string }[]>(() =>\n (this.chain() ?? [])\n .filter((r): r is Route & { route_display_name: string } => !!r.route_display_name)\n .map((r) => ({ label: r.route_display_name, link: r.route_redirect ?? '' })),\n );\n\n /** Degraus do `hm-breadcrumb`: nível sem endereço (grupo) vira texto, sem link. */\n protected readonly trail = computed<BreadcrumbItem[]>(() =>\n this.crumbs().map(({ label, link }) => (link ? { label, routerLink: link } : { label })),\n );\n\n protected readonly title = computed<string>(() => this.crumbs().at(-1)?.label ?? '');\n\n /** Ícone da própria página; cai no do módulo quando a página não tem. */\n protected readonly icon = computed<string | null>(() => {\n const chain = this.chain() ?? [];\n return chain.at(-1)?.route_icon || chain[0]?.route_icon || null;\n });\n\n /** A página do painel como item de favorito/recente, com a trilha (\"onde fica\") dela. */\n private readonly currentItem = computed<QuickAccessItem | null>(() => {\n const crumbs = this.crumbs();\n const last = crumbs.at(-1);\n if (!last?.link) return null;\n return {\n id: last.link,\n icon: this.icon() || 'application',\n displayName: last.label,\n redirect: last.link,\n trail: crumbs.slice(0, -1).map((c) => c.label),\n };\n });\n\n protected readonly isFavorite = computed(() => this.quickAccess.isFavorite(this.currentItem()?.id));\n\n /** A tela para o retorno da pessoa (avaliar, sugerir): a rota e o caminho legível (\"Módulo › Tela\"). */\n protected readonly screenPath = computed(() => this.currentItem()?.redirect ?? null);\n protected readonly screenTrail = computed(() => this.crumbs().map((c) => c.label).join(' › '));\n\n protected toggleFavorite(): void {\n const item = this.currentItem();\n if (item) this.quickAccess.toggleFavorite(item);\n }\n\n protected copyLink(): void {\n try {\n void navigator.clipboard?.writeText(window.location.href);\n this.linkCopied.set(true);\n setTimeout(() => this.linkCopied.set(false), 2000);\n } catch {\n /* clipboard indisponível */\n }\n }\n\n}\n","import { InjectionToken, Signal } from '@angular/core';\n\n/** Query de uma aba, como objeto (o último valor de cada nome). */\nexport type SpineTabParams = Readonly<Record<string, string>>;\n\n/**\n * A aba do workspace em que a tela está montada (`inject(SPINE_TAB)` na tela). Com o keepAlive, várias abas da MESMA\n * tela ficam vivas ao mesmo tempo (um registro por aba); `window.location`/`ActivatedRoute` só refletem a aba do\n * painel focado. Aqui cada tela lê e escreve a SUA.\n *\n * ```ts\n * private readonly tab = inject(SPINE_TAB, { optional: true });\n * readonly pedido = computed(() => this.tab?.params()['pedido'] ?? null);\n * // trocar a seção: a mesma aba, sem recriar a tela (e o endereço do navegador acompanha, se a aba está à vista)\n * this.tab?.navigate({ queryParams: { secao: 'itens' } });\n * // o nome do registro no lugar do nome da rota\n * this.tab?.setLabel('Pedido 123');\n * ```\n */\nexport interface SpineTab {\n /** Identidade estável da aba (o caminho, ou o caminho com os parâmetros que a identificam). */\n readonly id: Signal<string>;\n /** O painel em que a aba está agora. */\n readonly panelId: Signal<string>;\n /** O endereço atual da aba, com a query. */\n readonly url: Signal<string>;\n /** A query da aba. */\n readonly params: Signal<SpineTabParams>;\n /** A aba é a visível do painel focado (é a que o endereço do navegador mostra). */\n readonly focused: Signal<boolean>;\n /** Troca o nome (e, se vier, o ícone) da aba; persiste no F5 nas abas com parâmetros. */\n setLabel(label: string, icon?: string): void;\n /**\n * Muda o endereço da própria aba. Com `queryParams`, mescla na query atual (`merge`, padrão) ou troca a query\n * inteira (`merge: false`); `null`/`undefined` tira o parâmetro. Mesma tela: só a query muda, a tela não é recriada.\n * Outra tela (um caminho diferente): é a navegação no lugar da aba, como um link dentro do painel.\n */\n navigate(target: string | { queryParams: Readonly<Record<string, string | number | boolean | null | undefined>>; merge?: boolean }): void;\n}\n\nexport const SPINE_TAB = new InjectionToken<SpineTab>('SPINE_TAB');\n","import { NgComponentOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, Injector, Type, computed, effect, inject, input, signal } from '@angular/core';\nimport { Title } from '@angular/platform-browser';\nimport { ViewService } from '@orfeu/angular/core';\nimport { IconComponent, LoadingSquareComponent } from '@trismegisto/angular';\nimport { Route, routerIdOf, SPINE_MESSAGES, spineRoutesOf } from '@trismegisto/spine';\nimport { ComponentDistributorService, LoggerService, resolveEffectiveRouteChain } from '@trismegisto/spine/routing';\nimport { SpinePageBarComponent } from './spine-page-bar.component';\nimport { SpinePageActionsSlot } from './spine-page-actions.directive';\nimport { SPINE_TAB, SpineTab } from './spine-tab';\nimport { SpineWorkspaceNavService, spineNormalizeUrl, spineParamsOf, spinePathOf } from './spine-workspace-nav.service';\n\n// Componente já carregado para cada TELA (o router_id; sem ele, o caminho), comum a todos os painéis: reabrir a mesma\n// tela em outro painel, voltar a ela ou abri-la de novo com outros parâmetros não passa de novo pelo distribuidor.\nconst componentCache = new Map<string, Type<unknown>>();\n\n/**\n * Conteúdo de um painel do `hm-workspace`. Como vários painéis ficam visíveis ao mesmo tempo, cada\n * um monta a sua tela a partir da própria `url`, sem `<router-outlet>`: o roteador só conhece uma\n * rota ativa, e aqui cada painel precisa manter a sua.\n *\n * Mostra o quadrado de carregamento enquanto o componente chega, a tela quando ele chega, ou o\n * aviso de \"não encontrado\" quando a url não leva a nenhuma rota com tela.\n */\n@Component({\n selector: 'spine-page-panel',\n imports: [NgComponentOutlet, LoadingSquareComponent, IconComponent, SpinePageBarComponent],\n // Um lugar de ações por painel: a tela montada aqui (o ngComponentOutlet herda este injetor) põe as dela na barra.\n providers: [SpinePageActionsSlot],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <spine-page-bar [chain]=\"chain()\" [recordRecent]=\"isFocusedPanel()\" />\n <div class=\"spine-page-panel__content\">\n @if (loading()) {\n <div class=\"spine-page-panel__loading\"><hm-loading-square /></div>\n } @else if (component(); as cmp) {\n <ng-container [ngComponentOutlet]=\"cmp\" [ngComponentOutletInjector]=\"tabInjector\" />\n } @else {\n <div class=\"spine-page-panel__empty\">\n <hm-icon shape=\"search-magnify\" size=\"xl\" />\n <p class=\"spine-page-panel__empty-title\">{{ text.notFoundTitle }}</p>\n <p class=\"spine-page-panel__empty-description\">{{ text.notFoundText }}</p>\n </div>\n }\n </div>\n `,\n styles: [`\n :host { display: flex; flex-direction: column; block-size: 100%; min-block-size: 0; }\n .spine-page-panel__content { flex: 1; min-block-size: 0; display: flex; flex-direction: column; padding: var(--hm-space-lg, 1.5rem) var(--hm-space-md, 1rem); }\n .spine-page-panel__loading { display: flex; flex: 1; align-items: center; justify-content: center; min-block-size: 50vh; padding: var(--hm-space-xl); }\n .spine-page-panel__empty {\n display: flex;\n flex: 1;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: var(--hm-space-sm);\n padding: var(--hm-space-xl);\n text-align: center;\n color: var(--hm-muted);\n }\n .spine-page-panel__empty hm-icon { color: var(--hm-muted); }\n .spine-page-panel__empty-title { margin: 0; color: var(--hm-text); font-size: var(--hm-font-size-lg, 18px); font-weight: var(--hm-font-weight-semibold); }\n .spine-page-panel__empty-description { margin: 0; max-inline-size: 32ch; font-size: var(--hm-font-size-sm, 14px); }\n `],\n})\nexport class SpinePagePanelComponent {\n protected readonly text = inject(SPINE_MESSAGES).pagePanel;\n readonly url = input.required<string>();\n /** Só o painel focado fala pela página inteira: visita recente, título da aba e rota no logger. */\n readonly isFocusedPanel = input(true);\n /** A aba deste painel (o `id` estável, que o keepAlive acompanha) e o painel onde ela está: a tela recebe os dois em `SPINE_TAB`. */\n readonly tabId = input('');\n readonly panelId = input('');\n\n private readonly nav = inject(SpineWorkspaceNavService, { optional: true });\n private readonly injector = inject(Injector);\n\n /**\n * A aba para a tela (`inject(SPINE_TAB)`): o endereço e a query DESTA aba (com o keepAlive, a mesma tela pode estar\n * viva em várias), e o nome e a navegação dela. Um injetor só por painel: a tela não é recriada quando a query muda.\n */\n private readonly tab: SpineTab = {\n id: computed(() => this.tabId()),\n panelId: computed(() => this.panelId()),\n url: computed(() => this.url()),\n params: computed(() => spineParamsOf(this.url())),\n focused: computed(() => this.isFocusedPanel()),\n setLabel: (label, icon) => this.nav?.setTabLabel(this.panelId(), this.tabId(), label, icon),\n navigate: (target) => {\n if (!this.nav || !this.tabId()) return;\n const url = typeof target === 'string' ? target : this.withParams(target.queryParams, target.merge ?? true);\n this.nav.navigateTab(this.panelId(), this.tabId(), url);\n },\n };\n protected readonly tabInjector = Injector.create({ providers: [{ provide: SPINE_TAB, useValue: this.tab }], parent: this.injector });\n\n private readonly viewService = inject(ViewService);\n private readonly distributor = inject(ComponentDistributorService);\n private readonly logger = inject(LoggerService);\n private readonly title = inject(Title);\n\n protected readonly loading = signal(true);\n protected readonly component = signal<Type<unknown> | null>(null);\n protected readonly chain = signal<Route[] | null>(null);\n\n constructor() {\n effect(() => {\n const url = this.url();\n void this.resolve(url);\n });\n // Com as abas mantidas vivas, o painel que recebe o foco de volta já tem a tela pronta; basta\n // reaplicar o que só o focado faz, sem carregar nada de novo.\n effect(() => {\n if (this.isFocusedPanel() && this.chain()) this.afterResolved();\n });\n }\n\n /** Cadeia de rotas da url (sem os nós que só agrupam) e o componente da última delas. */\n private async resolve(url: string): Promise<void> {\n const chain = resolveEffectiveRouteChain(\n spineRoutesOf(this.viewService.currentView),\n (u) => this.viewService.getLevel(u),\n (u, level) => this.viewService.getUrlAtLevel(u, level),\n url,\n );\n this.chain.set(chain);\n\n const leaf = chain?.at(-1) ?? null;\n if (!leaf) {\n this.component.set(null);\n this.loading.set(false);\n return;\n }\n\n const key = routerIdOf(leaf) ?? spinePathOf(url);\n const cached = componentCache.get(key);\n if (cached) {\n this.component.set(cached);\n this.loading.set(false);\n this.afterResolved();\n return;\n }\n\n this.loading.set(true);\n this.component.set(null);\n\n const component = await this.distributor.getComponent(routerIdOf(leaf) ?? '', leaf.source_template_router_id);\n\n // A url mudou enquanto o carregamento corria: este resultado já não interessa.\n if (url !== this.url()) return;\n\n componentCache.set(key, component);\n this.component.set(component);\n this.loading.set(false);\n this.afterResolved();\n }\n\n /** A query atual da aba com `params` aplicados (mesclados ou no lugar dela); `null`/`undefined` tira o parâmetro. */\n private withParams(params: Readonly<Record<string, string | number | boolean | null | undefined>>, merge: boolean): string {\n const query: Record<string, string> = merge ? { ...spineParamsOf(this.url()) } : {};\n for (const [name, value] of Object.entries(params)) {\n if (value === null || value === undefined) delete query[name];\n else query[name] = String(value);\n }\n const path = spinePathOf(this.url());\n const search = new URLSearchParams(query).toString();\n return spineNormalizeUrl(search ? `${path}?${search}` : path);\n }\n\n /** O que acontece quando a tela do painel focado fica pronta. */\n private afterResolved(): void {\n if (!this.isFocusedPanel()) return;\n const chain = this.chain();\n if (chain) this.logger.setLogger(chain);\n const leafName = chain?.at(-1)?.route_display_name;\n if (leafName) this.title.setTitle(leafName);\n }\n}\n","import { Directive, DestroyRef, ElementRef, inject, input, output } from '@angular/core';\n\n/**\n * Em painéis NÃO focados do `hm-workspace`, um `<a href>`/`[routerLink]` clicado navegaria o\n * `Router` de verdade — que só existe UM na aplicação, e está sempre atrelado ao painel FOCADO\n * (ver `SpineWorkspaceNavService`). Sem isto, clicar num link dentro de um painel secundário (um\n * item da sidebar, uma aba de submenu, um link de breadcrumb, qualquer `routerLink` dentro de uma\n * tela de feature) navegaria a tela ERRADA — o painel focado, não o painel onde o clique\n * aconteceu. Porte 1:1 do mesmo diretório do docs/website\n * (`docs/website/src/app/workspace/panel-local-link.directive.ts`) — genérico, sem nada\n * específico do site de documentação.\n *\n * Intercepta em fase de CAPTURA pra resolver a navegação LOCALMENTE antes do `RouterLink`\n * conseguir agir. Abrir em nova aba (Ctrl/⌘ + clique, clique do meio) continua funcionando\n * normalmente — só intercepta o clique comum.\n */\n@Directive({ selector: '[appPanelLocalLink]' })\nexport class PanelLocalLinkDirective {\n /** `true` = intercepta (painel não-focado); `false` = deixa o `RouterLink` normal agir. */\n readonly appPanelLocalLink = input(false);\n readonly localNavigate = output<string>();\n\n constructor() {\n const host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n const destroyRef = inject(DestroyRef);\n\n const onClick = (event: MouseEvent): void => {\n if (!this.appPanelLocalLink()) return;\n if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n\n const anchor = (event.target as HTMLElement).closest('a[href]');\n if (!anchor || !host.contains(anchor)) return;\n const href = anchor.getAttribute('href');\n if (!href || !href.startsWith('/')) return; // só rotas internas do próprio app\n\n event.preventDefault();\n event.stopPropagation();\n this.localNavigate.emit(href);\n };\n\n host.addEventListener('click', onClick, true);\n destroyRef.onDestroy(() => host.removeEventListener('click', onClick, true));\n }\n}\n","import DOMPurify, { type Config, type DOMPurify as Purifier } from 'dompurify';\n\n/**\n * Perfil do DOMPurify para o Markdown do spine (documentação de tela, novidades). Mais restrito que o\n * padrão: o HTML entra no DOM do shell (sem shadow DOM), então\n * - `<style>` e o atributo `style` ficam de fora (CSS valeria para a página inteira: esconder/redesenhar a\n * UI, sobrepor um aviso falso com `position: fixed`, exfiltrar por seletor de atributo);\n * - formulário e controles (`<form>`, `<input>`, `<button>`, `<textarea>`, `<select>`) e `<iframe>` ficam de\n * fora (tela de login falsa dentro do conteúdo);\n * - link para outra origem abre em outra aba com `rel=\"noopener noreferrer\"`.\n */\nexport const SPINE_MARKDOWN_PURIFY_CONFIG: Config = {\n FORBID_TAGS: ['style', 'form', 'input', 'button', 'textarea', 'select', 'option', 'iframe', 'frame', 'frameset', 'object', 'embed', 'link', 'meta', 'base'],\n FORBID_ATTR: ['style', 'target', 'formaction', 'action'],\n ALLOW_DATA_ATTR: false,\n};\n\nlet instance: Purifier | null | undefined;\n\n/** Instância própria (o hook de links não vaza para o DOMPurify global que o app use). `null` sem DOM. */\nfunction purifier(): Purifier | null {\n if (instance !== undefined) return instance;\n if (typeof window === 'undefined') return (instance = null);\n const purify = DOMPurify(window);\n if (!purify.isSupported) return (instance = null);\n purify.addHook('afterSanitizeAttributes', (node) => {\n if (node.nodeName !== 'A') return;\n const href = node.getAttribute('href');\n if (!href) return;\n let external = false;\n try {\n external = new URL(href, window.location.href).origin !== window.location.origin;\n } catch {\n external = false;\n }\n if (external) {\n node.setAttribute('target', '_blank');\n node.setAttribute('rel', 'noopener noreferrer');\n }\n });\n return (instance = purify);\n}\n\n/** HTML limpo pelo perfil do spine, ou `null` quando não há DOM (SSR: melhor não renderizar). */\nexport function sanitizeSpineMarkdownHtml(html: string): string | null {\n const purify = purifier();\n return purify ? (purify.sanitize(html, SPINE_MARKDOWN_PURIFY_CONFIG) as string) : null;\n}\n","import { ChangeDetectionStrategy, Component, ViewEncapsulation, computed, inject, input } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\nimport { Marked } from 'marked';\nimport { sanitizeSpineMarkdownHtml } from './markdown-sanitize';\n\n// Instância própria: não mexe nas opções globais do `marked` que o app possa usar.\nconst parser = new Marked({ gfm: true, breaks: false, async: false });\n\n/**\n * Renderiza Markdown (GFM) como HTML com a tipografia do design system. O texto é tratado como dado:\n * o HTML gerado passa pelo DOMPurify, com o perfil restrito do spine (`SPINE_MARKDOWN_PURIFY_CONFIG`: sem\n * `<style>`/`style`, formulários e `<iframe>`; link externo com `rel=\"noopener noreferrer\"`), antes de chegar ao DOM.\n */\n@Component({\n selector: 'spine-markdown',\n changeDetection: ChangeDetectionStrategy.OnPush,\n // O HTML injetado não recebe os atributos do encapsulamento; os estilos ficam presos a `.spine-md`.\n encapsulation: ViewEncapsulation.None,\n template: `\n @if (html(); as markup) {\n <div class=\"spine-md\" [innerHTML]=\"markup\"></div>\n }\n `,\n styles: `\n .spine-md {\n color: var(--hm-text);\n font-size: var(--hm-font-size-sm);\n line-height: var(--hm-line-height-normal);\n overflow-wrap: anywhere;\n }\n .spine-md > :first-child { margin-block-start: 0; }\n .spine-md > :last-child { margin-block-end: 0; }\n .spine-md :is(h1, h2, h3, h4, h5, h6) {\n margin-block: var(--hm-space-lg) var(--hm-space-sm);\n color: var(--hm-text);\n font-weight: var(--hm-font-weight-semibold);\n line-height: var(--hm-line-height-snug);\n }\n .spine-md h1 { font-size: var(--hm-font-size-xxl); }\n .spine-md h2 { font-size: var(--hm-font-size-xl); }\n .spine-md h3 { font-size: var(--hm-font-size-lg); }\n .spine-md :is(h4, h5, h6) { font-size: var(--hm-font-size-md); }\n .spine-md :is(p, ul, ol, blockquote, pre, table) { margin-block: 0 var(--hm-space-md); }\n .spine-md :is(ul, ol) { padding-inline-start: var(--hm-space-lg); }\n .spine-md li + li { margin-block-start: var(--hm-space-micro); }\n .spine-md blockquote {\n margin-inline: 0;\n padding-inline-start: var(--hm-space-md);\n border-inline-start: var(--hm-border-thin) solid var(--hm-divider);\n color: var(--hm-muted);\n }\n .spine-md code {\n padding-inline: var(--hm-space-micro);\n border-radius: var(--hm-radius-micro);\n background: var(--hm-surface-raised);\n font-family: var(--hm-font-mono);\n font-size: var(--hm-font-size-xs);\n }\n .spine-md pre {\n padding: var(--hm-space-sm) var(--hm-space-md);\n border-radius: var(--hm-radius);\n background: var(--hm-surface-raised);\n white-space: pre-wrap;\n }\n .spine-md pre code { padding: 0; background: none; }\n .spine-md table {\n display: block;\n max-inline-size: 100%;\n overflow-x: auto;\n border-collapse: collapse;\n overflow-wrap: normal;\n }\n .spine-md :is(th, td) {\n padding: var(--hm-space-xs) var(--hm-space-sm);\n border: var(--hm-border-hairline) solid var(--hm-divider);\n text-align: start;\n vertical-align: top;\n }\n .spine-md th { background: var(--hm-surface-raised); font-weight: var(--hm-font-weight-semibold); }\n .spine-md hr {\n margin-block: var(--hm-space-lg);\n border: 0;\n border-block-start: var(--hm-border-hairline) solid var(--hm-divider);\n }\n .spine-md a {\n color: var(--hm-accent);\n text-decoration: underline;\n text-underline-offset: 0.2em;\n }\n .spine-md a:focus-visible {\n outline: var(--hm-border-thin) solid var(--hm-accent);\n outline-offset: var(--hm-border-hairline);\n border-radius: var(--hm-radius-micro);\n }\n .spine-md img { max-inline-size: 100%; block-size: auto; }\n `,\n})\nexport class SpineMarkdownComponent {\n /** Markdown cru. Vazio não desenha nada. */\n readonly content = input('');\n\n readonly #sanitizer = inject(DomSanitizer);\n\n protected readonly html = computed<SafeHtml | null>(() => {\n const source = this.content();\n // Sem DOM (SSR) o DOMPurify não limpa nada; melhor não renderizar.\n if (!source) return null;\n const clean = sanitizeSpineMarkdownHtml(parser.parse(source) as string);\n return clean === null ? null : this.#sanitizer.bypassSecurityTrustHtml(clean);\n });\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, signal } from '@angular/core';\nimport {\n AlertComponent,\n ModalComponent,\n SegmentedControlComponent,\n SegmentedOption,\n SkeletonComponent,\n} from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { DocsEntry, DocsGroup, DocsView, SpineDocsService } from './docs.service';\nimport { SpineMarkdownComponent } from './markdown.component';\n\nlet sequence = 0;\n\n/** Compara sem acento e sem caixa. */\nfunction fold(text: string): string {\n return text.normalize('NFD').replace(/\\p{M}/gu, '').toLowerCase();\n}\n\n/**\n * Modal de documentação das telas: índice (com busca) à esquerda e leitura à direita. Montado uma vez\n * pelo `spine-layout`; abrir, fechar e o que se lê vêm todos do `SpineDocsService`.\n */\n@Component({\n selector: 'spine-docs',\n imports: [ModalComponent, AlertComponent, SkeletonComponent, SegmentedControlComponent, SpineMarkdownComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (docs.isOpen()) {\n <hm-modal [heading]=\"text.docs.heading\" size=\"large\" [open]=\"true\" (closed)=\"docs.close()\">\n <div class=\"layout\">\n <nav class=\"index\" [attr.aria-label]=\"text.docs.index\">\n <input\n class=\"filter\"\n type=\"search\"\n [placeholder]=\"text.docs.search\"\n [attr.aria-label]=\"text.docs.search\"\n [value]=\"query()\"\n (input)=\"query.set($any($event.target).value)\"\n />\n @for (group of filtered(); track group.title; let g = $index) {\n <p class=\"group-title\" [id]=\"groupId + g\">{{ group.title }}</p>\n <ul class=\"entries\" [attr.aria-labelledby]=\"groupId + g\">\n @for (entry of group.entries; track entry.id) {\n <li>\n <button\n type=\"button\"\n class=\"entry\"\n [class.entry--active]=\"entry.id === docs.current()?.id\"\n [attr.aria-current]=\"entry.id === docs.current()?.id ? 'true' : null\"\n (click)=\"select(entry)\"\n >\n {{ entry.title }}\n </button>\n </li>\n }\n </ul>\n } @empty {\n <p class=\"note\">{{ query().trim() ? text.docs.noMatch : text.docs.empty }}</p>\n }\n </nav>\n\n <section class=\"reader\">\n @if (docs.current(); as entry) {\n <h3 class=\"reader-title\">{{ entry.title }}</h3>\n @if (docs.showTechnical()) {\n <hm-segmented-control\n [label]=\"text.docs.view\"\n [options]=\"viewOptions()\"\n [value]=\"docs.view()\"\n (valueChange)=\"switchView($event)\"\n />\n }\n <!-- A chave muda com o documento ou a visão: o bloco é recriado e entra de novo. -->\n @for (key of readingKey(); track key) {\n <div class=\"reading\">\n @if (docs.loading()) {\n <hm-skeleton shape=\"text\" [count]=\"6\" [label]=\"text.docs.loading\" />\n } @else if (docs.error()) {\n <hm-alert variant=\"error\">{{ docs.error() }}</hm-alert>\n } @else {\n <spine-markdown [content]=\"docs.content()\" />\n }\n </div>\n }\n } @else {\n <p class=\"note\">{{ text.docs.invite }}</p>\n }\n </section>\n </div>\n </hm-modal>\n }\n `,\n styles: `\n .layout {\n display: grid;\n grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);\n gap: var(--hm-space-lg);\n block-size: min(70vh, 48rem);\n min-block-size: 0;\n }\n .index,\n .reader {\n min-block-size: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n }\n .index {\n display: flex;\n flex-direction: column;\n gap: var(--hm-space-xs);\n padding-inline-end: var(--hm-space-md);\n border-inline-end: var(--hm-border-hairline) solid var(--hm-divider);\n }\n .filter {\n box-sizing: border-box;\n inline-size: 100%;\n min-block-size: var(--hm-control-height);\n margin-block-end: var(--hm-space-sm);\n padding-inline: var(--hm-space-sm);\n border: var(--hm-border-hairline) solid var(--hm-border);\n border-radius: var(--hm-radius-control);\n background: var(--hm-surface-raised);\n color: var(--hm-text);\n font: inherit;\n font-size: var(--hm-font-size-sm);\n }\n .filter::placeholder { color: var(--hm-placeholder); }\n .filter:focus-visible {\n outline: var(--hm-border-thin) solid var(--hm-accent);\n outline-offset: var(--hm-border-hairline);\n }\n .group-title {\n margin: var(--hm-space-sm) 0 0;\n color: var(--hm-muted);\n font-size: var(--hm-font-size-xs);\n font-weight: var(--hm-font-weight-semibold);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n .entries {\n display: flex;\n flex-direction: column;\n gap: var(--hm-space-micro);\n margin: 0;\n padding: 0;\n list-style: none;\n }\n .entry {\n inline-size: 100%;\n padding: var(--hm-space-xs) var(--hm-space-sm);\n border: var(--hm-border-hairline) solid transparent;\n border-radius: var(--hm-radius-control);\n background: transparent;\n color: var(--hm-text);\n font: inherit;\n font-size: var(--hm-font-size-sm);\n text-align: start;\n cursor: pointer;\n transition: background-color var(--hm-duration-quick) var(--hm-ease);\n }\n .entry:hover { background: var(--hm-hover); }\n .entry:focus-visible {\n outline: var(--hm-border-thin) solid var(--hm-accent);\n outline-offset: calc(var(--hm-border-thin) * -1);\n }\n .entry--active {\n background: var(--hm-accent-subtle);\n color: var(--hm-accent-strong);\n font-weight: var(--hm-font-weight-semibold);\n }\n .reader {\n display: flex;\n flex-direction: column;\n gap: var(--hm-space-md);\n align-items: stretch;\n }\n .reader-title {\n margin: 0;\n color: var(--hm-text);\n font-size: var(--hm-font-size-lg);\n font-weight: var(--hm-font-weight-semibold);\n }\n .reading { animation: spine-docs-enter var(--hm-duration-standard) var(--hm-ease-decelerate); }\n .note {\n margin: 0;\n color: var(--hm-muted);\n font-size: var(--hm-font-size-sm);\n }\n @keyframes spine-docs-enter {\n from { opacity: 0; }\n to { opacity: 1; }\n }\n @media (max-width: 767px) {\n .layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: minmax(0, 2fr) minmax(0, 3fr);\n }\n .index {\n padding-inline-end: 0;\n padding-block-end: var(--hm-space-md);\n border-inline-end: 0;\n border-block-end: var(--hm-border-hairline) solid var(--hm-divider);\n }\n }\n @media (prefers-reduced-motion: reduce) {\n .reading { animation: none; }\n .entry { transition: none; }\n }\n :host-context([data-motion='reduce']) .reading { animation: none; }\n :host-context([data-motion='reduce']) .entry { transition: none; }\n @media (forced-colors: active) {\n .entry--active { border-color: Highlight; }\n }\n `,\n})\nexport class SpineDocsComponent {\n protected readonly docs = inject(SpineDocsService);\n protected readonly text = inject(SPINE_MESSAGES);\n protected readonly query = signal('');\n protected readonly groupId = `spine-docs-group-${++sequence}-`;\n\n protected readonly viewOptions = computed<SegmentedOption<DocsView>[]>(() => [\n { value: 'usage', label: this.text.docs.usage },\n { value: 'technical', label: this.text.docs.technical },\n ]);\n\n protected readonly filtered = computed<DocsGroup[]>(() => {\n const needle = fold(this.query().trim());\n const groups = this.docs.index();\n if (!needle) return groups;\n return groups\n .map((group) => ({\n title: group.title,\n entries: group.entries.filter((entry) => fold(`${entry.title} ${group.title}`).includes(needle)),\n }))\n .filter((group) => group.entries.length > 0);\n });\n\n protected readonly readingKey = computed(() => [`${this.docs.current()?.id ?? ''}:${this.docs.view()}`]);\n\n protected select(entry: DocsEntry): void {\n void this.docs.open(entry);\n }\n\n protected switchView(view: string): void {\n void this.docs.show(view === 'technical' ? 'technical' : 'usage');\n }\n}\n\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { Router } from '@angular/router';\nimport { AuthorizationService } from '@orfeu/angular/core';\nimport { AlertComponent, ButtonComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\n\n/**\n * Aviso discreto de conexão no topo do shell, sobre o `connectionState$` e o `reauthorizationRequired$` do\n * `@orfeu/angular`. A sessão nunca cai por nada disto (sem rede, Argos fora do ar, refresh recusado):\n * a lib segue tentando sozinha e este banner só conta o que está acontecendo.\n *\n * - `offline`: aviso (`warning`) — Argos inalcançável; a lib tenta de novo com backoff e na volta da rede/foco.\n * - `reconnecting` / `reauthorizing`: informativo (`info`), some quando volta a `online`.\n * - `reauthorizationRequired$`: o Argos recusou a renovação e a reautorização automática não aconteceu\n * (desligada, outra aba cuidando ou proteção contra loop). Oferece \"Entrar novamente\", que chama\n * `authorize(urlAtual)` — o login volta para a mesma tela. Nunca chama `logout()`.\n *\n * `hm-alert` em `appearance=\"banner\"` e `size=\"small\"`: faixa de largura total, sem cantos, com os tokens\n * de status do Hermes (`--hm-warning-*`/`--hm-info-*`); `role=\"status\"` (não interrompe o leitor de tela).\n */\n@Component({\n selector: 'spine-connection-banner',\n imports: [AlertComponent, ButtonComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @switch (notice()) {\n @case ('reauthorizationRequired') {\n <hm-alert appearance=\"banner\" size=\"small\" variant=\"warning\">\n {{ text.reauthorizationRequired }}\n <hm-button actions emphasis=\"medium\" size=\"small\" icon=\"login\" (clicked)=\"signInAgain()\">{{ text.signInAgain }}</hm-button>\n </hm-alert>\n }\n @case ('offline') {\n <hm-alert appearance=\"banner\" size=\"small\" variant=\"warning\">{{ text.offline }}</hm-alert>\n }\n @case ('reconnecting') {\n <hm-alert appearance=\"banner\" size=\"small\" variant=\"info\">{{ text.reconnecting }}</hm-alert>\n }\n @case ('reauthorizing') {\n <hm-alert appearance=\"banner\" size=\"small\" variant=\"info\">{{ text.reauthorizing }}</hm-alert>\n }\n }\n `,\n styles: [`:host { display: block; flex: none; }`],\n})\nexport class SpineConnectionBannerComponent {\n protected readonly text = inject(SPINE_MESSAGES).session;\n private readonly auth = inject(AuthorizationService);\n private readonly router = inject(Router);\n\n private readonly state = toSignal(this.auth.connectionState$, { initialValue: this.auth.connectionState });\n private readonly reauthRequired = toSignal(this.auth.reauthorizationRequired$, {\n initialValue: this.auth.reauthorizationRequired,\n });\n\n /** O que mostrar: a decisão pendente da pessoa vence o estado da conexão; `online` não mostra nada. */\n protected readonly notice = computed(() => (this.reauthRequired() ? 'reauthorizationRequired' : this.state()));\n\n protected signInAgain(): void {\n void this.auth.authorize(this.router.url);\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject } from '@angular/core';\nimport { ButtonComponent, ModalComponent } from '@trismegisto/angular';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\nimport { pluralMessage } from '@trismegisto/primitives';\nimport { SpineIdleService } from './idle.service';\n\n/**\n * Aviso de \"Encerrar por inatividade\" (`SpineIdleService`): contagem regressiva, \"Continuar conectado\" (padrão, e o\n * que fechar pelo X/Esc faz) e \"Sair agora\". Montado uma vez no `spine-layout`.\n */\n@Component({\n selector: 'spine-idle-warning',\n imports: [ButtonComponent, ModalComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n @if (idle.warning()) {\n <hm-modal [open]=\"true\" [heading]=\"text.idleWarningHeading\" size=\"small\" (openChange)=\"onOpenChange($event)\">\n <p class=\"sp-idle__text\" role=\"timer\">{{ countdown() }}</p>\n <div footer class=\"sp-idle__actions\">\n <hm-button emphasis=\"medium\" icon=\"logout\" (clicked)=\"idle.logoutNow()\">{{ text.idleLogout }}</hm-button>\n <hm-button emphasis=\"high\" (clicked)=\"idle.stay()\">{{ text.idleStay }}</hm-button>\n </div>\n </hm-modal>\n }\n `,\n styles: [`\n .sp-idle__text { margin: 0; }\n .sp-idle__actions { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--hm-space-sm); }\n `],\n})\nexport class SpineIdleWarningComponent {\n protected readonly idle = inject(SpineIdleService);\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.accountFeatures;\n protected readonly countdown = computed(() =>\n pluralMessage(this.text.idleWarningText, this.idle.secondsLeft(), this.messages.meta.locale));\n\n protected onOpenChange(open: boolean): void {\n if (!open) this.idle.stay();\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HermesUnsavedChangesService, registerUnsavedChanges } from '@trismegisto/angular';\nimport { WorkspaceStore, findPanelTabs } from '@trismegisto/primitives';\nimport { SPINE_CONFIG } from '@trismegisto/spine';\nimport { SPINE_TAB } from './spine-tab';\nimport { SpineWorkspaceNavService } from './spine-workspace-nav.service';\n\n/**\n * Registra a verificação de alterações da tela, presa à aba do workspace em que ela está (`SPINE_TAB`):\n * com `SpineFeatures.unsavedChanges` ligado, fechar ESSA aba (ou o painel dela, ou \"fechar as outras\") e\n * trocar de tela dentro dela pergunta antes. Chame num contexto de injeção (campo da tela); a verificação\n * sai sozinha quando a tela é destruída.\n *\n * ```ts\n * readonly #unsaved = registerSpineUnsavedChanges(() => this.form.dirty);\n * ```\n *\n * Sem o recurso ligado, continua registrando no `HermesUnsavedChangesService` (o `hermesUnsavedChangesGuard`\n * de uma rota do app enxerga), mas o shell não pergunta nada.\n */\nexport function registerSpineUnsavedChanges(check: () => boolean): () => void {\n const tab = inject(SPINE_TAB, { optional: true });\n return registerUnsavedChanges(check, tab ? { scope: () => tab.id() } : {});\n}\n\n/**\n * O lado do shell do aviso de alterações não salvas (`SpineFeatures.unsavedChanges`, desligado por padrão).\n * Ligado: o `hm-workspace` recebe um store que pergunta antes de fechar aba com alteração; trocar de tela\n * dentro da aba pergunta também; e o navegador avisa ao recarregar/fechar a página. Desligado: `store` é o\n * mesmo do `SpineWorkspaceNavService` e nada muda.\n */\n@Injectable({ providedIn: 'root' })\nexport class SpineUnsavedChangesService {\n private readonly config = inject(SPINE_CONFIG, { optional: true });\n private readonly unsaved = inject(HermesUnsavedChangesService);\n private readonly nav = inject(SpineWorkspaceNavService);\n\n /** O recurso está ligado no app. */\n readonly enabled = !!this.config?.features?.unsavedChanges;\n /** O store que o shell passa para o `hm-workspace`. */\n readonly store: WorkspaceStore = this.enabled ? this.guard(this.nav.store) : this.nav.store;\n\n /** Liga o aviso do navegador (só com o recurso ligado). Devolve a função que desliga. */\n start(): () => void {\n return this.enabled ? this.unsaved.warnBeforeUnload() : () => {};\n }\n\n /** Pode trocar a tela da aba ativa do painel? Sem o recurso ou sem alteração nela, `true` na hora. */\n canReplaceActive(panelId: string): boolean | Promise<boolean> {\n if (!this.enabled) return true;\n const active = findPanelTabs(this.nav.store.getState().root, panelId)?.activeId;\n return active && this.unsaved.hasUnsavedChanges(active) ? this.unsaved.confirmDiscard() : true;\n }\n\n private guard(store: WorkspaceStore): WorkspaceStore {\n const tabsOf = (panelId: string): string[] => findPanelTabs(store.getState().root, panelId)?.tabs.map((t) => t.id) ?? [];\n // Sem alteração em nenhuma das abas, fecha na hora (mesmo comportamento de antes); com alteração, pergunta.\n const closing = (ids: readonly string[], close: () => void): void => {\n if (!ids.some((id) => this.unsaved.hasUnsavedChanges(id))) {\n close();\n return;\n }\n void this.unsaved.confirmDiscard().then((leave) => leave && close());\n };\n return {\n ...store,\n closeTab: (panelId, tabId) => closing([tabId], () => store.closeTab(panelId, tabId)),\n closePanel: (panelId) => closing(tabsOf(panelId), () => store.closePanel(panelId)),\n closeOtherTabs: (panelId, tabId) =>\n closing(tabsOf(panelId).filter((id) => id !== tabId), () => store.closeOtherTabs(panelId, tabId)),\n closeTabsToTheRight: (panelId, tabId) => {\n const ids = tabsOf(panelId);\n closing(ids.slice(ids.indexOf(tabId) + 1), () => store.closeTabsToTheRight(panelId, tabId));\n },\n };\n }\n}\n","import { Component, OnInit, ChangeDetectionStrategy, inject } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { NavigationEnd, Router, RouterOutlet } from '@angular/router';\nimport { filter } from 'rxjs';\nimport { SkipLinkComponent, ToastStackComponent, WorkspaceComponent } from '@trismegisto/angular';\nimport { HermesSidebarService } from '@trismegisto/angular/sidebar';\nimport { ModalComponent } from '@trismegisto/spine/modal';\nimport { SidePanelComponent } from '@trismegisto/spine/side-panel';\nimport { ThemeService, SpinePreferencesService } from '@trismegisto/spine';\nimport { HeaderComponent } from './header/header.component';\nimport { SidebarComponent } from './sidebar/sidebar.component';\nimport { SpineInitialSetupComponent } from './setup/initial-setup.component';\nimport { SpineInitialSetupService } from './setup/initial-setup.service';\nimport { SpineNewsComponent } from './news/news.component';\nimport { SpineNewsService } from './news/news.service';\nimport { ShortcutsCheatsheetComponent } from './shortcuts/shortcuts-cheatsheet.component';\nimport { SettingsPanelComponent } from './settings/settings-panel.component';\nimport { SpineSettingsService } from './settings/settings.service';\nimport { ShortcutService } from './shortcuts/shortcut.service';\nimport { SpineWorkspaceNavService } from './workspace/spine-workspace-nav.service';\nimport { SpinePagePanelComponent } from './workspace/spine-page-panel.component';\nimport { PanelLocalLinkDirective } from './workspace/panel-local-link.directive';\nimport { SpineDocsComponent } from './docs/docs-modal.component';\nimport { SpineConnectionBannerComponent } from './connection/connection-banner.component';\nimport { SpineLogoutService } from './logout/logout.service';\nimport { SpineIdleService } from './idle/idle.service';\nimport { SpineIdleWarningComponent } from './idle/idle-warning.component';\nimport { SpineStartPageService } from './start-page/start-page.service';\nimport { SpineAccountPreferencesService } from './account-preferences/account-preferences.service';\nimport { SpineUnsavedChangesService } from './workspace/spine-unsaved-changes';\nimport { SPINE_CONFIG } from '@trismegisto/spine';\nimport { DestroyRef } from '@angular/core';\n\n/**\n * Shell do spine — MESMA estrutura do `docs/website`'s `app.component.html`/`.scss` (decisão de\n * 2026-09-28, ver `hefesto-migration-plan.md`): `.shell` com altura de viewport de verdade\n * (`100dvh`, não `%` cascateado — `@trismegisto/core` não fixa altura de `html`/`body`, é\n * responsabilidade de quem consome, mesmo tanto quanto o docs faz no próprio `styles.scss`),\n * `hm-header` (utilitários — tema/densidade/apps/perfil, nunca navegação de página) + `.body`\n * (`hm-sidebar` fixa + `.main` com `hm-workspace`). **Sem barra de breadcrumb própria** — isso\n * era resíduo do spine antigo (`spine-navigation`), removido: o docs não tem uma, a navegação\n * inteira mora na sidebar. Entre o header e o corpo fica o `spine-connection-banner` (aviso de conexão\n * do `@orfeu/angular`, vazio quando `online`). Todos os avisos (os do `NotificationService`,\n * os do `SpineNoticesService` e os do próprio app) saem no `hm-toast-stack` (`HermesToastService`), montado aqui: o\n * app não monta nenhum.\n *\n * O `<router-outlet>` que sobra aqui é só pra `/no-permission` (a única rota do shell com\n * `component` de verdade — o resto da árvore do backend nunca passa pelo `Router` pra renderizar,\n * só pra `ViewGuard` confirmar que a URL resolve). Fica sempre montado (nunca dentro de um `@if`)\n * e escondido via `[hidden]` quando não é a rota ativa — destruir/recriar o outlet num `@if`\n * arriscaria perder a ativação da rota se a navegação e a checagem de `isNoPermission` não\n * corressem na mesma volta de detecção de mudanças.\n */\n@Component({\n selector: 'spine-layout',\n imports: [\n SpineNewsComponent,\n SpineDocsComponent,\n HeaderComponent,\n SidebarComponent,\n SpineConnectionBannerComponent,\n SpinePagePanelComponent,\n PanelLocalLinkDirective,\n WorkspaceComponent,\n ToastStackComponent,\n RouterOutlet,\n ModalComponent,\n SidePanelComponent,\n SpineInitialSetupComponent,\n ShortcutsCheatsheetComponent,\n SettingsPanelComponent,\n SpineIdleWarningComponent,\n SkipLinkComponent,\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <!-- \"Pular para o conteúdo\" (SpineFeatures.skipLink): primeira parada do Tab. -->\n @if (skipLink) {\n <hm-skip-link target=\"spine-main\" />\n }\n <div class=\"shell\" [attr.inert]=\"setup.isOpen() ? '' : null\">\n <spine-header></spine-header>\n <!-- Aviso de conexão do @orfeu/angular (offline/reconectando/reautorizando): faixa entre o header e o corpo. -->\n <spine-connection-banner />\n <div class=\"body\">\n @if (!isNoPermission) {\n <spine-sidebar class=\"sidebar\"></spine-sidebar>\n }\n <div class=\"main\" role=\"main\" [attr.id]=\"skipLink ? 'spine-main' : null\">\n <div [hidden]=\"isNoPermission\" class=\"workspace-area\">\n <!-- Dividir em painéis só com a preferência \"Dividir abas\" ligada (desligada por padrão), até 2 × 2. -->\n <hm-workspace [keepAlive]=\"true\" [split]=\"workspace.split()\" [maxColumns]=\"workspace.limits.maxColumns ?? null\" [maxRows]=\"workspace.limits.maxRows ?? null\" [providedStore]=\"unsaved.store\" (newTabRequested)=\"workspace.openNewTab($event)\">\n <ng-template #content let-tab let-panelId=\"panelId\" let-active=\"active\">\n <div\n class=\"panel-content\"\n [appPanelLocalLink]=\"panelId !== workspace.focusedPanelId()\"\n (localNavigate)=\"onLocalNavigate(panelId, $event)\"\n >\n <spine-page-panel [url]=\"tab.url ?? tab.id\" [tabId]=\"tab.id\" [panelId]=\"panelId\"\n [isFocusedPanel]=\"active && panelId === workspace.focusedPanelId()\" />\n </div>\n </ng-template>\n </hm-workspace>\n </div>\n <router-outlet></router-outlet>\n </div>\n </div>\n </div>\n <!-- Todos os avisos (respostas do servidor, avisos do app, configurações, auto-serviço…). Se o app também montar\n uma, só uma desenha (o serviço escolhe a pilha ativa): nunca em dobro. -->\n <hm-toast-stack />\n <spine-side-panel />\n <spine-modal />\n <spine-shortcuts-cheatsheet></spine-shortcuts-cheatsheet>\n <spine-settings-panel></spine-settings-panel>\n <spine-docs />\n <spine-news />\n <!-- Configuração inicial em tela cheia (primeiro acesso, \"Refazer\", \"Rever o essencial\"): por cima de tudo, com o shell inert. -->\n @if (setup.isOpen()) {\n <spine-initial-setup />\n }\n <!-- Aviso de \"Encerrar por inatividade\" (SpineFeatures.idleTimeout): só desenha quando abre. -->\n <spine-idle-warning />\n `,\n styles: [`\n :host { display: block; }\n .shell { display: flex; flex-direction: column; height: 100vh; height: 100dvh; background: var(--hm-surface); color: var(--hm-text); }\n .body { position: relative; display: flex; flex: 1; min-height: 0; overflow: hidden; }\n .main { display: flex; flex: 1; min-width: 0; flex-direction: column; }\n /* Abaixo da barra de abas vem a barra de contexto (spine-page-bar, tom elevado), não a folha da\n página: a aba ativa toma o tom dela — o encosto que emenda aba e barra — e a faixa das abas\n inativas fica num tom próprio (--hm-shell-tab-strip-bg: cinza nítido no claro, como no\n navegador; o surface no escuro). Só aqui: o padrão do DS (aba ativa = tom da folha) continua\n valendo para quem usa o hm-workspace com o conteúdo direto embaixo. */\n .workspace-area {\n flex: 1; min-height: 0; display: flex; flex-direction: column;\n --hm-tab-strip-bg: var(--hm-shell-tab-strip-bg);\n --hm-tab-active-bg: var(--hm-surface-raised);\n }\n hm-workspace { flex: 1; min-height: 0; }\n /* Sem padding aqui: a barra de contexto (spine-page-bar) ocupa a largura toda do painel; o respiro\n do conteúdo da página é do .spine-page-panel__content (ver spine-page-panel.component.ts). */\n .panel-content { display: flex; flex-direction: column; height: 100%; min-height: 0; }\n `],\n})\nexport class LayoutComponent implements OnInit {\n /** Aplica no boot o idioma e o fuso que a pessoa escolheu nas configurações. */\n private readonly preferences = inject(SpinePreferencesService);\n protected readonly workspace = inject(SpineWorkspaceNavService);\n private readonly settings = inject(SpineSettingsService);\n private readonly sidebar = inject(HermesSidebarService);\n /** Também liga, uma vez, o aviso de falha do logout (`logoutFailed$` do `@orfeu/angular`). */\n protected readonly logoutNotice = inject(SpineLogoutService);\n /** Recursos opcionais (`SpineConfig.features`): cada serviço não faz nada com o seu recurso desligado. */\n private readonly idle = inject(SpineIdleService);\n private readonly startPage = inject(SpineStartPageService);\n private readonly accountPreferences = inject(SpineAccountPreferencesService);\n protected readonly setup = inject(SpineInitialSetupService);\n /** Aviso de alterações não salvas (SpineFeatures.unsavedChanges): sem o recurso, `unsaved.store` é o próprio `workspace.store`. */\n protected readonly unsaved = inject(SpineUnsavedChangesService);\n /** SpineFeatures.skipLink. */\n protected readonly skipLink = !!inject(SPINE_CONFIG, { optional: true })?.features?.skipLink;\n private readonly destroyRef = inject(DestroyRef);\n\n /** Esconde sidebar e área de trabalho quando a rota ATIVA (do Router real, ver\n * `router.events` abaixo) é a de sem-permissão — nesse caso não existe menu/página válido\n * como contexto. Note que isto reflete só a URL do painel FOCADO (dona do Router real); um\n * painel secundário navegando localmente pra `/no-permission` não passa por aqui — cenário raro\n * o bastante (sem-permissão normalmente bloqueia o app inteiro, não uma aba) pra não justificar\n * mais complexidade agora. */\n public isNoPermission: boolean;\n\n constructor(\n private router: Router,\n private theme: ThemeService,\n private shortcuts: ShortcutService,\n private news: SpineNewsService,\n ) {\n this.isNoPermission = this.matchesNoPermission(this.router.url);\n this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd), takeUntilDestroyed())\n .subscribe(e => { this.isNoPermission = this.matchesNoPermission(e.urlAfterRedirects); });\n }\n\n private matchesNoPermission(url: string): boolean {\n return url.split(/[?#]/)[0] === '/no-permission';\n }\n\n ngOnInit(): void {\n // Preferências na conta (lê e aplica uma vez por sessão do app), inatividade e a \"última tela visitada\".\n void this.accountPreferences.start();\n this.idle.start();\n this.startPage.track();\n this.destroyRef.onDestroy(this.unsaved.start());\n\n // Liga os atalhos de teclado globais às ações reais do sistema.\n this.shortcuts.setActions({\n navigate: (url) => this.router.navigateByUrl(url),\n toggleTheme: () => this.theme.setTheme(this.theme.current === 'light' ? 'dark' : 'light'),\n openSettings: () => this.settings.toggle(),\n toggleSidebar: () => this.toggleSidebar(),\n });\n\n // Link direto pra uma seção do painel de configurações: `?settings=aparencia` (ou só\n // `?settings`). Tira o parâmetro da URL depois de abrir — senão ele volta a abrir o painel a\n // cada F5 e acompanha a URL copiada pra outra pessoa.\n const params = new URLSearchParams(window.location.search);\n if (params.has('settings')) {\n this.settings.open(params.get('settings') ?? '');\n void this.router.navigate([], { queryParams: { settings: null }, queryParamsHandling: 'merge', replaceUrl: true });\n }\n\n // Configuração inicial no primeiro acesso da pessoa (espera a conta dizer se já foi feita).\n this.setup.maybeOpen();\n // Novidades do app (argos-admin /me/news): um aviso discreto, uma vez por novidade, depois da configuração inicial.\n void this.news.announceOnEntry();\n }\n\n /**\n * `Mod+B`. Tela estreita: a gaveta. Fixo e compacto: troca um pelo outro (é a preferência da pessoa, fica gravada).\n * Automático: a coluna abre por cima e fica até o próximo `Mod+B`, sem mudar a preferência.\n */\n private toggleSidebar(): void {\n if (this.isNoPermission) return;\n if (window.matchMedia?.('(max-width: 767.98px)').matches) this.sidebar.toggleMobile();\n else if (this.sidebar.mode() === 'auto') this.sidebar.holdOpen(!this.sidebar.expanded());\n else this.sidebar.setMode(this.sidebar.mode() === 'fixed' ? 'compact' : 'fixed');\n }\n\n protected onLocalNavigate(panelId: string, href: string): void {\n const allowed = this.unsaved.canReplaceActive(panelId);\n if (allowed === true) this.workspace.navigateLocally(panelId, href);\n else void Promise.resolve(allowed).then((ok) => ok && this.workspace.navigateLocally(panelId, href));\n }\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, input, model, output, viewChild } from '@angular/core';\nimport {\n BubbleComponent, ButtonComponent, IconComponent, MessageComponent, MessageDividerComponent, MessageScrollerComponent,\n TagComponent, TextareaComponent, TooltipDirective,\n} from '@trismegisto/angular';\nimport { formatMessage, isMessageContinuation } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES, SpinePreferencesService } from '@trismegisto/spine';\nimport {\n SPINE_SUGGESTION_STATUS_COLORS, SpineSuggestionPerson, SpineSuggestionStatus,\n} from './suggestions.service';\n\n/** De que lado da conversa a tela está: a de quem pede (página) ou a da equipe (detalhe da tarefa). */\nexport type SpineChatSide = 'solicitante' | 'equipe';\n\n/** Uma mensagem da conversa de uma sugestão, do jeito que o chat desenha (a página e o detalhe convertem para isto). */\nexport interface SpineChatMessage {\n id: string;\n text: string;\n created_at: string;\n author: SpineSuggestionPerson | null;\n /** Escrita como quem pede (pela página); `false` = como equipe (pelo detalhe da tarefa). */\n from_requester: boolean;\n /** Comentário interno da equipe (só aparece do lado da equipe). */\n internal?: boolean;\n /** A mudança de status que o comentário acompanha. */\n status?: SpineSuggestionStatus | null;\n}\n\n/** Uma linha do chat já resolvida: lado, cabeçalho, agrupamento e o divisor de dia antes dela. */\ninterface ChatRow {\n message: SpineChatMessage;\n mine: boolean;\n author: string;\n grouped: boolean;\n day: string | null;\n}\n\n/**\n * A conversa de uma sugestão como chat (`hm-message-scroller` + `hm-message` + `hm-bubble`), com o campo de resposta\n * embaixo. Usado nos dois lados: a página de quem pede (`side=\"solicitante\"`) e o detalhe da tarefa da equipe\n * (`side=\"equipe\"`).\n *\n * **Quem fica à direita** é quem está com a tela aberta, no papel desta tela: a mensagem é da pessoa (`me`) E foi\n * escrita do mesmo lado (`from_requester` casa com `side`). A mesma pessoa no outro papel (quem administra e também\n * pediu, por exemplo) aparece à esquerda, como qualquer outro participante, com o papel no cabeçalho — a conversa\n * mostra de que lado cada mensagem foi escrita, não só quem a escreveu.\n *\n * - Mensagens do mais ANTIGO ao mais novo; o histórico mais antigo carrega pelo topo (`loadHistory`) sem tirar a\n * pessoa do lugar. Divisor de dia (\"Hoje\", \"Ontem\", a data) antes da primeira de cada dia.\n * - Mensagens seguidas da mesma pessoa, no mesmo papel e em poucos minutos se agrupam (sem repetir o cabeçalho).\n * - Comentário interno (só a equipe vê) em balão de destaque, com um cadeado pequeno no começo (sem selo embaixo: não\n * gasta uma linha); a mudança de status que o comentário acompanha, com o selo do status.\n * - O campo, numa linha só: Enter envia, Shift+Enter quebra a linha. Conteúdo extra do campo (o \"Só para a equipe\" do detalhe) entra\n * por projeção com o atributo `spineChatComposer`. Sem `canWrite`, no lugar do campo vai o conteúdo projetado com\n * `spineChatReadOnly`.\n */\n@Component({\n selector: 'spine-suggestion-chat',\n imports: [BubbleComponent, ButtonComponent, IconComponent, TooltipDirective, MessageComponent, MessageDividerComponent, MessageScrollerComponent, TagComponent, TextareaComponent],\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <div class=\"spine-chat\">\n <hm-message-scroller class=\"spine-chat__scroller\" [label]=\"label()\" [hasMoreHistory]=\"hasMore()\"\n [loadingHistory]=\"loading()\" (loadHistory)=\"loadHistory.emit()\">\n @for (row of rows(); track row.message.id) {\n @if (row.day) { <hm-message-divider [label]=\"row.day\" /> }\n <hm-message [author]=\"row.author\" [avatarUrl]=\"row.message.author?.picture\" [time]=\"row.message.created_at\"\n [timeFormat]=\"timeFormat\" [align]=\"row.mine ? 'end' : 'start'\" [showAvatar]=\"!row.mine\"\n [grouped]=\"row.grouped\">\n <!-- Interno: o balão em destaque já diferencia; só um cadeado pequeno no começo (o nome na dica e no leitor de tela). -->\n <hm-bubble [variant]=\"row.message.internal ? 'emphasis' : null\">\n @if (row.message.internal) {\n <span class=\"spine-chat__internal\" [attr.title]=\"text.internalTag\"><hm-icon shape=\"lock-close\" /><span class=\"spine-chat__sr\">{{ text.internalTag }}: </span></span>\n }<span class=\"spine-chat__text\">{{ row.message.text }}</span>\n </hm-bubble>\n @if (statusOf(row.message); as st) {\n <span hmMessageActions class=\"spine-chat__tags\"><hm-tag [name]=\"text.statuses[st]\" [color]=\"statusColors[st]\" /></span>\n }\n </hm-message>\n } @empty {\n @if (!loading()) { <p class=\"spine-chat__empty\">{{ empty() }}</p> }\n }\n </hm-message-scroller>\n\n @if (canWrite()) {\n <div class=\"spine-chat__composer\">\n <!-- Uma linha só: o campo cresce com o texto; ao lado, o extra (o \"Só para a equipe\") e o Enviar. Sem a linha de\n dica e contador embaixo: \"Enter envia\" fica na dica do botão (o servidor recusa acima do limite). -->\n <hm-textarea class=\"spine-chat__field\" [label]=\"composerLabel()\" labelHidden [placeholder]=\"placeholder()\"\n [rows]=\"1\" autoGrow [maxRows]=\"6\" [error]=\"error()\" [(value)]=\"draft\" (keydown)=\"onKey($event)\" />\n <div class=\"spine-chat__actions\">\n <ng-content select=\"[spineChatComposer]\" />\n <hm-button icon=\"arrow-send\" [hmTooltip]=\"text.chatSendHint\" [loading]=\"sending()\" [disabled]=\"!draft().trim()\"\n (clicked)=\"submit()\">{{ sendLabel() }}</hm-button>\n </div>\n </div>\n } @else {\n <ng-content select=\"[spineChatReadOnly]\" />\n }\n </div>\n `,\n styles: [`\n :host { display: block; min-inline-size: 0; }\n .spine-chat {\n display: flex;\n flex-direction: column;\n block-size: var(--spine-chat-height, min(70dvh, 44rem));\n overflow: hidden;\n border: var(--hm-border-hairline) solid var(--hm-border);\n border-radius: var(--hm-radius);\n background: var(--hm-surface);\n }\n .spine-chat__scroller { flex: 1 1 auto; min-block-size: 0; }\n .spine-chat__text { white-space: pre-line; overflow-wrap: anywhere; }\n .spine-chat__tags { display: inline-flex; flex-wrap: wrap; gap: var(--hm-space-xxxs); }\n .spine-chat__internal { display: inline-flex; margin-inline-end: var(--hm-space-micro); color: var(--hm-warning); vertical-align: -0.125em; }\n .spine-chat__internal hm-icon { --hm-icon-size: 0.875rem; }\n .spine-chat__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }\n .spine-chat__empty { margin: auto; padding: var(--hm-space-md); color: var(--hm-muted); font-size: var(--hm-font-size-sm); text-align: center; }\n .spine-chat__composer {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n gap: var(--hm-space-xs);\n padding: var(--hm-space-xs) var(--hm-space-sm);\n border-block-start: var(--hm-border-hairline) solid var(--hm-border);\n }\n .spine-chat__field { flex: 1 1 16rem; min-inline-size: 0; }\n .spine-chat__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: var(--hm-space-sm); }\n `],\n})\nexport class SpineSuggestionChatComponent {\n private readonly messages = inject(SPINE_MESSAGES);\n protected readonly text = this.messages.suggestions;\n private readonly preferences = inject(SpinePreferencesService);\n private readonly scroller = viewChild(MessageScrollerComponent);\n\n /** As mensagens, do mais antigo ao mais novo. */\n readonly items = input<readonly SpineChatMessage[]>([]);\n /** O papel desta tela: as mensagens da pessoa escritas deste lado ficam à direita. */\n readonly side = input.required<SpineChatSide>();\n /** O `user_id` de quem está com a tela aberta. */\n readonly me = input('');\n readonly label = input('');\n readonly empty = input('');\n readonly hasMore = input(false);\n readonly loading = input(false);\n readonly canWrite = input(true);\n readonly composerLabel = input('');\n readonly placeholder = input('');\n readonly sendLabel = input('');\n readonly sending = input(false);\n readonly error = input('');\n /** O texto do campo (em mão dupla: quem usa limpa depois de enviar). */\n readonly draft = model('');\n\n readonly loadHistory = output<void>();\n /** Enviar: o texto aparado (nunca vazio). */\n readonly send = output<string>();\n\n protected readonly statusColors = SPINE_SUGGESTION_STATUS_COLORS;\n protected readonly timeFormat: Intl.DateTimeFormatOptions = { hour: '2-digit', minute: '2-digit' };\n\n protected readonly rows = computed<ChatRow[]>(() => {\n const me = this.me();\n const side = this.side();\n const list = this.items();\n // A chave do agrupamento é a pessoa NO PAPEL: a mesma pessoa como equipe e como quem pede não se junta.\n const keyOf = (m: SpineChatMessage) => `${m.author?.user_id ?? '?'}:${m.from_requester ? 'r' : 't'}`;\n return list.map((message, i) => {\n const previous = list[i - 1];\n const day = !previous || this.dayKey(previous.created_at) !== this.dayKey(message.created_at) ? this.dayLabel(message.created_at) : null;\n const mine = !!me && message.author?.user_id === me && message.from_requester === (side === 'solicitante');\n return {\n message,\n mine,\n author: mine ? this.text.page.you : this.authorText(message),\n grouped: !day && isMessageContinuation(\n previous ? { author: keyOf(previous), time: previous.created_at } : null,\n { author: keyOf(message), time: message.created_at },\n ),\n day,\n };\n });\n });\n\n /** Depois de enviar: a pessoa quer ver a própria mensagem, mesmo se estava lendo lá em cima. */\n scrollToEnd(): void {\n this.scroller()?.scrollToEnd('smooth');\n }\n\n protected onKey(event: Event): void {\n const key = event as KeyboardEvent;\n if (key.key !== 'Enter' || key.shiftKey || key.isComposing) return;\n key.preventDefault();\n this.submit();\n }\n\n protected submit(): void {\n const text = this.draft().trim();\n if (text && !this.sending()) this.send.emit(text);\n }\n\n protected statusOf(m: SpineChatMessage): SpineSuggestionStatus | null {\n return m.status && this.statusColors[m.status] ? m.status : null;\n }\n\n /** \"Ana Souza (Equipe)\": do outro lado, o papel junto do nome — inclusive a própria pessoa no outro papel. */\n private authorText(m: SpineChatMessage): string {\n const name = m.author?.name || m.author?.username || this.text.removedAuthor;\n const role = m.from_requester ? this.text.fromRequester : this.text.page.team;\n return formatMessage(this.text.chatAuthor, { name, role });\n }\n\n private dayKey(iso: string): string {\n try {\n return new Intl.DateTimeFormat('en-CA', { timeZone: this.preferences.effectiveTimeZone() }).format(new Date(iso));\n } catch {\n return iso.slice(0, 10);\n }\n }\n\n /** \"Hoje\", \"Ontem\" ou a data por extenso (no idioma do catálogo e no fuso da pessoa). */\n private dayLabel(iso: string): string {\n const locale = this.messages.meta.locale;\n const today = this.dayKey(new Date().toISOString());\n const days = Math.round((Date.parse(`${today}T00:00:00Z`) - Date.parse(`${this.dayKey(iso)}T00:00:00Z`)) / 86_400_000);\n try {\n if (days === 0 || days === 1) {\n const word = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(-days, 'day');\n return word.charAt(0).toLocaleUpperCase(locale) + word.slice(1);\n }\n return new Intl.DateTimeFormat(locale, {\n weekday: 'long', day: 'numeric', month: 'long', timeZone: this.preferences.effectiveTimeZone(),\n }).format(new Date(iso));\n } catch {\n return this.dayKey(iso);\n }\n }\n}\n","import {\n ChangeDetectionStrategy, Component, DestroyRef, ElementRef, Injector, PLATFORM_ID, afterNextRender, computed, effect, inject,\n input, signal, untracked,\n} from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\nimport { formatMessage } from '@trismegisto/primitives';\nimport { SPINE_MESSAGES } from '@trismegisto/spine';\n\n/** Um selo da linha: o nome e, se quiser, a cor (1..8, a paleta categórica do tema); sem cor, uma estável pelo id. */\nexport interface SpineTagRowItem { id: string; name: string; color?: number }\n\n/** Cor categórica estável para um id (o mesmo grupo sempre na mesma cor, em qualquer tela). */\nexport function spineTagColor(id: string): number {\n let hash = 0;\n for (let i = 0; i < id.length; i++) hash = (hash * 31 + id.charCodeAt(i)) | 0;\n return (Math.abs(hash) % 8) + 1;\n}\n\n/**\n * Selos numa linha só, no modelo dos rótulos do quadro (fundo claro da cor e o ponto na cor cheia): cabem os que cabem\n * na largura e o resto vira \"+N\", com os nomes na dica e para o leitor de tela. Mede de novo quando a largura muda\n * (ResizeObserver) e quando a lista muda; sem medida (servidor, teste sem layout), mostra todos.\n *\n * Os que não cabem continuam no DOM, fora do fluxo e invisíveis (`visibility: hidden`), só para a largura deles poder\n * ser medida; ficam `aria-hidden` — quem lê a tela ouve os nomes no \"+N\".\n */\n@Component({\n selector: 'spine-tag-row',\n changeDetection: ChangeDetectionStrategy.OnPush,\n template: `\n <ul class=\"spine-tags\" [attr.aria-label]=\"label() || null\">\n @for (t of tags(); track t.id; let i = $index) {\n <li class=\"spine-tags__tag\" [class.spine-tags__tag--out]=\"i >= visible()\" [attr.aria-hidden]=\"i >= visible() ? 'true' : null\"\n [attr.title]=\"t.name\" [style.--spine-tag]=\"'var(--hm-data-categorical-' + t.color + ')'\">{{ t.name }}</li>\n } @empty {\n @if (empty()) { <li class=\"spine-tags__empty\">{{ empty() }}</li> }\n }\n @if (hiddenCount()) {\n <li class=\"spine-tags__tag spine-tags__more\" [attr.title]=\"hiddenNames()\">{{ moreText() }}<span class=\"spine-tags__sr\">: {{ hiddenNames() }}</span></li>\n }\n <!-- A largura de um \"+N\" com dois dígitos: reservada antes de saber quantos sobram. -->\n <li class=\"spine-tags__tag spine-tags__more spine-tags__probe\" aria-hidden=\"true\">+99</li>\n </ul>\n `,\n styles: [`\n :host { display: block; min-inline-size: 0; }\n .spine-tags { position: relative; display: flex; flex-wrap: nowrap; align-items: center; gap: var(--hm-space-micro); margin: 0; padding: 0; overflow: hidden; list-style: none; }\n .spine-tags__tag {\n display: inline-flex;\n flex: none;\n align-items: center;\n gap: var(--hm-space-micro);\n max-inline-size: 100%;\n padding: 0 var(--hm-space-xxxs);\n overflow: hidden;\n border-radius: var(--hm-radius-pill);\n background: color-mix(in srgb, var(--spine-tag, var(--hm-border)) 18%, var(--hm-surface-raised));\n color: var(--hm-text);\n font-size: var(--hm-font-size-xs);\n font-weight: var(--hm-font-weight-semibold);\n line-height: 1.6;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n .spine-tags__tag::before { flex: none; inline-size: 0.5rem; block-size: 0.5rem; border-radius: 50%; background: var(--spine-tag, var(--hm-border)); content: ''; }\n .spine-tags__tag--out,\n .spine-tags__probe { position: absolute; visibility: hidden; pointer-events: none; }\n .spine-tags__more { color: var(--hm-muted); cursor: help; }\n .spine-tags__more::before { display: none; }\n .spine-tags__empty { color: var(--hm-muted); font-size: var(--hm-font-size-sm); }\n .spine-tags__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }\n @media (forced-colors: active) { .spine-tags__tag { border: var(--hm-border-hairline) solid CanvasText; } }\n `],\n})\nexport class SpineTagRowComponent {\n private readonly text = inject(SPINE_MESSAGES).suggestions;\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly browser = isPlatformBrowser(inject(PLATFORM_ID));\n private readonly injector = inject(Injector);\n private readonly destroyRef = inject(DestroyRef);\n\n readonly items = input<readonly SpineTagRowItem[]>([]);\n readonly label = input('');\n /** Texto quando não há nenhum (vazio = nada). */\n readonly empty = input('');\n\n protected readonly tags = computed(() => this.items().map((t) => ({ ...t, color: t.color ?? spineTagColor(t.id) })));\n /** Quantos cabem; começa com todos (sem medida, todos aparecem). */\n protected readonly visible = signal(Number.MAX_SAFE_INTEGER);\n protected readonly hiddenCount = computed(() => Math.max(0, this.tags().length - this.visible()));\n protected readonly hiddenNames = computed(() => this.tags().slice(this.visible()).map((t) => t.name).join(', '));\n protected readonly moreText = computed(() => formatMessage(this.text.moreAssignees, { count: this.hiddenCount() }));\n\n constructor() {\n if (!this.browser) return;\n // Lista nova: mede depois de desenhar.\n effect(() => {\n this.tags();\n untracked(() => afterNextRender(() => this.measure(), { injector: this.injector }));\n });\n afterNextRender(() => {\n if (typeof ResizeObserver === 'undefined') return;\n const observer = new ResizeObserver(() => this.measure());\n observer.observe(this.host.nativeElement);\n this.destroyRef.onDestroy(() => observer.disconnect());\n });\n }\n\n /** Quantos selos cabem na largura, reservando o \"+N\" quando nem todos cabem. */\n private measure(): void {\n const list = this.host.nativeElement.querySelector<HTMLElement>('.spine-tags');\n if (!list) return;\n const width = list.clientWidth;\n const tags = Array.from(list.querySelectorAll<HTMLElement>('.spine-tags__tag:not(.spine-tags__more)'));\n if (!width || !tags.length) {\n this.visible.set(Number.MAX_SAFE_INTEGER);\n return;\n }\n const gap = parseFloat(getComputedStyle(list).columnGap) || 0;\n const more = list.querySelector<HTMLElement>('.spine-tags__probe')?.offsetWidth ?? 0;\n const widths = tags.map((t) => t.offsetWidth);\n const total = widths.reduce((sum, w) => sum + w, 0) + gap * (widths.length - 1);\n if (total <= width) {\n this.visible.set(widths.length);\n return;\n }\n let used = more;\n let fit = 0;\n for (const w of widths) {\n if (used + gap + w > width) break;\n used += gap + w;\n fit++;\n }\n // Pelo menos um aparece (cortado com reticências se for maior que a linha).\n this.visible.set(Math.max(1, fit));\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["HermesHeaderComponent","i1","HermesSidebarComponent","fold","sequence","findPanelTabs","HermesSidebarService","i2","i3.ShortcutService","i4.SpineNewsService","ModalComponent"],"mappings":"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"}