@franzzemen/brokenstock-shell 0.9.0 → 0.9.2
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"franzzemen-brokenstock-shell.mjs","sources":["../../src/lib/types/command.types.ts","../../src/lib/tokens/shell-tokens.ts","../../src/lib/provide-shell-config.ts","../../src/lib/services/thinking.service.ts","../../src/lib/services/session-token-store.ts","../../src/lib/services/cross-window-lock.ts","../../src/lib/services/renewal-decision.ts","../../src/lib/services/authenticator.types.ts","../../src/lib/services/authentication.service.ts","../../src/lib/guards/auth.guard.ts","../../src/lib/guards/guest.guard.ts","../../src/lib/interceptors/auth.interceptor.ts","../../src/lib/directives/regex-validator.directive.ts","../../src/lib/faq/faq.types.ts","../../src/lib/faq/faq-content-loader.token.ts","../../src/lib/faq/faq-markdown-renderer.service.ts","../../src/lib/faq/http-faq-content-loader.service.ts","../../src/lib/faq/faq-history.service.ts","../../src/lib/faq/faq.service.ts","../../src/lib/faq/faq-dev-mode.token.ts","../../src/lib/faq/faq-modal/faq-modal.ts","../../src/lib/faq/faq-modal/faq-modal.html","../../src/lib/faq/faq-authoring-panel/faq-authoring-panel.ts","../../src/lib/faq/faq-authoring-panel/faq-authoring-panel.html","../../src/lib/faq/public-faq-toc/public-faq-toc.ts","../../src/lib/faq/faq-seo.tokens.ts","../../src/lib/faq/public-faq-index/public-faq-index.ts","../../src/lib/faq/public-faq-page/public-faq-page.ts","../../src/lib/services/theme.service.ts","../../src/lib/services/phone-layout.service.ts","../../src/lib/services/terminal-focus.service.ts","../../src/lib/services/terminal-visibility.service.ts","../../src/lib/services/keyboard-shortcut.service.ts","../../src/lib/commands/faq.command.ts","../../src/lib/services/command-registry.service.ts","../../src/lib/commands/command.utils.ts","../../src/lib/services/command.service.ts","../../src/lib/components/status-bar/status-bar.ts","../../src/lib/components/status-bar/status-bar.html","../../src/lib/components/side-menu/side-menu.ts","../../src/lib/components/side-menu/side-menu.html","../../src/lib/components/main-content/main-content.ts","../../src/lib/components/main-content/main-content.html","../../src/lib/components/command-terminal/command-terminal.ts","../../src/lib/components/command-terminal/command-terminal.html","../../src/lib/components/shell/shell.ts","../../src/lib/components/shell/shell.html","../../src/lib/components/recovery-codes/recovery-codes.ts","../../src/lib/components/login/login.ts","../../src/lib/components/login/login.html","../../src/lib/components/authenticator-settings/authenticator-settings.ts","../../src/lib/components/authenticator-settings/authenticator-settings.html","../../src/lib/components/code-dialog/code-dialog.ts","../../src/lib/components/confirm-dialog/confirm-dialog.ts","../../src/public-api.ts","../../src/franzzemen-brokenstock-shell.ts"],"sourcesContent":["/*\n * Command framework types — absorbed from brokenstock-lexicon.\n * Platform-agnostic; no Angular dependencies.\n */\nimport { z } from 'zod/v4';\n\nexport type Severity = 'error' | 'warning' | 'info';\n\nexport interface CommandResult {\n success: boolean;\n message: string;\n timestamp: Date;\n severity?: Severity;\n isHelp?: boolean;\n}\n\nexport interface CommandHistoryEntry {\n input: string;\n result: CommandResult;\n repeatCount?: number;\n}\n\n\n/**\n * An alternate name for a command. Mirrors `CommandAlias` in\n * @franzzemen/brokenstock-lexicon — this library keeps its own copy of the\n * command types (see the file header), and the two MUST stay in step.\n *\n * TWO SHAPES:\n * - A plain alternate is another word for the same command (`scan` for\n * `scanner`); arguments pass through untouched.\n * - An alternate carrying `prependArgs` also supplies leading arguments, so\n * one word stands for a command AND its subcommand: `scans NVDA` runs\n * `scanner select NVDA`. The expansion is literal, so anything the\n * subcommand accepts keeps working through the short form.\n *\n * The real name is what `help` lists; alternates are named in the command's own\n * usage text. The registry refuses a name already taken, real or alternate.\n */\nexport interface CommandAlias {\n readonly name: string;\n readonly prependArgs?: readonly string[];\n}\n\n/**\n * Where a command belongs. Mirrors `@franzzemen/brokenstock-lexicon`'s\n * `RouteScope` — the lexicon is the source of truth and carries the full\n * rationale (trades-tree.prd.md D29–D33); this copy exists because the shell\n * deliberately does not depend on the lexicon.\n *\n * - `'navigate'`: the command takes you to its screen and acts; the shell never\n * refuses it, and `help` says where it lives.\n * - `'refuse'`: the command depends on state only its screen sets; typed\n * anywhere else the shell refuses with a message naming the screen.\n */\nexport interface RouteScope {\n /** \"the Trades screen\" — used verbatim in refusals and in `help`. */\n readonly screen: string;\n /** Route patterns; see {@link matchesRoute}. */\n readonly routes: readonly string[];\n readonly elsewhere: 'navigate' | 'refuse';\n}\n\nexport type CommandScope = 'global' | RouteScope;\n\n/**\n * Does `url` fall inside any of `patterns`? Query string and fragment are\n * stripped; a pattern matches when the path equals it or continues past it at\n * a `/`; a `:param` segment matches any one non-empty segment. Same rule as\n * the lexicon's `matchesRoute`, tested there and here.\n */\nexport function matchesRoute(url: string, patterns: readonly string[]): boolean {\n const path = url.split('?')[0]!.split('#')[0]!.replace(/\\/+$/, '') || '/';\n const segments = path.split('/');\n return patterns.some(pattern => {\n const want = pattern.replace(/\\/+$/, '').split('/');\n if (want.length > segments.length) return false;\n return want.every((w, i) => (w.startsWith(':') ? segments[i]!.length > 0 : w === segments[i]));\n });\n}\n\n/**\n * Lexicon entry: the platform-agnostic definition of a command.\n * Execution is provided by each consumer (Angular app, CLI app, etc.).\n */\nexport interface CommandLexiconEntry {\n readonly name: string;\n readonly description: string;\n readonly usage: string;\n readonly requiresAuth: boolean;\n readonly argsSchema: z.ZodType;\n /** Where the command belongs. Required: every command declares it. */\n readonly scope: CommandScope;\n /** Alternate names for this command. See {@link CommandAlias}. */\n readonly aliases?: readonly CommandAlias[];\n sanitizeInput?(input: string): string;\n}\n\n/**\n * Result of a command's readiness check. `reason` is surfaced verbatim to the\n * user and MUST be non-empty when `ok` is false — the terminal renders nothing\n * at all for an empty message, which would look like the command silently did\n * nothing.\n */\nexport interface CommandAvailability {\n ok: boolean;\n reason?: string;\n}\n\n/**\n * Full command definition including execution.\n */\nexport interface CommandDefinition extends CommandLexiconEntry {\n /**\n * Declarative readiness gate, checked centrally before `execute`. Use for\n * preconditions the user can act on (entitlement, onboarding state) rather\n * than checking imperatively as the first statement of `execute` — the\n * framework can only annotate `help` for gates it can see.\n *\n * A command that fails this check stays listed in `help` and in\n * tab-completion, annotated with its reason. Hiding it would read as a broken\n * CLI; an explained refusal reads as guidance.\n *\n * Omit for always-available.\n */\n isAvailable?(): CommandAvailability;\n\n execute(args: string[]): CommandResult | Promise<CommandResult>;\n}\n","import { InjectionToken } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { MenuItem } from '../types/menu.types';\n\nexport interface ShellAuthUrls {\n login: string;\n logout: string;\n refresh: string;\n}\n\nexport const SHELL_APP_NAME = new InjectionToken<string>('SHELL_APP_NAME');\nexport const SHELL_MENU_ITEMS = new InjectionToken<MenuItem[]>('SHELL_MENU_ITEMS');\nexport const SHELL_AUTH_URLS = new InjectionToken<ShellAuthUrls>('SHELL_AUTH_URLS');\n\n/**\n * App-specific commands to register alongside the built-in command set.\n * Provide via provideShellConfig().\n */\nexport const SHELL_COMMANDS = new InjectionToken<CommandDefinition[]>('SHELL_COMMANDS');\n\nexport const SHELL_POST_LOGIN_ROUTE = new InjectionToken<string>('SHELL_POST_LOGIN_ROUTE');\n\n/**\n * Whether this app shares one session across every window of the browser\n * (multiple-windows PRD D2/D7).\n *\n * ⚠ OFF unless an app opts in, and only `broken-stock` does. Turning it on puts\n * the sign-in token in browser storage, where any script on the origin can read\n * it and it persists on disk. The admin apps send their renewal cookie\n * cross-site and can change other people's data, which makes that a materially\n * different exposure — extending this to them is a separate decision, not a\n * default.\n */\nexport const SHELL_SHARED_SESSION = new InjectionToken<boolean>('SHELL_SHARED_SESSION');\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { CommandDefinition } from './types/command.types';\nimport { MenuItem } from './types/menu.types';\nimport { SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_SHARED_SESSION, ShellAuthUrls } from './tokens/shell-tokens';\n\nexport interface ShellConfig {\n appName: string;\n menuItems: MenuItem[];\n authUrls: ShellAuthUrls;\n commands?: CommandDefinition[];\n /**\n * Share one session across every window of the browser. Defaults to false.\n * See {@link SHELL_SHARED_SESSION} for why this is opt-in.\n */\n sharedSession?: boolean;\n}\n\nexport function provideShellConfig(config: ShellConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: SHELL_APP_NAME, useValue: config.appName },\n { provide: SHELL_MENU_ITEMS, useValue: config.menuItems },\n { provide: SHELL_AUTH_URLS, useValue: config.authUrls },\n { provide: SHELL_COMMANDS, useValue: config.commands ?? [] },\n { provide: SHELL_SHARED_SESSION, useValue: config.sharedSession ?? false },\n ]);\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class ThinkingService {\n readonly #activeCount = signal(0);\n\n readonly isThinking = computed(() => this.#activeCount() > 0);\n\n startThinking(): void {\n this.#activeCount.update(c => c + 1);\n }\n\n stopThinking(): void {\n this.#activeCount.update(c => Math.max(0, c - 1));\n }\n\n reset(): void {\n this.#activeCount.set(0);\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nThe sign-in token's home in browser storage (multiple-windows PRD D2).\n\nWHY THIS IS ITS OWN FILE, AND WHY IT DOES NOT USE `LocalStorageService`.\nThat service swallows a failed write on purpose — losing a remembered pane width\nmust never break the screen that was trying to remember it. That policy is\nexactly wrong here. A silently dropped token write is a silently lost session:\nthe window keeps working on the token it holds in memory, every other window\nnever learns it, and the failure surfaces minutes later somewhere else entirely.\nSo this writes directly and THROWS.\n\nREADS ARE THE SOURCE OF TRUTH, NOT A CACHE. `AuthenticationService.auth` reads\nthrough to this on every access rather than keeping a copy. That is the whole\nreason the design works with several windows open: the tape socket asks for the\ntoken on a sixty-second heartbeat and a window that is frozen or backgrounded may\nnever receive a queued `storage` event, so a copy refreshed by an event is only\nas fresh as the last event delivered. Reading through removes the question.\n\n⚠ NOT under the `bs.pref.` namespace. `LocalStorageService` wipes that namespace\nwholesale, and a preference wipe must never sign the user out.\n*/\n\nimport { Injectable } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken } from '@franzzemen/utility';\n\n/** Deliberately outside `bs.pref.` — see the header. */\nexport const SESSION_TOKEN_KEY = 'bs.auth.token';\n\n@Injectable({ providedIn: 'root' })\nexport class SessionTokenStore {\n /** False during prerendering, where there is no `window` at all. */\n readonly #available = typeof window !== 'undefined' && !!window.localStorage;\n\n get available(): boolean {\n return this.#available;\n }\n\n /**\n * The stored token, or undefined.\n *\n * A stored value that is not a well-formed bearer is treated as absent and\n * removed. It cannot be authenticated with, and leaving it there would make\n * every later read fail the same way with nothing to explain it.\n */\n read(): BearerToken | undefined {\n if (!this.#available) return undefined;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(SESSION_TOKEN_KEY);\n } catch {\n // Storage disabled by the browser. Not recoverable here, and not fatal —\n // the caller falls back to its in-memory token and this window works\n // alone, which is exactly today's behaviour.\n return undefined;\n }\n if (!raw) return undefined;\n if (!BEARER_TOKEN_REGEX.test(raw)) {\n this.clear();\n return undefined;\n }\n return raw as BearerToken;\n }\n\n /**\n * Stores the token. THROWS on failure — see the header.\n *\n * @throws if the value is not a bearer token, or the write does not stick.\n */\n write(token: BearerToken): void {\n if (!this.#available) return;\n if (!BEARER_TOKEN_REGEX.test(token)) {\n throw new Error('SessionTokenStore.write refused a value that is not a bearer token');\n }\n try {\n window.localStorage.setItem(SESSION_TOKEN_KEY, token);\n } catch (error) {\n throw new Error(`Could not store the session token: ${String(error)}`);\n }\n }\n\n clear(): void {\n if (!this.#available) return;\n try {\n window.localStorage.removeItem(SESSION_TOKEN_KEY);\n } catch {\n // Nothing useful to do. The in-memory state is cleared by the caller\n // regardless, so this window is signed out either way.\n }\n }\n\n /**\n * Calls back when ANOTHER window changes the token.\n *\n * `storage` does not fire in the window that made the change, which is\n * correct — that window is the one doing it and has already acted.\n *\n * ⚠ `event.key === null` is what `localStorage.clear()` produces, and it means\n * everything went, this key included. Treating it as \"not our key\" is how a\n * whole-storage clear silently fails to sign the user out.\n */\n onExternalChange(handler: (token: BearerToken | undefined) => void): () => void {\n if (!this.#available) return () => undefined;\n const listener = (event: StorageEvent) => {\n if (event.key !== null && event.key !== SESSION_TOKEN_KEY) return;\n handler(this.read());\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nRun something in exactly one window (multiple-windows PRD D5).\n\nTHE PROBLEM. Several windows share one session. When the token expires they all\nnotice at once and all try to renew. The server serialises renewal correctly and\nREFUSES the losers, so without coordination every window but one is signed out —\nand it happens every token lifetime, several times a day.\n\nWHY `ifAvailable` RATHER THAN WAITING ON THE LOCK. A waiter blocks on a peer it\ncannot supervise. If the window holding the lock is frozen, backgrounded or its\nrequest hangs, the waiters wait forever — screens simply stop updating, with\nnothing logged and nothing on screen. `ifAvailable` refuses immediately instead,\nwhich turns \"wait on a peer\" into \"wait for a value to appear, with my own\nbound\". A bound you own is a bound you can honour.\n\n⚠ A lock held by a DESTROYED document is released by the browser, so closing a\nwindow is safe. A merely frozen document is NOT destroyed — which is why every\npath here is bounded regardless.\n\n⚠ `navigator.locks` needs a secure context and is absent in some. Absent means\nfall back to running uncoordinated — today's behaviour — never throw. A missing\nAPI must not be the reason nobody can sign in.\n*/\n\n/**\n * Checked at CALL time, not once at module load.\n *\n * Module-level would be evaluated during import — before `navigator` exists at\n * all under prerendering, and before a test can arrange anything — permanently\n * fixing the answer to \"no\" for the life of the process. Found by writing the\n * test for the fallback path, which could not be reached any other way.\n */\nfunction locksAvailable(): boolean {\n return typeof navigator !== 'undefined' && typeof navigator.locks?.request === 'function';\n}\n\nexport type LockOutcome<T> =\n /** We held the lock and ran. */\n | {ran: true; value: T}\n /** Another window held it. We did not run. */\n | {ran: false};\n\n/**\n * Runs `work` if this window can take the lock right now.\n *\n * Returns `{ran: false}` when another window holds it — the caller decides what\n * to do instead, which is the point: only the caller knows whether waiting for\n * the peer's result or proceeding alone is correct.\n *\n * When `navigator.locks` is unavailable the work RUNS, uncoordinated. That is a\n * deliberate degradation to today's behaviour rather than a refusal.\n */\nexport async function runExclusive<T>(name: string, work: () => Promise<T>): Promise<LockOutcome<T>> {\n if (!locksAvailable()) {\n console.warn(`[shell] navigator.locks unavailable; \"${name}\" runs without cross-window coordination`);\n return {ran: true, value: await work()};\n }\n let outcome: LockOutcome<T> = {ran: false};\n await navigator.locks.request(name, {ifAvailable: true}, async lock => {\n if (!lock) return;\n outcome = {ran: true, value: await work()};\n });\n return outcome;\n}\n\n/**\n * Polls `read` until it returns something other than `unchanged`, or the bound\n * elapses.\n *\n * Polling rather than listening for `storage` on purpose: the event does not\n * fire in a window that is frozen at the moment it is dispatched, and this is\n * the path that recovers such a window. A poll asks the question again.\n *\n * Resolves `undefined` on timeout — \"the peer did not deliver\", which is a\n * legitimate answer the caller must handle, not an error.\n */\nexport async function awaitChange<T>(\n read: () => T,\n unchanged: T,\n timeoutMs: number,\n pollMs = 100,\n): Promise<T | undefined> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const current = read();\n if (current !== unchanged) return current;\n if (Date.now() >= deadline) return undefined;\n await new Promise(resolve => setTimeout(resolve, pollMs));\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nWhat a window should do once it can act on a session renewal\n(multiple-windows PRD D5).\n\nWHY THIS IS A NAMED FUNCTION RATHER THAN THREE `if`s INSIDE THE SERVICE. The\nrule was originally written as \"retry with a token different from the one you\nfailed with\", which is not a well-defined instruction: the in-window\nsingle-flight already collapses requests that were sent with DIFFERENT tokens,\nso \"the one you failed with\" is not a single value. Pulling the decision out\nforces the three cases to be named, and lets them be tested without mocking a\nnetwork call — which is what they deserve, because getting this wrong shows up\nhours later as \"a window signed me out\" with nothing linking cause to effect.\n*/\n\nimport { BearerToken } from '@franzzemen/utility';\n\nexport type RenewalDecision =\n /** The token is gone: the window that renewed failed permanently, or signed out. */\n | 'sign-out'\n /** Another window renewed while we queued. Take its token; do NOT rotate again. */\n | 'adopt'\n /** Nothing has moved. This window performs the renewal itself. */\n | 'renew';\n\n/**\n * @param before the token this window held immediately BEFORE asking for the lock\n * @param current the token in shared storage now that this window can act\n */\nexport function decideRenewal(\n before: BearerToken | undefined,\n current: BearerToken | undefined,\n): RenewalDecision {\n // Gone. Retrying would present nothing and 401 again; worse, it would look\n // like a transient failure when it is a definite answer.\n if (before && !current) return 'sign-out';\n // Someone else's fresh token. Rotating again would invalidate the token every\n // OTHER window just adopted — turning one window's recovery into everyone\n // else's sign-out.\n if (current && current !== before) return 'adopt';\n // Unchanged, or nothing stored to begin with.\n return 'renew';\n}\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nAuthenticator sign-in — what the browser sees (authenticator-sign-in.prd.md).\n*/\n\n/** The `reason` the auth worker puts on every authenticator refusal. */\nexport type AuthenticatorReason =\n | 'code-required'\n | 'invalid-code'\n | 'too-many-attempts'\n | 'authenticator-not-set-up'\n | 'setup-required';\n\n/** Which extra step the sign-in screen is on, after the password was accepted. */\nexport type SignInCodeStep = 'none' | 'code' | 'setup';\n\n/** GET {login}/authenticator. */\nexport type AuthenticatorStatus = {\n enrolled: boolean;\n recoveryCodesLeft: number;\n /** Yes/no only — the server never sends when it ends (D12). */\n bypassActive: boolean;\n codeRequired: boolean;\n};\n\n/** What a code-bearing request carries: a 6-digit code or a recovery code. */\nexport type CodeEntry = {code?: string; recoveryCode?: string};\n\n/** The QR shown once during setup, and the same secret as text for typing in by hand. */\nexport type SetupChallenge = {qr: string; key: string};\n\n/**\n * The one message for a pause (D8). The server sends no time and the screen invents none.\n */\nexport const TOO_MANY_ATTEMPTS = 'Too many attempts.';\n\n/** Plain words for each refusal, shown on the sign-in screen and in the code dialog. */\nexport function authenticatorMessage(reason: AuthenticatorReason | undefined): string {\n switch (reason) {\n case 'code-required': return 'Enter the 6-digit code from your authenticator app.';\n case 'invalid-code': return 'That code did not work. Try the current one.';\n case 'too-many-attempts': return TOO_MANY_ATTEMPTS;\n case 'authenticator-not-set-up': return 'This account has no authenticator set up. Ask the administrator to reset it.';\n case 'setup-required': return 'Scan this QR code with your authenticator app, then enter the 6-digit code it shows.';\n default: return 'Unable to sign in';\n }\n}\n\n/** The text file the Download button saves (D7). */\nexport function recoveryCodesFile(appName: string, username: string | undefined, codes: readonly string[], now = new Date()): string {\n return [\n `${appName} recovery codes${username ? ` for ${username}` : ''}`,\n `Generated ${now.toISOString()}`,\n '',\n 'Each code works once, in place of the 6-digit code from your authenticator app.',\n 'Keep this file somewhere safe and offline. Anyone with these codes and your password can sign in.',\n '',\n ...codes,\n '',\n ].join('\\n');\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken, HttpHeader } from '@franzzemen/utility';\nimport { AuthenticationResponse, Credentials, SessionSummary, UserSession, validateCredentials } from '@franzzemen/identity';\nimport { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { ThinkingService } from './thinking.service';\nimport { SHELL_AUTH_URLS, SHELL_SHARED_SESSION } from '../tokens/shell-tokens';\nimport { SessionTokenStore } from './session-token-store';\nimport { awaitChange, runExclusive } from './cross-window-lock';\nimport { decideRenewal } from './renewal-decision';\nimport { firstValueFrom } from 'rxjs';\nimport {\n AuthenticatorReason,\n AuthenticatorStatus,\n authenticatorMessage,\n CodeEntry,\n SetupChallenge,\n SignInCodeStep,\n} from './authenticator.types';\n\n/**\n * A refusal from an authenticator route, carrying the server's `reason`\n * (authenticator-sign-in.prd.md). `message` is plain words for the screen.\n */\nexport class AuthenticatorError extends Error {\n constructor(readonly reason: AuthenticatorReason | undefined, message: string, readonly status: number) {\n super(message);\n this.name = 'AuthenticatorError';\n }\n}\n\n/** Sign-in rejected because the next step is a code (or setting one up), not because anything failed. */\nexport const CODE_STEP = 'code-step';\n\n/**\n * What the user decided about sessions they already hold, sent on the SECOND\n * sign-in attempt (multiple-devices D2/D6).\n *\n * Mutually exclusive in practice, and the screen only ever sets one: taking\n * over everything is `force` on the call itself, signing in beside them is\n * `additional`, and ending a chosen few is `endSessionIds`.\n */\nexport type LoginChoice = {\n additional?: boolean;\n /** Identifiers read off the refusal. The server acts on them only after the password verifies, and only for that user's own sessions. */\n endSessionIds?: string[];\n /** The 6-digit authenticator code (authenticator-sign-in.prd.md). */\n code?: string;\n /** A one-time recovery code, in place of `code`. */\n recoveryCode?: string;\n};\n\n/**\n * The sign-in request body, exactly as sent (multiple-devices E8, authenticator-sign-in.prd.md).\n *\n * Fields appear only when they carry a decision: the route's body schema is strict,\n * and `additional: false` on a first attempt would be a statement where silence is\n * meant. A code typed now wins; otherwise a ticket from a 409 that followed a\n * correct code stands in for it (the server accepts a code only once, D20).\n */\nexport function buildLoginBody(\n credentials: Credentials,\n force: boolean,\n options: LoginChoice,\n signInTicket?: string,\n): Record<string, unknown> {\n const proof = options.code\n ? {code: options.code}\n : options.recoveryCode\n ? {recoveryCode: options.recoveryCode}\n : signInTicket ? {signInTicket} : {};\n return {\n ...credentials,\n ...(force ? {force: true} : {}),\n ...(options.additional ? {additional: true} : {}),\n ...(options.endSessionIds?.length ? {endSessionIds: options.endSessionIds} : {}),\n ...proof,\n };\n}\n\n/** Name of the cross-window renewal lock (PRD D5). */\nconst RENEWAL_LOCK = 'brokenstock.session.renew';\n\n/** How long a window waits for the renewing window to publish a token (PRD D5). */\nconst PEER_RENEWAL_WAIT_MS = 10_000;\n\n/** How long the renewal request itself may take before it is abandoned (PRD D5). */\nconst RENEWAL_TIMEOUT_MS = 15_000;\n\n@Injectable({ providedIn: 'root' })\nexport class AuthenticationService {\n readonly authenticated = signal(false);\n readonly authenticating = signal(false);\n readonly userSession = signal<UserSession | undefined>(undefined);\n readonly conflictSessions = signal<SessionSummary[] | undefined>(undefined);\n /**\n * Whether this app lets you sign in ALONGSIDE the sessions listed in\n * `conflictSessions` (multiple-devices D3).\n *\n * ⚠ READ FROM THE SERVER'S REFUSAL, NEVER DECIDED HERE. This component is\n * shared by the trading app and both admin consoles, which have different\n * rules. Deciding it locally would put the policy in two places, and the one\n * a reader would find is not the one that enforces it — an admin screen would\n * happily offer a button the server refuses.\n */\n readonly additionalSignInAllowed = signal(false);\n readonly pendingCredentials = signal<Credentials | undefined>(undefined);\n\n // ----- Authenticator (authenticator-sign-in.prd.md) -----\n /** The extra step the sign-in screen is on after the password was accepted. */\n readonly codeStep = signal<SignInCodeStep>('none');\n /** Inside an AWS-opened setup window: the QR and key to show (D9, D10). */\n readonly setupChallenge = signal<SetupChallenge | undefined>(undefined);\n /** New recovery codes to show ONCE, with a Download button (D7). Cleared when acknowledged. */\n readonly recoveryCodesToShow = signal<string[] | undefined>(undefined);\n /** Recovery codes left, from the last sign-in or status read. */\n readonly recoveryCodesLeft = signal<number | undefined>(undefined);\n /**\n * Whether the AWS-set bypass is on for this account (D12). Drives the banner on\n * every screen. Yes/no only: the server never says when it ends.\n */\n readonly bypassActive = signal(false);\n /**\n * The ticket from a 409 that followed a correct code. The retry sends it in place\n * of the code, which the server will not accept twice (D20). Never shown.\n */\n #signInTicket: string | undefined;\n\n #refreshing: Promise<boolean> | null = null;\n #auth: BearerToken = 'Bearer ..' as BearerToken;\n\n readonly #httpClient = inject(HttpClient);\n readonly #thinkingService = inject(ThinkingService);\n readonly #router = inject(Router);\n readonly #authUrls = inject(SHELL_AUTH_URLS);\n readonly #store = inject(SessionTokenStore);\n /** Off by default: an app opts in to sharing its session across windows (PRD D7). */\n readonly #sharedSession = inject(SHELL_SHARED_SESSION, { optional: true }) ?? false;\n\n constructor() {\n if (!this.#sharedSession) return;\n // Adopt a token this browser already holds. This runs during construction,\n // and `authGuard` injecting this service IS the first read of `authenticated`\n // — a field initializer completes before `inject()` returns — so the guard\n // sees the restored state without becoming asynchronous (PRD D4).\n //\n // The token may well be expired. That is not this constructor's problem: the\n // first request 401s and the interceptor renews and retries, which is the\n // path that already works today.\n const stored = this.#store.read();\n if (stored) {\n this.#auth = stored;\n this.authenticated.set(true);\n }\n // Another window signing out must sign this one out too (PRD D6). A token\n // that merely CHANGED needs no action here — `auth` reads through, so the\n // next caller gets the new value without anyone copying it.\n this.#store.onExternalChange(token => {\n if (!token && this.authenticated()) this.#clearSession();\n });\n }\n\n /**\n * The bearer for outbound calls.\n *\n * READ-THROUGH, not a cached copy, whenever the session is shared across\n * windows (PRD D2/D10). A copy is only as fresh as the last `storage` event\n * delivered, and the consumer that matters most is outside the request path:\n * the market-tape socket re-presents this token on a sixty-second heartbeat,\n * and the server closes the socket with a code the client does NOT retry if it\n * is stale. A window that was frozen when the event fired would lose its live\n * prices permanently. Reading through removes the question of which window\n * holds which token.\n */\n get auth(): BearerToken {\n if (this.#sharedSession) {\n const stored = this.#store.read();\n if (stored) return stored;\n }\n return this.#auth;\n }\n\n /**\n * Adopts a freshly issued token: in memory, and in shared storage so every\n * other window of this browser sees it on their next read.\n *\n * A failed write THROWS out of here rather than being absorbed — see\n * `SessionTokenStore`. A session the other windows cannot see is the failure\n * this whole design exists to prevent.\n */\n #adoptToken(token: BearerToken): void {\n this.#auth = token;\n if (this.#sharedSession) this.#store.write(token);\n }\n\n // Legacy hasRole/hasAnyRole removed (legacy-authz-teardown): sessions carry no\n // roles, and every gate moved to hasFeature (commerce) with the BE enforcing the\n // security axis.\n //\n // `hasFeature` and `featureValue` are now gone too, with all entitlement gating\n // (commercial-surface-decommission.prd.md D3). BrokenStock is not a commercial\n // product; there is nothing to be entitled to. Per P1 every capability they hid is\n // unconditionally available, so the callers did not migrate to some other check —\n // they simply stopped asking. The session's `features` map is no longer read here at\n // all, which is what makes it safe for the back end to stop populating it (E9).\n //\n // The security axis is unaffected and still enforced server-side: this app cannot see\n // security roles by design (`@franzzemen/endpoint-identity` is deliberately absent\n // from its dependency graph).\n\n refresh(): Promise<boolean> {\n if (this.#refreshing) {\n return this.#refreshing;\n }\n this.#refreshing = this.#doRefresh().finally(() => { this.#refreshing = null; });\n return this.#refreshing;\n }\n\n clearConflict(): void {\n this.conflictSessions.set(undefined);\n this.additionalSignInAllowed.set(false);\n this.pendingCredentials.set(undefined);\n this.#signInTicket = undefined;\n }\n\n /** Back to the password form from the code or setup step. */\n cancelCodeStep(): void {\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.pendingCredentials.set(undefined);\n this.#signInTicket = undefined;\n }\n\n /** The new recovery codes have been seen (and, we hope, downloaded). */\n acknowledgeRecoveryCodes(): void {\n this.recoveryCodesToShow.set(undefined);\n }\n\n /**\n * The session is gone and cannot be recovered — renewal failed permanently,\n * or another window signed out.\n *\n * ⚠ THIS EXISTS BECAUSE THERE ARE TWO SIGN-OUT PATHS AND ONLY ONE USED TO\n * CLEAR THE TOKEN. `logout()` went through `#clearSession()`; the 401\n * interceptor set the signals and navigated but left `#auth` alone. Harmless\n * while the token lived only in memory and died with the tab — but once it is\n * in storage, a dead token left behind means every later window marks itself\n * signed in, passes the guard, renders, 401s and bounces to the login screen.\n * The reload fix would have become \"the app flashes, then throws me out\",\n * which is harder to diagnose than the behaviour it replaced.\n */\n sessionLost(): void {\n this.#thinkingService.reset();\n this.#clearSession();\n }\n\n logout(): void {\n const subscription = this.#httpClient\n .get<void>(this.#authUrls.logout, {\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n })\n .subscribe({\n next: () => {\n this.#clearSession();\n subscription.unsubscribe();\n },\n error: () => {\n this.#thinkingService.reset();\n this.#clearSession();\n },\n });\n }\n\n /**\n * Signs in, and — on a second attempt — says what to do about the sessions\n * already held (multiple-devices D2/D6).\n *\n * `force` and `additional` are different answers, not synonyms: `force` ends\n * every session in this app, `additional` leaves them all running.\n * `endSessionIds` ends the ones the user picked and leaves the rest. None of\n * the three appears on a first attempt — they exist because the server\n * refused once and said what was live.\n */\n login(credentials: Credentials, force = false, options: LoginChoice = {}): Promise<void> {\n const validation = validateCredentials(credentials);\n if (validation !== true) {\n return Promise.reject('Invalid credentials');\n }\n this.conflictSessions.set(undefined);\n this.#thinkingService.startThinking();\n return new Promise((resolve, reject) => {\n this.authenticating.set(true);\n const body = buildLoginBody(credentials, force, options, this.#signInTicket);\n const subscription = this.#httpClient\n .post<HttpResponse<AuthenticationResponse>>(\n this.#authUrls.login,\n body,\n {\n headers: {\n [HttpHeader.ContentType]: 'application/json',\n [HttpHeader.AppContext]: 'brokenstock',\n },\n observe: 'response',\n responseType: 'json',\n withCredentials: true,\n },\n )\n .subscribe({\n next: (response: HttpResponse<any>) => {\n try {\n const authResponse: AuthenticationResponse = response.body;\n // @ts-ignore\n delete authResponse.session.token;\n this.userSession.set(authResponse.session);\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) {\n reject('Unable to login');\n return;\n }\n this.#adoptToken(auth as BearerToken);\n const authenticator = (response.body as {authenticator?: {recoveryCodes?: string[]; recoveryCodesLeft?: number; bypassActive?: boolean}}).authenticator;\n this.recoveryCodesLeft.set(authenticator?.recoveryCodesLeft);\n this.bypassActive.set(authenticator?.bypassActive === true);\n if (authenticator?.recoveryCodes?.length) this.recoveryCodesToShow.set(authenticator.recoveryCodes);\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.#signInTicket = undefined;\n this.authenticated.set(true);\n this.pendingCredentials.set(undefined);\n resolve();\n } catch {\n reject('Unable to login');\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n error: (err: HttpErrorResponse) => {\n try {\n const reason = err.error?.reason as AuthenticatorReason | undefined;\n if (err.status === 409) {\n // After a correct code: the retry carries this instead (D20), and\n // new recovery codes from a setup must not be lost to this panel.\n if (typeof err.error?.signInTicket === 'string') this.#signInTicket = err.error.signInTicket;\n if (Array.isArray(err.error?.recoveryCodes)) this.recoveryCodesToShow.set(err.error.recoveryCodes);\n // The code is done; the session choice is all that is left on screen.\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.conflictSessions.set(err.error?.activeSessions ?? []);\n // Absent means false: an older back end that does not send this\n // does not permit signing in alongside, so the screen must not\n // offer it.\n this.additionalSignInAllowed.set(err.error?.additionalSignInAllowed === true);\n this.pendingCredentials.set(credentials);\n reject('conflict');\n } else if (reason === 'code-required') {\n this.codeStep.set('code');\n this.pendingCredentials.set(credentials);\n reject(CODE_STEP);\n } else if (reason === 'setup-required') {\n this.codeStep.set('setup');\n this.setupChallenge.set({qr: err.error.qr, key: err.error.key});\n this.pendingCredentials.set(credentials);\n reject(CODE_STEP);\n } else if (reason) {\n // invalid-code / too-many-attempts / authenticator-not-set-up:\n // stay on the step the user is on; say what happened, in plain words.\n if (reason === 'too-many-attempts' || reason === 'authenticator-not-set-up') this.#signInTicket = undefined;\n reject(authenticatorMessage(reason));\n } else if (err.status === 401) {\n reject('Wrong username or password');\n } else {\n reject(err.message ?? 'Unable to login');\n }\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n });\n });\n }\n\n // ---------------------------------------------------------------------------\n // Authenticator settings and the on-demand check (authenticator-sign-in.prd.md)\n //\n // All under the sign-in URL (`/login/…` or `/admin/login/…`), on the auth\n // worker. A wrong code here is 403, never 401, so the interceptor does not\n // read it as an expired session.\n // ---------------------------------------------------------------------------\n\n /** Whether an authenticator is set up, codes left, and whether the bypass is on. Refreshes the banner. */\n async authenticatorStatus(): Promise<AuthenticatorStatus> {\n const status = await this.#authenticatorCall<AuthenticatorStatus>('GET', 'authenticator');\n this.bypassActive.set(status.bypassActive);\n this.recoveryCodesLeft.set(status.recoveryCodesLeft);\n return status;\n }\n\n /** Begin setting up (or replacing) the authenticator: the password again, plus a current code when replacing (D5). */\n startAuthenticatorSetup(password: string, current: CodeEntry = {}): Promise<SetupChallenge> {\n return this.#authenticatorCall<SetupChallenge>('POST', 'authenticator/start', {password, ...current});\n }\n\n /** Finish setup with the first code from the newly scanned app. Returns the 10 recovery codes, once. */\n async confirmAuthenticatorSetup(code: string): Promise<string[]> {\n const {recoveryCodes} = await this.#authenticatorCall<{recoveryCodes: string[]}>('POST', 'authenticator/confirm', {code});\n this.recoveryCodesLeft.set(recoveryCodes.length);\n return recoveryCodes;\n }\n\n /** Ten new recovery codes; the old ones stop working (D7). Needs a current code. */\n async reissueRecoveryCodes(code: string): Promise<string[]> {\n const {recoveryCodes} = await this.#authenticatorCall<{recoveryCodes: string[]}>('POST', 'recovery-codes', {code});\n this.recoveryCodesLeft.set(recoveryCodes.length);\n return recoveryCodes;\n }\n\n /**\n * The on-demand check (D15): proves the code again on this session and returns\n * when it was recorded. `purpose` is a short label for the log, e.g.\n * 'arm-live-trading' — it changes nothing. The bypass never satisfies this.\n */\n async verifyCode(entry: CodeEntry, purpose?: string): Promise<number> {\n const {codeVerifiedAtEpoch} = await this.#authenticatorCall<{codeVerifiedAtEpoch: number}>(\n 'POST', 'verify-code', {...entry, ...(purpose ? {purpose} : {})});\n return codeVerifiedAtEpoch;\n }\n\n async #authenticatorCall<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<T> {\n const url = `${this.#authUrls.login}/${path}`;\n const headers = {\n [HttpHeader.Authorization]: this.auth,\n [HttpHeader.AppContext]: 'brokenstock',\n ...(body !== undefined ? {[HttpHeader.ContentType]: 'application/json'} : {}),\n };\n try {\n return method === 'GET'\n ? await firstValueFrom(this.#httpClient.get<T>(url, {headers}))\n : await firstValueFrom(this.#httpClient.post<T>(url, body, {headers}));\n } catch (err) {\n if (err instanceof HttpErrorResponse) {\n const reason = err.error?.reason as AuthenticatorReason | undefined;\n const message = reason\n ? authenticatorMessage(reason)\n : err.status === 400 ? 'Check what you typed and try again.' : (err.error?.message ?? 'Something went wrong');\n throw new AuthenticatorError(reason, message, err.status);\n }\n throw err;\n }\n }\n\n /**\n * Renews the session, coordinating with the other windows of this browser.\n *\n * WHY COORDINATION IS REQUIRED, NOT AN OPTIMISATION. Every window shares one\n * session, so they all find the token expired at the same moment and all try\n * to renew. The server serialises rotation on the session row and REFUSES the\n * losers — so uncoordinated, every window but one is signed out, every token\n * lifetime, several times a day.\n *\n * The lock is taken with `ifAvailable`, so a window that does not get it is\n * told so immediately and then waits for the WINNER'S RESULT with a bound of\n * its own, rather than blocking on a peer it cannot supervise. A frozen\n * window holding the lock would otherwise stop every other window forever,\n * with nothing on screen and nothing logged.\n */\n async #doRefresh(): Promise<boolean> {\n if (!this.#sharedSession) return this.#renew();\n\n // Captured BEFORE asking for the lock: it is what \"did someone else renew\n // while I waited?\" is measured against.\n const before = this.#store.read();\n\n const outcome = await runExclusive(RENEWAL_LOCK, () => this.#renewOrAdopt(before));\n if (outcome.ran) return outcome.value;\n\n // Another window is renewing. Wait for its token to appear.\n const published = await awaitChange(() => this.#store.read(), before, PEER_RENEWAL_WAIT_MS);\n if (published) {\n this.#auth = published;\n return true;\n }\n // Either the winner cleared the token (its renewal failed permanently), or\n // it never delivered inside the bound. Re-read to tell those apart: an\n // absent token is a definite answer and must not be retried, whereas a\n // still-unchanged one means the winner is gone and this window should try.\n if (before && !this.#store.read()) return false;\n return this.#renewOrAdopt(before);\n }\n\n /**\n * The three-way rule, applied once this window holds the lock (PRD D5).\n *\n * Stated precisely because \"retry with a token different from the one you\n * failed with\" is not well defined: the in-window single-flight already\n * collapses requests that were sent with different tokens.\n */\n async #renewOrAdopt(before: BearerToken | undefined): Promise<boolean> {\n const current = this.#store.read();\n switch (decideRenewal(before, current)) {\n case 'sign-out':\n return false;\n case 'adopt':\n this.#auth = current!;\n return true;\n case 'renew':\n return this.#renew();\n }\n }\n\n /**\n * The renewal request itself.\n *\n * ⚠ THE TIMEOUT IS LOAD-BEARING. Without it a hung request holds the\n * cross-window lock indefinitely and every other window waits behind it.\n */\n async #renew(): Promise<boolean> {\n try {\n const response = await fetch(this.#authUrls.refresh, {\n method: 'POST',\n headers: {\n [HttpHeader.Authorization]: this.auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n credentials: 'include',\n signal: AbortSignal.timeout(RENEWAL_TIMEOUT_MS),\n });\n if (!response.ok) return false;\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) return false;\n const body: AuthenticationResponse = await response.json();\n this.#adoptToken(auth as BearerToken);\n // The raw token is stripped exactly as `login()` strips it. `/refresh`\n // returns `{session: {token}}`, and assigning that straight through put\n // the bearer into a PUBLIC signal — a second copy of the credential in a\n // place nothing needs it, which contradicts the care taken everywhere\n // else about where this token may live.\n const session = { ...(body.session ?? {}) } as Partial<UserSession> & { token?: string };\n delete session.token;\n this.userSession.set(session as UserSession);\n return true;\n } catch {\n // Includes the abort. A timed-out renewal is a failed renewal.\n return false;\n }\n }\n\n /**\n * THE ONE PLACE a session ends. Both sign-out paths route through here so the\n * stored token cannot outlive the session it belongs to — see `sessionLost`.\n */\n #clearSession(): void {\n this.authenticated.set(false);\n this.userSession.set(undefined);\n this.conflictSessions.set(undefined);\n this.pendingCredentials.set(undefined);\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.recoveryCodesToShow.set(undefined);\n this.recoveryCodesLeft.set(undefined);\n this.bypassActive.set(false);\n this.#signInTicket = undefined;\n this.#auth = 'Bearer ..' as BearerToken;\n this.#store.clear();\n this.#router.navigate(['/login']).catch(console.error);\n }\n}\n","import { inject } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivateFn,\n Router,\n RouterStateSnapshot,\n} from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\n\nexport const authGuard: CanActivateFn = (\n _route: ActivatedRouteSnapshot,\n state: RouterStateSnapshot,\n) => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n\n if (authService.authenticated()) {\n return true;\n }\n return router.createUrlTree(['/login'], {\n queryParams: { returnUrl: state.url },\n });\n};\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { SHELL_POST_LOGIN_ROUTE } from '../tokens/shell-tokens';\n\nexport const guestGuard: CanActivateFn = () => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n const postLoginRoute = inject(SHELL_POST_LOGIN_ROUTE, { optional: true }) ?? '/';\n\n if (authService.authenticated()) {\n return router.parseUrl(postLoginRoute);\n }\n return true;\n};\n","import { HttpInterceptorFn } from '@angular/common/http';\nimport { inject } from '@angular/core';\nimport { from, switchMap, catchError, throwError } from 'rxjs';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\nimport { HttpHeader } from '@franzzemen/utility';\n\nexport const authInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(AuthenticationService);\n const authUrls = inject(SHELL_AUTH_URLS);\n\n return next(req).pipe(\n catchError((error) => {\n const isRefreshOrLogin = req.url === authUrls.refresh || req.url === authUrls.login;\n if (error.status === 401 && !isRefreshOrLogin) {\n return from(authService.refresh()).pipe(\n switchMap((refreshed) => {\n if (refreshed) {\n const retryReq = req.clone({\n setHeaders: { [HttpHeader.Authorization]: authService.auth },\n });\n return next(retryReq);\n }\n // `sessionLost()` and not the three lines that used to be here: it\n // also clears the STORED token. Leaving a dead token behind makes\n // every later window sign itself in, render, 401 and bounce.\n authService.sessionLost();\n return throwError(() => error);\n }),\n catchError(() => {\n authService.sessionLost();\n return throwError(() => error);\n }),\n );\n }\n return throwError(() => error);\n }),\n );\n};\n","import { Directive, input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';\n\n@Directive({\n selector: '[regexValidator]',\n providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }],\n})\nexport class RegexValidatorDirective implements Validator {\n regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i);\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (!control.value || !this.regex().test(control.value)) {\n return { regexValidator: { value: control.value } };\n }\n return null;\n }\n}\n","/**\n * Shared types for the FAQ help system.\n *\n * Manifest is generated by the build-time validator (E9) and read at runtime\n * by FaqContentLoader (E1) and FaqService (E2).\n */\n\nexport type FaqAudience = 'public' | 'authenticated';\nexport type FaqRenderContext = 'modal' | 'page';\n\n/** Raw frontmatter as authored in the `.md` file. */\nexport interface FaqFrontmatter {\n title: string;\n category: string;\n order?: number;\n audience?: FaqAudience;\n 'image-prefix'?: string;\n description?: string;\n 'seo-ready'?: boolean;\n}\n\n/** One row in the generated manifest — normalized form of frontmatter + file path. */\nexport interface FaqEntry {\n /** Dot-notation key, e.g. \"trade.segments\". */\n key: string;\n title: string;\n category: string;\n order: number;\n audience: FaqAudience;\n description?: string;\n seoReady: boolean;\n imagePrefix?: string;\n /**\n * Path to the source file relative to `/assets/faq/`, without `.md`.\n * Example: `trade/segments` (subdirs allowed; key path-separator is `.`,\n * file path-separator is `/`).\n */\n file: string;\n}\n\nexport interface FaqManifest {\n /** ISO timestamp set by the validator at generation time. */\n generatedAt: string;\n entries: FaqEntry[];\n}\n\nexport interface ParsedFaq {\n frontmatter: FaqFrontmatter;\n body: string;\n}\n\nexport interface FaqRenderOptions {\n context: FaqRenderContext;\n /**\n * Optional override for the entry's `image-prefix` frontmatter.\n * When set, relative image hrefs are prefixed with this string.\n */\n imagePrefix?: string;\n}\n","import { InjectionToken } from '@angular/core';\nimport { FaqManifest } from './faq.types';\n\n/**\n * Pluggable content source for FAQ markdown + manifest.\n *\n * Default implementation is `HttpFaqContentLoader`, which fetches from\n * `/assets/faq/manifest.json` and `/assets/faq/<file>.md`. Consumer apps\n * may override (e.g. broken-stock-admin pulling from an internal source),\n * but most apps will just use the HTTP default.\n */\nexport interface FaqContentLoader {\n /** Loads (and may cache) the manifest. Idempotent. */\n loadManifest(): Promise<FaqManifest>;\n\n /**\n * Resolves the manifest entry for `key`, then loads its .md body.\n * Returns `null` when the key is not in the manifest.\n */\n loadContent(key: string): Promise<string | null>;\n}\n\nexport const FAQ_CONTENT_LOADER = new InjectionToken<FaqContentLoader>(\n 'FAQ_CONTENT_LOADER',\n);\n","import { Injectable } from '@angular/core';\nimport { Marked, Renderer } from 'marked';\nimport { gfmHeadingId } from 'marked-gfm-heading-id';\nimport fm from 'front-matter';\nimport { FaqFrontmatter, FaqRenderOptions, ParsedFaq } from './faq.types';\n\n/**\n * Stateless markdown renderer for FAQ content.\n *\n * Two responsibilities:\n * 1. Split a `.md` file into `{ frontmatter, body }` (front-matter parser).\n * 2. Render the body to HTML via marked with a context-aware link hook:\n * - `faq:<key>` — in-modal nav (modal) | `<a href=\"/help/<file>\">` (page)\n * - `app:/path` — close-modal-and-route (modal) | `<a href=\"/path\">` (page)\n * - `http(s)://...` — external, target=_blank rel=noopener (both)\n * - `#anchor` — intra-page scroll (both)\n *\n * In modal context, links are emitted with `data-faq-href` / `data-faq-kind`\n * sentinels so the modal's click handler (E5) can intercept and dispatch.\n * In page context, links are emitted as plain navigable anchors; the prerendered\n * static HTML can be clicked through directly.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqMarkdownRendererService {\n parse(raw: string): ParsedFaq {\n const parsed = fm<FaqFrontmatter>(raw);\n return {\n frontmatter: parsed.attributes,\n body: parsed.body,\n };\n }\n\n render(body: string, opts: FaqRenderOptions): string {\n const marked = new Marked({ gfm: true, breaks: false });\n marked.use(gfmHeadingId());\n marked.use({ renderer: this.buildRenderer(opts) });\n return marked.parse(body, { async: false }) as string;\n }\n\n private buildRenderer(opts: FaqRenderOptions): Partial<Renderer> {\n const { context, imagePrefix } = opts;\n return {\n link: ({ href, title, tokens }) => {\n // marked passes child tokens; we render their textual form ourselves.\n const text = tokens.map((t) => ('text' in t ? t.text : '')).join('');\n const titleAttr = title ? ` title=\"${escapeAttr(title)}\"` : '';\n\n // Intra-page anchor\n if (href.startsWith('#')) {\n return `<a href=\"${escapeAttr(href)}\"${titleAttr} data-faq-kind=\"anchor\">${text}</a>`;\n }\n\n // faq: protocol — in-modal nav (modal) | static link to /help/<key path> (page)\n if (href.startsWith('faq:')) {\n const key = href.slice('faq:'.length);\n if (context === 'modal') {\n return `<a href=\"#\" data-faq-href=\"${escapeAttr(href)}\" data-faq-kind=\"faq\">${text}</a>`;\n }\n const filePath = key.replace(/\\./g, '/');\n return `<a href=\"/help/${escapeAttr(filePath)}\"${titleAttr} data-faq-kind=\"faq\">${text}</a>`;\n }\n\n // app: protocol — close modal + route (modal) | normal anchor (page)\n if (href.startsWith('app:')) {\n const path = href.slice('app:'.length);\n if (context === 'modal') {\n return `<a href=\"#\" data-faq-href=\"${escapeAttr(href)}\" data-faq-kind=\"app\">${text} <span class=\"faq-app-arrow\" aria-hidden=\"true\">→</span></a>`;\n }\n return `<a href=\"${escapeAttr(path)}\"${titleAttr} data-faq-kind=\"app\">${text} <span class=\"faq-app-arrow\" aria-hidden=\"true\">→</span></a>`;\n }\n\n // External\n if (/^https?:\\/\\//i.test(href)) {\n return `<a href=\"${escapeAttr(href)}\"${titleAttr} target=\"_blank\" rel=\"noopener\" data-faq-kind=\"external\">${text}</a>`;\n }\n\n // Fallback: treat as relative; render plain anchor.\n return `<a href=\"${escapeAttr(href)}\"${titleAttr}>${text}</a>`;\n },\n image: ({ href, title, text }) => {\n const resolved = resolveImageHref(href, imagePrefix);\n const titleAttr = title ? ` title=\"${escapeAttr(title)}\"` : '';\n return `<img src=\"${escapeAttr(resolved)}\" alt=\"${escapeAttr(text)}\"${titleAttr} loading=\"lazy\" />`;\n },\n };\n }\n}\n\nfunction escapeAttr(s: string): string {\n return s.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<');\n}\n\nfunction resolveImageHref(href: string, prefix: string | undefined): string {\n if (!prefix) return href;\n if (/^([a-z]+:)?\\/\\//i.test(href) || href.startsWith('/')) return href;\n const cleaned = prefix.endsWith('/') ? prefix : `${prefix}/`;\n return `${cleaned}${href}`;\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { FaqContentLoader } from './faq-content-loader.token';\nimport { FaqEntry, FaqManifest } from './faq.types';\n\n/**\n * Default FaqContentLoader. Reads the build-generated manifest from\n * `/assets/faq/manifest.json` and lazy-fetches individual `.md` files\n * from `/assets/faq/<entry.file>.md`.\n *\n * Manifest is cached after first load; .md fetches are cached per key.\n */\n@Injectable({ providedIn: 'root' })\nexport class HttpFaqContentLoader implements FaqContentLoader {\n private readonly http = inject(HttpClient);\n private manifestPromise: Promise<FaqManifest> | null = null;\n private readonly contentCache = new Map<string, Promise<string | null>>();\n\n loadManifest(): Promise<FaqManifest> {\n if (!this.manifestPromise) {\n this.manifestPromise = firstValueFrom(\n this.http.get<FaqManifest>('/assets/faq/manifest.json'),\n ).catch((err) => {\n this.manifestPromise = null;\n throw err;\n });\n }\n return this.manifestPromise;\n }\n\n async loadContent(key: string): Promise<string | null> {\n const cached = this.contentCache.get(key);\n if (cached) return cached;\n\n const manifest = await this.loadManifest();\n const entry = manifest.entries.find((e: FaqEntry) => e.key === key);\n if (!entry) return null;\n\n const fetchPromise = firstValueFrom(\n this.http.get(`/assets/faq/${entry.file}.md`, { responseType: 'text' }),\n ).catch(() => null);\n this.contentCache.set(key, fetchPromise);\n return fetchPromise;\n }\n}\n","import { Injectable, signal } from '@angular/core';\n\n/**\n * E8 — In-modal navigation history.\n *\n * The browser's `history` API is shared by Angular Router and any other\n * code that calls `pushState`. We tag each FAQ entry's state object with\n * `faq: true` so we can distinguish our entries from router/app entries.\n *\n * On open: `pushState({faq:true, faqPosition:0})` once; stack=[initialKey].\n * On in-modal nav: truncate forward, push key, `pushState({faq:true,\n * faqPosition:position})`.\n * On browser back/forward (`popstate`):\n * - If next state has `faq:true` → set position to its `faqPosition`,\n * swap content for `stack[position]`.\n * - If next state lacks `faq:true` (user backed out of the modal entirely)\n * → close modal without further history manipulation.\n * On explicit close (close button / Esc / backdrop): `history.go(-(position+1))`\n * to unwind our entries; suppress in-flight popstates while unwinding;\n * finalize close once we've seen the expected number of popstates.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqHistoryService {\n private readonly _stack = signal<string[]>([]);\n private readonly _position = signal(0);\n readonly stack = this._stack.asReadonly();\n readonly position = this._position.asReadonly();\n\n /** True when popstate is processing the unwind kicked off by closeAndUnwind(). */\n private unwinding = false;\n private unwindRemaining = 0;\n private onUnwindComplete: (() => void) | null = null;\n\n private popstateListener: ((e: PopStateEvent) => void) | null = null;\n private onInModalNav: ((key: string) => void) | null = null;\n private onExitModal: (() => void) | null = null;\n\n /**\n * Begin a new FAQ history session. Pushes the initial state entry and\n * starts listening for popstate. Callbacks fire for in-modal navs and\n * for popping out of FAQ entirely.\n */\n begin(\n initialKey: string,\n onNav: (key: string) => void,\n onExit: () => void,\n ): void {\n this._stack.set([initialKey]);\n this._position.set(0);\n this.onInModalNav = onNav;\n this.onExitModal = onExit;\n this.pushHistoryState(0);\n this.attachListener();\n }\n\n /** Push a new key onto the stack. Truncates any forward history. */\n navigate(key: string): void {\n const stack = this._stack();\n const pos = this._position();\n const next = [...stack.slice(0, pos + 1), key];\n const nextPos = next.length - 1;\n this._stack.set(next);\n this._position.set(nextPos);\n this.pushHistoryState(nextPos);\n }\n\n canGoBack(): boolean {\n return this._position() > 0;\n }\n\n canGoForward(): boolean {\n return this._position() < this._stack().length - 1;\n }\n\n /** Programmatic back — triggers a real browser back so popstate handles UI. */\n back(): void {\n if (!this.canGoBack()) return;\n history.back();\n }\n\n forward(): void {\n if (!this.canGoForward()) return;\n history.forward();\n }\n\n /** Currently rendered key. */\n currentKey(): string | null {\n return this._stack()[this._position()] ?? null;\n }\n\n /**\n * Close the modal cleanly by unwinding our FAQ history entries so the\n * underlying app route is left exactly where it was before the modal opened.\n * `onComplete` fires after the unwind settles.\n */\n closeAndUnwind(onComplete: () => void): void {\n const depth = this._position() + 1;\n if (depth === 0) {\n this.teardown();\n onComplete();\n return;\n }\n this.unwinding = true;\n this.unwindRemaining = depth;\n this.onUnwindComplete = () => {\n this.teardown();\n onComplete();\n };\n history.go(-depth);\n }\n\n private teardown(): void {\n this._stack.set([]);\n this._position.set(0);\n this.detachListener();\n this.onInModalNav = null;\n this.onExitModal = null;\n this.unwinding = false;\n this.unwindRemaining = 0;\n this.onUnwindComplete = null;\n }\n\n private pushHistoryState(position: number): void {\n history.pushState({ faq: true, faqPosition: position }, '');\n }\n\n private attachListener(): void {\n if (this.popstateListener) return;\n this.popstateListener = (e: PopStateEvent) => this.handlePopState(e);\n window.addEventListener('popstate', this.popstateListener);\n }\n\n private detachListener(): void {\n if (!this.popstateListener) return;\n window.removeEventListener('popstate', this.popstateListener);\n this.popstateListener = null;\n }\n\n private handlePopState(e: PopStateEvent): void {\n if (this.unwinding) {\n this.unwindRemaining--;\n if (this.unwindRemaining <= 0) {\n const cb = this.onUnwindComplete;\n this.onUnwindComplete = null;\n cb?.();\n }\n return;\n }\n const state = e.state as { faq?: boolean; faqPosition?: number } | null;\n if (state?.faq && typeof state.faqPosition === 'number') {\n // In-modal back/forward\n const target = state.faqPosition;\n this._position.set(target);\n const key = this._stack()[target];\n if (key && this.onInModalNav) this.onInModalNav(key);\n return;\n }\n // User backed out beyond our entries — close modal, leave history alone.\n const exit = this.onExitModal;\n this.teardown();\n exit?.();\n }\n}\n","import { Injectable, computed, inject, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { FAQ_CONTENT_LOADER } from './faq-content-loader.token';\nimport { FaqHistoryService } from './faq-history.service';\nimport { FaqAudience, FaqEntry, FaqManifest } from './faq.types';\n\nexport interface FaqRegistrationHandle {\n /** Call from the component's destroy hook (or DestroyRef) to clear the registration. */\n deregister(): void;\n}\n\nexport interface FaqResolution {\n /** The key that produced a content match, or `null` when nothing matched. */\n key: string | null;\n /** Raw .md content for `key`, or `null` when nothing matched. */\n content: string | null;\n /** The entry whose content was returned, or `null` when nothing matched. */\n entry: FaqEntry | null;\n /**\n * The chain of keys actually attempted, in order\n * (e.g. `[\"trade.segments\", \"trade\", \"index\"]`).\n */\n attempted: string[];\n}\n\n/**\n * Central FAQ state + resolution service.\n *\n * Responsibilities:\n * - Track the current route's FAQ key (set by components on activation /\n * tab change via `register()`).\n * - Lazy-load and cache the FAQ manifest from the configured FaqContentLoader.\n * - Resolve a dot-notation key against the manifest with parent fallback,\n * audience filtering, and `index` as the terminal fallback.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqService {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly history = inject(FaqHistoryService);\n private readonly auth = inject(AuthenticationService);\n private readonly router = inject(Router);\n\n private readonly _currentFaqKey = signal<string | null>(null);\n /** Component-set current key. Bare `faq` opens at this key. */\n readonly currentFaqKey = this._currentFaqKey.asReadonly();\n\n private readonly _manifest = signal<FaqManifest | null>(null);\n readonly manifest = this._manifest.asReadonly();\n readonly entries = computed(() => this._manifest()?.entries ?? []);\n\n // Modal state (E3 + E8).\n private readonly _modalOpen = signal(false);\n readonly modalOpen = this._modalOpen.asReadonly();\n\n private readonly _activeEntry = signal<FaqEntry | null>(null);\n readonly activeEntry = this._activeEntry.asReadonly();\n\n private readonly _activeContent = signal<string | null>(null);\n readonly activeContent = this._activeContent.asReadonly();\n\n private readonly _activeAttempted = signal<string[]>([]);\n readonly activeAttempted = this._activeAttempted.asReadonly();\n\n private readonly _navigating = signal(false);\n readonly navigating = this._navigating.asReadonly();\n\n // Search pre-fill consumed by E4 search UI on modal open / navigateTo.\n private readonly _initialSearchTerm = signal<string | null>(null);\n readonly initialSearchTerm = this._initialSearchTerm.asReadonly();\n\n /** Called by the search UI once it has consumed the pre-fill term. */\n consumeInitialSearchTerm(): void {\n this._initialSearchTerm.set(null);\n }\n\n readonly canGoBack = computed(() => this.history.position() > 0);\n readonly canGoForward = computed(\n () => this.history.position() < this.history.stack().length - 1,\n );\n\n private manifestPromise: Promise<FaqManifest> | null = null;\n\n /**\n * Triggers manifest load if not already loaded. Idempotent. Subsequent\n * calls return the cached promise.\n */\n ensureManifest(): Promise<FaqManifest> {\n if (this._manifest()) return Promise.resolve(this._manifest()!);\n if (!this.manifestPromise) {\n this.manifestPromise = this.loader\n .loadManifest()\n .then((m) => {\n this._manifest.set(m);\n return m;\n })\n .catch((err) => {\n this.manifestPromise = null;\n throw err;\n });\n }\n return this.manifestPromise;\n }\n\n /**\n * Walks the dot-notation fallback chain (`a.b.c` → `a.b` → `a` → `index`)\n * and returns the first entry whose audience allows the caller and whose\n * content loads. Audience filtering: unauthenticated callers only see\n * `audience: public` entries.\n */\n async resolveKey(\n key: string | null,\n isAuthenticated: boolean,\n ): Promise<FaqResolution> {\n await this.ensureManifest();\n const entries = this.entries();\n const chain = buildFallbackChain(key);\n\n for (const candidate of chain) {\n const entry = entries.find((e) => e.key === candidate);\n if (!entry) continue;\n if (!audienceAllowed(entry.audience, isAuthenticated)) continue;\n const content = await this.loader.loadContent(entry.key);\n if (content === null) continue;\n return { key: entry.key, content, entry, attempted: chain };\n }\n\n return { key: null, content: null, entry: null, attempted: chain };\n }\n\n /**\n * Component registration. Sets `currentFaqKey`; on `deregister()` the\n * key is cleared only if it still matches (so a sibling tab activating\n * mid-teardown doesn't get its key clobbered).\n */\n register(key: string): FaqRegistrationHandle {\n this._currentFaqKey.set(key);\n return {\n deregister: () => {\n if (this._currentFaqKey() === key) this._currentFaqKey.set(null);\n },\n };\n }\n\n /**\n * E3 — Open the FAQ modal. If `initialKey` is omitted, falls back to\n * `currentFaqKey` and then to `'index'`. Resolves the key, loads content,\n * and starts an E8 history session so subsequent in-modal nav uses\n * `history.pushState`.\n */\n async openModal(\n initialKey?: string,\n opts?: { searchTerm?: string },\n ): Promise<void> {\n // Unauthenticated visitors get routed to the public /help SSR surface\n // instead of the in-app modal. The modal is an authenticated experience;\n // /help/* is the SEO/marketing-funnel surface.\n if (!this.auth.authenticated()) {\n await this.ensureManifest();\n const entries = this.entries();\n const target = initialKey ?? this._currentFaqKey() ?? null;\n let route = '/help';\n if (target) {\n const chain = buildFallbackChain(target);\n for (const candidate of chain) {\n const entry = entries.find((e) => e.key === candidate);\n if (entry && entry.audience === 'public' && entry.seoReady) {\n route = `/help/${entry.file}`;\n break;\n }\n }\n }\n await this.router.navigateByUrl(route);\n return;\n }\n\n const searchTerm = opts?.searchTerm?.trim();\n this._initialSearchTerm.set(searchTerm && searchTerm.length > 0 ? searchTerm : null);\n if (this._modalOpen()) {\n // Already open — treat as a navigate-to instead.\n if (initialKey) await this.navigateTo(initialKey);\n return;\n }\n const target = initialKey ?? this._currentFaqKey() ?? 'index';\n this._modalOpen.set(true);\n await this.loadIntoActive(target);\n const resolved = this._activeEntry()?.key ?? target;\n this.history.begin(\n resolved,\n (key) => {\n // popstate-driven in-modal nav: load without pushing a new entry.\n void this.loadIntoActive(key);\n },\n () => {\n // User backed out of FAQ history entirely — close without unwinding.\n this.finalizeClose();\n },\n );\n }\n\n /**\n * Programmatic in-modal nav. Pushes a new history entry and loads `key`\n * into the active slot. Use this for click handlers on `faq:` links and\n * for the TOC sidebar.\n */\n async navigateTo(key: string): Promise<void> {\n if (!this._modalOpen()) {\n await this.openModal(key);\n return;\n }\n await this.loadIntoActive(key);\n const resolved = this._activeEntry()?.key ?? key;\n this.history.navigate(resolved);\n }\n\n back(): void {\n this.history.back();\n }\n forward(): void {\n this.history.forward();\n }\n\n /**\n * Close button / Esc / backdrop close. Unwinds the FAQ history entries\n * so the underlying app route is left untouched.\n */\n closeModal(): void {\n if (!this._modalOpen()) return;\n this.history.closeAndUnwind(() => this.finalizeClose());\n }\n\n private finalizeClose(): void {\n this._modalOpen.set(false);\n this._activeContent.set(null);\n this._activeEntry.set(null);\n this._activeAttempted.set([]);\n }\n\n private async loadIntoActive(key: string): Promise<void> {\n this._navigating.set(true);\n try {\n const resolution = await this.resolveKey(key, this.auth.authenticated());\n this._activeEntry.set(resolution.entry);\n this._activeContent.set(resolution.content);\n this._activeAttempted.set(resolution.attempted);\n } finally {\n this._navigating.set(false);\n }\n }\n}\n\nexport function buildFallbackChain(key: string | null): string[] {\n if (!key) return ['index'];\n const parts = key.split('.').filter(Boolean);\n if (parts.length === 0) return ['index'];\n const chain: string[] = [];\n for (let i = parts.length; i > 0; i--) {\n chain.push(parts.slice(0, i).join('.'));\n }\n chain.push('index');\n return chain;\n}\n\nexport function audienceAllowed(\n audience: FaqAudience,\n isAuthenticated: boolean,\n): boolean {\n if (audience === 'public') return true;\n return isAuthenticated;\n}\n","import { InjectionToken, isDevMode } from '@angular/core';\n\n/**\n * Gate for the dev-only FAQ authoring panel (E11).\n *\n * Defaults to Angular's `isDevMode()` so the panel auto-enables in `ng serve`\n * and auto-disables in production builds. Consumers can override with an\n * explicit value (e.g. `!environment.production`, or `true` for a staging\n * diagnostic build) via `{provide: FAQ_DEV_MODE, useValue: ...}`.\n *\n * The panel is loaded via dynamic `import()` and lives in its own lazy chunk;\n * builds where this resolves to `false` never request the chunk.\n */\nexport const FAQ_DEV_MODE = new InjectionToken<boolean>('FAQ_DEV_MODE', {\n providedIn: 'root',\n factory: () => isDevMode(),\n});\n\n/**\n * Optional absolute filesystem root of the consuming app's workspace (e.g.\n * `/Users/foo/dev/broken-stock`). When set, the authoring panel emits\n * `webstorm://open?file=<root>/<relative-path>` deeplinks pointing at the\n * exact source file. When unset, the panel falls back to a relative path.\n */\nexport const FAQ_DEV_WORKSPACE_ROOT = new InjectionToken<string>(\n 'FAQ_DEV_WORKSPACE_ROOT',\n { providedIn: 'root', factory: () => '' },\n);\n\n/**\n * Editor URL scheme for the \"Open in editor\" deeplink. Defaults to WebStorm.\n * Set to `'vscode'` (or any custom scheme handler) per consuming app.\n */\nexport type FaqDevEditor = 'webstorm' | 'vscode';\nexport const FAQ_DEV_EDITOR = new InjectionToken<FaqDevEditor>(\n 'FAQ_DEV_EDITOR',\n { providedIn: 'root', factory: () => 'webstorm' },\n);\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n ViewChild,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { FaqAuthoringPanel } from '../faq-authoring-panel/faq-authoring-panel';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FAQ_DEV_MODE } from '../faq-dev-mode.token';\nimport { FaqMarkdownRendererService } from '../faq-markdown-renderer.service';\nimport { FaqService } from '../faq.service';\nimport { FaqEntry } from '../faq.types';\n\ninterface TocGroup {\n category: string;\n entries: FaqEntry[];\n}\n\ninterface SearchResult {\n key: string;\n title: string;\n category: string;\n snippet: string;\n}\n\n// Minimal structural type so we don't depend on fuse.js types at parse time\n// (the package is dynamic-imported on first search activation).\ninterface FuseLike<T> {\n search(query: string): Array<{\n item: T;\n matches?: ReadonlyArray<{\n key?: string;\n indices: ReadonlyArray<readonly [number, number]>;\n }>;\n }>;\n}\n\ninterface SearchDoc {\n key: string;\n title: string;\n category: string;\n body: string;\n}\n\n/**\n * E3 — FAQ modal. Two-pane layout (TOC sidebar + content pane), 80% viewport.\n *\n * E4 — Search uses a lazy-imported `fuse.js` index over title + body,\n * built on first search activation, filtered by audience, cached for the\n * modal session and invalidated on auth state change.\n *\n * E5 — `app:` link clicks close the modal and route to the app path; the\n * returnUrl-aware `authGuard` funnels unauthenticated users through\n * `/login?returnUrl=...`, and `Login` honors returnUrl on success.\n */\n@Component({\n selector: 'faq-modal',\n standalone: true,\n imports: [FaqAuthoringPanel],\n templateUrl: './faq-modal.html',\n styleUrl: './faq-modal.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class FaqModal {\n readonly devMode = inject(FAQ_DEV_MODE);\n\n private readonly faq = inject(FaqService);\n private readonly renderer = inject(FaqMarkdownRendererService);\n private readonly auth = inject(AuthenticationService);\n private readonly router = inject(Router);\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n\n readonly open = this.faq.modalOpen;\n readonly navigating = this.faq.navigating;\n readonly activeEntry = this.faq.activeEntry;\n readonly attempted = this.faq.activeAttempted;\n readonly canGoBack = this.faq.canGoBack;\n readonly canGoForward = this.faq.canGoForward;\n\n readonly sidebarCollapsed = signal(false);\n readonly searchMode = signal(false);\n readonly searchQuery = signal('');\n readonly searchLoading = signal(false);\n readonly searchResults = signal<SearchResult[]>([]);\n\n private fuse: FuseLike<SearchDoc> | null = null;\n private fuseBuild: Promise<void> | null = null;\n\n readonly renderedHtml = computed(() => {\n const content = this.faq.activeContent();\n const entry = this.faq.activeEntry();\n if (!content) return '';\n const parsed = this.renderer.parse(content);\n return this.renderer.render(parsed.body, {\n context: 'modal',\n imagePrefix: entry?.imagePrefix ?? parsed.frontmatter['image-prefix'],\n });\n });\n\n readonly toc = computed<TocGroup[]>(() => {\n const isAuth = this.auth.authenticated();\n const entries = this.faq.entries().filter((e) => {\n if (e.audience === 'public') return true;\n return isAuth;\n });\n const groups = new Map<string, FaqEntry[]>();\n for (const e of entries) {\n const list = groups.get(e.category) ?? [];\n list.push(e);\n groups.set(e.category, list);\n }\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([category, list]) => ({\n category,\n entries: list.sort(\n (a, b) =>\n a.order - b.order || a.title.localeCompare(b.title),\n ),\n }));\n });\n\n @ViewChild('contentPane') contentPaneRef?: ElementRef<HTMLDivElement>;\n\n constructor() {\n // Scroll content pane to top on key change.\n effect(() => {\n this.activeEntry();\n queueMicrotask(() => {\n this.contentPaneRef?.nativeElement.scrollTo({ top: 0 });\n });\n });\n\n // Invalidate the search index on auth state change so the audience\n // filter is re-applied on next search activation.\n effect(() => {\n this.auth.authenticated();\n this.fuse = null;\n this.fuseBuild = null;\n if (this.searchMode()) this.searchResults.set([]);\n });\n\n // Consume `faq search <term>` pre-fill: when FaqService.initialSearchTerm\n // is non-null while the modal is open, switch to search mode with that\n // query and immediately invoke the index build.\n effect(() => {\n const term = this.faq.initialSearchTerm();\n if (!term || !this.faq.modalOpen()) return;\n untracked(() => {\n this.searchMode.set(true);\n this.searchQuery.set(term);\n this.faq.consumeInitialSearchTerm();\n void this.ensureSearchIndex().then(() => this.runSearch(term));\n });\n });\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.open()) this.close();\n }\n\n close(): void {\n this.faq.closeModal();\n }\n\n onBackdropClick(): void {\n this.close();\n }\n\n stopPropagation(event: Event): void {\n event.stopPropagation();\n }\n\n toggleSidebar(): void {\n this.sidebarCollapsed.update((v) => !v);\n }\n\n goBack(): void {\n this.faq.back();\n }\n\n goForward(): void {\n this.faq.forward();\n }\n\n goIndex(): void {\n void this.faq.navigateTo('index');\n }\n\n toggleSearch(): void {\n const next = !this.searchMode();\n this.searchMode.set(next);\n if (next) {\n void this.ensureSearchIndex().then(() => this.runSearch(this.searchQuery()));\n }\n }\n\n onSearchInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.searchQuery.set(value);\n void this.ensureSearchIndex().then(() => this.runSearch(value));\n }\n\n onSearchResultClick(key: string): void {\n void this.faq.navigateTo(key);\n }\n\n onTocClick(key: string): void {\n void this.faq.navigateTo(key);\n }\n\n private async ensureSearchIndex(): Promise<void> {\n if (this.fuse) return;\n if (this.fuseBuild) return this.fuseBuild;\n this.searchLoading.set(true);\n this.fuseBuild = (async () => {\n const [{ default: Fuse }] = await Promise.all([\n import('fuse.js'),\n this.faq.ensureManifest(),\n ]);\n const isAuth = this.auth.authenticated();\n const entries = this.faq.entries().filter((e) =>\n e.audience === 'public' ? true : isAuth,\n );\n const docs: SearchDoc[] = await Promise.all(\n entries.map(async (e) => {\n const body = (await this.loader.loadContent(e.key)) ?? '';\n return { key: e.key, title: e.title, category: e.category, body };\n }),\n );\n this.fuse = new Fuse(docs, {\n keys: [\n { name: 'title', weight: 0.6 },\n { name: 'body', weight: 0.4 },\n ],\n includeMatches: true,\n ignoreLocation: true,\n threshold: 0.4,\n minMatchCharLength: 2,\n }) as unknown as FuseLike<SearchDoc>;\n })()\n .catch((err) => {\n console.error('FAQ search index build failed', err);\n this.fuseBuild = null;\n })\n .finally(() => {\n this.searchLoading.set(false);\n });\n return this.fuseBuild;\n }\n\n private runSearch(query: string): void {\n const q = query.trim();\n if (!q || !this.fuse) {\n this.searchResults.set([]);\n return;\n }\n const hits = this.fuse.search(q).slice(0, 30);\n this.searchResults.set(\n hits.map((h) => ({\n key: h.item.key,\n title: h.item.title,\n category: h.item.category,\n snippet: buildSnippet(h.item.body, h.matches),\n })),\n );\n }\n\n /**\n * Event-delegated click handler for the rendered content pane.\n * Intercepts our sentinel anchors emitted by FaqMarkdownRendererService.\n */\n onContentClick(event: MouseEvent): void {\n const target = event.target;\n if (!(target instanceof HTMLElement)) return;\n const anchor = target.closest<HTMLAnchorElement>('a[data-faq-kind]');\n if (!anchor) return;\n const kind = anchor.getAttribute('data-faq-kind');\n\n if (kind === 'external') {\n return;\n }\n\n if (kind === 'anchor') {\n event.preventDefault();\n const href = anchor.getAttribute('href') ?? '';\n const id = href.startsWith('#') ? href.slice(1) : href;\n if (!id) return;\n const pane = this.contentPaneRef?.nativeElement;\n const el = pane?.querySelector(`#${CSS.escape(id)}`);\n el?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n return;\n }\n\n const faqHref = anchor.getAttribute('data-faq-href') ?? '';\n\n if (kind === 'faq' && faqHref.startsWith('faq:')) {\n event.preventDefault();\n const key = faqHref.slice('faq:'.length);\n void this.faq.navigateTo(key);\n return;\n }\n\n if (kind === 'app' && faqHref.startsWith('app:')) {\n event.preventDefault();\n const path = faqHref.slice('app:'.length);\n this.close();\n // Defer route until after modal close finishes unwinding history,\n // so navigation lands as a fresh entry on top of the pre-modal URL.\n // The returnUrl-aware authGuard handles unauthenticated callers by\n // redirecting to /login?returnUrl=<path>; Login honors it on success.\n queueMicrotask(() => {\n void this.router.navigateByUrl(path);\n });\n return;\n }\n }\n}\n\n/**\n * Builds a short contextual snippet around the first body match. Falls back\n * to the head of the body when the only matches are in the title.\n */\nfunction buildSnippet(\n body: string,\n matches:\n | ReadonlyArray<{\n key?: string;\n indices: ReadonlyArray<readonly [number, number]>;\n }>\n | undefined,\n): string {\n const RADIUS = 60;\n const MAX = 180;\n const bodyMatch = matches?.find((m) => m.key === 'body' && m.indices.length);\n if (!bodyMatch) {\n return body.replace(/\\s+/g, ' ').slice(0, MAX).trim();\n }\n const [start, end] = bodyMatch.indices[0];\n const from = Math.max(0, start - RADIUS);\n const to = Math.min(body.length, end + RADIUS);\n let snippet = body.slice(from, to).replace(/\\s+/g, ' ').trim();\n if (from > 0) snippet = '…' + snippet;\n if (to < body.length) snippet = snippet + '…';\n return snippet.length > MAX ? snippet.slice(0, MAX) + '…' : snippet;\n}\n","@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >☰</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >‹</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >›</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >⌂</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >⌕</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >✕</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ…\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index…</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading…</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' → ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel…</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport {\n FAQ_DEV_EDITOR,\n FAQ_DEV_WORKSPACE_ROOT,\n FaqDevEditor,\n} from '../faq-dev-mode.token';\nimport { FaqService } from '../faq.service';\nimport { FaqEntry } from '../faq.types';\n\n/**\n * E11 — Dev-only FAQ authoring panel.\n *\n * Two modes, both dynamic-imported by `FaqModal` and gated behind\n * `FAQ_DEV_MODE`:\n * - `missing`: full scaffold panel rendered when no FAQ resolved.\n * - `existing`: collapsed source strip rendered below the article when an\n * entry IS resolved.\n *\n * The panel never imports `environment.*` directly — gating is the modal's\n * responsibility (via the FAQ_DEV_MODE token + dynamic import).\n */\n@Component({\n selector: 'faq-authoring-panel',\n standalone: true,\n imports: [NgClass],\n templateUrl: './faq-authoring-panel.html',\n styleUrl: './faq-authoring-panel.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FaqAuthoringPanel {\n private readonly faq = inject(FaqService);\n private readonly workspaceRoot = inject(FAQ_DEV_WORKSPACE_ROOT);\n private readonly editor: FaqDevEditor = inject(FAQ_DEV_EDITOR);\n\n /** `'missing'` shows the full scaffold; `'existing'` shows the collapsed strip. */\n readonly mode = input.required<'missing' | 'existing'>();\n /**\n * The dot-notation key actually being authored. For `missing` mode this is\n * the deepest attempted key (chain[0]); for `existing` it's the resolved key.\n */\n readonly key = input.required<string>();\n /** Fallback chain that was attempted. For `missing` every entry is missing. */\n readonly attempted = input<string[]>([]);\n /** Resolved entry — only set in `existing` mode. */\n readonly entry = input<FaqEntry | null>(null);\n\n readonly expanded = signal(false);\n readonly showAllFiles = signal(false);\n readonly copyState = signal<string | null>(null);\n\n readonly relPath = computed(() => {\n const e = this.entry();\n if (e) return `src/assets/faq/${e.file}.md`;\n return `src/assets/faq/${keyToFilePath(this.key())}.md`;\n });\n\n readonly absPath = computed(() => {\n const rel = this.relPath();\n return this.workspaceRoot ? joinPosix(this.workspaceRoot, rel) : rel;\n });\n\n readonly editorHref = computed(() => {\n const abs = this.absPath();\n if (this.editor === 'vscode') return `vscode://file/${abs}`;\n return `webstorm://open?file=${encodeURI(abs)}`;\n });\n\n readonly editorLabel = computed(() =>\n this.editor === 'vscode' ? 'Open in VS Code' : 'Open in WebStorm',\n );\n\n readonly scaffoldCmd = computed(() => `npm run faq:new -- ${this.key()}`);\n\n readonly frontmatterScaffold = computed(() => {\n const k = this.key();\n const title = humanize(k);\n const category = humanize(k.split('.')[0]);\n return [\n '---',\n `title: \"${title}\"`,\n `category: \"${category}\"`,\n 'audience: authenticated',\n 'seo-ready: false',\n 'description: \"\"',\n '---',\n '',\n `# ${title}`,\n '',\n `TODO: write content for \"${title}\".`,\n '',\n ].join('\\n');\n });\n\n readonly allEntries = computed(() => this.faq.entries());\n\n readonly missedChain = computed(() => {\n const present = new Set(this.allEntries().map((e) => e.key));\n return this.attempted().map((k) => ({ key: k, present: present.has(k) }));\n });\n\n toggleExpanded(): void {\n this.expanded.update((v) => !v);\n }\n\n toggleAllFiles(): void {\n this.showAllFiles.update((v) => !v);\n }\n\n async copy(text: string, label: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n this.copyState.set(label);\n setTimeout(() => {\n if (this.copyState() === label) this.copyState.set(null);\n }, 1500);\n } catch {\n this.copyState.set(`${label}:err`);\n }\n }\n}\n\nfunction keyToFilePath(key: string): string {\n return key.split('.').join('/');\n}\n\nfunction humanize(s: string): string {\n return s\n .split(/[.\\-_/]/)\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1))\n .join(' ');\n}\n\nfunction joinPosix(a: string, b: string): string {\n const left = a.endsWith('/') ? a.slice(0, -1) : a;\n const right = b.startsWith('/') ? b.slice(1) : b;\n return `${left}/${right}`;\n}\n","@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '✓' : '✗' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} ↗</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> — in-modal nav</li>\n <li><code>[label](app:/settings)</code> — navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> — external (new tab)</li>\n <li><code>[label](#section-id)</code> — intra-page anchor</li>\n <li><code></code> — image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">•</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} ↗</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '▲ Less' : '▼ More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '✓' : '✗' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> — in-modal nav</li>\n <li><code>[label](app:/settings)</code> — navigates the app</li>\n <li><code>[label](https://example.com)</code> — external</li>\n <li><code>[label](#section-id)</code> — intra-page anchor</li>\n <li><code></code> — image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n","import { CommonModule } from '@angular/common';\nimport {\n Component,\n OnInit,\n computed,\n inject,\n input,\n signal,\n ChangeDetectionStrategy\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FaqEntry } from '../faq.types';\n\ninterface CategoryGroup {\n category: string;\n entries: FaqEntry[];\n}\n\n/**\n * Shared TOC sidebar for the public /help pages. Lists every\n * `audience: 'public' && seoReady: true` entry grouped by category.\n *\n * Pass `activeFile` from the parent page so the matching link gets\n * the `active` style. RouterLinkActive isn't sufficient on its own\n * because the index page (`/help`) and entry pages\n * (`/help/<file>`) all share this sidebar.\n */\n@Component({\n selector: 'public-faq-toc',\n standalone: true,\n imports: [CommonModule, RouterLink, RouterLinkActive],\n template: `\n <nav class=\"public-faq-toc\" aria-label=\"Help contents\">\n <a\n class=\"public-faq-toc__index\"\n routerLink=\"/help\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >Brokenstock Help</a>\n @for (group of groups(); track group.category) {\n <div class=\"public-faq-toc__group\">\n <h3 class=\"public-faq-toc__category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <a\n [routerLink]=\"['/help', entry.file]\"\n [class.active]=\"activeFile() === entry.file\"\n >{{ entry.title }}</a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-toc {\n padding: 1.25rem 1rem;\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n font-size: 0.95rem;\n line-height: 1.4;\n }\n .public-faq-toc__index {\n display: block;\n font-weight: 600;\n color: #cfd6e4;\n text-decoration: none;\n padding: 0.4rem 0.5rem;\n border-radius: 4px;\n margin-bottom: 0.75rem;\n }\n .public-faq-toc__index.active,\n .public-faq-toc__index:hover {\n background: rgba(255, 255, 255, 0.06);\n }\n .public-faq-toc__group { margin-bottom: 1rem; }\n .public-faq-toc__category {\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: #8a93a3;\n margin: 0 0 0.35rem;\n padding: 0 0.5rem;\n }\n .public-faq-toc ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n .public-faq-toc li a {\n display: block;\n padding: 0.35rem 0.5rem;\n border-radius: 4px;\n color: #cfd6e4;\n text-decoration: none;\n }\n .public-faq-toc li a:hover {\n background: rgba(255, 255, 255, 0.05);\n }\n .public-faq-toc li a.active {\n background: rgba(110, 168, 254, 0.18);\n color: #fff;\n }\n `],\n})\nexport class PublicFaqToc implements OnInit {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n\n /** Currently-active entry file path (e.g. `landing`). Empty/undefined on the index. */\n readonly activeFile = input<string | undefined>(undefined);\n\n private readonly _entries = signal<FaqEntry[]>([]);\n\n readonly groups = computed<CategoryGroup[]>(() => {\n const visible = this._entries().filter(\n (e) => e.audience === 'public' && e.seoReady,\n );\n const byCategory = new Map<string, FaqEntry[]>();\n for (const entry of visible) {\n const list = byCategory.get(entry.category) ?? [];\n list.push(entry);\n byCategory.set(entry.category, list);\n }\n const groups: CategoryGroup[] = [];\n for (const [category, entries] of byCategory) {\n entries.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title));\n groups.push({ category, entries });\n }\n groups.sort((a, b) => a.category.localeCompare(b.category));\n return groups;\n });\n\n async ngOnInit(): Promise<void> {\n const manifest = await this.loader.loadManifest();\n this._entries.set(manifest.entries);\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Canonical public base URL (no trailing slash) used for OpenGraph,\n * Twitter, JSON-LD canonical URLs, and sitemap entries on the\n * public FAQ pages. Default empty string — falls back to relative\n * `og:url` etc. when unset, which is fine for previewing but\n * suboptimal for production SEO. Consumer apps should override.\n */\nexport const FAQ_PUBLIC_SITE_BASE_URL = new InjectionToken<string>(\n 'FAQ_PUBLIC_SITE_BASE_URL',\n { providedIn: 'root', factory: () => '' },\n);\n\n/**\n * Publisher / author Organization embedded in schema.org JSON-LD on\n * public FAQ pages. `logo` is optional — Google's validator warns but\n * does not error when omitted. Add it later via a one-line provider\n * override.\n */\nexport interface FaqPublicPublisher {\n name: string;\n url?: string;\n logo?: string;\n}\n\nexport const FAQ_PUBLIC_PUBLISHER = new InjectionToken<FaqPublicPublisher>(\n 'FAQ_PUBLIC_PUBLISHER',\n { providedIn: 'root', factory: () => ({ name: '' }) },\n);\n","import { CommonModule } from '@angular/common';\nimport { Component, OnInit, computed, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { Meta, Title } from '@angular/platform-browser';\nimport { RouterLink } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { PublicFaqToc } from '../public-faq-toc/public-faq-toc';\nimport {\n FAQ_PUBLIC_PUBLISHER,\n FAQ_PUBLIC_SITE_BASE_URL,\n} from '../faq-seo.tokens';\nimport { FaqEntry } from '../faq.types';\n\ninterface CategoryGroup {\n category: string;\n entries: FaqEntry[];\n}\n\n/**\n * Public, SEO-targeted FAQ index. Prerendered at build time on the\n * consumer side (e.g. /help in broken-stock). Lists every manifest\n * entry where `audience === 'public' && seoReady === true`, grouped\n * by category and ordered by `order`.\n *\n * SEO (E17): sets <title>, meta description, OG, and Twitter tags.\n * JSON-LD (E18): emits a schema.org CollectionPage referencing\n * each child entry as an ItemList.\n */\n@Component({\n selector: 'public-faq-index',\n standalone: true,\n imports: [CommonModule, RouterLink, PublicFaqToc],\n template: `\n <div class=\"public-faq-layout\">\n <aside class=\"public-faq-sidebar\">\n <public-faq-toc />\n </aside>\n <article class=\"public-faq-index\">\n <header>\n <h1>Brokenstock Help</h1>\n <p class=\"lead\">Documentation and walkthroughs for the Brokenstock trade-journal platform.</p>\n </header>\n @if (loading()) {\n <p>Loading…</p>\n } @else if (groups().length === 0) {\n <p>No help pages are published yet.</p>\n } @else {\n @for (group of groups(); track group.category) {\n <section>\n <h2>{{ group.category }}</h2>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <a [routerLink]=\"['/help', entry.file]\">{{ entry.title }}</a>\n @if (entry.description) {\n <span class=\"desc\"> — {{ entry.description }}</span>\n }\n </li>\n }\n </ul>\n </section>\n }\n }\n @if (jsonLd(); as ld) {\n <script type=\"application/ld+json\">{{ ld }}</script>\n }\n </article>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-layout {\n display: grid;\n grid-template-columns: minmax(220px, 280px) 1fr;\n gap: 1.5rem;\n max-width: 1280px;\n margin: 0 auto;\n padding: 1.5rem 1.25rem 4rem;\n }\n .public-faq-sidebar {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n align-self: start;\n position: sticky;\n top: 1rem;\n max-height: calc(100vh - 2rem);\n overflow-y: auto;\n }\n .public-faq-index {\n max-width: 860px;\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n line-height: 1.55;\n }\n header h1 { font-size: 2.25rem; margin: 0 0 0.5rem; }\n .lead { color: #9aa3b3; margin: 0 0 2rem; font-size: 1.1rem; }\n h2 { font-size: 1.35rem; margin: 1.75rem 0 0.5rem; border-bottom: 1px solid rgba(255, 255, 255, 0.08); padding-bottom: 0.25rem; }\n ul { list-style: none; padding: 0; margin: 0; }\n li { padding: 0.4rem 0; }\n .public-faq-index a { color: #6ea8fe; text-decoration: none; font-weight: 500; }\n .public-faq-index a:hover { text-decoration: underline; }\n .desc { color: #8a93a3; font-weight: 400; }\n @media (max-width: 900px) {\n .public-faq-layout { grid-template-columns: 1fr; }\n .public-faq-sidebar {\n position: static;\n max-height: none;\n border-right: none;\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n }\n `],\n})\nexport class PublicFaqIndex implements OnInit {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly title = inject(Title);\n private readonly meta = inject(Meta);\n private readonly siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);\n private readonly publisher = inject(FAQ_PUBLIC_PUBLISHER);\n\n private readonly _entries = signal<FaqEntry[]>([]);\n readonly loading = signal(true);\n\n readonly visibleEntries = computed(() =>\n this._entries().filter((e) => e.audience === 'public' && e.seoReady),\n );\n\n readonly groups = computed<CategoryGroup[]>(() => {\n const visible = this.visibleEntries();\n const byCategory = new Map<string, FaqEntry[]>();\n for (const entry of visible) {\n const list = byCategory.get(entry.category) ?? [];\n list.push(entry);\n byCategory.set(entry.category, list);\n }\n const groups: CategoryGroup[] = [];\n for (const [category, entries] of byCategory) {\n entries.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title));\n groups.push({ category, entries });\n }\n groups.sort((a, b) => a.category.localeCompare(b.category));\n return groups;\n });\n\n readonly jsonLd = computed<string | null>(() => {\n const entries = this.visibleEntries();\n if (entries.length === 0) return null;\n const base = this.siteBase.replace(/\\/+$/, '');\n const indexUrl = `${base}/help`;\n const ld: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'CollectionPage',\n name: 'Brokenstock Help',\n url: indexUrl,\n mainEntity: {\n '@type': 'ItemList',\n itemListElement: entries.map((entry, idx) => ({\n '@type': 'ListItem',\n position: idx + 1,\n url: `${base}/help/${entry.file}`,\n name: entry.title,\n })),\n },\n };\n if (this.publisher.name) {\n const pub: Record<string, unknown> = {\n '@type': 'Organization',\n name: this.publisher.name,\n };\n if (this.publisher.url) pub['url'] = this.publisher.url;\n if (this.publisher.logo) pub['logo'] = this.publisher.logo;\n ld['publisher'] = pub;\n }\n return serializeJsonLd(ld);\n });\n\n async ngOnInit(): Promise<void> {\n try {\n const manifest = await this.loader.loadManifest();\n this._entries.set(manifest.entries);\n this.applyMeta();\n } finally {\n this.loading.set(false);\n }\n }\n\n private applyMeta(): void {\n const base = this.siteBase.replace(/\\/+$/, '');\n const url = `${base}/help`;\n const description =\n 'Documentation and walkthroughs for the Brokenstock trade-journal platform.';\n this.title.setTitle('Help — Brokenstock');\n this.meta.updateTag({ name: 'description', content: description });\n this.meta.updateTag({ property: 'og:type', content: 'website' });\n this.meta.updateTag({ property: 'og:title', content: 'Help — Brokenstock' });\n this.meta.updateTag({ property: 'og:description', content: description });\n this.meta.updateTag({ property: 'og:url', content: url });\n if (this.publisher.name) {\n this.meta.updateTag({ property: 'og:site_name', content: this.publisher.name });\n }\n this.meta.updateTag({ name: 'twitter:card', content: 'summary' });\n this.meta.updateTag({ name: 'twitter:title', content: 'Help — Brokenstock' });\n this.meta.updateTag({ name: 'twitter:description', content: description });\n }\n}\n\nfunction serializeJsonLd(obj: unknown): string {\n return JSON.stringify(obj).replace(/</g, '\\\\u003c');\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, OnInit, computed, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { Meta, Title } from '@angular/platform-browser';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FaqMarkdownRendererService } from '../faq-markdown-renderer.service';\nimport { PublicFaqToc } from '../public-faq-toc/public-faq-toc';\nimport {\n FAQ_PUBLIC_PUBLISHER,\n FAQ_PUBLIC_SITE_BASE_URL,\n} from '../faq-seo.tokens';\nimport { FaqEntry } from '../faq.types';\n\n/**\n * Public, SEO-targeted FAQ page. Prerendered at build time per\n * qualifying manifest entry (e.g. /help/landing, /help/trade/segments).\n *\n * The route is `help/**` so multi-segment file paths work; this\n * component reads the wildcard path off `ActivatedRoute.url`.\n *\n * SEO (E17): sets <title>, meta description, OpenGraph and Twitter\n * Card tags using Angular's Title + Meta services (SSR-compatible).\n * JSON-LD (E18): emits a schema.org Article (or BlogPosting) object\n * via an inline <script type=\"application/ld+json\"> element. The\n * raw JSON has `<` escaped to `<` so a stray `</script>` inside\n * data won't break the surrounding tag.\n */\n@Component({\n selector: 'public-faq-page',\n standalone: true,\n imports: [CommonModule, RouterLink, PublicFaqToc],\n template: `\n <div class=\"public-faq-layout\">\n <aside class=\"public-faq-sidebar\">\n <public-faq-toc [activeFile]=\"activeFile()\" />\n </aside>\n <article class=\"public-faq-page\">\n @if (loading()) {\n <p>Loading…</p>\n } @else if (!entry()) {\n <header>\n <h1>Page not found</h1>\n <p>That help page doesn't exist or isn't published. Try the <a routerLink=\"/help\">help index</a>.</p>\n </header>\n } @else {\n <header>\n <h1>{{ entry()!.title }}</h1>\n @if (entry()!.description) {\n <p class=\"lead\">{{ entry()!.description }}</p>\n }\n </header>\n <div class=\"body\" [innerHTML]=\"renderedHtml()\"></div>\n @if (jsonLd(); as ld) {\n <script type=\"application/ld+json\">{{ ld }}</script>\n }\n }\n </article>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-layout {\n display: grid;\n grid-template-columns: minmax(220px, 280px) 1fr;\n gap: 1.5rem;\n max-width: 1280px;\n margin: 0 auto;\n padding: 1.5rem 1.25rem 4rem;\n }\n .public-faq-sidebar {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n align-self: start;\n position: sticky;\n top: 1rem;\n max-height: calc(100vh - 2rem);\n overflow-y: auto;\n }\n .public-faq-page {\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n line-height: 1.6;\n max-width: 860px;\n }\n header h1 { font-size: 2.1rem; margin: 0 0 0.5rem; }\n .lead { color: #9aa3b3; font-size: 1.1rem; margin: 0 0 1.5rem; }\n .body :is(h1, h2, h3, h4) { margin-top: 2rem; }\n .body a { color: #6ea8fe; }\n .body img { max-width: 100%; height: auto; }\n .body pre { background: rgba(0, 0, 0, 0.35); padding: 0.75rem 1rem; border-radius: 6px; overflow-x: auto; }\n .body code { background: rgba(255, 255, 255, 0.08); padding: 0.1rem 0.3rem; border-radius: 3px; font-size: 0.9em; }\n .body pre code { background: transparent; padding: 0; }\n @media (max-width: 900px) {\n .public-faq-layout { grid-template-columns: 1fr; }\n .public-faq-sidebar {\n position: static;\n max-height: none;\n border-right: none;\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n }\n `],\n})\nexport class PublicFaqPage implements OnInit {\n private readonly route = inject(ActivatedRoute);\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly renderer = inject(FaqMarkdownRendererService);\n private readonly title = inject(Title);\n private readonly meta = inject(Meta);\n private readonly siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);\n private readonly publisher = inject(FAQ_PUBLIC_PUBLISHER);\n\n readonly entry = signal<FaqEntry | null>(null);\n readonly body = signal<string>('');\n readonly loading = signal(true);\n\n readonly activeFile = computed(() => this.entry()?.file);\n\n readonly renderedHtml = computed(() => {\n const entry = this.entry();\n const body = this.body();\n if (!entry || !body) return '';\n return this.renderer.render(body, {\n context: 'page',\n imagePrefix: entry.imagePrefix\n ? `/assets/faq/${entry.imagePrefix}`\n : undefined,\n });\n });\n\n readonly jsonLd = computed<string | null>(() => {\n const entry = this.entry();\n if (!entry) return null;\n const url = this.canonicalUrl(entry);\n const ld: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: entry.title,\n url,\n mainEntityOfPage: url,\n };\n if (entry.description) ld['description'] = entry.description;\n if (this.publisher.name) {\n const pub: Record<string, unknown> = {\n '@type': 'Organization',\n name: this.publisher.name,\n };\n if (this.publisher.url) pub['url'] = this.publisher.url;\n if (this.publisher.logo) pub['logo'] = this.publisher.logo;\n ld['publisher'] = pub;\n ld['author'] = pub;\n }\n return serializeJsonLd(ld);\n });\n\n async ngOnInit(): Promise<void> {\n try {\n const segments = this.route.snapshot.url.map((s) => s.path);\n const filePath = segments.join('/');\n if (!filePath) {\n this.applyNotFoundMeta();\n return;\n }\n const manifest = await this.loader.loadManifest();\n const match = manifest.entries.find(\n (e) => e.file === filePath && e.audience === 'public' && e.seoReady,\n );\n if (!match) {\n this.applyNotFoundMeta();\n return;\n }\n const content = await this.loader.loadContent(match.key);\n if (content === null) {\n this.applyNotFoundMeta();\n return;\n }\n const parsed = this.renderer.parse(content);\n this.entry.set(match);\n this.body.set(parsed.body);\n this.applyMeta(match);\n } finally {\n this.loading.set(false);\n }\n }\n\n private applyMeta(entry: FaqEntry): void {\n const url = this.canonicalUrl(entry);\n const description = entry.description ?? '';\n const title = `${entry.title} — Help`;\n this.title.setTitle(title);\n this.meta.updateTag({ name: 'description', content: description });\n this.meta.updateTag({ property: 'og:type', content: 'article' });\n this.meta.updateTag({ property: 'og:title', content: entry.title });\n this.meta.updateTag({ property: 'og:description', content: description });\n this.meta.updateTag({ property: 'og:url', content: url });\n if (this.publisher.name) {\n this.meta.updateTag({ property: 'og:site_name', content: this.publisher.name });\n }\n this.meta.updateTag({ name: 'twitter:card', content: 'summary' });\n this.meta.updateTag({ name: 'twitter:title', content: entry.title });\n this.meta.updateTag({ name: 'twitter:description', content: description });\n }\n\n private applyNotFoundMeta(): void {\n this.title.setTitle('Page not found — Help');\n this.meta.updateTag({ name: 'robots', content: 'noindex' });\n }\n\n private canonicalUrl(entry: FaqEntry): string {\n const base = this.siteBase.replace(/\\/+$/, '');\n return `${base}/help/${entry.file}`;\n }\n}\n\n/**\n * Serializes a JSON-LD object for safe inclusion in a\n * `<script type=\"application/ld+json\">` element. Escapes `<` so a\n * stray `</script>` inside any string field cannot break out of the\n * script tag. (Browsers and crawlers parse the resulting `<`\n * back to `<` per JSON spec.)\n */\nfunction serializeJsonLd(obj: unknown): string {\n return JSON.stringify(obj).replace(/</g, '\\\\u003c');\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\nexport type ThemeMode = 'dark';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly mode = signal<ThemeMode>('dark');\n readonly isDark = computed(() => this.mode() === 'dark');\n}\n","/*\nCreated by Franz Zemen 2026-10-16\nLicense Type: UNLICENSED\n\nPhone layout of the app frame (broken-stock scanner-phone-display.prd.md D9 / E8).\n*/\n\nimport { DestroyRef, Injectable, Signal, inject, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\n\n/**\n * Below this width the frame is in its phone layout: no icon column, a ☰ menu\n * button in the top bar, a one-line top bar.\n *\n * The same 820px line broken-stock's screens use (scanner-filter-editor.prd.md\n * D11), written the same way. `819.98px` rather than `819px` so a fractional\n * width from browser zoom (819.5px) does not fall between the two layouts.\n *\n * ⚠ The CSS repeats this query in shell.css and status-bar.css —\n * a media query cannot read a TypeScript constant. phone-layout.service.spec.ts\n * fails if any of them drifts from this value.\n */\nexport const SHELL_PHONE_MEDIA_QUERY = '(max-width: 819.98px)';\n\n/**\n * Whether the frame is in its phone layout, and whether the phone menu is open.\n *\n * Desktop never sees any of this: `isPhone` is false there, the menu cannot open,\n * and the rail renders exactly as before.\n */\n@Injectable({ providedIn: 'root' })\nexport class PhoneLayoutService {\n readonly #window = inject(DOCUMENT).defaultView;\n readonly #isPhone = signal(false);\n readonly #menuOpen = signal(false);\n\n /** True below 820px. Always false where there is no window (server rendering). */\n readonly isPhone: Signal<boolean> = this.#isPhone.asReadonly();\n\n /** The ☰ menu's open state. Only ever true while `isPhone` is true. */\n readonly menuOpen: Signal<boolean> = this.#menuOpen.asReadonly();\n\n constructor() {\n const mql = this.#window?.matchMedia?.(SHELL_PHONE_MEDIA_QUERY);\n if (!mql) return;\n this.#isPhone.set(mql.matches);\n const onChange = (event: MediaQueryListEvent): void => {\n this.#isPhone.set(event.matches);\n // Rotating or widening past 820px brings the rail back; a menu left open\n // would then cover the screen with nothing on it to close it.\n if (!event.matches) this.#menuOpen.set(false);\n };\n mql.addEventListener('change', onChange);\n inject(DestroyRef).onDestroy(() => mql.removeEventListener('change', onChange));\n }\n\n toggleMenu(): void {\n this.#menuOpen.set(this.#isPhone() && !this.#menuOpen());\n }\n\n closeMenu(): void {\n this.#menuOpen.set(false);\n }\n}\n","import { Injectable, inject, signal } from '@angular/core';\nimport { PhoneLayoutService } from './phone-layout.service';\n\n/**\n * Asks the command box to take the cursor. Called by the shell after most\n * actions (rail choices, Log Out, ?, ⧉, Escape, sign-in) and by apps.\n *\n * ⚠ A NO-OP ON A PHONE (scanner-phone-display D10/E11). The console is shown\n * below 820px, but nothing may put the cursor in it there: focusing a text box\n * on a phone raises the on-screen keyboard over the screen the user just opened.\n * The one place every focus request passes through is here, so this is where it\n * is refused. Refusing it at the source also means a request made on a phone is\n * not left counted up, to be acted on after a rotation to a wider screen.\n */\n@Injectable({ providedIn: 'root' })\nexport class TerminalFocusService {\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly focusRequested = signal(0);\n\n requestFocus(): void {\n if (this.#phoneLayout.isPhone()) return;\n this.focusRequested.update(v => v + 1);\n }\n}\n","import { Injectable, Signal, signal } from '@angular/core';\n\n/**\n * The choice a NEW window starts with. Shared by the whole browser.\n * Written on every toggle, read only at construction.\n */\nconst DEFAULT_KEY = 'shell.commandTerminalVisible';\n\n/**\n * THIS window's current choice. Per-window by definition, so two windows cannot\n * fight over it.\n */\nconst WINDOW_KEY = 'shell.commandTerminalVisible.window';\n\n/**\n * Controls visibility of the command terminal at the bottom of the shell.\n *\n * ⚠ TWO KEYS, AND THE SPLIT IS THE POINT (multiple-windows F6).\n *\n * This used to be one `localStorage` value, read once at construction and\n * written on every change, with nothing listening for another window. That was\n * correct while the app could only be open once. It is not now: two windows\n * would each write the shared value on every toggle, so whichever you touched\n * last decided what BOTH windows got on their next start — a setting that\n * quietly refuses to stay put, which reads as a bug in the shell rather than in\n * storage.\n *\n * The resolution is not \"make them agree\". You genuinely may want the terminal\n * up on the scanner window and out of the way on the other, so forcing them into\n * step would be the wrong fix as well as a harder one. Instead:\n *\n * - the LIVE state is per-window (`sessionStorage`), so the two never collide\n * and a reload still restores what this window had;\n * - the DEFAULT for a brand-new window is shared (`localStorage`), so your\n * last choice anywhere still carries into the next window and across a\n * browser restart, which is the behaviour the single key was providing.\n *\n * Both writes are best-effort: losing a remembered layout must never break the\n * screen trying to remember it.\n *\n * ⚠ `visible` is READ-ONLY to the outside and `toggle()` is the only mutator.\n * It used to be a writable signal persisted by an `effect`, which meant any\n * caller could `set()` it — and whether that got remembered depended on an\n * effect firing somewhere else. Persisting inside the one mutator makes it\n * impossible to change this without persisting it.\n */\n@Injectable({ providedIn: 'root' })\nexport class TerminalVisibilityService {\n readonly #visible = signal(this.#readInitial());\n\n /** Read-only on purpose — see the header. */\n readonly visible: Signal<boolean> = this.#visible.asReadonly();\n\n toggle(): void {\n const next = !this.#visible();\n this.#visible.set(next);\n this.#write(sessionStorage, WINDOW_KEY, next);\n this.#write(localStorage, DEFAULT_KEY, next);\n }\n\n /**\n * This window's own choice wins; otherwise the last choice made anywhere;\n * otherwise visible.\n *\n * The order matters on a reload: a window that had hidden the terminal must\n * not have it reappear because another window showed one since.\n */\n #readInitial(): boolean {\n const own = this.#read(sessionStorage, WINDOW_KEY);\n if (own !== undefined) return own;\n const shared = this.#read(localStorage, DEFAULT_KEY);\n return shared ?? true;\n }\n\n #read(store: Storage, key: string): boolean | undefined {\n try {\n const raw = store.getItem(key);\n return raw === null ? undefined : raw === '1';\n } catch {\n // Storage unavailable (private mode / prerender) — fall through.\n return undefined;\n }\n }\n\n #write(store: Storage, key: string, value: boolean): void {\n try {\n store.setItem(key, value ? '1' : '0');\n } catch {\n // Non-fatal by policy: a lost layout preference must not break the screen.\n }\n }\n}\n","import { computed, inject, Injectable, NgZone, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { TerminalFocusService } from './terminal-focus.service';\n\n/**\n * A key binding a screen registers while it is mounted.\n *\n * **`key` is what the help overlay shows and, by default, what is matched.**\n * `code` overrides the matching without changing the display, which matters more\n * than it sounds: on a US layout `shift`+1 delivers `event.key === '!'`, not\n * `'1'` with a shift flag. A screen binding shifted digits and comparing `key`\n * ships shortcuts that never fire — and registering `'!'` instead APPEARS to\n * work and then breaks on any non-US keyboard. `code: 'Digit1'` is the physical\n * key and is layout-independent.\n */\nexport interface ShortcutRegistration {\n /** Displayed in the help overlay, and matched against `event.key` unless `code` is set. */\n key: string;\n /**\n * Match `event.code` instead — the PHYSICAL key, independent of layout and of\n * what modifiers do to the character produced. Use for anything shifted.\n */\n code?: string;\n modifier?: 'Alt' | 'Shift';\n action: () => void;\n description: string;\n}\n\n/**\n * Elements that mean \"the user is typing\", where an unmodified shortcut must not fire.\n *\n * Kept as a set of tag names plus a `contenteditable` check rather than a\n * selector string, so it is greppable and so the reasoning stays attached to it.\n */\nconst TEXT_ENTRY_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT']);\n\n@Injectable({ providedIn: 'root' })\nexport class KeyboardShortcutService {\n readonly #groups = new Map<string, ShortcutRegistration[]>();\n readonly #activeGroupId = signal<string | null>(null);\n\n readonly #document = inject(DOCUMENT);\n readonly #zone = inject(NgZone);\n readonly #focusService = inject(TerminalFocusService);\n\n readonly helpVisible = signal(false);\n\n /**\n * True while unmodified shortcuts are being suppressed — the user is typing,\n * or a dialog is open.\n *\n * Exposed because a screen binding BARE keys needs to tell the user whether the\n * next keystroke acts or types, and that indicator must read the service's own\n * dispatch state. A screen keeping its own boolean will eventually disagree\n * with the service, and an indicator that lies about whether a keystroke sells\n * a thousand shares is worse than no indicator at all.\n */\n readonly suppressed = signal(false);\n\n readonly activeShortcuts = computed(() => {\n const groupId = this.#activeGroupId();\n if (!groupId) return null;\n const shortcuts = this.#groups.get(groupId);\n if (!shortcuts) return null;\n return { groupId, shortcuts };\n });\n\n constructor() {\n this.#zone.runOutsideAngular(() => {\n this.#document.addEventListener('keydown', (event: KeyboardEvent) => {\n this.#handleKeydown(event);\n });\n // ⚠ THE WRITE IS DEFERRED, AND THAT IS NOT AN OPTIMISATION.\n //\n // `element.focus()` dispatches `focusin` SYNCHRONOUSLY. Angular calls\n // `.focus()` from template-driven code — an autofocused input, the shell's\n // terminal reclaiming focus — so this listener can run in the middle of a\n // render, and a signal write there throws NG0600, \"writing to signals is\n // not allowed while Angular renders the template\".\n //\n // That throw shipped: it aborted the login transition, so the sign-in POST\n // returned 200 and the app still showed \"not logged in\", with every\n // authenticated request that followed answering 401. Nothing in the failure\n // pointed at the keyboard.\n //\n // A microtask runs after the render completes, which is soon enough for an\n // indicator a human reads and late enough to be outside the reactive\n // context. The value is compared first so an unchanged focus move writes\n // nothing at all.\n const refresh = (): void => {\n queueMicrotask(() => {\n const next = this.#isSuppressed();\n if (next !== this.suppressed()) this.suppressed.set(next);\n });\n };\n this.#document.addEventListener('focusin', refresh, true);\n this.#document.addEventListener('focusout', refresh, true);\n });\n }\n\n registerGroup(groupId: string, shortcuts: ShortcutRegistration[]): void {\n this.#groups.set(groupId, shortcuts);\n this.#activeGroupId.set(groupId);\n // Same hazard as the focus listener above: a screen registers from\n // `ngOnInit`, which Angular may run inside a render.\n queueMicrotask(() => {\n const next = this.#isSuppressed();\n if (next !== this.suppressed()) this.suppressed.set(next);\n });\n }\n\n unregisterGroup(groupId: string): void {\n this.#groups.delete(groupId);\n if (this.#activeGroupId() === groupId) {\n const keys = [...this.#groups.keys()];\n this.#activeGroupId.set(keys.length > 0 ? keys[keys.length - 1] : null);\n }\n }\n\n toggleHelp(): void {\n this.helpVisible.update(v => !v);\n }\n\n /**\n * Would an unmodified shortcut be ignored right now?\n *\n * Two cases: a text-entry element has focus, or a dialog is open. Alt\n * combinations are exempt — they do not collide with typing, which is why\n * every binding in the app before this guard existed used one.\n */\n #isSuppressed(): boolean {\n const active = this.#document.activeElement as HTMLElement | null;\n if (active) {\n if (TEXT_ENTRY_TAGS.has(active.tagName)) return true;\n if (active.isContentEditable) return true;\n }\n // Angular Material puts every dialog in this container. A shortcut firing\n // behind an open dialog acts on a screen the user cannot currently see.\n return this.#document.querySelector('.cdk-overlay-container .cdk-overlay-pane') !== null;\n }\n\n #matches(shortcut: ShortcutRegistration, event: KeyboardEvent): boolean {\n // The physical key when `code` is given, the produced character otherwise.\n const hit = shortcut.code ? shortcut.code === event.code : shortcut.key === event.key;\n if (!hit) return false;\n if (shortcut.modifier === 'Alt') return event.altKey;\n if (shortcut.modifier === 'Shift') {\n return event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;\n }\n // Unmodified. `ctrl`/`alt`/`meta` are excluded because the page still\n // receives a keystroke carrying the digit when the browser handles\n // `ctrl`+1 as a tab switch — without this, switching tabs would also fire\n // whatever a bare `1` is bound to.\n return !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;\n }\n\n #handleKeydown(event: KeyboardEvent): boolean {\n const activeId = this.#activeGroupId();\n if (activeId) {\n const shortcuts = this.#groups.get(activeId);\n if (shortcuts) {\n const match = shortcuts.find(s => this.#matches(s, event));\n if (match) {\n const alt = match.modifier === 'Alt';\n // Alt bindings are exempt from both guards below, so nothing that\n // existed before them changes behaviour: Alt does not collide with\n // typing, and holding Alt+ArrowDown to walk a list is wanted.\n if (!alt) {\n // A key held down repeats at roughly thirty a second. On a screen\n // where a bare key places an order, that is fifteen orders in half a\n // second, and a synchronous action path will run every one of them.\n if (event.repeat) return false;\n if (this.#isSuppressed()) return false;\n }\n event.preventDefault();\n this.#zone.run(() => match.action());\n return true;\n }\n }\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.#zone.run(() => {\n this.helpVisible.set(false);\n this.#focusService.requestFocus();\n });\n return true;\n }\n\n if (!event.altKey) return false;\n\n if (event.key === '?' || event.key === '/') {\n event.preventDefault();\n this.#zone.run(() => this.toggleHelp());\n return true;\n }\n\n return false;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { z } from 'zod/v4';\nimport { CommandDefinition, CommandResult } from '../types/command.types';\nimport { FaqService } from '../faq/faq.service';\n\nconst FAQ_USAGE =\n 'faq\\n' +\n 'faq <key>\\n' +\n 'faq search <term>\\n' +\n 'faq index\\n' +\n 'faq help\\n\\n' +\n ' Opens the in-app FAQ help system. Does not require authentication.\\n\\n' +\n ' Subcommands:\\n' +\n ' (none) Open the FAQ at the current route\\'s resolved key.\\n' +\n ' <key> Open at a specific dot-notation key (e.g. trade.segments).\\n' +\n ' search <term> Open with the search field pre-filled.\\n' +\n ' index Open at the index table-of-contents.\\n' +\n ' help Show this help.';\n\n@Injectable({ providedIn: 'root' })\nexport class FaqCommand implements CommandDefinition {\n private readonly faqService = inject(FaqService);\n\n readonly name = 'faq';\n readonly description = 'Open the in-app FAQ help system';\n readonly usage = FAQ_USAGE;\n readonly requiresAuth = false;\n readonly scope = 'global' as const;\n readonly argsSchema = z.array(z.string()).max(50);\n\n execute(args: string[]): CommandResult {\n const ts = () => new Date();\n if (args.length === 0) {\n void this.faqService.openModal();\n return { success: true, message: '', timestamp: ts() };\n }\n const sub = args[0].toLowerCase();\n if (sub === 'index') {\n void this.faqService.openModal('index');\n return { success: true, message: '', timestamp: ts() };\n }\n if (sub === 'search') {\n const term = args.slice(1).join(' ').trim();\n if (!term) {\n return {\n success: false,\n message: 'Usage: faq search <term>',\n timestamp: ts(),\n };\n }\n void this.faqService.openModal(undefined, { searchTerm: term });\n return { success: true, message: '', timestamp: ts() };\n }\n void this.faqService.openModal(args[0]);\n return { success: true, message: '', timestamp: ts() };\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CommandAlias, CommandDefinition } from '../types/command.types';\nimport { SHELL_COMMANDS } from '../tokens/shell-tokens';\nimport { FaqCommand } from '../commands/faq.command';\n\n/**\n * What a typed word resolves to: the command it names, plus any words the\n * alternate name carries with it (see {@link CommandAlias}).\n */\nexport interface ResolvedCommand {\n readonly command: CommandDefinition;\n readonly prependArgs: readonly string[];\n}\n\n/**\n * Names the shell handles itself, ahead of the registry. A command taking one\n * of these would be registered and then never reachable, so registration\n * refuses them outright rather than leaving a command that silently never runs.\n */\nconst RESERVED_NAMES: readonly string[] = ['clear', 'help'];\n\n@Injectable({ providedIn: 'root' })\nexport class CommandRegistryService {\n private readonly commands = new Map<string, CommandDefinition>();\n private readonly aliases = new Map<string, ResolvedCommand>();\n\n constructor() {\n // Built-in shell commands registered ahead of app-provided commands so\n // an app cannot accidentally shadow them.\n this.register(inject(FaqCommand));\n\n const appCommands = inject(SHELL_COMMANDS, { optional: true }) ?? [];\n for (const cmd of appCommands) {\n this.register(cmd);\n }\n }\n\n /**\n * Register a command and claim its names.\n *\n * ⭐ THROWS on a name already taken — real name or alternate. It used to be a\n * bare `set`, which meant a clash silently overwrote whichever command\n * registered first, and the constructor's \"built-ins first so an app cannot\n * shadow them\" comment was not actually true of the map. A shadowed command\n * is indistinguishable from a broken one, and this is the map dispatch reads,\n * so the failure belongs at startup where it cannot be missed\n * (scanner-command-speed.prd.md D4).\n */\n register(command: CommandDefinition): void {\n this.#claim(command.name, `command '${command.name}'`);\n this.commands.set(command.name, command);\n for (const alias of command.aliases ?? []) {\n this.#claim(alias.name, `alias '${alias.name}' of '${command.name}'`);\n this.aliases.set(alias.name, { command, prependArgs: alias.prependArgs ?? [] });\n }\n }\n\n #claim(name: string, what: string): void {\n if (RESERVED_NAMES.includes(name)) {\n throw new Error(`${what} collides with a reserved command name`);\n }\n if (this.commands.has(name) || this.aliases.has(name)) {\n throw new Error(`${what} collides with a command name already registered`);\n }\n }\n\n /**\n * Resolve a word the user typed to the command it names — real name or\n * alternate. `prependArgs` is empty except for an alternate that carries a\n * subcommand.\n *\n * Use this wherever a TYPED word is being looked up. {@link get} deliberately\n * stays blind to alternates so callers that mean \"the command called X\" keep\n * meaning exactly that.\n */\n resolve(name: string): ResolvedCommand | undefined {\n const command = this.commands.get(name);\n if (command) return { command, prependArgs: [] };\n return this.aliases.get(name);\n }\n\n get(name: string): CommandDefinition | undefined {\n return this.commands.get(name);\n }\n\n getAll(): CommandDefinition[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Returns command name suggestions for tab-completion.\n * Built-ins (clear, help) are included when authenticated.\n */\n getSuggestions(prefix: string, isAuthenticated: boolean): string[] {\n if (!prefix) return [];\n if (!isAuthenticated) {\n const open = ['login', ...[...this.commands.values()]\n .filter(c => c.requiresAuth === false)\n .flatMap(c => [c.name, ...(c.aliases ?? []).map(a => a.name)])];\n return open.filter(name => name.startsWith(prefix) && name !== prefix).sort();\n }\n const builtIns = ['clear', 'help'];\n // Alternate names are offered too: typing `sca` and being offered nothing\n // is the exact failure that produced the ref/reference pair (D5).\n const registered = [...this.commands.keys(), ...this.aliases.keys()];\n return [...builtIns, ...registered]\n .filter(name => name.startsWith(prefix) && name !== prefix)\n .sort();\n }\n}\n","/**\n * Quote-aware command tokenizer. Treats \"...\" as single tokens and strips enclosing quotes.\n */\nexport function tokenize(input: string): string[] {\n return (input.match(/(?:\"[^\"]*\"|\\S)+/g) ?? []).map(t => t.replace(/\"([^\"]*)\"/g, '$1'));\n}\n\nexport const CLEAR_USAGE =\n 'clear\\n\\n' +\n ' Clears the terminal history.\\n' +\n ' No arguments required.';\n\nexport const HELP_USAGE =\n 'help [command]\\n\\n' +\n ' With no arguments, lists all available commands.\\n' +\n ' With a command name, shows detailed usage for that command.\\n\\n' +\n ' Arguments:\\n' +\n ' [command] Optional command name to show detailed help for';\n","import { inject, Injectable, signal, computed, effect } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { z } from 'zod/v4';\nimport { CommandResult, CommandHistoryEntry, CommandScope, Severity, matchesRoute } from '../types/command.types';\nimport { tokenize, CLEAR_USAGE, HELP_USAGE } from '../commands/command.utils';\nimport { CommandRegistryService } from './command-registry.service';\nimport { AuthenticationService } from './authentication.service';\n\nexport type { CommandResult, CommandHistoryEntry, Severity };\n\nconst CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');\n\n@Injectable({ providedIn: 'root' })\nexport class CommandService {\n readonly history = signal<CommandHistoryEntry[]>([]);\n readonly currentInput = signal('');\n readonly isProcessing = signal(false);\n readonly helpOverlay = signal<string | null>(null);\n\n private readonly authService = inject(AuthenticationService);\n private readonly registry = inject(CommandRegistryService);\n private readonly router = inject(Router);\n\n constructor() {\n effect(() => {\n if (!this.authService.authenticated()) {\n this.history.set([]);\n }\n });\n }\n\n readonly lastResult = computed(() => {\n const h = this.history();\n return h.length > 0 ? h[h.length - 1].result : null;\n });\n\n dismissHelp(): void {\n this.helpOverlay.set(null);\n }\n\n echoCommand(input: string): void {\n if (this.#coalesce(input)) return;\n this.history.update(h => [...h, {\n input,\n result: { success: true, message: '', timestamp: new Date() },\n repeatCount: 1,\n }]);\n }\n\n pushNotification(notification: { message: string; severity: Severity }): void {\n this.history.update(h => [...h, {\n input: '',\n result: {\n success: notification.severity !== 'error',\n message: notification.message,\n timestamp: new Date(),\n severity: notification.severity,\n },\n }]);\n }\n\n execute(rawInput: string): void {\n const validation = CommandInputSchema.safeParse(rawInput);\n if (!validation.success) {\n this.history.update(h => [...h, {\n input: rawInput,\n result: { success: false, message: validation.error.issues[0].message, timestamp: new Date() },\n }]);\n this.currentInput.set('');\n return;\n }\n\n const input = validation.data;\n const parts = tokenize(input);\n const command = parts[0].toLowerCase();\n\n // Resolved rather than looked up by name: a command typed under an\n // alternate name must still get its own input sanitiser (a password line\n // masked under `login` stays masked under any other word for it).\n const def = this.registry.resolve(command)?.command;\n const displayInput = def?.sanitizeInput ? def.sanitizeInput(input) : input;\n\n const resultOrPromise = this.#dispatch(command, parts.slice(1));\n this.currentInput.set('');\n\n if (resultOrPromise instanceof Promise) {\n this.isProcessing.set(true);\n resultOrPromise\n .then(result => {\n if (result.isHelp && result.message) {\n this.helpOverlay.set(result.message);\n }\n const historyResult = result.isHelp ? { ...result, message: '' } : result;\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: historyResult, repeatCount: 1 }]);\n }\n })\n .finally(() => this.isProcessing.set(false));\n } else {\n if (resultOrPromise.isHelp && resultOrPromise.message) {\n this.helpOverlay.set(resultOrPromise.message);\n }\n const historyResult = resultOrPromise.isHelp ? { ...resultOrPromise, message: '' } : resultOrPromise;\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: historyResult, repeatCount: 1 }]);\n }\n }\n }\n\n #coalesce(input: string): boolean {\n if (!input) return false;\n const h = this.history();\n for (let i = h.length - 1; i >= 0; i--) {\n if (h[i].input) {\n if (h[i].input === input) {\n this.history.update(history => {\n const updated = [...history];\n updated[i] = { ...updated[i], repeatCount: (updated[i].repeatCount ?? 1) + 1 };\n return updated;\n });\n return true;\n }\n return false;\n }\n }\n return false;\n }\n\n #dispatch(command: string, args: string[]): CommandResult | Promise<CommandResult> {\n // Normalize \"help <command>\" → \"<command> help\" so auth and dispatch rules apply uniformly\n if (command === 'help' && args.length > 0 && args[0].toLowerCase() !== 'help') {\n [command, args] = [args[0].toLowerCase(), ['help']];\n }\n\n const hasHelp = args.some(a => a.toLowerCase() === 'help');\n const isAuthenticated = this.authService.authenticated();\n const notLoggedIn = (): CommandResult => ({\n success: false,\n message: 'Not logged in. Use \"login\" to authenticate.',\n timestamp: new Date(),\n });\n\n if (command === 'clear') {\n if (!isAuthenticated) return notLoggedIn();\n if (hasHelp) return { success: true, message: CLEAR_USAGE, timestamp: new Date(), isHelp: true };\n this.history.set([]);\n return { success: true, message: '', timestamp: new Date() };\n }\n\n if (command === 'help') {\n if (!isAuthenticated) return notLoggedIn();\n const target = args[0]?.toLowerCase();\n if (target) return this.#commandHelp(target);\n const registered = this.registry.getAll();\n const lines = [\n ' clear — Clear terminal history',\n ' help — List available commands',\n // Unavailable commands stay listed, annotated. Removing them would make\n // the CLI look broken rather than gated.\n // A command scoped to another screen stays listed too, with its screen\n // named rather than hidden (trades-tree.prd.md D31): hiding it would\n // read as a broken CLI.\n ...registered.map(c => {\n const availability = c.isAvailable?.();\n const suffix = availability && !availability.ok ? ` [unavailable — ${availability.reason}]` : this.#scopeSuffix(c.scope);\n return ` ${c.name} — ${c.description}${suffix}`;\n }),\n ];\n return {\n success: true,\n message: 'Available commands:\\n' + lines.join('\\n') + '\\n\\nType \"help <command>\" or \"<command> help\" for detailed usage.',\n timestamp: new Date(),\n isHelp: true,\n };\n }\n\n /*\n * Resolution, not a name lookup — `scan` and `scans` reach the scanner the\n * same way `scanner` does. An alternate may also carry leading words\n * (`scans NVDA` IS `scanner select NVDA`), which are inserted ahead of what\n * the user typed.\n *\n * ⭐ `command` keeps the word the USER typed. Every message below\n * interpolates it, and telling someone who typed `scan` that the arguments\n * of 'scanner' are wrong reads as though something else ran. The two-word\n * swap is the one deliberate exception, because there the typed first word\n * really was an argument.\n */\n let resolved = this.registry.resolve(command);\n if (resolved) {\n args = [...resolved.prependArgs, ...args];\n }\n let def = resolved?.command;\n if (!def) {\n // Try swapping the first two tokens: \"disable user foo\" → \"user disable foo\"\n const swapped = args[0]?.toLowerCase();\n const swappedResolved = swapped ? this.registry.resolve(swapped) : undefined;\n if (swappedResolved) {\n def = swappedResolved.command;\n args = [...swappedResolved.prependArgs, command, ...args.slice(1)];\n command = swapped!;\n } else {\n if (!isAuthenticated && command !== 'login') return notLoggedIn();\n return { success: false, message: `Unknown command: ${command}`, timestamp: new Date() };\n }\n }\n\n if (!isAuthenticated && command !== 'login' && def.requiresAuth !== false) {\n return notLoggedIn();\n }\n\n if (hasHelp) {\n // `help <command>` is normalised to `<command> help` above, so this is\n // the one place a command's usage is shown; the screen it works on goes\n // here (D31).\n return { success: true, message: def.usage + this.#whereNote(def.scope), timestamp: new Date(), isHelp: true };\n }\n\n // Screen gate (trades-tree.prd.md D30). A command bound to state only one\n // screen sets is refused off that screen with the screen named, the way\n // `tab` always did on its own. A command that navigates to its screen is\n // never refused here — declaring its routes is what lets `help` say where\n // it lives, and taking the user there is the handler's job (D32).\n if (def.scope !== 'global' && def.scope.elsewhere === 'refuse' && !matchesRoute(this.router.url, def.scope.routes)) {\n return {\n success: false,\n message: `'${command}' works on ${def.scope.screen}.`,\n severity: 'error',\n timestamp: new Date(),\n };\n }\n\n // Readiness gate. Deliberately ahead of argument validation: \"you can't use\n // this yet, here's why\" is more useful than a complaint about the arguments\n // of a command that wouldn't have run anyway.\n const availability = def.isAvailable?.();\n if (availability && !availability.ok) {\n return {\n success: false,\n message: availability.reason || `'${command}' is not available yet.`,\n severity: 'error',\n timestamp: new Date(),\n };\n }\n\n const validation = def.argsSchema.safeParse(args);\n if (!validation.success) {\n return { success: false, message: `Invalid arguments for '${command}': ${validation.error.issues[0].message}`, timestamp: new Date() };\n }\n\n return def.execute(args);\n }\n\n #commandHelp(name: string): CommandResult {\n if (name === 'clear') return { success: true, message: CLEAR_USAGE, timestamp: new Date(), isHelp: true };\n if (name === 'help') return { success: true, message: HELP_USAGE, timestamp: new Date(), isHelp: true };\n const def = this.registry.resolve(name)?.command;\n if (!def) return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };\n // Usage is still shown for a gated command — knowing how it works is how a\n // user decides whether it's worth unlocking. The gate is noted, not enforced.\n const availability = def.isAvailable?.();\n const note = availability && !availability.ok ? `\\n\\nCurrently unavailable — ${availability.reason}` : '';\n return { success: true, message: def.usage + this.#whereNote(def.scope) + note, timestamp: new Date(), isHelp: true };\n }\n\n /** \"Works on the Trades screen.\" — appended to a scoped command's usage. */\n #whereNote(scope: CommandScope): string {\n return scope === 'global' ? '' : `\\n\\nWorks on ${scope.screen}.`;\n }\n\n /** `help`'s annotation for a command scoped to a screen other than the current one. */\n #scopeSuffix(scope: CommandScope): string {\n if (scope === 'global' || matchesRoute(this.router.url, scope.routes)) return '';\n return ` [${scope.screen}]`;\n }\n}\n","import { Component, computed, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { SHELL_SHARED_SESSION } from '../../tokens/shell-tokens';\nimport { MatIconModule } from '@angular/material/icon';\n\n/** Roomy enough for the scanner beside a chart, small enough for a laptop. */\nconst POP_OUT_WIDTH = 1280;\nconst POP_OUT_HEIGHT = 900;\n\n@Component({\n selector: 'shell-status-bar',\n imports: [MatIconModule],\n templateUrl: './status-bar.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './status-bar.css',\n})\nexport class StatusBar {\n readonly #authService = inject(AuthenticationService);\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n\n readonly #sharedSession = inject(SHELL_SHARED_SESSION, { optional: true }) ?? false;\n\n readonly #phoneLayout = inject(PhoneLayoutService);\n\n readonly isAuthenticated = this.#authService.authenticated;\n\n /** The ☰ button: phones only, and only when there is a menu to open (signed in). */\n readonly showMenuButton = computed(() => this.#phoneLayout.isPhone() && this.isAuthenticated());\n readonly menuOpen = this.#phoneLayout.menuOpen;\n\n /**\n * Whether a second window is offered at all (multiple-windows PRD D14).\n *\n * ⚠ GATED ON SHARED SESSIONS, and this is a correctness gate rather than a\n * tidiness one. Without a session shared across windows, the new window starts\n * with no token, goes to the login screen, and signing in there ends the\n * session THIS window is using. A pop-out button in an app without sharing is\n * a button that signs you out — the exact failure the multiple-windows work\n * exists to remove.\n */\n readonly canPopOut = computed(() => this.#sharedSession && this.isAuthenticated());\n readonly loginStatus = computed(() =>\n this.#authService.authenticating()\n ? 'Authenticating...'\n : this.#authService.authenticated()\n ? 'Logged in'\n : 'Not logged in',\n );\n\n logout(): void {\n this.#authService.logout();\n this.#commandService.echoCommand('logout');\n this.#focusService.requestFocus();\n }\n\n /**\n * Open the screen you are on in a second, sized window.\n *\n * There is no mechanism by which this differs from the browser's own\n * \"Duplicate tab\": every window is a separate copy of the app started at some\n * address. It exists for the sizing and because it is discoverable — Ctrl+T,\n * a bookmark and dragging a tab out all work equally well once the session is\n * shared.\n *\n * `noopener` is deliberate. The new window needs nothing from this one — it\n * reads the session from storage — and leaving the opener reachable would give\n * two windows script access to each other for no purpose.\n */\n popOut(): void {\n if (typeof window === 'undefined') return;\n window.open(\n window.location.href,\n '_blank',\n `noopener,noreferrer,width=${POP_OUT_WIDTH},height=${POP_OUT_HEIGHT}`,\n );\n this.#focusService.requestFocus();\n }\n\n toggleMenu(): void {\n this.#phoneLayout.toggleMenu();\n }\n\n openFaq(): void {\n this.#commandService.execute('faq');\n this.#focusService.requestFocus();\n }\n}\n","<div class=\"status-bar\">\n @if (showMenuButton()) {\n <!-- Phone only (scanner-phone-display D9): the icon column is folded into this menu. -->\n <button\n type=\"button\"\n class=\"menu-button text-interactive\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-controls=\"shell-phone-menu\"\n aria-label=\"Menu\"\n ><mat-icon>menu</mat-icon></button>\n }\n <div class=\"status-item status-item-own\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n @if (canPopOut()) {\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"popOut()\"\n title=\"Open this screen in a second window\"\n aria-label=\"Open this screen in a second window\"\n >⧉</button>\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandService } from '../../services/command.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\nimport { TerminalVisibilityService } from '../../services/terminal-visibility.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { SHELL_MENU_ITEMS } from '../../tokens/shell-tokens';\nimport { MenuItem } from '../../types/menu.types';\n\nexport { MenuItem };\n\n@Component({\n selector: 'shell-side-menu',\n imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule],\n templateUrl: './side-menu.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './side-menu.css',\n})\nexport class SideMenu {\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly #terminalVisibility = inject(TerminalVisibilityService);\n readonly hasShortcuts = this.#shortcutService.activeShortcuts;\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly terminalVisible = this.#terminalVisibility.visible;\n\n /**\n * Phone-menu rendering (scanner-phone-display D9): the same items as the icon\n * column, each with its label as visible text — a tooltip needs a hover a\n * touch screen does not have.\n *\n * ⚠ The keyboard-shortcuts button (Alt+?) is left out here. It opens a list of\n * Alt-key bindings, and a phone has no Alt key. The shortcuts themselves are\n * untouched — they are document-level listeners and work from a hardware\n * keyboard whatever the layout.\n *\n * The console show/hide button stays (Franz, 2026-10-17: the console is back\n * on phones, reversing 0.8.1). Turning the console ON from here does not put\n * the cursor in the command box on a phone — see CommandTerminal.focusOnAppear.\n */\n readonly drawer = input(false);\n\n readonly #allMenuItems: MenuItem[] = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];\n\n readonly menuItems = computed(() =>\n this.#allMenuItems.filter(item => !item.visible || item.visible()),\n );\n\n /**\n * Readiness, not entitlement — an unentitled item never reaches here, having\n * been filtered out by `visible` above. Read from the template so the\n * predicate's signal reads are tracked and the strip regreys live when the\n * user's state changes.\n */\n isEnabled(item: MenuItem): boolean {\n return !item.enabled || item.enabled();\n }\n\n disabledReasonFor(item: MenuItem): string {\n return item.disabledReason?.() ?? item.label;\n }\n\n onMenuClick(item: MenuItem): void {\n if (item.command) {\n this.#commandService.echoCommand(item.command);\n }\n if (this.drawer()) {\n // ⚠ No terminal focus from the phone menu. Focusing the command box on a\n // phone raises the on-screen keyboard over half the screen you just\n // navigated to.\n this.#phoneLayout.closeMenu();\n return;\n }\n this.#focusService.requestFocus();\n }\n\n toggleHelp(): void {\n this.#shortcutService.toggleHelp();\n }\n\n toggleTerminal(): void {\n this.#terminalVisibility.toggle();\n // ⚠ No terminal focus here either: on a phone, showing the console is not a\n // request to type. The menu closes so the user sees the console appear.\n if (this.drawer()) this.#phoneLayout.closeMenu();\n }\n}\n","<nav class=\"side-menu\" [class.drawer]=\"drawer()\" [attr.aria-label]=\"drawer() ? 'Menu' : null\">\n @for (item of menuItems(); track item.route) {\n @if (isEnabled(item)) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">{{ item.label }}</span>\n }\n </a>\n } @else {\n <!-- No routerLink: the item is inert. Pointer events stay live (see the\n .disabled rule) so the tooltip still fires — it carries the only\n explanation the user gets. In the phone menu the explanation is shown\n as text instead, since there is no hover to fire it. -->\n <span\n class=\"menu-item disabled\"\n [matTooltip]=\"disabledReasonFor(item)\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n aria-disabled=\"true\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">\n {{ item.label }}\n <span class=\"menu-reason\">{{ disabledReasonFor(item) }}</span>\n </span>\n }\n </span>\n }\n }\n <div class=\"menu-spacer\"></div>\n <button\n class=\"menu-item terminal-toggle\"\n type=\"button\"\n [class.active]=\"terminalVisible()\"\n [matTooltip]=\"terminalVisible() ? 'Hide command console' : 'Show command console'\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n [attr.aria-pressed]=\"terminalVisible()\"\n (click)=\"toggleTerminal()\"\n >\n <mat-icon>terminal</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">{{ terminalVisible() ? 'Hide command console' : 'Show command console' }}</span>\n }\n </button>\n @if (hasShortcuts() && !drawer()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n","import { Component, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\n\n@Component({\n selector: 'shell-main-content',\n imports: [RouterOutlet, MatProgressSpinnerModule],\n templateUrl: './main-content.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './main-content.css',\n})\nexport class MainContent {\n readonly #thinkingService = inject(ThinkingService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly shortcutHelpVisible = this.#shortcutService.helpVisible;\n readonly activeShortcuts = this.#shortcutService.activeShortcuts;\n\n formatKey(key: string): string {\n const keyMap: Record<string, string> = {\n ArrowUp: '↑', ArrowDown: '↓', ArrowLeft: '←', ArrowRight: '→',\n PageUp: 'PgUp', PageDown: 'PgDn',\n };\n return keyMap[key] ?? key;\n }\n\n closeShortcutHelp(): void {\n this.#shortcutService.helpVisible.set(false);\n }\n}\n","<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <!--\n Esc is documented rather than added (scanner-command-speed.prd.md D24/E4).\n It has always put the cursor in the command box, from anywhere and even\n while typing in a field — it was simply never written down, which is why\n it read as a missing feature. Worded for what it actually does: it also\n closes this panel, and it does not check whether a dialog is open.\n -->\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-text-primary\">Put the cursor in the command box, from anywhere</span>\n </div>\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n","import { Component, inject, input, ElementRef, viewChild, effect, afterNextRender, computed, ChangeDetectionStrategy } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommandService } from '../../services/command.service';\nimport { CommandRegistryService } from '../../services/command-registry.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { CommandResult } from '../../types/command.types';\n\n@Component({\n selector: 'shell-command-terminal',\n imports: [FormsModule],\n templateUrl: './command-terminal.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './command-terminal.css',\n})\nexport class CommandTerminal {\n private readonly commandService = inject(CommandService);\n private readonly registry = inject(CommandRegistryService);\n private readonly authService = inject(AuthenticationService);\n private readonly terminalFocusService = inject(TerminalFocusService);\n readonly #phoneLayout = inject(PhoneLayoutService);\n\n /**\n * Whether the command box takes the cursor when the console first appears.\n *\n * True for a standalone console. The shell passes false on a phone (below\n * 820px), including when the user turns the console on from the ☰ menu:\n * showing the console is not a request to type, and focusing the box would\n * raise the on-screen keyboard over it (scanner-phone-display D10). On a\n * phone, focusInput() refuses anyway; this keeps the intent explicit.\n */\n readonly focusOnAppear = input(true);\n\n readonly history = computed(() => [...this.commandService.history()].reverse());\n readonly currentInput = this.commandService.currentInput;\n readonly isProcessing = this.commandService.isProcessing;\n\n private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('terminalInput');\n\n private tabCycleIndex = -1;\n private lastTabPrefix = '';\n\n readonly ghostText = computed(() => {\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return '';\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n return suggestions.length > 0 ? suggestions[0] : '';\n });\n\n constructor() {\n afterNextRender(() => {\n if (this.focusOnAppear()) this.focusInput();\n });\n\n // Both effects below skip their first run. An effect runs once when it is\n // created, so without the skip each would focus the box on appearance a\n // second and third time — after `focusOnAppear` had said not to. Appearance\n // is the afterNextRender above's job alone; these react to CHANGES.\n let firstProcessingRun = true;\n effect(() => {\n const busy = this.isProcessing();\n if (firstProcessingRun) {\n firstProcessingRun = false;\n return;\n }\n if (!busy) {\n setTimeout(() => this.focusInput());\n }\n });\n\n let firstRequestRun = true;\n effect(() => {\n this.terminalFocusService.focusRequested();\n if (firstRequestRun) {\n firstRequestRun = false;\n return;\n }\n setTimeout(() => this.focusInput());\n });\n }\n\n onSubmit(): void {\n const input = this.currentInput();\n if (!input.trim()) return;\n this.commandService.execute(input);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n this.focusInput();\n }\n\n onInputChange(value: string): void {\n this.currentInput.set(value);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n if (this.commandService.helpOverlay()) {\n this.commandService.dismissHelp();\n }\n }\n\n dismissHelp(): void {\n this.commandService.dismissHelp();\n }\n\n onTab(event: KeyboardEvent): void {\n event.preventDefault();\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return;\n\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n if (suggestions.length === 0) return;\n\n if (suggestions.length === 1) {\n this.currentInput.set(suggestions[0] + ' ');\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n return;\n }\n\n if (this.lastTabPrefix !== prefix) {\n this.lastTabPrefix = prefix;\n this.tabCycleIndex = -1;\n }\n\n if (event.shiftKey) {\n this.tabCycleIndex = this.tabCycleIndex <= 0 ? suggestions.length - 1 : this.tabCycleIndex - 1;\n } else {\n this.tabCycleIndex = (this.tabCycleIndex + 1) % suggestions.length;\n }\n\n this.currentInput.set(suggestions[this.tabCycleIndex]);\n }\n\n getSeverityClass(result: CommandResult): string {\n if (result.severity === 'info') return 'info';\n if (result.severity === 'warning') return 'warning';\n if (result.severity === 'error' || !result.success) return 'error';\n return '';\n }\n\n /**\n * ⚠ A no-op on a phone (scanner-phone-display D10/E11). The console is shown\n * there, but only the user tapping the box may give it the cursor; every\n * programmatic path (first appearance, a finished command, a focus request,\n * an app calling this) ends here and is refused, so nothing on a phone can\n * raise the on-screen keyboard unasked.\n */\n focusInput(): void {\n if (this.#phoneLayout.isPhone()) return;\n this.inputEl()?.nativeElement.focus();\n }\n}\n","<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"dismissHelp()\"\n placeholder=\"Type a command...\"\n [disabled]=\"isProcessing()\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(×{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n","import { Component, computed, effect, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { StatusBar } from '../status-bar/status-bar';\nimport { SideMenu } from '../side-menu/side-menu';\nimport { MainContent } from '../main-content/main-content';\nimport { CommandTerminal } from '../command-terminal/command-terminal';\nimport { FaqModal } from '../../faq/faq-modal/faq-modal';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { CommandService } from '../../services/command.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalVisibilityService } from '../../services/terminal-visibility.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { CdkTrapFocus } from '@angular/cdk/a11y';\n\nconst MIN_TERMINAL_HEIGHT = 80;\nconst MAX_TERMINAL_RATIO = 0.6;\nconst DEFAULT_TERMINAL_HEIGHT = 160;\n/**\n * How often a signed-in window re-reads whether the AWS-set bypass is on\n * (authenticator-sign-in.prd.md D12). The server never says when it ends, so the\n * banner goes away on the first read after it has.\n */\nconst BYPASS_RECHECK_MS = 2 * 60 * 1000;\n\n@Component({\n selector: 'shell-root',\n imports: [StatusBar, SideMenu, MainContent, CommandTerminal, FaqModal, CdkTrapFocus],\n templateUrl: './shell.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './shell.css',\n})\nexport class Shell {\n readonly #thinkingService = inject(ThinkingService);\n readonly #commandService = inject(CommandService);\n readonly #authService = inject(AuthenticationService);\n readonly #terminalVisibility = inject(TerminalVisibilityService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly isAuthenticated = this.#authService.authenticated;\n readonly helpOverlay = this.#commandService.helpOverlay;\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly terminalVisible = this.#terminalVisibility.visible;\n /** Below 820px the icon column is replaced by the ☰ menu (scanner-phone-display D9). */\n readonly isPhone = this.#phoneLayout.isPhone;\n readonly phoneMenuOpen = this.#phoneLayout.menuOpen;\n\n /**\n * Whether the command box takes the cursor when the console appears: on a\n * desktop yes, on a phone never (scanner-phone-display D10, Franz 2026-10-17).\n *\n * The console is shown on a phone again (reversing 0.8.1), but nothing may\n * put the cursor in its box there — the on-screen keyboard would cover the\n * screen. That includes the user turning the console ON from the ☰ menu: a\n * show is not a request to type, and the keyboard rising over the console the\n * moment it appears would hide the output the user wanted to see. Tapping the\n * box is the only way it gets the cursor on a phone.\n *\n * Rotating across 820px never mounts or unmounts the console (its visibility\n * is the user's choice alone), so this is only read when the user turns it on\n * or at start-up. CommandTerminal.focusInput also refuses on a phone, as a\n * second guard.\n */\n readonly consoleFocusOnAppear = computed(() => !this.isPhone());\n\n /** \"Sign-in code check is off.\" on every screen while the bypass is on (D12). */\n readonly bypassActive = this.#authService.bypassActive;\n\n /**\n * Keeps `bypassActive` current while signed in: once now (a window restored from\n * storage never saw the sign-in response) and then every two minutes.\n */\n readonly #bypassWatch = effect(onCleanup => {\n if (!this.isAuthenticated()) return;\n const read = () => { this.#authService.authenticatorStatus().catch(() => undefined); };\n read();\n const timer = setInterval(read, BYPASS_RECHECK_MS);\n onCleanup(() => clearInterval(timer));\n });\n\n closePhoneMenu(): void {\n this.#phoneLayout.closeMenu();\n }\n\n dismissHelp(): void {\n this.#commandService.dismissHelp();\n }\n readonly terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`);\n readonly isDragging = signal(false);\n\n #startY = 0;\n #startHeight = DEFAULT_TERMINAL_HEIGHT;\n\n #resizeTo(clientY: number): void {\n const deltaY = clientY - this.#startY;\n const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);\n const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));\n this.terminalHeight.set(`${newHeight}px`);\n }\n\n readonly #onMouseMove = (event: MouseEvent) => this.#resizeTo(event.clientY);\n\n readonly #onMouseUp = () => {\n this.isDragging.set(false);\n document.removeEventListener('mousemove', this.#onMouseMove);\n document.removeEventListener('mouseup', this.#onMouseUp);\n };\n\n onResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.#startY = event.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('mousemove', this.#onMouseMove);\n document.addEventListener('mouseup', this.#onMouseUp);\n }\n\n // Touch drag for the resize bar (scanner-phone-display E12): tablets and,\n // since the console is back there (D10, 2026-10-17), phones. Kept separate from the mouse path so the desktop's behaviour is unchanged;\n // the bar's `touch-action: none` stops the page scrolling under the finger.\n readonly #onTouchMove = (event: TouchEvent) => {\n const touch = event.touches[0];\n if (touch) this.#resizeTo(touch.clientY);\n };\n\n readonly #onTouchEnd = () => {\n this.isDragging.set(false);\n document.removeEventListener('touchmove', this.#onTouchMove);\n document.removeEventListener('touchend', this.#onTouchEnd);\n document.removeEventListener('touchcancel', this.#onTouchEnd);\n };\n\n onResizeTouchStart(event: TouchEvent): void {\n const touch = event.touches[0];\n if (!touch || event.touches.length > 1) return;\n this.#startY = touch.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('touchmove', this.#onTouchMove);\n document.addEventListener('touchend', this.#onTouchEnd);\n document.addEventListener('touchcancel', this.#onTouchEnd);\n }\n}\n","<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\" [class.terminal-hidden]=\"!terminalVisible()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated() && !isPhone()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n @if (terminalVisible()) {\n <!-- On a phone too (scanner-phone-display D10), but never given the cursor there: see Shell.consoleFocusOnAppear. -->\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" [focusOnAppear]=\"consoleFocusOnAppear()\" />\n }\n @if (isAuthenticated() && phoneMenuOpen()) {\n <!-- Phone menu (scanner-phone-display D9): the icon column's items, opened from the ☰ button. -->\n <div class=\"phone-menu-backdrop\" (click)=\"closePhoneMenu()\"></div>\n <shell-side-menu\n id=\"shell-phone-menu\"\n class=\"phone-menu\"\n [class.disabled-zone]=\"isThinking()\"\n [drawer]=\"true\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Menu\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n (keydown.escape)=\"closePhoneMenu()\"\n />\n }\n @if (isAuthenticated() && bypassActive()) {\n <!-- authenticator-sign-in.prd.md D12: cannot be dismissed; no end time (the server never sends one). -->\n <div class=\"bypass-banner\" role=\"status\">Sign-in code check is off.</div>\n }\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">✕</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words — e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nThe 10 recovery codes, shown ONCE (authenticator-sign-in.prd.md D7), with Download (a text file made\nin the browser — nothing is stored on the server as a file) and Copy. \"Continue\" is the only way on,\nso the codes cannot scroll past unseen.\n*/\n\nimport { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { recoveryCodesFile } from '../../services/authenticator.types';\n\n@Component({\n selector: 'shell-recovery-codes',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MatButtonModule, MatIconModule],\n template: `\n <div class=\"recovery-codes\">\n <p class=\"recovery-codes-lead text-text-primary\"><strong>Save your recovery codes.</strong></p>\n <p class=\"text-secondary-info\">\n Each one works once, in place of the 6-digit code, if you lose your phone.\n They will not be shown again.\n </p>\n <ol class=\"recovery-codes-list\">\n @for (code of codes(); track code) {\n <li><code>{{ code }}</code></li>\n }\n </ol>\n <div class=\"recovery-codes-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"download()\">\n <mat-icon>download</mat-icon> Download\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"copy()\">\n <mat-icon>content_copy</mat-icon> {{ copied() ? 'Copied' : 'Copy' }}\n </button>\n <button mat-flat-button type=\"button\" (click)=\"done.emit()\">I have saved them — continue</button>\n </div>\n </div>\n `,\n styles: [`\n .recovery-codes { max-width: 360px; padding: 12px 16px; border-radius: 4px; background-color: var(--color-surface-light); text-align: left; font-size: 0.9rem; }\n .recovery-codes p { margin: 0 0 8px 0; }\n .recovery-codes-list { columns: 2; margin: 8px 0 12px 0; padding-left: 1.5em; font-family: var(--shell-mono, monospace); }\n .recovery-codes-list li { margin: 2px 0; }\n .recovery-codes-actions { display: flex; flex-wrap: wrap; gap: 8px; }\n `],\n})\nexport class RecoveryCodes {\n readonly codes = input.required<readonly string[]>();\n readonly appName = input('BrokenStock');\n readonly username = input<string | undefined>(undefined);\n readonly done = output<void>();\n protected readonly copied = signal(false);\n\n download(): void {\n const text = recoveryCodesFile(this.appName(), this.username(), this.codes());\n const url = URL.createObjectURL(new Blob([text], {type: 'text/plain'}));\n const a = document.createElement('a');\n a.href = url;\n a.download = `${this.appName().toLowerCase().replace(/[^a-z0-9]+/g, '-')}-recovery-codes.txt`;\n a.click();\n setTimeout(() => URL.revokeObjectURL(url));\n }\n\n copy(): void {\n navigator.clipboard?.writeText(this.codes().join('\\n')).then(() => this.copied.set(true)).catch(() => undefined);\n }\n}\n","import { Component, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AutofillEvent, TextFieldModule } from '@angular/cdk/text-field';\nimport { Credentials, SessionSummary, validateCredentials } from '@franzzemen/identity';\nimport { PASSWORD_REGEX, USERNAME_REGEX } from '@franzzemen/utility';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatInput, MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatIconModule } from '@angular/material/icon';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { DatePipe } from '@angular/common';\nimport { AuthenticationService, CODE_STEP, LoginChoice } from '../../services/authentication.service';\nimport { RecoveryCodes } from '../recovery-codes/recovery-codes';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { RegexValidatorDirective } from '../../directives/regex-validator.directive';\nimport { SHELL_APP_NAME, SHELL_POST_LOGIN_ROUTE } from '../../tokens/shell-tokens';\n\n@Component({\n selector: 'shell-login',\n templateUrl: './login.html',\n styleUrl: './login.css',\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [\n FormsModule,\n MatFormField,\n MatLabel,\n MatInput,\n MatInputModule,\n MatButtonModule,\n MatCheckboxModule,\n MatIconModule,\n RegexValidatorDirective,\n TextFieldModule,\n DatePipe,\n RecoveryCodes,\n ],\n})\nexport class Login {\n model: Credentials = { username: '', password: '' };\n submitted = false;\n hide = signal(true);\n errors: { ndx: number; message: string }[] = [];\n\n /**\n * Session identifiers the user has ticked for ending (multiple-devices D7).\n *\n * ⚠ THE TAKEOVER CHECKBOX THAT USED TO LIVE ON THIS FORM IS GONE, and its\n * removal is the point rather than a tidy-up. It defaulted to ON and sat on\n * the FIRST form, before anything was known about what was live — so once a\n * user deliberately holds sessions on two machines, one absent-minded submit\n * ended the session on the machine in the other room. The choice belongs\n * here, on the screen that lists what is actually running.\n */\n readonly selected = signal<ReadonlySet<string>>(new Set());\n\n /** The code or recovery code typed on the code step (authenticator-sign-in.prd.md). */\n codeText = '';\n /** Typing a recovery code instead of the 6-digit code. */\n readonly useRecovery = signal(false);\n\n protected readonly USERNAME_REGEX = USERNAME_REGEX;\n protected readonly PASSWORD_REGEX = PASSWORD_REGEX;\n protected readonly appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';\n readonly #postLoginRoute = inject(SHELL_POST_LOGIN_ROUTE, { optional: true }) ?? '/';\n\n readonly #commandService = inject(CommandService);\n readonly #terminalFocusService = inject(TerminalFocusService);\n\n readonly #activatedRoute = inject(ActivatedRoute);\n\n constructor(\n protected authenticationService: AuthenticationService,\n protected router: Router,\n ) {}\n\n /**\n * Returns the post-login destination. Honors a `returnUrl` query param if\n * present and safe (same-origin, leading `/`, not protocol-relative);\n * otherwise falls back to `SHELL_POST_LOGIN_ROUTE`.\n */\n #resolvePostLoginUrl(): string {\n const candidate = this.#activatedRoute.snapshot.queryParamMap.get('returnUrl');\n if (!candidate) return this.#postLoginRoute;\n if (!candidate.startsWith('/')) return this.#postLoginRoute;\n if (candidate.startsWith('//')) return this.#postLoginRoute;\n if (/^https?:\\/\\//i.test(candidate)) return this.#postLoginRoute;\n return candidate;\n }\n\n onAutofill(event: AutofillEvent, inputEl: HTMLInputElement): void {\n if (event.isAutofilled) {\n setTimeout(() => {\n const length = inputEl.value.length;\n inputEl.setSelectionRange(length, length);\n });\n }\n }\n\n clickEvent(event: MouseEvent): void {\n this.hide.set(!this.hide());\n event.stopPropagation();\n }\n\n onSubmit(event: Event): void {\n this.errors = [];\n event.preventDefault();\n this.submitted = true;\n const result = validateCredentials(this.model);\n if (result === true) {\n // A first attempt makes no claim about other sessions. If any exist the\n // server refuses, and the conflict panel below is where the decision is\n // made — with the sessions on screen.\n this.#doLogin(false);\n } else {\n for (let ndx = 0; ndx < result.length; ndx++) {\n this.errors.push({\n ndx,\n message: `${result[ndx].message ?? 'Unknown error'}: ${result[ndx].field ?? 'Unknown field'} ${result[ndx].type ?? 'Unknown type'} Expected: ${result[ndx].expected} Actual: ${result[ndx].actual}`,\n });\n }\n this.submitted = false;\n }\n }\n\n /** Whether individual sessions can be ticked: only when the server named them. */\n canEndIndividually(): boolean {\n return (this.authenticationService.conflictSessions() ?? []).some(s => !!s.sessionId);\n }\n\n isSelected(session: SessionSummary): boolean {\n return !!session.sessionId && this.selected().has(session.sessionId);\n }\n\n toggleSelected(session: SessionSummary, checked: boolean): void {\n if (!session.sessionId) return;\n const next = new Set(this.selected());\n if (checked) next.add(session.sessionId); else next.delete(session.sessionId);\n this.selected.set(next);\n }\n\n selectedCount(): number {\n return this.selected().size;\n }\n\n /**\n * What to call a session on screen.\n *\n * Falls back to the application name, which is what this screen showed before\n * devices were recorded, and then to something plainly non-committal. It never\n * invents a device: a session that predates the column genuinely has none, and\n * guessing would make two machines look like one.\n */\n deviceLabel(session: SessionSummary): string {\n return session.deviceDescription ?? session.appContext ?? 'Another session';\n }\n\n onTakeOver(): void {\n this.errors = [];\n this.selected.set(new Set());\n // ⚠ This used to hand the terminal `login --force`, with no username or\n // password on it — the terminal's login command reads its credentials from\n // the words typed after it, found none, and answered \"Invalid syntax\". The\n // credentials the user already typed are on this form; sign in with them,\n // the same way the other two buttons here do.\n this.#doLogin(true);\n }\n\n onSignInAsWell(): void {\n this.errors = [];\n this.selected.set(new Set());\n this.#doLogin(false, {additional: true});\n }\n\n onEndSelected(): void {\n this.errors = [];\n const ids = [...this.selected()];\n this.selected.set(new Set());\n this.#doLogin(false, {endSessionIds: ids});\n }\n\n /** The code step: the 6-digit code (or a recovery code), with the credentials already accepted. */\n onSubmitCode(event: Event): void {\n event.preventDefault();\n this.errors = [];\n const typed = this.codeText.trim();\n if (!typed) return;\n this.submitted = true;\n this.#doLogin(false, this.useRecovery() ? {recoveryCode: typed} : {code: typed});\n }\n\n onToggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.codeText = '';\n this.errors = [];\n }\n\n /** Back to the password form. */\n onCancelCode(): void {\n this.authenticationService.cancelCodeStep();\n this.codeText = '';\n this.useRecovery.set(false);\n this.errors = [];\n this.submitted = false;\n }\n\n /** New recovery codes were shown after sign-in; now go where sign-in was going. */\n onRecoveryCodesSaved(): void {\n this.authenticationService.acknowledgeRecoveryCodes();\n // Setup can finish on an attempt that then stops at \"already signed in\n // elsewhere\": the codes are shown first, and the session choice is still open.\n if (this.authenticationService.authenticated()) this.#navigateAfterLogin();\n }\n\n onCancelConflict(): void {\n this.authenticationService.clearConflict();\n this.selected.set(new Set());\n this.submitted = false;\n }\n\n #doLogin(force: boolean, choice: LoginChoice = {}): void {\n this.authenticationService\n .login(this.model, force, choice)\n .then(() => {\n this.#commandService.echoCommand(`login ${this.model.username}`);\n this.codeText = '';\n this.useRecovery.set(false);\n // Setup finished during this sign-in: the codes are on screen and must be\n // seen before the app takes over the page.\n if (this.authenticationService.recoveryCodesToShow()) {\n this.submitted = false;\n return;\n }\n this.#navigateAfterLogin();\n })\n .catch((err) => {\n if (err !== 'conflict' && err !== CODE_STEP) {\n this.errors.push({ ndx: 0, message: typeof err === 'string' ? err : 'Unable to login' });\n }\n this.codeText = '';\n this.submitted = false;\n });\n }\n\n #navigateAfterLogin(): void {\n this.router.navigateByUrl(this.#resolvePostLoginUrl()).then(() => {\n setTimeout(() => this.#terminalFocusService.requestFocus());\n }).catch(console.error);\n }\n}\n","@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n @let step = authenticationService.codeStep();\n @if (authenticationService.recoveryCodesToShow(); as codes) {\n <shell-recovery-codes [codes]=\"codes\" [appName]=\"appName\" [username]=\"model.username\" (done)=\"onRecoveryCodesSaved()\" />\n } @else if (step !== 'none') {\n <form (submit)=\"onSubmitCode($event)\" class=\"login-form\" aria-label=\"Authenticator code\">\n @if (step === 'setup' && authenticationService.setupChallenge(); as challenge) {\n <p class=\"text-secondary-info login-code-lead\">\n Set up your authenticator: scan this with Google Authenticator (or Authy, 1Password),\n then enter the 6-digit code it shows.\n </p>\n <img class=\"login-qr\" [src]=\"challenge.qr\" alt=\"QR code for your authenticator app\" width=\"200\" height=\"200\" />\n <p class=\"text-secondary-info login-key\">Can't scan? Enter this key: <code>{{ challenge.key }}</code></p>\n } @else {\n <p class=\"text-secondary-info login-code-lead\">\n @if (useRecovery()) {\n Enter one of your recovery codes.\n } @else {\n Enter the 6-digit code from your authenticator app.\n }\n </p>\n }\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Code' }}</mat-label>\n <input\n matInput\n name=\"code\"\n [(ngModel)]=\"codeText\"\n [disabled]=\"submitted\"\n [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\"\n [attr.maxlength]=\"useRecovery() ? 16 : 7\"\n [placeholder]=\"useRecovery() ? 'xxxxx-xxxxx' : '123456'\"\n autofocus\n />\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n {{ step === 'setup' ? 'Finish setup and sign in' : 'Sign in' }}\n </button>\n <div class=\"login-code-links\">\n @if (step === 'code') {\n <button mat-button type=\"button\" (click)=\"onToggleRecovery()\">\n {{ useRecovery() ? 'Use the 6-digit code' : 'Use a recovery code' }}\n </button>\n }\n <button mat-button type=\"button\" (click)=\"onCancelCode()\">Back</button>\n </div>\n </form>\n } @else {\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n }\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n <p class=\"text-secondary-info\">\n You are already signed in {{ sessions.length === 1 ? 'somewhere else' : 'on other devices' }}:\n </p>\n @for (session of sessions; track session.sessionId ?? $index) {\n <div class=\"login-conflict-session\">\n @if (canEndIndividually()) {\n <mat-checkbox\n [checked]=\"isSelected(session)\"\n [disabled]=\"!session.sessionId\"\n (change)=\"toggleSelected(session, $event.checked)\"\n [attr.aria-label]=\"'End ' + deviceLabel(session)\"\n ></mat-checkbox>\n }\n <span class=\"text-secondary-info\">\n <strong>{{ deviceLabel(session) }}</strong>\n <!-- signedInAtEpoch is when the password was typed. startEpoch is\n when the row was written, which renewal resets — so it is shown\n only when there is nothing better, and labelled for what it is. -->\n @if (session.signedInAtEpoch) {\n — since {{ session.signedInAtEpoch | date:'short' }}\n } @else {\n — last active {{ session.startEpoch | date:'short' }}\n }\n </span>\n </div>\n }\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n @if (selectedCount() > 0) {\n <button mat-stroked-button type=\"button\" (click)=\"onEndSelected()\">\n End {{ selectedCount() === 1 ? 'that one' : selectedCount() + ' of them' }} and sign in\n </button>\n }\n <button mat-stroked-button type=\"button\" (click)=\"onTakeOver()\">\n {{ sessions.length === 1 ? 'End it and sign in' : 'End them all and sign in' }}\n </button>\n @if (authenticationService.additionalSignInAllowed()) {\n <button mat-flat-button type=\"button\" (click)=\"onSignInAsWell()\">Sign in here as well</button>\n }\n </div>\n </div>\n }\n</div>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nSettings → Sign-in code (authenticator-sign-in.prd.md D5, D7). Shared by every app: each routes to\n`AuthenticatorSettings` wherever its settings live.\n\n - Set up an authenticator (or replace one): the password again, plus a current code or a\n recovery code when replacing → QR + typed-in key → the first code → 10 recovery codes.\n - New recovery codes: a current code → 10 new ones; the old ones stop working.\n\n⛔ There is deliberately no \"remove\" and no \"turn off\" here (D13). Those are AWS-only; the screen\nsays how to get them done.\n*/\n\nimport { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { AuthenticationService, AuthenticatorError } from '../../services/authentication.service';\nimport { AuthenticatorStatus, SetupChallenge } from '../../services/authenticator.types';\nimport { SHELL_APP_NAME } from '../../tokens/shell-tokens';\nimport { RecoveryCodes } from '../recovery-codes/recovery-codes';\n\ntype Mode = 'view' | 'password' | 'scan' | 'reissue' | 'codes';\n\n@Component({\n selector: 'shell-authenticator-settings',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, MatButtonModule, MatFormFieldModule, MatInputModule, RecoveryCodes],\n templateUrl: './authenticator-settings.html',\n styleUrl: './authenticator-settings.css',\n})\nexport class AuthenticatorSettings implements OnInit {\n readonly #auth = inject(AuthenticationService);\n protected readonly appName = inject(SHELL_APP_NAME, {optional: true}) ?? 'BrokenStock';\n\n protected readonly status = signal<AuthenticatorStatus | undefined>(undefined);\n protected readonly mode = signal<Mode>('view');\n protected readonly busy = signal(false);\n protected readonly error = signal<string | undefined>(undefined);\n protected readonly challenge = signal<SetupChallenge | undefined>(undefined);\n protected readonly codes = signal<string[] | undefined>(undefined);\n protected readonly useRecovery = signal(false);\n\n password = '';\n code = '';\n\n ngOnInit(): void {\n void this.#load();\n }\n\n async #load(): Promise<void> {\n try {\n this.status.set(await this.#auth.authenticatorStatus());\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Could not load your sign-in code settings.');\n }\n }\n\n begin(mode: 'password' | 'reissue'): void {\n this.#reset();\n this.mode.set(mode);\n }\n\n cancel(): void {\n this.#reset();\n this.mode.set('view');\n }\n\n toggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.code = '';\n }\n\n /** Password (and current code when replacing) → QR. */\n async start(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n const current = this.status()?.enrolled\n ? (this.useRecovery() ? {recoveryCode: this.code.trim()} : {code: this.code.trim()})\n : {};\n this.challenge.set(await this.#auth.startAuthenticatorSetup(this.password, current));\n this.password = '';\n this.code = '';\n this.useRecovery.set(false);\n this.mode.set('scan');\n });\n }\n\n /** The first code from the newly scanned app → recovery codes. */\n async confirm(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n this.codes.set(await this.#auth.confirmAuthenticatorSetup(this.code.trim()));\n this.challenge.set(undefined);\n this.code = '';\n this.mode.set('codes');\n });\n }\n\n async reissue(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n this.codes.set(await this.#auth.reissueRecoveryCodes(this.code.trim()));\n this.code = '';\n this.mode.set('codes');\n });\n }\n\n async codesSaved(): Promise<void> {\n this.#reset();\n this.mode.set('view');\n await this.#load();\n }\n\n async #run(work: () => Promise<void>): Promise<void> {\n this.busy.set(true);\n this.error.set(undefined);\n try {\n await work();\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Something went wrong');\n this.code = '';\n } finally {\n this.busy.set(false);\n }\n }\n\n #reset(): void {\n this.password = '';\n this.code = '';\n this.error.set(undefined);\n this.challenge.set(undefined);\n this.codes.set(undefined);\n this.useRecovery.set(false);\n }\n}\n","<section class=\"authenticator-settings\">\n <h2 class=\"text-text-primary\">Sign-in code</h2>\n <p class=\"text-secondary-info\">\n Signing in asks for your password and a 6-digit code from an authenticator app on your phone\n (Google Authenticator, Authy, 1Password).\n </p>\n\n @if (status(); as s) {\n @switch (mode()) {\n @case ('view') {\n <dl class=\"authenticator-facts\">\n <dt>Authenticator</dt>\n <dd>{{ s.enrolled ? 'Set up' : 'Not set up' }}</dd>\n @if (s.enrolled) {\n <dt>Recovery codes left</dt>\n <dd [class.text-loss]=\"s.recoveryCodesLeft <= 2\">{{ s.recoveryCodesLeft }} of 10</dd>\n }\n <dt>Code required at sign-in</dt>\n <dd>{{ s.enrolled ? 'Yes' : (s.codeRequired ? 'Yes' : 'Not yet — set one up') }}</dd>\n </dl>\n <div class=\"authenticator-actions\">\n <button mat-flat-button type=\"button\" (click)=\"begin('password')\">\n {{ s.enrolled ? 'Replace authenticator' : 'Set up authenticator' }}\n </button>\n @if (s.enrolled) {\n <button mat-stroked-button type=\"button\" (click)=\"begin('reissue')\">New recovery codes</button>\n }\n </div>\n <p class=\"text-secondary-info authenticator-note\">\n Lost your phone? Sign in with a recovery code, then replace the authenticator here.\n No recovery codes left? Only the administrator can reset it, from AWS — there is no way\n to switch the code off from inside the app.\n </p>\n }\n\n @case ('password') {\n <form class=\"authenticator-form\" (submit)=\"start($event)\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Password</mat-label>\n <input matInput type=\"password\" name=\"password\" [(ngModel)]=\"password\" autocomplete=\"current-password\" [disabled]=\"busy()\" />\n </mat-form-field>\n @if (s.enrolled) {\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Current 6-digit code' }}</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\" [disabled]=\"busy()\" />\n </mat-form-field>\n <button mat-button type=\"button\" class=\"authenticator-link\" (click)=\"toggleRecovery()\">\n {{ useRecovery() ? 'Use the 6-digit code' : 'Lost the phone? Use a recovery code' }}\n </button>\n }\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !password || (s.enrolled && !code.trim())\">Continue</button>\n </div>\n </form>\n }\n\n @case ('scan') {\n @if (challenge(); as c) {\n <form class=\"authenticator-form\" (submit)=\"confirm($event)\">\n <p class=\"text-secondary-info\">Scan this with your authenticator app, then enter the 6-digit code it shows.</p>\n <img class=\"authenticator-qr\" [src]=\"c.qr\" alt=\"QR code for your authenticator app\" width=\"200\" height=\"200\" />\n <p class=\"text-secondary-info authenticator-key\">Can't scan? Enter this key: <code>{{ c.key }}</code></p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Code</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" inputmode=\"numeric\" autocomplete=\"one-time-code\" [disabled]=\"busy()\" />\n </mat-form-field>\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !code.trim()\">Finish setup</button>\n </div>\n @if (s.enrolled) {\n <p class=\"text-secondary-info authenticator-note\">Your old authenticator keeps working until you finish.</p>\n }\n </form>\n }\n }\n\n @case ('reissue') {\n <form class=\"authenticator-form\" (submit)=\"reissue($event)\">\n <p class=\"text-secondary-info\">Ten new recovery codes. The ones you have now will stop working.</p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Current 6-digit code</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" inputmode=\"numeric\" autocomplete=\"one-time-code\" [disabled]=\"busy()\" />\n </mat-form-field>\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !code.trim()\">Make new codes</button>\n </div>\n </form>\n }\n\n @case ('codes') {\n @if (codes(); as list) {\n <shell-recovery-codes [codes]=\"list\" [appName]=\"appName\" (done)=\"codesSaved()\" />\n }\n }\n }\n }\n\n @if (error(); as message) {\n <p class=\"text-loss authenticator-error\" role=\"alert\">{{ message }}</p>\n }\n</section>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\n\"Enter your code\" — the reusable dialog for the on-demand check (authenticator-sign-in.prd.md D15).\nLive Trading opens it to arm trading; anything else that needs the code again can too.\n\nCloses with the time the server recorded (epoch ms), or `undefined` if cancelled. Wrong codes keep\nthe dialog open with the reason in plain words; after five, \"Too many attempts.\" and nothing more.\n\n const at = await openCodeDialog(dialog, {title: 'Arm live trading', purpose: 'arm-live-trading'});\n*/\n\nimport { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthenticationService, AuthenticatorError } from '../../services/authentication.service';\n\nexport interface CodeDialogData {\n title: string;\n /** One line under the title saying what the code is for. */\n message?: string;\n /** Short lowercase label for the log, e.g. 'arm-live-trading' (D17). Changes nothing. */\n purpose?: string;\n confirmLabel?: string;\n}\n\n@Component({\n selector: 'shell-code-dialog',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, MatDialogModule, MatButtonModule, MatFormFieldModule, MatInputModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <form (submit)=\"submit($event)\">\n <mat-dialog-content>\n <p>{{ data.message ?? (useRecovery() ? 'Enter one of your recovery codes.' : 'Enter the 6-digit code from your authenticator app.') }}</p>\n <mat-form-field appearance=\"outline\" class=\"code-field\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Code' }}</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"text\" [disabled]=\"busy()\"\n [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\" cdkFocusInitial />\n </mat-form-field>\n @if (error(); as message) {\n <p class=\"code-error text-loss\" role=\"alert\">{{ message }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button type=\"button\" (click)=\"toggleRecovery()\">{{ useRecovery() ? 'Use the 6-digit code' : 'Use a recovery code' }}</button>\n <button mat-button type=\"button\" (click)=\"dialogRef.close(undefined)\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !text.trim()\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n </form>\n `,\n styles: [`\n :host { display: block; }\n .code-field { width: 100%; }\n .code-error { margin: 0; }\n `],\n})\nexport class CodeDialog {\n readonly data = inject<CodeDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<CodeDialog, number | undefined>);\n readonly #auth = inject(AuthenticationService);\n text = '';\n protected readonly useRecovery = signal(false);\n protected readonly busy = signal(false);\n protected readonly error = signal<string | undefined>(undefined);\n\n toggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.text = '';\n this.error.set(undefined);\n }\n\n async submit(event: Event): Promise<void> {\n event.preventDefault();\n const typed = this.text.trim();\n if (!typed) return;\n this.busy.set(true);\n this.error.set(undefined);\n try {\n const at = await this.#auth.verifyCode(this.useRecovery() ? {recoveryCode: typed} : {code: typed}, this.data.purpose);\n this.dialogRef.close(at);\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Something went wrong');\n this.text = '';\n } finally {\n this.busy.set(false);\n }\n }\n}\n\n/** Opens the dialog; resolves with the recorded time (epoch ms), or undefined when cancelled. */\nexport function openCodeDialog(dialog: MatDialog, data: CodeDialogData): Promise<number | undefined> {\n return firstValueFrom(dialog.open<CodeDialog, CodeDialogData, number | undefined>(CodeDialog, {data, width: '360px'}).afterClosed());\n}\n","import { Component, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport interface ConfirmDialogData {\n title: string;\n message: string;\n warningMessage?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\n@Component({\n selector: 'shell-confirm-dialog',\n imports: [MatDialogModule, MatButtonModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <mat-dialog-content>\n <p>{{ data.message }}</p>\n @if (data.warningMessage) {\n <p class=\"warning-message\">{{ data.warningMessage }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button (click)=\"dialogRef.close(false)\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button mat-flat-button color=\"warn\" (click)=\"dialogRef.close(true)\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .warning-message { color: var(--color-warning); margin-top: 8px; }\n `],\n})\nexport class ConfirmDialog {\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n}\n","/*\n * Public API surface for @franzzemen/brokenstock-shell\n */\n\n// Types\nexport * from './lib/types/command.types';\nexport * from './lib/types/menu.types';\n\n// Tokens & config\nexport * from './lib/tokens/shell-tokens';\nexport * from './lib/provide-shell-config';\n\n// Guards\nexport * from './lib/guards/auth.guard';\nexport * from './lib/guards/guest.guard';\n\n// Interceptors\nexport * from './lib/interceptors/auth.interceptor';\n\n// Directives\nexport * from './lib/directives/regex-validator.directive';\n\n// FAQ help system\nexport * from './lib/faq/faq.types';\nexport * from './lib/faq/faq-content-loader.token';\nexport * from './lib/faq/faq-markdown-renderer.service';\nexport * from './lib/faq/http-faq-content-loader.service';\nexport * from './lib/faq/faq.service';\nexport * from './lib/faq/faq-history.service';\nexport * from './lib/faq/faq-modal/faq-modal';\nexport * from './lib/faq/faq-dev-mode.token';\nexport * from './lib/faq/faq-authoring-panel/faq-authoring-panel';\nexport * from './lib/faq/public-faq-index/public-faq-index';\nexport * from './lib/faq/public-faq-page/public-faq-page';\nexport * from './lib/faq/public-faq-toc/public-faq-toc';\nexport * from './lib/faq/faq-seo.tokens';\n\n// Services\nexport * from './lib/services/thinking.service';\nexport * from './lib/services/session-token-store';\nexport * from './lib/services/renewal-decision';\nexport * from './lib/services/theme.service';\nexport * from './lib/services/terminal-focus.service';\nexport * from './lib/services/terminal-visibility.service';\nexport * from './lib/services/phone-layout.service';\nexport * from './lib/services/keyboard-shortcut.service';\nexport * from './lib/services/authentication.service';\nexport * from './lib/services/authenticator.types';\nexport * from './lib/services/command-registry.service';\nexport * from './lib/services/command.service';\n\n// Commands\nexport * from './lib/commands/command.utils';\n\n// Components\nexport * from './lib/components/shell/shell';\nexport * from './lib/components/side-menu/side-menu';\nexport * from './lib/components/status-bar/status-bar';\nexport * from './lib/components/main-content/main-content';\nexport * from './lib/components/command-terminal/command-terminal';\nexport * from './lib/components/login/login';\nexport * from './lib/components/recovery-codes/recovery-codes';\nexport * from './lib/components/authenticator-settings/authenticator-settings';\nexport * from './lib/components/code-dialog/code-dialog';\nexport * from './lib/components/confirm-dialog/confirm-dialog';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["serializeJsonLd","i1","i2","i1.AuthenticationService","i3","i8"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"franzzemen-brokenstock-shell.mjs","sources":["../../src/lib/types/command.types.ts","../../src/lib/tokens/shell-tokens.ts","../../src/lib/provide-shell-config.ts","../../src/lib/services/thinking.service.ts","../../src/lib/services/session-token-store.ts","../../src/lib/services/cross-window-lock.ts","../../src/lib/services/renewal-decision.ts","../../src/lib/services/authenticator.types.ts","../../src/lib/services/authentication.service.ts","../../src/lib/guards/auth.guard.ts","../../src/lib/guards/guest.guard.ts","../../src/lib/interceptors/auth.interceptor.ts","../../src/lib/directives/regex-validator.directive.ts","../../src/lib/faq/faq.types.ts","../../src/lib/faq/faq-content-loader.token.ts","../../src/lib/faq/faq-markdown-renderer.service.ts","../../src/lib/faq/http-faq-content-loader.service.ts","../../src/lib/faq/faq-history.service.ts","../../src/lib/faq/faq.service.ts","../../src/lib/faq/faq-dev-mode.token.ts","../../src/lib/faq/faq-modal/faq-modal.ts","../../src/lib/faq/faq-modal/faq-modal.html","../../src/lib/faq/faq-authoring-panel/faq-authoring-panel.ts","../../src/lib/faq/faq-authoring-panel/faq-authoring-panel.html","../../src/lib/faq/public-faq-toc/public-faq-toc.ts","../../src/lib/faq/faq-seo.tokens.ts","../../src/lib/faq/public-faq-index/public-faq-index.ts","../../src/lib/faq/public-faq-page/public-faq-page.ts","../../src/lib/services/theme.service.ts","../../src/lib/services/phone-layout.service.ts","../../src/lib/services/terminal-focus.service.ts","../../src/lib/services/terminal-visibility.service.ts","../../src/lib/services/keyboard-shortcut.service.ts","../../src/lib/commands/faq.command.ts","../../src/lib/services/command-registry.service.ts","../../src/lib/commands/command.utils.ts","../../src/lib/services/pending-prompt.ts","../../src/lib/services/command.service.ts","../../src/lib/components/status-bar/status-bar.ts","../../src/lib/components/status-bar/status-bar.html","../../src/lib/components/side-menu/side-menu.ts","../../src/lib/components/side-menu/side-menu.html","../../src/lib/components/main-content/main-content.ts","../../src/lib/components/main-content/main-content.html","../../src/lib/components/command-terminal/command-terminal.ts","../../src/lib/components/command-terminal/command-terminal.html","../../src/lib/components/shell/shell.ts","../../src/lib/components/shell/shell.html","../../src/lib/components/recovery-codes/recovery-codes.ts","../../src/lib/components/login/login.ts","../../src/lib/components/login/login.html","../../src/lib/components/authenticator-settings/authenticator-settings.ts","../../src/lib/components/authenticator-settings/authenticator-settings.html","../../src/lib/components/code-dialog/code-dialog.ts","../../src/lib/components/confirm-dialog/confirm-dialog.ts","../../src/public-api.ts","../../src/franzzemen-brokenstock-shell.ts"],"sourcesContent":["/*\n * Command framework types — absorbed from brokenstock-lexicon.\n * Platform-agnostic; no Angular dependencies.\n */\nimport { z } from 'zod/v4';\n\nexport type Severity = 'error' | 'warning' | 'info';\n\nexport interface CommandResult {\n success: boolean;\n message: string;\n timestamp: Date;\n severity?: Severity;\n isHelp?: boolean;\n}\n\nexport interface CommandHistoryEntry {\n input: string;\n result: CommandResult;\n repeatCount?: number;\n}\n\n\n/**\n * An alternate name for a command. Mirrors `CommandAlias` in\n * @franzzemen/brokenstock-lexicon — this library keeps its own copy of the\n * command types (see the file header), and the two MUST stay in step.\n *\n * TWO SHAPES:\n * - A plain alternate is another word for the same command (`scan` for\n * `scanner`); arguments pass through untouched.\n * - An alternate carrying `prependArgs` also supplies leading arguments, so\n * one word stands for a command AND its subcommand: `scans NVDA` runs\n * `scanner select NVDA`. The expansion is literal, so anything the\n * subcommand accepts keeps working through the short form.\n *\n * The real name is what `help` lists; alternates are named in the command's own\n * usage text. The registry refuses a name already taken, real or alternate.\n */\nexport interface CommandAlias {\n readonly name: string;\n readonly prependArgs?: readonly string[];\n}\n\n/**\n * Where a command belongs. Mirrors `@franzzemen/brokenstock-lexicon`'s\n * `RouteScope` — the lexicon is the source of truth and carries the full\n * rationale (trades-tree.prd.md D29–D33); this copy exists because the shell\n * deliberately does not depend on the lexicon.\n *\n * - `'navigate'`: the command takes you to its screen and acts; the shell never\n * refuses it, and `help` says where it lives.\n * - `'refuse'`: the command depends on state only its screen sets; typed\n * anywhere else the shell refuses with a message naming the screen.\n */\nexport interface RouteScope {\n /** \"the Trades screen\" — used verbatim in refusals and in `help`. */\n readonly screen: string;\n /** Route patterns; see {@link matchesRoute}. */\n readonly routes: readonly string[];\n readonly elsewhere: 'navigate' | 'refuse';\n}\n\nexport type CommandScope = 'global' | RouteScope;\n\n/**\n * Does `url` fall inside any of `patterns`? Query string and fragment are\n * stripped; a pattern matches when the path equals it or continues past it at\n * a `/`; a `:param` segment matches any one non-empty segment. Same rule as\n * the lexicon's `matchesRoute`, tested there and here.\n */\nexport function matchesRoute(url: string, patterns: readonly string[]): boolean {\n const path = url.split('?')[0]!.split('#')[0]!.replace(/\\/+$/, '') || '/';\n const segments = path.split('/');\n return patterns.some(pattern => {\n const want = pattern.replace(/\\/+$/, '').split('/');\n if (want.length > segments.length) return false;\n return want.every((w, i) => (w.startsWith(':') ? segments[i]!.length > 0 : w === segments[i]));\n });\n}\n\n/**\n * Lexicon entry: the platform-agnostic definition of a command.\n * Execution is provided by each consumer (Angular app, CLI app, etc.).\n */\nexport interface CommandLexiconEntry {\n readonly name: string;\n readonly description: string;\n readonly usage: string;\n readonly requiresAuth: boolean;\n readonly argsSchema: z.ZodType;\n /** Where the command belongs. Required: every command declares it. */\n readonly scope: CommandScope;\n /** Alternate names for this command. See {@link CommandAlias}. */\n readonly aliases?: readonly CommandAlias[];\n sanitizeInput?(input: string): string;\n}\n\n/**\n * Result of a command's readiness check. `reason` is surfaced verbatim to the\n * user and MUST be non-empty when `ok` is false — the terminal renders nothing\n * at all for an empty message, which would look like the command silently did\n * nothing.\n */\nexport interface CommandAvailability {\n ok: boolean;\n reason?: string;\n}\n\n/**\n * Full command definition including execution.\n */\nexport interface CommandDefinition extends CommandLexiconEntry {\n /**\n * Declarative readiness gate, checked centrally before `execute`. Use for\n * preconditions the user can act on (entitlement, onboarding state) rather\n * than checking imperatively as the first statement of `execute` — the\n * framework can only annotate `help` for gates it can see.\n *\n * A command that fails this check stays listed in `help` and in\n * tab-completion, annotated with its reason. Hiding it would read as a broken\n * CLI; an explained refusal reads as guidance.\n *\n * Omit for always-available.\n */\n isAvailable?(): CommandAvailability;\n\n execute(args: string[]): CommandResult | Promise<CommandResult>;\n}\n","import { InjectionToken } from '@angular/core';\nimport { CommandDefinition } from '../types/command.types';\nimport { MenuItem } from '../types/menu.types';\n\nexport interface ShellAuthUrls {\n login: string;\n logout: string;\n refresh: string;\n}\n\nexport const SHELL_APP_NAME = new InjectionToken<string>('SHELL_APP_NAME');\nexport const SHELL_MENU_ITEMS = new InjectionToken<MenuItem[]>('SHELL_MENU_ITEMS');\nexport const SHELL_AUTH_URLS = new InjectionToken<ShellAuthUrls>('SHELL_AUTH_URLS');\n\n/**\n * App-specific commands to register alongside the built-in command set.\n * Provide via provideShellConfig().\n */\nexport const SHELL_COMMANDS = new InjectionToken<CommandDefinition[]>('SHELL_COMMANDS');\n\nexport const SHELL_POST_LOGIN_ROUTE = new InjectionToken<string>('SHELL_POST_LOGIN_ROUTE');\n\n/**\n * Whether this app shares one session across every window of the browser\n * (multiple-windows PRD D2/D7).\n *\n * ⚠ OFF unless an app opts in, and only `broken-stock` does. Turning it on puts\n * the sign-in token in browser storage, where any script on the origin can read\n * it and it persists on disk. The admin apps send their renewal cookie\n * cross-site and can change other people's data, which makes that a materially\n * different exposure — extending this to them is a separate decision, not a\n * default.\n */\nexport const SHELL_SHARED_SESSION = new InjectionToken<boolean>('SHELL_SHARED_SESSION');\n","import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\nimport { CommandDefinition } from './types/command.types';\nimport { MenuItem } from './types/menu.types';\nimport { SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_SHARED_SESSION, ShellAuthUrls } from './tokens/shell-tokens';\n\nexport interface ShellConfig {\n appName: string;\n menuItems: MenuItem[];\n authUrls: ShellAuthUrls;\n commands?: CommandDefinition[];\n /**\n * Share one session across every window of the browser. Defaults to false.\n * See {@link SHELL_SHARED_SESSION} for why this is opt-in.\n */\n sharedSession?: boolean;\n}\n\nexport function provideShellConfig(config: ShellConfig): EnvironmentProviders {\n return makeEnvironmentProviders([\n { provide: SHELL_APP_NAME, useValue: config.appName },\n { provide: SHELL_MENU_ITEMS, useValue: config.menuItems },\n { provide: SHELL_AUTH_URLS, useValue: config.authUrls },\n { provide: SHELL_COMMANDS, useValue: config.commands ?? [] },\n { provide: SHELL_SHARED_SESSION, useValue: config.sharedSession ?? false },\n ]);\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\n@Injectable({ providedIn: 'root' })\nexport class ThinkingService {\n readonly #activeCount = signal(0);\n\n readonly isThinking = computed(() => this.#activeCount() > 0);\n\n startThinking(): void {\n this.#activeCount.update(c => c + 1);\n }\n\n stopThinking(): void {\n this.#activeCount.update(c => Math.max(0, c - 1));\n }\n\n reset(): void {\n this.#activeCount.set(0);\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nThe sign-in token's home in browser storage (multiple-windows PRD D2).\n\nWHY THIS IS ITS OWN FILE, AND WHY IT DOES NOT USE `LocalStorageService`.\nThat service swallows a failed write on purpose — losing a remembered pane width\nmust never break the screen that was trying to remember it. That policy is\nexactly wrong here. A silently dropped token write is a silently lost session:\nthe window keeps working on the token it holds in memory, every other window\nnever learns it, and the failure surfaces minutes later somewhere else entirely.\nSo this writes directly and THROWS.\n\nREADS ARE THE SOURCE OF TRUTH, NOT A CACHE. `AuthenticationService.auth` reads\nthrough to this on every access rather than keeping a copy. That is the whole\nreason the design works with several windows open: the tape socket asks for the\ntoken on a sixty-second heartbeat and a window that is frozen or backgrounded may\nnever receive a queued `storage` event, so a copy refreshed by an event is only\nas fresh as the last event delivered. Reading through removes the question.\n\n⚠ NOT under the `bs.pref.` namespace. `LocalStorageService` wipes that namespace\nwholesale, and a preference wipe must never sign the user out.\n*/\n\nimport { Injectable } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken } from '@franzzemen/utility';\n\n/** Deliberately outside `bs.pref.` — see the header. */\nexport const SESSION_TOKEN_KEY = 'bs.auth.token';\n\n@Injectable({ providedIn: 'root' })\nexport class SessionTokenStore {\n /** False during prerendering, where there is no `window` at all. */\n readonly #available = typeof window !== 'undefined' && !!window.localStorage;\n\n get available(): boolean {\n return this.#available;\n }\n\n /**\n * The stored token, or undefined.\n *\n * A stored value that is not a well-formed bearer is treated as absent and\n * removed. It cannot be authenticated with, and leaving it there would make\n * every later read fail the same way with nothing to explain it.\n */\n read(): BearerToken | undefined {\n if (!this.#available) return undefined;\n let raw: string | null;\n try {\n raw = window.localStorage.getItem(SESSION_TOKEN_KEY);\n } catch {\n // Storage disabled by the browser. Not recoverable here, and not fatal —\n // the caller falls back to its in-memory token and this window works\n // alone, which is exactly today's behaviour.\n return undefined;\n }\n if (!raw) return undefined;\n if (!BEARER_TOKEN_REGEX.test(raw)) {\n this.clear();\n return undefined;\n }\n return raw as BearerToken;\n }\n\n /**\n * Stores the token. THROWS on failure — see the header.\n *\n * @throws if the value is not a bearer token, or the write does not stick.\n */\n write(token: BearerToken): void {\n if (!this.#available) return;\n if (!BEARER_TOKEN_REGEX.test(token)) {\n throw new Error('SessionTokenStore.write refused a value that is not a bearer token');\n }\n try {\n window.localStorage.setItem(SESSION_TOKEN_KEY, token);\n } catch (error) {\n throw new Error(`Could not store the session token: ${String(error)}`);\n }\n }\n\n clear(): void {\n if (!this.#available) return;\n try {\n window.localStorage.removeItem(SESSION_TOKEN_KEY);\n } catch {\n // Nothing useful to do. The in-memory state is cleared by the caller\n // regardless, so this window is signed out either way.\n }\n }\n\n /**\n * Calls back when ANOTHER window changes the token.\n *\n * `storage` does not fire in the window that made the change, which is\n * correct — that window is the one doing it and has already acted.\n *\n * ⚠ `event.key === null` is what `localStorage.clear()` produces, and it means\n * everything went, this key included. Treating it as \"not our key\" is how a\n * whole-storage clear silently fails to sign the user out.\n */\n onExternalChange(handler: (token: BearerToken | undefined) => void): () => void {\n if (!this.#available) return () => undefined;\n const listener = (event: StorageEvent) => {\n if (event.key !== null && event.key !== SESSION_TOKEN_KEY) return;\n handler(this.read());\n };\n window.addEventListener('storage', listener);\n return () => window.removeEventListener('storage', listener);\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nRun something in exactly one window (multiple-windows PRD D5).\n\nTHE PROBLEM. Several windows share one session. When the token expires they all\nnotice at once and all try to renew. The server serialises renewal correctly and\nREFUSES the losers, so without coordination every window but one is signed out —\nand it happens every token lifetime, several times a day.\n\nWHY `ifAvailable` RATHER THAN WAITING ON THE LOCK. A waiter blocks on a peer it\ncannot supervise. If the window holding the lock is frozen, backgrounded or its\nrequest hangs, the waiters wait forever — screens simply stop updating, with\nnothing logged and nothing on screen. `ifAvailable` refuses immediately instead,\nwhich turns \"wait on a peer\" into \"wait for a value to appear, with my own\nbound\". A bound you own is a bound you can honour.\n\n⚠ A lock held by a DESTROYED document is released by the browser, so closing a\nwindow is safe. A merely frozen document is NOT destroyed — which is why every\npath here is bounded regardless.\n\n⚠ `navigator.locks` needs a secure context and is absent in some. Absent means\nfall back to running uncoordinated — today's behaviour — never throw. A missing\nAPI must not be the reason nobody can sign in.\n*/\n\n/**\n * Checked at CALL time, not once at module load.\n *\n * Module-level would be evaluated during import — before `navigator` exists at\n * all under prerendering, and before a test can arrange anything — permanently\n * fixing the answer to \"no\" for the life of the process. Found by writing the\n * test for the fallback path, which could not be reached any other way.\n */\nfunction locksAvailable(): boolean {\n return typeof navigator !== 'undefined' && typeof navigator.locks?.request === 'function';\n}\n\nexport type LockOutcome<T> =\n /** We held the lock and ran. */\n | {ran: true; value: T}\n /** Another window held it. We did not run. */\n | {ran: false};\n\n/**\n * Runs `work` if this window can take the lock right now.\n *\n * Returns `{ran: false}` when another window holds it — the caller decides what\n * to do instead, which is the point: only the caller knows whether waiting for\n * the peer's result or proceeding alone is correct.\n *\n * When `navigator.locks` is unavailable the work RUNS, uncoordinated. That is a\n * deliberate degradation to today's behaviour rather than a refusal.\n */\nexport async function runExclusive<T>(name: string, work: () => Promise<T>): Promise<LockOutcome<T>> {\n if (!locksAvailable()) {\n console.warn(`[shell] navigator.locks unavailable; \"${name}\" runs without cross-window coordination`);\n return {ran: true, value: await work()};\n }\n let outcome: LockOutcome<T> = {ran: false};\n await navigator.locks.request(name, {ifAvailable: true}, async lock => {\n if (!lock) return;\n outcome = {ran: true, value: await work()};\n });\n return outcome;\n}\n\n/**\n * Polls `read` until it returns something other than `unchanged`, or the bound\n * elapses.\n *\n * Polling rather than listening for `storage` on purpose: the event does not\n * fire in a window that is frozen at the moment it is dispatched, and this is\n * the path that recovers such a window. A poll asks the question again.\n *\n * Resolves `undefined` on timeout — \"the peer did not deliver\", which is a\n * legitimate answer the caller must handle, not an error.\n */\nexport async function awaitChange<T>(\n read: () => T,\n unchanged: T,\n timeoutMs: number,\n pollMs = 100,\n): Promise<T | undefined> {\n const deadline = Date.now() + timeoutMs;\n for (;;) {\n const current = read();\n if (current !== unchanged) return current;\n if (Date.now() >= deadline) return undefined;\n await new Promise(resolve => setTimeout(resolve, pollMs));\n }\n}\n","/*\nCreated by Franz Zemen 2026-08-29\nLicense Type: UNLICENSED\n\nWhat a window should do once it can act on a session renewal\n(multiple-windows PRD D5).\n\nWHY THIS IS A NAMED FUNCTION RATHER THAN THREE `if`s INSIDE THE SERVICE. The\nrule was originally written as \"retry with a token different from the one you\nfailed with\", which is not a well-defined instruction: the in-window\nsingle-flight already collapses requests that were sent with DIFFERENT tokens,\nso \"the one you failed with\" is not a single value. Pulling the decision out\nforces the three cases to be named, and lets them be tested without mocking a\nnetwork call — which is what they deserve, because getting this wrong shows up\nhours later as \"a window signed me out\" with nothing linking cause to effect.\n*/\n\nimport { BearerToken } from '@franzzemen/utility';\n\nexport type RenewalDecision =\n /** The token is gone: the window that renewed failed permanently, or signed out. */\n | 'sign-out'\n /** Another window renewed while we queued. Take its token; do NOT rotate again. */\n | 'adopt'\n /** Nothing has moved. This window performs the renewal itself. */\n | 'renew';\n\n/**\n * @param before the token this window held immediately BEFORE asking for the lock\n * @param current the token in shared storage now that this window can act\n */\nexport function decideRenewal(\n before: BearerToken | undefined,\n current: BearerToken | undefined,\n): RenewalDecision {\n // Gone. Retrying would present nothing and 401 again; worse, it would look\n // like a transient failure when it is a definite answer.\n if (before && !current) return 'sign-out';\n // Someone else's fresh token. Rotating again would invalidate the token every\n // OTHER window just adopted — turning one window's recovery into everyone\n // else's sign-out.\n if (current && current !== before) return 'adopt';\n // Unchanged, or nothing stored to begin with.\n return 'renew';\n}\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nAuthenticator sign-in — what the browser sees (authenticator-sign-in.prd.md).\n*/\n\n/** The `reason` the auth worker puts on every authenticator refusal. */\nexport type AuthenticatorReason =\n | 'code-required'\n | 'invalid-code'\n | 'too-many-attempts'\n | 'authenticator-not-set-up'\n | 'setup-required';\n\n/** Which extra step the sign-in screen is on, after the password was accepted. */\nexport type SignInCodeStep = 'none' | 'code' | 'setup';\n\n/** GET {login}/authenticator. */\nexport type AuthenticatorStatus = {\n enrolled: boolean;\n recoveryCodesLeft: number;\n /** Yes/no only — the server never sends when it ends (D12). */\n bypassActive: boolean;\n codeRequired: boolean;\n};\n\n/** What a code-bearing request carries: a 6-digit code or a recovery code. */\nexport type CodeEntry = {code?: string; recoveryCode?: string};\n\n/** The QR shown once during setup, and the same secret as text for typing in by hand. */\nexport type SetupChallenge = {qr: string; key: string};\n\n/**\n * The one message for a pause (D8). The server sends no time and the screen invents none.\n */\nexport const TOO_MANY_ATTEMPTS = 'Too many attempts.';\n\n/** Plain words for each refusal, shown on the sign-in screen and in the code dialog. */\nexport function authenticatorMessage(reason: AuthenticatorReason | undefined): string {\n switch (reason) {\n case 'code-required': return 'Enter the 6-digit code from your authenticator app.';\n case 'invalid-code': return 'That code did not work. Try the current one.';\n case 'too-many-attempts': return TOO_MANY_ATTEMPTS;\n case 'authenticator-not-set-up': return 'This account has no authenticator set up. Ask the administrator to reset it.';\n case 'setup-required': return 'Scan this QR code with your authenticator app, then enter the 6-digit code it shows.';\n default: return 'Unable to sign in';\n }\n}\n\n/** The text file the Download button saves (D7). */\nexport function recoveryCodesFile(appName: string, username: string | undefined, codes: readonly string[], now = new Date()): string {\n return [\n `${appName} recovery codes${username ? ` for ${username}` : ''}`,\n `Generated ${now.toISOString()}`,\n '',\n 'Each code works once, in place of the 6-digit code from your authenticator app.',\n 'Keep this file somewhere safe and offline. Anyone with these codes and your password can sign in.',\n '',\n ...codes,\n '',\n ].join('\\n');\n}\n","import { computed, inject, Injectable, signal } from '@angular/core';\nimport { BEARER_TOKEN_REGEX, BearerToken, HttpHeader } from '@franzzemen/utility';\nimport { AuthenticationResponse, Credentials, SessionSummary, UserSession, validateCredentials } from '@franzzemen/identity';\nimport { HttpClient, HttpErrorResponse, HttpResponse } from '@angular/common/http';\nimport { Router } from '@angular/router';\nimport { ThinkingService } from './thinking.service';\nimport { SHELL_AUTH_URLS, SHELL_SHARED_SESSION } from '../tokens/shell-tokens';\nimport { SessionTokenStore } from './session-token-store';\nimport { awaitChange, runExclusive } from './cross-window-lock';\nimport { decideRenewal } from './renewal-decision';\nimport { firstValueFrom } from 'rxjs';\nimport {\n AuthenticatorReason,\n AuthenticatorStatus,\n authenticatorMessage,\n CodeEntry,\n SetupChallenge,\n SignInCodeStep,\n} from './authenticator.types';\n\n/**\n * A refusal from an authenticator route, carrying the server's `reason`\n * (authenticator-sign-in.prd.md). `message` is plain words for the screen.\n */\nexport class AuthenticatorError extends Error {\n constructor(readonly reason: AuthenticatorReason | undefined, message: string, readonly status: number) {\n super(message);\n this.name = 'AuthenticatorError';\n }\n}\n\n/** Sign-in rejected because the next step is a code (or setting one up), not because anything failed. */\nexport const CODE_STEP = 'code-step';\n\n/**\n * What the user decided about sessions they already hold, sent on the SECOND\n * sign-in attempt (multiple-devices D2/D6).\n *\n * Mutually exclusive in practice, and the screen only ever sets one: taking\n * over everything is `force` on the call itself, signing in beside them is\n * `additional`, and ending a chosen few is `endSessionIds`.\n */\nexport type LoginChoice = {\n additional?: boolean;\n /** Identifiers read off the refusal. The server acts on them only after the password verifies, and only for that user's own sessions. */\n endSessionIds?: string[];\n /** The 6-digit authenticator code (authenticator-sign-in.prd.md). */\n code?: string;\n /** A one-time recovery code, in place of `code`. */\n recoveryCode?: string;\n};\n\n/**\n * The sign-in request body, exactly as sent (multiple-devices E8, authenticator-sign-in.prd.md).\n *\n * Fields appear only when they carry a decision: the route's body schema is strict,\n * and `additional: false` on a first attempt would be a statement where silence is\n * meant. A code typed now wins; otherwise a ticket from a 409 that followed a\n * correct code stands in for it (the server accepts a code only once, D20).\n */\nexport function buildLoginBody(\n credentials: Credentials,\n force: boolean,\n options: LoginChoice,\n signInTicket?: string,\n): Record<string, unknown> {\n const proof = options.code\n ? {code: options.code}\n : options.recoveryCode\n ? {recoveryCode: options.recoveryCode}\n : signInTicket ? {signInTicket} : {};\n return {\n ...credentials,\n ...(force ? {force: true} : {}),\n ...(options.additional ? {additional: true} : {}),\n ...(options.endSessionIds?.length ? {endSessionIds: options.endSessionIds} : {}),\n ...proof,\n };\n}\n\n/** Name of the cross-window renewal lock (PRD D5). */\nconst RENEWAL_LOCK = 'brokenstock.session.renew';\n\n/** How long a window waits for the renewing window to publish a token (PRD D5). */\nconst PEER_RENEWAL_WAIT_MS = 10_000;\n\n/** How long the renewal request itself may take before it is abandoned (PRD D5). */\nconst RENEWAL_TIMEOUT_MS = 15_000;\n\n@Injectable({ providedIn: 'root' })\nexport class AuthenticationService {\n readonly authenticated = signal(false);\n readonly authenticating = signal(false);\n readonly userSession = signal<UserSession | undefined>(undefined);\n readonly conflictSessions = signal<SessionSummary[] | undefined>(undefined);\n /**\n * Whether this app lets you sign in ALONGSIDE the sessions listed in\n * `conflictSessions` (multiple-devices D3).\n *\n * ⚠ READ FROM THE SERVER'S REFUSAL, NEVER DECIDED HERE. This component is\n * shared by the trading app and both admin consoles, which have different\n * rules. Deciding it locally would put the policy in two places, and the one\n * a reader would find is not the one that enforces it — an admin screen would\n * happily offer a button the server refuses.\n */\n readonly additionalSignInAllowed = signal(false);\n readonly pendingCredentials = signal<Credentials | undefined>(undefined);\n\n // ----- Authenticator (authenticator-sign-in.prd.md) -----\n /** The extra step the sign-in screen is on after the password was accepted. */\n readonly codeStep = signal<SignInCodeStep>('none');\n /** Inside an AWS-opened setup window: the QR and key to show (D9, D10). */\n readonly setupChallenge = signal<SetupChallenge | undefined>(undefined);\n /** New recovery codes to show ONCE, with a Download button (D7). Cleared when acknowledged. */\n readonly recoveryCodesToShow = signal<string[] | undefined>(undefined);\n /** Recovery codes left, from the last sign-in or status read. */\n readonly recoveryCodesLeft = signal<number | undefined>(undefined);\n /**\n * Whether the AWS-set bypass is on for this account (D12). Drives the banner on\n * every screen. Yes/no only: the server never says when it ends.\n */\n readonly bypassActive = signal(false);\n /**\n * The ticket from a 409 that followed a correct code. The retry sends it in place\n * of the code, which the server will not accept twice (D20). Never shown.\n */\n #signInTicket: string | undefined;\n\n #refreshing: Promise<boolean> | null = null;\n #auth: BearerToken = 'Bearer ..' as BearerToken;\n\n readonly #httpClient = inject(HttpClient);\n readonly #thinkingService = inject(ThinkingService);\n readonly #router = inject(Router);\n readonly #authUrls = inject(SHELL_AUTH_URLS);\n readonly #store = inject(SessionTokenStore);\n /** Off by default: an app opts in to sharing its session across windows (PRD D7). */\n readonly #sharedSession = inject(SHELL_SHARED_SESSION, { optional: true }) ?? false;\n\n constructor() {\n if (!this.#sharedSession) return;\n // Adopt a token this browser already holds. This runs during construction,\n // and `authGuard` injecting this service IS the first read of `authenticated`\n // — a field initializer completes before `inject()` returns — so the guard\n // sees the restored state without becoming asynchronous (PRD D4).\n //\n // The token may well be expired. That is not this constructor's problem: the\n // first request 401s and the interceptor renews and retries, which is the\n // path that already works today.\n const stored = this.#store.read();\n if (stored) {\n this.#auth = stored;\n this.authenticated.set(true);\n }\n // Another window signing out must sign this one out too (PRD D6). A token\n // that merely CHANGED needs no action here — `auth` reads through, so the\n // next caller gets the new value without anyone copying it.\n this.#store.onExternalChange(token => {\n if (!token && this.authenticated()) this.#clearSession();\n });\n }\n\n /**\n * The bearer for outbound calls.\n *\n * READ-THROUGH, not a cached copy, whenever the session is shared across\n * windows (PRD D2/D10). A copy is only as fresh as the last `storage` event\n * delivered, and the consumer that matters most is outside the request path:\n * the market-tape socket re-presents this token on a sixty-second heartbeat,\n * and the server closes the socket with a code the client does NOT retry if it\n * is stale. A window that was frozen when the event fired would lose its live\n * prices permanently. Reading through removes the question of which window\n * holds which token.\n */\n get auth(): BearerToken {\n if (this.#sharedSession) {\n const stored = this.#store.read();\n if (stored) return stored;\n }\n return this.#auth;\n }\n\n /**\n * Adopts a freshly issued token: in memory, and in shared storage so every\n * other window of this browser sees it on their next read.\n *\n * A failed write THROWS out of here rather than being absorbed — see\n * `SessionTokenStore`. A session the other windows cannot see is the failure\n * this whole design exists to prevent.\n */\n #adoptToken(token: BearerToken): void {\n this.#auth = token;\n if (this.#sharedSession) this.#store.write(token);\n }\n\n // Legacy hasRole/hasAnyRole removed (legacy-authz-teardown): sessions carry no\n // roles, and every gate moved to hasFeature (commerce) with the BE enforcing the\n // security axis.\n //\n // `hasFeature` and `featureValue` are now gone too, with all entitlement gating\n // (commercial-surface-decommission.prd.md D3). BrokenStock is not a commercial\n // product; there is nothing to be entitled to. Per P1 every capability they hid is\n // unconditionally available, so the callers did not migrate to some other check —\n // they simply stopped asking. The session's `features` map is no longer read here at\n // all, which is what makes it safe for the back end to stop populating it (E9).\n //\n // The security axis is unaffected and still enforced server-side: this app cannot see\n // security roles by design (`@franzzemen/endpoint-identity` is deliberately absent\n // from its dependency graph).\n\n refresh(): Promise<boolean> {\n if (this.#refreshing) {\n return this.#refreshing;\n }\n this.#refreshing = this.#doRefresh().finally(() => { this.#refreshing = null; });\n return this.#refreshing;\n }\n\n clearConflict(): void {\n this.conflictSessions.set(undefined);\n this.additionalSignInAllowed.set(false);\n this.pendingCredentials.set(undefined);\n this.#signInTicket = undefined;\n }\n\n /** Back to the password form from the code or setup step. */\n cancelCodeStep(): void {\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.pendingCredentials.set(undefined);\n this.#signInTicket = undefined;\n }\n\n /** The new recovery codes have been seen (and, we hope, downloaded). */\n acknowledgeRecoveryCodes(): void {\n this.recoveryCodesToShow.set(undefined);\n }\n\n /**\n * The session is gone and cannot be recovered — renewal failed permanently,\n * or another window signed out.\n *\n * ⚠ THIS EXISTS BECAUSE THERE ARE TWO SIGN-OUT PATHS AND ONLY ONE USED TO\n * CLEAR THE TOKEN. `logout()` went through `#clearSession()`; the 401\n * interceptor set the signals and navigated but left `#auth` alone. Harmless\n * while the token lived only in memory and died with the tab — but once it is\n * in storage, a dead token left behind means every later window marks itself\n * signed in, passes the guard, renders, 401s and bounces to the login screen.\n * The reload fix would have become \"the app flashes, then throws me out\",\n * which is harder to diagnose than the behaviour it replaced.\n */\n sessionLost(): void {\n this.#thinkingService.reset();\n this.#clearSession();\n }\n\n logout(): void {\n const subscription = this.#httpClient\n .get<void>(this.#authUrls.logout, {\n headers: {\n [HttpHeader.Authorization]: this.#auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n })\n .subscribe({\n next: () => {\n this.#clearSession();\n subscription.unsubscribe();\n },\n error: () => {\n this.#thinkingService.reset();\n this.#clearSession();\n },\n });\n }\n\n /**\n * Signs in, and — on a second attempt — says what to do about the sessions\n * already held (multiple-devices D2/D6).\n *\n * `force` and `additional` are different answers, not synonyms: `force` ends\n * every session in this app, `additional` leaves them all running.\n * `endSessionIds` ends the ones the user picked and leaves the rest. None of\n * the three appears on a first attempt — they exist because the server\n * refused once and said what was live.\n */\n login(credentials: Credentials, force = false, options: LoginChoice = {}): Promise<void> {\n const validation = validateCredentials(credentials);\n if (validation !== true) {\n return Promise.reject('Invalid credentials');\n }\n this.conflictSessions.set(undefined);\n this.#thinkingService.startThinking();\n return new Promise((resolve, reject) => {\n this.authenticating.set(true);\n const body = buildLoginBody(credentials, force, options, this.#signInTicket);\n const subscription = this.#httpClient\n .post<HttpResponse<AuthenticationResponse>>(\n this.#authUrls.login,\n body,\n {\n headers: {\n [HttpHeader.ContentType]: 'application/json',\n [HttpHeader.AppContext]: 'brokenstock',\n },\n observe: 'response',\n responseType: 'json',\n withCredentials: true,\n },\n )\n .subscribe({\n next: (response: HttpResponse<any>) => {\n try {\n const authResponse: AuthenticationResponse = response.body;\n // @ts-ignore\n delete authResponse.session.token;\n this.userSession.set(authResponse.session);\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) {\n reject('Unable to login');\n return;\n }\n this.#adoptToken(auth as BearerToken);\n const authenticator = (response.body as {authenticator?: {recoveryCodes?: string[]; recoveryCodesLeft?: number; bypassActive?: boolean}}).authenticator;\n this.recoveryCodesLeft.set(authenticator?.recoveryCodesLeft);\n this.bypassActive.set(authenticator?.bypassActive === true);\n if (authenticator?.recoveryCodes?.length) this.recoveryCodesToShow.set(authenticator.recoveryCodes);\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.#signInTicket = undefined;\n this.authenticated.set(true);\n this.pendingCredentials.set(undefined);\n resolve();\n } catch {\n reject('Unable to login');\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n error: (err: HttpErrorResponse) => {\n try {\n const reason = err.error?.reason as AuthenticatorReason | undefined;\n if (err.status === 409) {\n // After a correct code: the retry carries this instead (D20), and\n // new recovery codes from a setup must not be lost to this panel.\n if (typeof err.error?.signInTicket === 'string') this.#signInTicket = err.error.signInTicket;\n if (Array.isArray(err.error?.recoveryCodes)) this.recoveryCodesToShow.set(err.error.recoveryCodes);\n // The code is done; the session choice is all that is left on screen.\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.conflictSessions.set(err.error?.activeSessions ?? []);\n // Absent means false: an older back end that does not send this\n // does not permit signing in alongside, so the screen must not\n // offer it.\n this.additionalSignInAllowed.set(err.error?.additionalSignInAllowed === true);\n this.pendingCredentials.set(credentials);\n reject('conflict');\n } else if (reason === 'code-required') {\n this.codeStep.set('code');\n this.pendingCredentials.set(credentials);\n reject(CODE_STEP);\n } else if (reason === 'setup-required') {\n this.codeStep.set('setup');\n this.setupChallenge.set({qr: err.error.qr, key: err.error.key});\n this.pendingCredentials.set(credentials);\n reject(CODE_STEP);\n } else if (reason) {\n // invalid-code / too-many-attempts / authenticator-not-set-up:\n // stay on the step the user is on; say what happened, in plain words.\n if (reason === 'too-many-attempts' || reason === 'authenticator-not-set-up') this.#signInTicket = undefined;\n reject(authenticatorMessage(reason));\n } else if (err.status === 401) {\n reject('Wrong username or password');\n } else {\n reject(err.message ?? 'Unable to login');\n }\n } finally {\n this.authenticating.set(false);\n subscription.unsubscribe();\n this.#thinkingService.stopThinking();\n }\n },\n });\n });\n }\n\n // ---------------------------------------------------------------------------\n // Authenticator settings and the on-demand check (authenticator-sign-in.prd.md)\n //\n // All under the sign-in URL (`/login/…` or `/admin/login/…`), on the auth\n // worker. A wrong code here is 403, never 401, so the interceptor does not\n // read it as an expired session.\n // ---------------------------------------------------------------------------\n\n /** Whether an authenticator is set up, codes left, and whether the bypass is on. Refreshes the banner. */\n async authenticatorStatus(): Promise<AuthenticatorStatus> {\n const status = await this.#authenticatorCall<AuthenticatorStatus>('GET', 'authenticator');\n this.bypassActive.set(status.bypassActive);\n this.recoveryCodesLeft.set(status.recoveryCodesLeft);\n return status;\n }\n\n /** Begin setting up (or replacing) the authenticator: the password again, plus a current code when replacing (D5). */\n startAuthenticatorSetup(password: string, current: CodeEntry = {}): Promise<SetupChallenge> {\n return this.#authenticatorCall<SetupChallenge>('POST', 'authenticator/start', {password, ...current});\n }\n\n /** Finish setup with the first code from the newly scanned app. Returns the 10 recovery codes, once. */\n async confirmAuthenticatorSetup(code: string): Promise<string[]> {\n const {recoveryCodes} = await this.#authenticatorCall<{recoveryCodes: string[]}>('POST', 'authenticator/confirm', {code});\n this.recoveryCodesLeft.set(recoveryCodes.length);\n return recoveryCodes;\n }\n\n /** Ten new recovery codes; the old ones stop working (D7). Needs a current code. */\n async reissueRecoveryCodes(code: string): Promise<string[]> {\n const {recoveryCodes} = await this.#authenticatorCall<{recoveryCodes: string[]}>('POST', 'recovery-codes', {code});\n this.recoveryCodesLeft.set(recoveryCodes.length);\n return recoveryCodes;\n }\n\n /**\n * The on-demand check (D15): proves the code again on this session and returns\n * when it was recorded. `purpose` is a short label for the log, e.g.\n * 'arm-live-trading' — it changes nothing. The bypass never satisfies this.\n */\n async verifyCode(entry: CodeEntry, purpose?: string): Promise<number> {\n const {codeVerifiedAtEpoch} = await this.#authenticatorCall<{codeVerifiedAtEpoch: number}>(\n 'POST', 'verify-code', {...entry, ...(purpose ? {purpose} : {})});\n return codeVerifiedAtEpoch;\n }\n\n async #authenticatorCall<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<T> {\n const url = `${this.#authUrls.login}/${path}`;\n const headers = {\n [HttpHeader.Authorization]: this.auth,\n [HttpHeader.AppContext]: 'brokenstock',\n ...(body !== undefined ? {[HttpHeader.ContentType]: 'application/json'} : {}),\n };\n try {\n return method === 'GET'\n ? await firstValueFrom(this.#httpClient.get<T>(url, {headers}))\n : await firstValueFrom(this.#httpClient.post<T>(url, body, {headers}));\n } catch (err) {\n if (err instanceof HttpErrorResponse) {\n const reason = err.error?.reason as AuthenticatorReason | undefined;\n const message = reason\n ? authenticatorMessage(reason)\n : err.status === 400 ? 'Check what you typed and try again.' : (err.error?.message ?? 'Something went wrong');\n throw new AuthenticatorError(reason, message, err.status);\n }\n throw err;\n }\n }\n\n /**\n * Renews the session, coordinating with the other windows of this browser.\n *\n * WHY COORDINATION IS REQUIRED, NOT AN OPTIMISATION. Every window shares one\n * session, so they all find the token expired at the same moment and all try\n * to renew. The server serialises rotation on the session row and REFUSES the\n * losers — so uncoordinated, every window but one is signed out, every token\n * lifetime, several times a day.\n *\n * The lock is taken with `ifAvailable`, so a window that does not get it is\n * told so immediately and then waits for the WINNER'S RESULT with a bound of\n * its own, rather than blocking on a peer it cannot supervise. A frozen\n * window holding the lock would otherwise stop every other window forever,\n * with nothing on screen and nothing logged.\n */\n async #doRefresh(): Promise<boolean> {\n if (!this.#sharedSession) return this.#renew();\n\n // Captured BEFORE asking for the lock: it is what \"did someone else renew\n // while I waited?\" is measured against.\n const before = this.#store.read();\n\n const outcome = await runExclusive(RENEWAL_LOCK, () => this.#renewOrAdopt(before));\n if (outcome.ran) return outcome.value;\n\n // Another window is renewing. Wait for its token to appear.\n const published = await awaitChange(() => this.#store.read(), before, PEER_RENEWAL_WAIT_MS);\n if (published) {\n this.#auth = published;\n return true;\n }\n // Either the winner cleared the token (its renewal failed permanently), or\n // it never delivered inside the bound. Re-read to tell those apart: an\n // absent token is a definite answer and must not be retried, whereas a\n // still-unchanged one means the winner is gone and this window should try.\n if (before && !this.#store.read()) return false;\n return this.#renewOrAdopt(before);\n }\n\n /**\n * The three-way rule, applied once this window holds the lock (PRD D5).\n *\n * Stated precisely because \"retry with a token different from the one you\n * failed with\" is not well defined: the in-window single-flight already\n * collapses requests that were sent with different tokens.\n */\n async #renewOrAdopt(before: BearerToken | undefined): Promise<boolean> {\n const current = this.#store.read();\n switch (decideRenewal(before, current)) {\n case 'sign-out':\n return false;\n case 'adopt':\n this.#auth = current!;\n return true;\n case 'renew':\n return this.#renew();\n }\n }\n\n /**\n * The renewal request itself.\n *\n * ⚠ THE TIMEOUT IS LOAD-BEARING. Without it a hung request holds the\n * cross-window lock indefinitely and every other window waits behind it.\n */\n async #renew(): Promise<boolean> {\n try {\n const response = await fetch(this.#authUrls.refresh, {\n method: 'POST',\n headers: {\n [HttpHeader.Authorization]: this.auth,\n [HttpHeader.AppContext]: 'brokenstock',\n },\n credentials: 'include',\n signal: AbortSignal.timeout(RENEWAL_TIMEOUT_MS),\n });\n if (!response.ok) return false;\n const auth = response.headers.get(HttpHeader.Authorization);\n if (!auth || !BEARER_TOKEN_REGEX.test(auth)) return false;\n const body: AuthenticationResponse = await response.json();\n this.#adoptToken(auth as BearerToken);\n // The raw token is stripped exactly as `login()` strips it. `/refresh`\n // returns `{session: {token}}`, and assigning that straight through put\n // the bearer into a PUBLIC signal — a second copy of the credential in a\n // place nothing needs it, which contradicts the care taken everywhere\n // else about where this token may live.\n const session = { ...(body.session ?? {}) } as Partial<UserSession> & { token?: string };\n delete session.token;\n this.userSession.set(session as UserSession);\n return true;\n } catch {\n // Includes the abort. A timed-out renewal is a failed renewal.\n return false;\n }\n }\n\n /**\n * THE ONE PLACE a session ends. Both sign-out paths route through here so the\n * stored token cannot outlive the session it belongs to — see `sessionLost`.\n */\n #clearSession(): void {\n this.authenticated.set(false);\n this.userSession.set(undefined);\n this.conflictSessions.set(undefined);\n this.pendingCredentials.set(undefined);\n this.codeStep.set('none');\n this.setupChallenge.set(undefined);\n this.recoveryCodesToShow.set(undefined);\n this.recoveryCodesLeft.set(undefined);\n this.bypassActive.set(false);\n this.#signInTicket = undefined;\n this.#auth = 'Bearer ..' as BearerToken;\n this.#store.clear();\n this.#router.navigate(['/login']).catch(console.error);\n }\n}\n","import { inject } from '@angular/core';\nimport {\n ActivatedRouteSnapshot,\n CanActivateFn,\n Router,\n RouterStateSnapshot,\n} from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\n\nexport const authGuard: CanActivateFn = (\n _route: ActivatedRouteSnapshot,\n state: RouterStateSnapshot,\n) => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n\n if (authService.authenticated()) {\n return true;\n }\n return router.createUrlTree(['/login'], {\n queryParams: { returnUrl: state.url },\n });\n};\n","import { inject } from '@angular/core';\nimport { CanActivateFn, Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { SHELL_POST_LOGIN_ROUTE } from '../tokens/shell-tokens';\n\nexport const guestGuard: CanActivateFn = () => {\n const authService = inject(AuthenticationService);\n const router = inject(Router);\n const postLoginRoute = inject(SHELL_POST_LOGIN_ROUTE, { optional: true }) ?? '/';\n\n if (authService.authenticated()) {\n return router.parseUrl(postLoginRoute);\n }\n return true;\n};\n","import { HttpInterceptorFn } from '@angular/common/http';\nimport { inject } from '@angular/core';\nimport { from, switchMap, catchError, throwError } from 'rxjs';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { SHELL_AUTH_URLS } from '../tokens/shell-tokens';\nimport { HttpHeader } from '@franzzemen/utility';\n\nexport const authInterceptor: HttpInterceptorFn = (req, next) => {\n const authService = inject(AuthenticationService);\n const authUrls = inject(SHELL_AUTH_URLS);\n\n return next(req).pipe(\n catchError((error) => {\n const isRefreshOrLogin = req.url === authUrls.refresh || req.url === authUrls.login;\n if (error.status === 401 && !isRefreshOrLogin) {\n return from(authService.refresh()).pipe(\n switchMap((refreshed) => {\n if (refreshed) {\n const retryReq = req.clone({\n setHeaders: { [HttpHeader.Authorization]: authService.auth },\n });\n return next(retryReq);\n }\n // `sessionLost()` and not the three lines that used to be here: it\n // also clears the STORED token. Leaving a dead token behind makes\n // every later window sign itself in, render, 401 and bounce.\n authService.sessionLost();\n return throwError(() => error);\n }),\n catchError(() => {\n authService.sessionLost();\n return throwError(() => error);\n }),\n );\n }\n return throwError(() => error);\n }),\n );\n};\n","import { Directive, input } from '@angular/core';\nimport { AbstractControl, NG_VALIDATORS, ValidationErrors, Validator } from '@angular/forms';\n\n@Directive({\n selector: '[regexValidator]',\n providers: [{ provide: NG_VALIDATORS, useExisting: RegexValidatorDirective, multi: true }],\n})\nexport class RegexValidatorDirective implements Validator {\n regex = input(/^[A-Z0-9._%+-@!?]{4,64}$/i);\n\n validate(control: AbstractControl): ValidationErrors | null {\n if (!control.value || !this.regex().test(control.value)) {\n return { regexValidator: { value: control.value } };\n }\n return null;\n }\n}\n","/**\n * Shared types for the FAQ help system.\n *\n * Manifest is generated by the build-time validator (E9) and read at runtime\n * by FaqContentLoader (E1) and FaqService (E2).\n */\n\nexport type FaqAudience = 'public' | 'authenticated';\nexport type FaqRenderContext = 'modal' | 'page';\n\n/** Raw frontmatter as authored in the `.md` file. */\nexport interface FaqFrontmatter {\n title: string;\n category: string;\n order?: number;\n audience?: FaqAudience;\n 'image-prefix'?: string;\n description?: string;\n 'seo-ready'?: boolean;\n}\n\n/** One row in the generated manifest — normalized form of frontmatter + file path. */\nexport interface FaqEntry {\n /** Dot-notation key, e.g. \"trade.segments\". */\n key: string;\n title: string;\n category: string;\n order: number;\n audience: FaqAudience;\n description?: string;\n seoReady: boolean;\n imagePrefix?: string;\n /**\n * Path to the source file relative to `/assets/faq/`, without `.md`.\n * Example: `trade/segments` (subdirs allowed; key path-separator is `.`,\n * file path-separator is `/`).\n */\n file: string;\n}\n\nexport interface FaqManifest {\n /** ISO timestamp set by the validator at generation time. */\n generatedAt: string;\n entries: FaqEntry[];\n}\n\nexport interface ParsedFaq {\n frontmatter: FaqFrontmatter;\n body: string;\n}\n\nexport interface FaqRenderOptions {\n context: FaqRenderContext;\n /**\n * Optional override for the entry's `image-prefix` frontmatter.\n * When set, relative image hrefs are prefixed with this string.\n */\n imagePrefix?: string;\n}\n","import { InjectionToken } from '@angular/core';\nimport { FaqManifest } from './faq.types';\n\n/**\n * Pluggable content source for FAQ markdown + manifest.\n *\n * Default implementation is `HttpFaqContentLoader`, which fetches from\n * `/assets/faq/manifest.json` and `/assets/faq/<file>.md`. Consumer apps\n * may override (e.g. broken-stock-admin pulling from an internal source),\n * but most apps will just use the HTTP default.\n */\nexport interface FaqContentLoader {\n /** Loads (and may cache) the manifest. Idempotent. */\n loadManifest(): Promise<FaqManifest>;\n\n /**\n * Resolves the manifest entry for `key`, then loads its .md body.\n * Returns `null` when the key is not in the manifest.\n */\n loadContent(key: string): Promise<string | null>;\n}\n\nexport const FAQ_CONTENT_LOADER = new InjectionToken<FaqContentLoader>(\n 'FAQ_CONTENT_LOADER',\n);\n","import { Injectable } from '@angular/core';\nimport { Marked, Renderer } from 'marked';\nimport { gfmHeadingId } from 'marked-gfm-heading-id';\nimport fm from 'front-matter';\nimport { FaqFrontmatter, FaqRenderOptions, ParsedFaq } from './faq.types';\n\n/**\n * Stateless markdown renderer for FAQ content.\n *\n * Two responsibilities:\n * 1. Split a `.md` file into `{ frontmatter, body }` (front-matter parser).\n * 2. Render the body to HTML via marked with a context-aware link hook:\n * - `faq:<key>` — in-modal nav (modal) | `<a href=\"/help/<file>\">` (page)\n * - `app:/path` — close-modal-and-route (modal) | `<a href=\"/path\">` (page)\n * - `http(s)://...` — external, target=_blank rel=noopener (both)\n * - `#anchor` — intra-page scroll (both)\n *\n * In modal context, links are emitted with `data-faq-href` / `data-faq-kind`\n * sentinels so the modal's click handler (E5) can intercept and dispatch.\n * In page context, links are emitted as plain navigable anchors; the prerendered\n * static HTML can be clicked through directly.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqMarkdownRendererService {\n parse(raw: string): ParsedFaq {\n const parsed = fm<FaqFrontmatter>(raw);\n return {\n frontmatter: parsed.attributes,\n body: parsed.body,\n };\n }\n\n render(body: string, opts: FaqRenderOptions): string {\n const marked = new Marked({ gfm: true, breaks: false });\n marked.use(gfmHeadingId());\n marked.use({ renderer: this.buildRenderer(opts) });\n return marked.parse(body, { async: false }) as string;\n }\n\n private buildRenderer(opts: FaqRenderOptions): Partial<Renderer> {\n const { context, imagePrefix } = opts;\n return {\n link: ({ href, title, tokens }) => {\n // marked passes child tokens; we render their textual form ourselves.\n const text = tokens.map((t) => ('text' in t ? t.text : '')).join('');\n const titleAttr = title ? ` title=\"${escapeAttr(title)}\"` : '';\n\n // Intra-page anchor\n if (href.startsWith('#')) {\n return `<a href=\"${escapeAttr(href)}\"${titleAttr} data-faq-kind=\"anchor\">${text}</a>`;\n }\n\n // faq: protocol — in-modal nav (modal) | static link to /help/<key path> (page)\n if (href.startsWith('faq:')) {\n const key = href.slice('faq:'.length);\n if (context === 'modal') {\n return `<a href=\"#\" data-faq-href=\"${escapeAttr(href)}\" data-faq-kind=\"faq\">${text}</a>`;\n }\n const filePath = key.replace(/\\./g, '/');\n return `<a href=\"/help/${escapeAttr(filePath)}\"${titleAttr} data-faq-kind=\"faq\">${text}</a>`;\n }\n\n // app: protocol — close modal + route (modal) | normal anchor (page)\n if (href.startsWith('app:')) {\n const path = href.slice('app:'.length);\n if (context === 'modal') {\n return `<a href=\"#\" data-faq-href=\"${escapeAttr(href)}\" data-faq-kind=\"app\">${text} <span class=\"faq-app-arrow\" aria-hidden=\"true\">→</span></a>`;\n }\n return `<a href=\"${escapeAttr(path)}\"${titleAttr} data-faq-kind=\"app\">${text} <span class=\"faq-app-arrow\" aria-hidden=\"true\">→</span></a>`;\n }\n\n // External\n if (/^https?:\\/\\//i.test(href)) {\n return `<a href=\"${escapeAttr(href)}\"${titleAttr} target=\"_blank\" rel=\"noopener\" data-faq-kind=\"external\">${text}</a>`;\n }\n\n // Fallback: treat as relative; render plain anchor.\n return `<a href=\"${escapeAttr(href)}\"${titleAttr}>${text}</a>`;\n },\n image: ({ href, title, text }) => {\n const resolved = resolveImageHref(href, imagePrefix);\n const titleAttr = title ? ` title=\"${escapeAttr(title)}\"` : '';\n return `<img src=\"${escapeAttr(resolved)}\" alt=\"${escapeAttr(text)}\"${titleAttr} loading=\"lazy\" />`;\n },\n };\n }\n}\n\nfunction escapeAttr(s: string): string {\n return s.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<');\n}\n\nfunction resolveImageHref(href: string, prefix: string | undefined): string {\n if (!prefix) return href;\n if (/^([a-z]+:)?\\/\\//i.test(href) || href.startsWith('/')) return href;\n const cleaned = prefix.endsWith('/') ? prefix : `${prefix}/`;\n return `${cleaned}${href}`;\n}\n","import { HttpClient } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { firstValueFrom } from 'rxjs';\nimport { FaqContentLoader } from './faq-content-loader.token';\nimport { FaqEntry, FaqManifest } from './faq.types';\n\n/**\n * Default FaqContentLoader. Reads the build-generated manifest from\n * `/assets/faq/manifest.json` and lazy-fetches individual `.md` files\n * from `/assets/faq/<entry.file>.md`.\n *\n * Manifest is cached after first load; .md fetches are cached per key.\n */\n@Injectable({ providedIn: 'root' })\nexport class HttpFaqContentLoader implements FaqContentLoader {\n private readonly http = inject(HttpClient);\n private manifestPromise: Promise<FaqManifest> | null = null;\n private readonly contentCache = new Map<string, Promise<string | null>>();\n\n loadManifest(): Promise<FaqManifest> {\n if (!this.manifestPromise) {\n this.manifestPromise = firstValueFrom(\n this.http.get<FaqManifest>('/assets/faq/manifest.json'),\n ).catch((err) => {\n this.manifestPromise = null;\n throw err;\n });\n }\n return this.manifestPromise;\n }\n\n async loadContent(key: string): Promise<string | null> {\n const cached = this.contentCache.get(key);\n if (cached) return cached;\n\n const manifest = await this.loadManifest();\n const entry = manifest.entries.find((e: FaqEntry) => e.key === key);\n if (!entry) return null;\n\n const fetchPromise = firstValueFrom(\n this.http.get(`/assets/faq/${entry.file}.md`, { responseType: 'text' }),\n ).catch(() => null);\n this.contentCache.set(key, fetchPromise);\n return fetchPromise;\n }\n}\n","import { Injectable, signal } from '@angular/core';\n\n/**\n * E8 — In-modal navigation history.\n *\n * The browser's `history` API is shared by Angular Router and any other\n * code that calls `pushState`. We tag each FAQ entry's state object with\n * `faq: true` so we can distinguish our entries from router/app entries.\n *\n * On open: `pushState({faq:true, faqPosition:0})` once; stack=[initialKey].\n * On in-modal nav: truncate forward, push key, `pushState({faq:true,\n * faqPosition:position})`.\n * On browser back/forward (`popstate`):\n * - If next state has `faq:true` → set position to its `faqPosition`,\n * swap content for `stack[position]`.\n * - If next state lacks `faq:true` (user backed out of the modal entirely)\n * → close modal without further history manipulation.\n * On explicit close (close button / Esc / backdrop): `history.go(-(position+1))`\n * to unwind our entries; suppress in-flight popstates while unwinding;\n * finalize close once we've seen the expected number of popstates.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqHistoryService {\n private readonly _stack = signal<string[]>([]);\n private readonly _position = signal(0);\n readonly stack = this._stack.asReadonly();\n readonly position = this._position.asReadonly();\n\n /** True when popstate is processing the unwind kicked off by closeAndUnwind(). */\n private unwinding = false;\n private unwindRemaining = 0;\n private onUnwindComplete: (() => void) | null = null;\n\n private popstateListener: ((e: PopStateEvent) => void) | null = null;\n private onInModalNav: ((key: string) => void) | null = null;\n private onExitModal: (() => void) | null = null;\n\n /**\n * Begin a new FAQ history session. Pushes the initial state entry and\n * starts listening for popstate. Callbacks fire for in-modal navs and\n * for popping out of FAQ entirely.\n */\n begin(\n initialKey: string,\n onNav: (key: string) => void,\n onExit: () => void,\n ): void {\n this._stack.set([initialKey]);\n this._position.set(0);\n this.onInModalNav = onNav;\n this.onExitModal = onExit;\n this.pushHistoryState(0);\n this.attachListener();\n }\n\n /** Push a new key onto the stack. Truncates any forward history. */\n navigate(key: string): void {\n const stack = this._stack();\n const pos = this._position();\n const next = [...stack.slice(0, pos + 1), key];\n const nextPos = next.length - 1;\n this._stack.set(next);\n this._position.set(nextPos);\n this.pushHistoryState(nextPos);\n }\n\n canGoBack(): boolean {\n return this._position() > 0;\n }\n\n canGoForward(): boolean {\n return this._position() < this._stack().length - 1;\n }\n\n /** Programmatic back — triggers a real browser back so popstate handles UI. */\n back(): void {\n if (!this.canGoBack()) return;\n history.back();\n }\n\n forward(): void {\n if (!this.canGoForward()) return;\n history.forward();\n }\n\n /** Currently rendered key. */\n currentKey(): string | null {\n return this._stack()[this._position()] ?? null;\n }\n\n /**\n * Close the modal cleanly by unwinding our FAQ history entries so the\n * underlying app route is left exactly where it was before the modal opened.\n * `onComplete` fires after the unwind settles.\n */\n closeAndUnwind(onComplete: () => void): void {\n const depth = this._position() + 1;\n if (depth === 0) {\n this.teardown();\n onComplete();\n return;\n }\n this.unwinding = true;\n this.unwindRemaining = depth;\n this.onUnwindComplete = () => {\n this.teardown();\n onComplete();\n };\n history.go(-depth);\n }\n\n private teardown(): void {\n this._stack.set([]);\n this._position.set(0);\n this.detachListener();\n this.onInModalNav = null;\n this.onExitModal = null;\n this.unwinding = false;\n this.unwindRemaining = 0;\n this.onUnwindComplete = null;\n }\n\n private pushHistoryState(position: number): void {\n history.pushState({ faq: true, faqPosition: position }, '');\n }\n\n private attachListener(): void {\n if (this.popstateListener) return;\n this.popstateListener = (e: PopStateEvent) => this.handlePopState(e);\n window.addEventListener('popstate', this.popstateListener);\n }\n\n private detachListener(): void {\n if (!this.popstateListener) return;\n window.removeEventListener('popstate', this.popstateListener);\n this.popstateListener = null;\n }\n\n private handlePopState(e: PopStateEvent): void {\n if (this.unwinding) {\n this.unwindRemaining--;\n if (this.unwindRemaining <= 0) {\n const cb = this.onUnwindComplete;\n this.onUnwindComplete = null;\n cb?.();\n }\n return;\n }\n const state = e.state as { faq?: boolean; faqPosition?: number } | null;\n if (state?.faq && typeof state.faqPosition === 'number') {\n // In-modal back/forward\n const target = state.faqPosition;\n this._position.set(target);\n const key = this._stack()[target];\n if (key && this.onInModalNav) this.onInModalNav(key);\n return;\n }\n // User backed out beyond our entries — close modal, leave history alone.\n const exit = this.onExitModal;\n this.teardown();\n exit?.();\n }\n}\n","import { Injectable, computed, inject, signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AuthenticationService } from '../services/authentication.service';\nimport { FAQ_CONTENT_LOADER } from './faq-content-loader.token';\nimport { FaqHistoryService } from './faq-history.service';\nimport { FaqAudience, FaqEntry, FaqManifest } from './faq.types';\n\nexport interface FaqRegistrationHandle {\n /** Call from the component's destroy hook (or DestroyRef) to clear the registration. */\n deregister(): void;\n}\n\nexport interface FaqResolution {\n /** The key that produced a content match, or `null` when nothing matched. */\n key: string | null;\n /** Raw .md content for `key`, or `null` when nothing matched. */\n content: string | null;\n /** The entry whose content was returned, or `null` when nothing matched. */\n entry: FaqEntry | null;\n /**\n * The chain of keys actually attempted, in order\n * (e.g. `[\"trade.segments\", \"trade\", \"index\"]`).\n */\n attempted: string[];\n}\n\n/**\n * Central FAQ state + resolution service.\n *\n * Responsibilities:\n * - Track the current route's FAQ key (set by components on activation /\n * tab change via `register()`).\n * - Lazy-load and cache the FAQ manifest from the configured FaqContentLoader.\n * - Resolve a dot-notation key against the manifest with parent fallback,\n * audience filtering, and `index` as the terminal fallback.\n */\n@Injectable({ providedIn: 'root' })\nexport class FaqService {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly history = inject(FaqHistoryService);\n private readonly auth = inject(AuthenticationService);\n private readonly router = inject(Router);\n\n private readonly _currentFaqKey = signal<string | null>(null);\n /** Component-set current key. Bare `faq` opens at this key. */\n readonly currentFaqKey = this._currentFaqKey.asReadonly();\n\n private readonly _manifest = signal<FaqManifest | null>(null);\n readonly manifest = this._manifest.asReadonly();\n readonly entries = computed(() => this._manifest()?.entries ?? []);\n\n // Modal state (E3 + E8).\n private readonly _modalOpen = signal(false);\n readonly modalOpen = this._modalOpen.asReadonly();\n\n private readonly _activeEntry = signal<FaqEntry | null>(null);\n readonly activeEntry = this._activeEntry.asReadonly();\n\n private readonly _activeContent = signal<string | null>(null);\n readonly activeContent = this._activeContent.asReadonly();\n\n private readonly _activeAttempted = signal<string[]>([]);\n readonly activeAttempted = this._activeAttempted.asReadonly();\n\n private readonly _navigating = signal(false);\n readonly navigating = this._navigating.asReadonly();\n\n // Search pre-fill consumed by E4 search UI on modal open / navigateTo.\n private readonly _initialSearchTerm = signal<string | null>(null);\n readonly initialSearchTerm = this._initialSearchTerm.asReadonly();\n\n /** Called by the search UI once it has consumed the pre-fill term. */\n consumeInitialSearchTerm(): void {\n this._initialSearchTerm.set(null);\n }\n\n readonly canGoBack = computed(() => this.history.position() > 0);\n readonly canGoForward = computed(\n () => this.history.position() < this.history.stack().length - 1,\n );\n\n private manifestPromise: Promise<FaqManifest> | null = null;\n\n /**\n * Triggers manifest load if not already loaded. Idempotent. Subsequent\n * calls return the cached promise.\n */\n ensureManifest(): Promise<FaqManifest> {\n if (this._manifest()) return Promise.resolve(this._manifest()!);\n if (!this.manifestPromise) {\n this.manifestPromise = this.loader\n .loadManifest()\n .then((m) => {\n this._manifest.set(m);\n return m;\n })\n .catch((err) => {\n this.manifestPromise = null;\n throw err;\n });\n }\n return this.manifestPromise;\n }\n\n /**\n * Walks the dot-notation fallback chain (`a.b.c` → `a.b` → `a` → `index`)\n * and returns the first entry whose audience allows the caller and whose\n * content loads. Audience filtering: unauthenticated callers only see\n * `audience: public` entries.\n */\n async resolveKey(\n key: string | null,\n isAuthenticated: boolean,\n ): Promise<FaqResolution> {\n await this.ensureManifest();\n const entries = this.entries();\n const chain = buildFallbackChain(key);\n\n for (const candidate of chain) {\n const entry = entries.find((e) => e.key === candidate);\n if (!entry) continue;\n if (!audienceAllowed(entry.audience, isAuthenticated)) continue;\n const content = await this.loader.loadContent(entry.key);\n if (content === null) continue;\n return { key: entry.key, content, entry, attempted: chain };\n }\n\n return { key: null, content: null, entry: null, attempted: chain };\n }\n\n /**\n * Component registration. Sets `currentFaqKey`; on `deregister()` the\n * key is cleared only if it still matches (so a sibling tab activating\n * mid-teardown doesn't get its key clobbered).\n */\n register(key: string): FaqRegistrationHandle {\n this._currentFaqKey.set(key);\n return {\n deregister: () => {\n if (this._currentFaqKey() === key) this._currentFaqKey.set(null);\n },\n };\n }\n\n /**\n * E3 — Open the FAQ modal. If `initialKey` is omitted, falls back to\n * `currentFaqKey` and then to `'index'`. Resolves the key, loads content,\n * and starts an E8 history session so subsequent in-modal nav uses\n * `history.pushState`.\n */\n async openModal(\n initialKey?: string,\n opts?: { searchTerm?: string },\n ): Promise<void> {\n // Unauthenticated visitors get routed to the public /help SSR surface\n // instead of the in-app modal. The modal is an authenticated experience;\n // /help/* is the SEO/marketing-funnel surface.\n if (!this.auth.authenticated()) {\n await this.ensureManifest();\n const entries = this.entries();\n const target = initialKey ?? this._currentFaqKey() ?? null;\n let route = '/help';\n if (target) {\n const chain = buildFallbackChain(target);\n for (const candidate of chain) {\n const entry = entries.find((e) => e.key === candidate);\n if (entry && entry.audience === 'public' && entry.seoReady) {\n route = `/help/${entry.file}`;\n break;\n }\n }\n }\n await this.router.navigateByUrl(route);\n return;\n }\n\n const searchTerm = opts?.searchTerm?.trim();\n this._initialSearchTerm.set(searchTerm && searchTerm.length > 0 ? searchTerm : null);\n if (this._modalOpen()) {\n // Already open — treat as a navigate-to instead.\n if (initialKey) await this.navigateTo(initialKey);\n return;\n }\n const target = initialKey ?? this._currentFaqKey() ?? 'index';\n this._modalOpen.set(true);\n await this.loadIntoActive(target);\n const resolved = this._activeEntry()?.key ?? target;\n this.history.begin(\n resolved,\n (key) => {\n // popstate-driven in-modal nav: load without pushing a new entry.\n void this.loadIntoActive(key);\n },\n () => {\n // User backed out of FAQ history entirely — close without unwinding.\n this.finalizeClose();\n },\n );\n }\n\n /**\n * Programmatic in-modal nav. Pushes a new history entry and loads `key`\n * into the active slot. Use this for click handlers on `faq:` links and\n * for the TOC sidebar.\n */\n async navigateTo(key: string): Promise<void> {\n if (!this._modalOpen()) {\n await this.openModal(key);\n return;\n }\n await this.loadIntoActive(key);\n const resolved = this._activeEntry()?.key ?? key;\n this.history.navigate(resolved);\n }\n\n back(): void {\n this.history.back();\n }\n forward(): void {\n this.history.forward();\n }\n\n /**\n * Close button / Esc / backdrop close. Unwinds the FAQ history entries\n * so the underlying app route is left untouched.\n */\n closeModal(): void {\n if (!this._modalOpen()) return;\n this.history.closeAndUnwind(() => this.finalizeClose());\n }\n\n private finalizeClose(): void {\n this._modalOpen.set(false);\n this._activeContent.set(null);\n this._activeEntry.set(null);\n this._activeAttempted.set([]);\n }\n\n private async loadIntoActive(key: string): Promise<void> {\n this._navigating.set(true);\n try {\n const resolution = await this.resolveKey(key, this.auth.authenticated());\n this._activeEntry.set(resolution.entry);\n this._activeContent.set(resolution.content);\n this._activeAttempted.set(resolution.attempted);\n } finally {\n this._navigating.set(false);\n }\n }\n}\n\nexport function buildFallbackChain(key: string | null): string[] {\n if (!key) return ['index'];\n const parts = key.split('.').filter(Boolean);\n if (parts.length === 0) return ['index'];\n const chain: string[] = [];\n for (let i = parts.length; i > 0; i--) {\n chain.push(parts.slice(0, i).join('.'));\n }\n chain.push('index');\n return chain;\n}\n\nexport function audienceAllowed(\n audience: FaqAudience,\n isAuthenticated: boolean,\n): boolean {\n if (audience === 'public') return true;\n return isAuthenticated;\n}\n","import { InjectionToken, isDevMode } from '@angular/core';\n\n/**\n * Gate for the dev-only FAQ authoring panel (E11).\n *\n * Defaults to Angular's `isDevMode()` so the panel auto-enables in `ng serve`\n * and auto-disables in production builds. Consumers can override with an\n * explicit value (e.g. `!environment.production`, or `true` for a staging\n * diagnostic build) via `{provide: FAQ_DEV_MODE, useValue: ...}`.\n *\n * The panel is loaded via dynamic `import()` and lives in its own lazy chunk;\n * builds where this resolves to `false` never request the chunk.\n */\nexport const FAQ_DEV_MODE = new InjectionToken<boolean>('FAQ_DEV_MODE', {\n providedIn: 'root',\n factory: () => isDevMode(),\n});\n\n/**\n * Optional absolute filesystem root of the consuming app's workspace (e.g.\n * `/Users/foo/dev/broken-stock`). When set, the authoring panel emits\n * `webstorm://open?file=<root>/<relative-path>` deeplinks pointing at the\n * exact source file. When unset, the panel falls back to a relative path.\n */\nexport const FAQ_DEV_WORKSPACE_ROOT = new InjectionToken<string>(\n 'FAQ_DEV_WORKSPACE_ROOT',\n { providedIn: 'root', factory: () => '' },\n);\n\n/**\n * Editor URL scheme for the \"Open in editor\" deeplink. Defaults to WebStorm.\n * Set to `'vscode'` (or any custom scheme handler) per consuming app.\n */\nexport type FaqDevEditor = 'webstorm' | 'vscode';\nexport const FAQ_DEV_EDITOR = new InjectionToken<FaqDevEditor>(\n 'FAQ_DEV_EDITOR',\n { providedIn: 'root', factory: () => 'webstorm' },\n);\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostListener,\n ViewChild,\n ViewEncapsulation,\n computed,\n effect,\n inject,\n signal,\n untracked,\n} from '@angular/core';\nimport { Router } from '@angular/router';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { FaqAuthoringPanel } from '../faq-authoring-panel/faq-authoring-panel';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FAQ_DEV_MODE } from '../faq-dev-mode.token';\nimport { FaqMarkdownRendererService } from '../faq-markdown-renderer.service';\nimport { FaqService } from '../faq.service';\nimport { FaqEntry } from '../faq.types';\n\ninterface TocGroup {\n category: string;\n entries: FaqEntry[];\n}\n\ninterface SearchResult {\n key: string;\n title: string;\n category: string;\n snippet: string;\n}\n\n// Minimal structural type so we don't depend on fuse.js types at parse time\n// (the package is dynamic-imported on first search activation).\ninterface FuseLike<T> {\n search(query: string): Array<{\n item: T;\n matches?: ReadonlyArray<{\n key?: string;\n indices: ReadonlyArray<readonly [number, number]>;\n }>;\n }>;\n}\n\ninterface SearchDoc {\n key: string;\n title: string;\n category: string;\n body: string;\n}\n\n/**\n * E3 — FAQ modal. Two-pane layout (TOC sidebar + content pane), 80% viewport.\n *\n * E4 — Search uses a lazy-imported `fuse.js` index over title + body,\n * built on first search activation, filtered by audience, cached for the\n * modal session and invalidated on auth state change.\n *\n * E5 — `app:` link clicks close the modal and route to the app path; the\n * returnUrl-aware `authGuard` funnels unauthenticated users through\n * `/login?returnUrl=...`, and `Login` honors returnUrl on success.\n */\n@Component({\n selector: 'faq-modal',\n standalone: true,\n imports: [FaqAuthoringPanel],\n templateUrl: './faq-modal.html',\n styleUrl: './faq-modal.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class FaqModal {\n readonly devMode = inject(FAQ_DEV_MODE);\n\n private readonly faq = inject(FaqService);\n private readonly renderer = inject(FaqMarkdownRendererService);\n private readonly auth = inject(AuthenticationService);\n private readonly router = inject(Router);\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n\n readonly open = this.faq.modalOpen;\n readonly navigating = this.faq.navigating;\n readonly activeEntry = this.faq.activeEntry;\n readonly attempted = this.faq.activeAttempted;\n readonly canGoBack = this.faq.canGoBack;\n readonly canGoForward = this.faq.canGoForward;\n\n readonly sidebarCollapsed = signal(false);\n readonly searchMode = signal(false);\n readonly searchQuery = signal('');\n readonly searchLoading = signal(false);\n readonly searchResults = signal<SearchResult[]>([]);\n\n private fuse: FuseLike<SearchDoc> | null = null;\n private fuseBuild: Promise<void> | null = null;\n\n readonly renderedHtml = computed(() => {\n const content = this.faq.activeContent();\n const entry = this.faq.activeEntry();\n if (!content) return '';\n const parsed = this.renderer.parse(content);\n return this.renderer.render(parsed.body, {\n context: 'modal',\n imagePrefix: entry?.imagePrefix ?? parsed.frontmatter['image-prefix'],\n });\n });\n\n readonly toc = computed<TocGroup[]>(() => {\n const isAuth = this.auth.authenticated();\n const entries = this.faq.entries().filter((e) => {\n if (e.audience === 'public') return true;\n return isAuth;\n });\n const groups = new Map<string, FaqEntry[]>();\n for (const e of entries) {\n const list = groups.get(e.category) ?? [];\n list.push(e);\n groups.set(e.category, list);\n }\n return [...groups.entries()]\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([category, list]) => ({\n category,\n entries: list.sort(\n (a, b) =>\n a.order - b.order || a.title.localeCompare(b.title),\n ),\n }));\n });\n\n @ViewChild('contentPane') contentPaneRef?: ElementRef<HTMLDivElement>;\n\n constructor() {\n // Scroll content pane to top on key change.\n effect(() => {\n this.activeEntry();\n queueMicrotask(() => {\n this.contentPaneRef?.nativeElement.scrollTo({ top: 0 });\n });\n });\n\n // Invalidate the search index on auth state change so the audience\n // filter is re-applied on next search activation.\n effect(() => {\n this.auth.authenticated();\n this.fuse = null;\n this.fuseBuild = null;\n if (this.searchMode()) this.searchResults.set([]);\n });\n\n // Consume `faq search <term>` pre-fill: when FaqService.initialSearchTerm\n // is non-null while the modal is open, switch to search mode with that\n // query and immediately invoke the index build.\n effect(() => {\n const term = this.faq.initialSearchTerm();\n if (!term || !this.faq.modalOpen()) return;\n untracked(() => {\n this.searchMode.set(true);\n this.searchQuery.set(term);\n this.faq.consumeInitialSearchTerm();\n void this.ensureSearchIndex().then(() => this.runSearch(term));\n });\n });\n }\n\n @HostListener('document:keydown.escape')\n onEscape(): void {\n if (this.open()) this.close();\n }\n\n close(): void {\n this.faq.closeModal();\n }\n\n onBackdropClick(): void {\n this.close();\n }\n\n stopPropagation(event: Event): void {\n event.stopPropagation();\n }\n\n toggleSidebar(): void {\n this.sidebarCollapsed.update((v) => !v);\n }\n\n goBack(): void {\n this.faq.back();\n }\n\n goForward(): void {\n this.faq.forward();\n }\n\n goIndex(): void {\n void this.faq.navigateTo('index');\n }\n\n toggleSearch(): void {\n const next = !this.searchMode();\n this.searchMode.set(next);\n if (next) {\n void this.ensureSearchIndex().then(() => this.runSearch(this.searchQuery()));\n }\n }\n\n onSearchInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.searchQuery.set(value);\n void this.ensureSearchIndex().then(() => this.runSearch(value));\n }\n\n onSearchResultClick(key: string): void {\n void this.faq.navigateTo(key);\n }\n\n onTocClick(key: string): void {\n void this.faq.navigateTo(key);\n }\n\n private async ensureSearchIndex(): Promise<void> {\n if (this.fuse) return;\n if (this.fuseBuild) return this.fuseBuild;\n this.searchLoading.set(true);\n this.fuseBuild = (async () => {\n const [{ default: Fuse }] = await Promise.all([\n import('fuse.js'),\n this.faq.ensureManifest(),\n ]);\n const isAuth = this.auth.authenticated();\n const entries = this.faq.entries().filter((e) =>\n e.audience === 'public' ? true : isAuth,\n );\n const docs: SearchDoc[] = await Promise.all(\n entries.map(async (e) => {\n const body = (await this.loader.loadContent(e.key)) ?? '';\n return { key: e.key, title: e.title, category: e.category, body };\n }),\n );\n this.fuse = new Fuse(docs, {\n keys: [\n { name: 'title', weight: 0.6 },\n { name: 'body', weight: 0.4 },\n ],\n includeMatches: true,\n ignoreLocation: true,\n threshold: 0.4,\n minMatchCharLength: 2,\n }) as unknown as FuseLike<SearchDoc>;\n })()\n .catch((err) => {\n console.error('FAQ search index build failed', err);\n this.fuseBuild = null;\n })\n .finally(() => {\n this.searchLoading.set(false);\n });\n return this.fuseBuild;\n }\n\n private runSearch(query: string): void {\n const q = query.trim();\n if (!q || !this.fuse) {\n this.searchResults.set([]);\n return;\n }\n const hits = this.fuse.search(q).slice(0, 30);\n this.searchResults.set(\n hits.map((h) => ({\n key: h.item.key,\n title: h.item.title,\n category: h.item.category,\n snippet: buildSnippet(h.item.body, h.matches),\n })),\n );\n }\n\n /**\n * Event-delegated click handler for the rendered content pane.\n * Intercepts our sentinel anchors emitted by FaqMarkdownRendererService.\n */\n onContentClick(event: MouseEvent): void {\n const target = event.target;\n if (!(target instanceof HTMLElement)) return;\n const anchor = target.closest<HTMLAnchorElement>('a[data-faq-kind]');\n if (!anchor) return;\n const kind = anchor.getAttribute('data-faq-kind');\n\n if (kind === 'external') {\n return;\n }\n\n if (kind === 'anchor') {\n event.preventDefault();\n const href = anchor.getAttribute('href') ?? '';\n const id = href.startsWith('#') ? href.slice(1) : href;\n if (!id) return;\n const pane = this.contentPaneRef?.nativeElement;\n const el = pane?.querySelector(`#${CSS.escape(id)}`);\n el?.scrollIntoView({ behavior: 'smooth', block: 'start' });\n return;\n }\n\n const faqHref = anchor.getAttribute('data-faq-href') ?? '';\n\n if (kind === 'faq' && faqHref.startsWith('faq:')) {\n event.preventDefault();\n const key = faqHref.slice('faq:'.length);\n void this.faq.navigateTo(key);\n return;\n }\n\n if (kind === 'app' && faqHref.startsWith('app:')) {\n event.preventDefault();\n const path = faqHref.slice('app:'.length);\n this.close();\n // Defer route until after modal close finishes unwinding history,\n // so navigation lands as a fresh entry on top of the pre-modal URL.\n // The returnUrl-aware authGuard handles unauthenticated callers by\n // redirecting to /login?returnUrl=<path>; Login honors it on success.\n queueMicrotask(() => {\n void this.router.navigateByUrl(path);\n });\n return;\n }\n }\n}\n\n/**\n * Builds a short contextual snippet around the first body match. Falls back\n * to the head of the body when the only matches are in the title.\n */\nfunction buildSnippet(\n body: string,\n matches:\n | ReadonlyArray<{\n key?: string;\n indices: ReadonlyArray<readonly [number, number]>;\n }>\n | undefined,\n): string {\n const RADIUS = 60;\n const MAX = 180;\n const bodyMatch = matches?.find((m) => m.key === 'body' && m.indices.length);\n if (!bodyMatch) {\n return body.replace(/\\s+/g, ' ').slice(0, MAX).trim();\n }\n const [start, end] = bodyMatch.indices[0];\n const from = Math.max(0, start - RADIUS);\n const to = Math.min(body.length, end + RADIUS);\n let snippet = body.slice(from, to).replace(/\\s+/g, ' ').trim();\n if (from > 0) snippet = '…' + snippet;\n if (to < body.length) snippet = snippet + '…';\n return snippet.length > MAX ? snippet.slice(0, MAX) + '…' : snippet;\n}\n","@if (open()) {\n <div class=\"faq-backdrop\" (click)=\"onBackdropClick()\" role=\"presentation\">\n <div\n class=\"faq-modal\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"activeEntry()?.title ?? 'FAQ'\"\n (click)=\"stopPropagation($event)\"\n >\n <header class=\"faq-toolbar\">\n <div class=\"faq-toolbar-nav\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSidebar()\"\n [attr.aria-label]=\"sidebarCollapsed() ? 'Show contents' : 'Hide contents'\"\n [attr.aria-pressed]=\"!sidebarCollapsed()\"\n >☰</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goBack()\"\n [disabled]=\"!canGoBack()\"\n aria-label=\"Back\"\n >‹</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goForward()\"\n [disabled]=\"!canGoForward()\"\n aria-label=\"Forward\"\n >›</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"goIndex()\"\n aria-label=\"Index\"\n >⌂</button>\n </div>\n <div class=\"faq-toolbar-title\">\n @if (activeEntry(); as entry) {\n <span class=\"faq-category\">{{ entry.category }}</span>\n <span class=\"faq-sep\">/</span>\n <span class=\"faq-title\">{{ entry.title }}</span>\n } @else {\n <span class=\"faq-title\">FAQ</span>\n }\n </div>\n <div class=\"faq-toolbar-actions\">\n <button\n type=\"button\"\n class=\"faq-icon-btn\"\n (click)=\"toggleSearch()\"\n [class.active]=\"searchMode()\"\n aria-label=\"Search\"\n >⌕</button>\n <button\n type=\"button\"\n class=\"faq-icon-btn faq-close-btn\"\n (click)=\"close()\"\n aria-label=\"Close\"\n >✕</button>\n </div>\n </header>\n\n <div class=\"faq-body\" [class.sidebar-collapsed]=\"sidebarCollapsed()\">\n <aside class=\"faq-sidebar\" aria-label=\"FAQ contents\">\n @if (searchMode()) {\n <div class=\"faq-search\">\n <input\n type=\"search\"\n class=\"faq-search-input\"\n placeholder=\"Search FAQ…\"\n aria-label=\"Search FAQ\"\n [value]=\"searchQuery()\"\n (input)=\"onSearchInput($event)\"\n />\n @if (searchLoading()) {\n <p class=\"faq-search-status\">Building index…</p>\n } @else if (!searchQuery().trim()) {\n <p class=\"faq-search-status\">Type to search titles and content.</p>\n } @else if (searchResults().length === 0) {\n <p class=\"faq-search-status\">No matches.</p>\n } @else {\n <ul class=\"faq-search-results\">\n @for (r of searchResults(); track r.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-search-result\"\n [class.active]=\"activeEntry()?.key === r.key\"\n (click)=\"onSearchResultClick(r.key)\"\n >\n <span class=\"faq-search-result-title\">{{ r.title }}</span>\n <span class=\"faq-search-result-category\">{{ r.category }}</span>\n @if (r.snippet) {\n <span class=\"faq-search-result-snippet\">{{ r.snippet }}</span>\n }\n </button>\n </li>\n }\n </ul>\n }\n </div>\n } @else {\n <nav class=\"faq-toc\">\n @for (group of toc(); track group.category) {\n <div class=\"faq-toc-group\">\n <h3 class=\"faq-toc-category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <button\n type=\"button\"\n class=\"faq-toc-link\"\n [class.active]=\"activeEntry()?.key === entry.key\"\n (click)=\"onTocClick(entry.key)\"\n >{{ entry.title }}</button>\n </li>\n }\n </ul>\n </div>\n } @empty {\n <p class=\"faq-toc-empty\">No FAQ entries yet.</p>\n }\n </nav>\n }\n </aside>\n\n <main\n #contentPane\n class=\"faq-content\"\n (click)=\"onContentClick($event)\"\n >\n @if (navigating()) {\n <div class=\"faq-loading\">Loading…</div>\n } @else if (renderedHtml(); as html) {\n <article class=\"faq-article\" [innerHTML]=\"html\"></article>\n @if (devMode && activeEntry(); as entry) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"existing\"\n [key]=\"entry.key\"\n [attempted]=\"attempted()\"\n [entry]=\"entry\"\n />\n }\n }\n } @else {\n <div class=\"faq-empty\">\n <h2>No FAQ available</h2>\n <p>No content is registered for this route.</p>\n @if (attempted().length) {\n <p class=\"faq-empty-chain\">\n Attempted keys:\n <code>{{ attempted().join(' → ') }}</code>\n </p>\n }\n @if (devMode && attempted().length) {\n @defer (when devMode) {\n <faq-authoring-panel\n mode=\"missing\"\n [key]=\"attempted()[0]\"\n [attempted]=\"attempted()\"\n />\n } @loading (minimum 100ms) {\n <p class=\"faq-empty-hint\">Loading authoring panel…</p>\n }\n }\n </div>\n }\n </main>\n </div>\n </div>\n </div>\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n input,\n signal,\n} from '@angular/core';\nimport { NgClass } from '@angular/common';\nimport {\n FAQ_DEV_EDITOR,\n FAQ_DEV_WORKSPACE_ROOT,\n FaqDevEditor,\n} from '../faq-dev-mode.token';\nimport { FaqService } from '../faq.service';\nimport { FaqEntry } from '../faq.types';\n\n/**\n * E11 — Dev-only FAQ authoring panel.\n *\n * Two modes, both dynamic-imported by `FaqModal` and gated behind\n * `FAQ_DEV_MODE`:\n * - `missing`: full scaffold panel rendered when no FAQ resolved.\n * - `existing`: collapsed source strip rendered below the article when an\n * entry IS resolved.\n *\n * The panel never imports `environment.*` directly — gating is the modal's\n * responsibility (via the FAQ_DEV_MODE token + dynamic import).\n */\n@Component({\n selector: 'faq-authoring-panel',\n standalone: true,\n imports: [NgClass],\n templateUrl: './faq-authoring-panel.html',\n styleUrl: './faq-authoring-panel.css',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class FaqAuthoringPanel {\n private readonly faq = inject(FaqService);\n private readonly workspaceRoot = inject(FAQ_DEV_WORKSPACE_ROOT);\n private readonly editor: FaqDevEditor = inject(FAQ_DEV_EDITOR);\n\n /** `'missing'` shows the full scaffold; `'existing'` shows the collapsed strip. */\n readonly mode = input.required<'missing' | 'existing'>();\n /**\n * The dot-notation key actually being authored. For `missing` mode this is\n * the deepest attempted key (chain[0]); for `existing` it's the resolved key.\n */\n readonly key = input.required<string>();\n /** Fallback chain that was attempted. For `missing` every entry is missing. */\n readonly attempted = input<string[]>([]);\n /** Resolved entry — only set in `existing` mode. */\n readonly entry = input<FaqEntry | null>(null);\n\n readonly expanded = signal(false);\n readonly showAllFiles = signal(false);\n readonly copyState = signal<string | null>(null);\n\n readonly relPath = computed(() => {\n const e = this.entry();\n if (e) return `src/assets/faq/${e.file}.md`;\n return `src/assets/faq/${keyToFilePath(this.key())}.md`;\n });\n\n readonly absPath = computed(() => {\n const rel = this.relPath();\n return this.workspaceRoot ? joinPosix(this.workspaceRoot, rel) : rel;\n });\n\n readonly editorHref = computed(() => {\n const abs = this.absPath();\n if (this.editor === 'vscode') return `vscode://file/${abs}`;\n return `webstorm://open?file=${encodeURI(abs)}`;\n });\n\n readonly editorLabel = computed(() =>\n this.editor === 'vscode' ? 'Open in VS Code' : 'Open in WebStorm',\n );\n\n readonly scaffoldCmd = computed(() => `npm run faq:new -- ${this.key()}`);\n\n readonly frontmatterScaffold = computed(() => {\n const k = this.key();\n const title = humanize(k);\n const category = humanize(k.split('.')[0]);\n return [\n '---',\n `title: \"${title}\"`,\n `category: \"${category}\"`,\n 'audience: authenticated',\n 'seo-ready: false',\n 'description: \"\"',\n '---',\n '',\n `# ${title}`,\n '',\n `TODO: write content for \"${title}\".`,\n '',\n ].join('\\n');\n });\n\n readonly allEntries = computed(() => this.faq.entries());\n\n readonly missedChain = computed(() => {\n const present = new Set(this.allEntries().map((e) => e.key));\n return this.attempted().map((k) => ({ key: k, present: present.has(k) }));\n });\n\n toggleExpanded(): void {\n this.expanded.update((v) => !v);\n }\n\n toggleAllFiles(): void {\n this.showAllFiles.update((v) => !v);\n }\n\n async copy(text: string, label: string): Promise<void> {\n try {\n await navigator.clipboard.writeText(text);\n this.copyState.set(label);\n setTimeout(() => {\n if (this.copyState() === label) this.copyState.set(null);\n }, 1500);\n } catch {\n this.copyState.set(`${label}:err`);\n }\n }\n}\n\nfunction keyToFilePath(key: string): string {\n return key.split('.').join('/');\n}\n\nfunction humanize(s: string): string {\n return s\n .split(/[.\\-_/]/)\n .filter(Boolean)\n .map((seg) => seg.charAt(0).toUpperCase() + seg.slice(1))\n .join(' ');\n}\n\nfunction joinPosix(a: string, b: string): string {\n const left = a.endsWith('/') ? a.slice(0, -1) : a;\n const right = b.startsWith('/') ? b.slice(1) : b;\n return `${left}/${right}`;\n}\n","@if (mode() === 'missing') {\n <section class=\"faq-authoring missing\" aria-label=\"FAQ authoring panel\">\n <header class=\"faq-authoring-header\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <h3>Start authoring this FAQ</h3>\n </header>\n\n <dl class=\"faq-authoring-meta\">\n <dt>Key</dt>\n <dd><code>{{ key() }}</code></dd>\n\n <dt>Fallback chain</dt>\n <dd>\n <ul class=\"faq-authoring-chain\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '✓' : '✗' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </dd>\n\n <dt>Target file</dt>\n <dd>\n <code>{{ relPath() }}</code>\n <a\n class=\"faq-authoring-editor\"\n [href]=\"editorHref()\"\n >{{ editorLabel() }} ↗</a>\n </dd>\n </dl>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Scaffold via CLI</span>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ scaffoldCmd() }}</code></pre>\n </div>\n\n <div class=\"faq-authoring-block\">\n <div class=\"faq-authoring-block-head\">\n <span>Frontmatter scaffold</span>\n <button type=\"button\" (click)=\"copy(frontmatterScaffold(), 'fm')\">\n {{ copyState() === 'fm' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n <pre><code>{{ frontmatterScaffold() }}</code></pre>\n </div>\n\n <details class=\"faq-authoring-cheat\">\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> — in-modal nav</li>\n <li><code>[label](app:/settings)</code> — navigates the app (modal closes)</li>\n <li><code>[label](https://example.com)</code> — external (new tab)</li>\n <li><code>[label](#section-id)</code> — intra-page anchor</li>\n <li><code></code> — image (drop into <code>src/assets/faq/images/</code>)</li>\n </ul>\n </details>\n\n <details class=\"faq-authoring-all\" [open]=\"showAllFiles()\">\n <summary (click)=\"toggleAllFiles(); $event.preventDefault()\">\n Show all FAQ files ({{ allEntries().length }})\n </summary>\n <ul class=\"faq-authoring-file-list\">\n @for (e of allEntries(); track e.key) {\n <li>\n <code>{{ e.key }}</code>\n <span class=\"faq-authoring-file-path\">src/assets/faq/{{ e.file }}.md</span>\n </li>\n } @empty {\n <li class=\"empty\">Manifest is empty.</li>\n }\n </ul>\n </details>\n </section>\n} @else {\n <aside class=\"faq-authoring existing\" aria-label=\"FAQ source info\">\n <div class=\"faq-authoring-strip\">\n <span class=\"faq-authoring-tag\">[dev]</span>\n <span>Key: <code>{{ key() }}</code></span>\n <span class=\"sep\">•</span>\n <span>Source: <code>{{ relPath() }}</code></span>\n <a class=\"faq-authoring-editor\" [href]=\"editorHref()\">{{ editorLabel() }} ↗</a>\n <button type=\"button\" class=\"faq-authoring-more\" (click)=\"toggleExpanded()\">\n {{ expanded() ? '▲ Less' : '▼ More' }}\n </button>\n </div>\n @if (expanded()) {\n <div class=\"faq-authoring-expanded\">\n <div>\n <strong>Fallback chain attempted:</strong>\n <ul class=\"faq-authoring-chain inline\">\n @for (step of missedChain(); track step.key) {\n <li [ngClass]=\"step.present ? 'present' : 'missed'\">\n <span class=\"mark\">{{ step.present ? '✓' : '✗' }}</span>\n <code>{{ step.key }}</code>\n </li>\n }\n </ul>\n </div>\n <details class=\"faq-authoring-cheat\" open>\n <summary>Link syntax cheat sheet</summary>\n <ul>\n <li><code>[label](faq:trade.segments)</code> — in-modal nav</li>\n <li><code>[label](app:/settings)</code> — navigates the app</li>\n <li><code>[label](https://example.com)</code> — external</li>\n <li><code>[label](#section-id)</code> — intra-page anchor</li>\n <li><code></code> — image</li>\n </ul>\n </details>\n <div class=\"faq-authoring-rescaffold\">\n <span>Re-scaffold (overwrites if you delete first):</span>\n <code>{{ scaffoldCmd() }}</code>\n <button type=\"button\" (click)=\"copy(scaffoldCmd(), 'cmd')\">\n {{ copyState() === 'cmd' ? 'Copied ✓' : 'Copy' }}\n </button>\n </div>\n </div>\n }\n </aside>\n}\n","import { CommonModule } from '@angular/common';\nimport {\n Component,\n OnInit,\n computed,\n inject,\n input,\n signal,\n ChangeDetectionStrategy\n} from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FaqEntry } from '../faq.types';\n\ninterface CategoryGroup {\n category: string;\n entries: FaqEntry[];\n}\n\n/**\n * Shared TOC sidebar for the public /help pages. Lists every\n * `audience: 'public' && seoReady: true` entry grouped by category.\n *\n * Pass `activeFile` from the parent page so the matching link gets\n * the `active` style. RouterLinkActive isn't sufficient on its own\n * because the index page (`/help`) and entry pages\n * (`/help/<file>`) all share this sidebar.\n */\n@Component({\n selector: 'public-faq-toc',\n standalone: true,\n imports: [CommonModule, RouterLink, RouterLinkActive],\n template: `\n <nav class=\"public-faq-toc\" aria-label=\"Help contents\">\n <a\n class=\"public-faq-toc__index\"\n routerLink=\"/help\"\n routerLinkActive=\"active\"\n [routerLinkActiveOptions]=\"{ exact: true }\"\n >Brokenstock Help</a>\n @for (group of groups(); track group.category) {\n <div class=\"public-faq-toc__group\">\n <h3 class=\"public-faq-toc__category\">{{ group.category }}</h3>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <a\n [routerLink]=\"['/help', entry.file]\"\n [class.active]=\"activeFile() === entry.file\"\n >{{ entry.title }}</a>\n </li>\n }\n </ul>\n </div>\n }\n </nav>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-toc {\n padding: 1.25rem 1rem;\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n font-size: 0.95rem;\n line-height: 1.4;\n }\n .public-faq-toc__index {\n display: block;\n font-weight: 600;\n color: #cfd6e4;\n text-decoration: none;\n padding: 0.4rem 0.5rem;\n border-radius: 4px;\n margin-bottom: 0.75rem;\n }\n .public-faq-toc__index.active,\n .public-faq-toc__index:hover {\n background: rgba(255, 255, 255, 0.06);\n }\n .public-faq-toc__group { margin-bottom: 1rem; }\n .public-faq-toc__category {\n font-size: 0.75rem;\n font-weight: 600;\n letter-spacing: 0.06em;\n text-transform: uppercase;\n color: #8a93a3;\n margin: 0 0 0.35rem;\n padding: 0 0.5rem;\n }\n .public-faq-toc ul {\n list-style: none;\n padding: 0;\n margin: 0;\n }\n .public-faq-toc li a {\n display: block;\n padding: 0.35rem 0.5rem;\n border-radius: 4px;\n color: #cfd6e4;\n text-decoration: none;\n }\n .public-faq-toc li a:hover {\n background: rgba(255, 255, 255, 0.05);\n }\n .public-faq-toc li a.active {\n background: rgba(110, 168, 254, 0.18);\n color: #fff;\n }\n `],\n})\nexport class PublicFaqToc implements OnInit {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n\n /** Currently-active entry file path (e.g. `landing`). Empty/undefined on the index. */\n readonly activeFile = input<string | undefined>(undefined);\n\n private readonly _entries = signal<FaqEntry[]>([]);\n\n readonly groups = computed<CategoryGroup[]>(() => {\n const visible = this._entries().filter(\n (e) => e.audience === 'public' && e.seoReady,\n );\n const byCategory = new Map<string, FaqEntry[]>();\n for (const entry of visible) {\n const list = byCategory.get(entry.category) ?? [];\n list.push(entry);\n byCategory.set(entry.category, list);\n }\n const groups: CategoryGroup[] = [];\n for (const [category, entries] of byCategory) {\n entries.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title));\n groups.push({ category, entries });\n }\n groups.sort((a, b) => a.category.localeCompare(b.category));\n return groups;\n });\n\n async ngOnInit(): Promise<void> {\n const manifest = await this.loader.loadManifest();\n this._entries.set(manifest.entries);\n }\n}\n","import { InjectionToken } from '@angular/core';\n\n/**\n * Canonical public base URL (no trailing slash) used for OpenGraph,\n * Twitter, JSON-LD canonical URLs, and sitemap entries on the\n * public FAQ pages. Default empty string — falls back to relative\n * `og:url` etc. when unset, which is fine for previewing but\n * suboptimal for production SEO. Consumer apps should override.\n */\nexport const FAQ_PUBLIC_SITE_BASE_URL = new InjectionToken<string>(\n 'FAQ_PUBLIC_SITE_BASE_URL',\n { providedIn: 'root', factory: () => '' },\n);\n\n/**\n * Publisher / author Organization embedded in schema.org JSON-LD on\n * public FAQ pages. `logo` is optional — Google's validator warns but\n * does not error when omitted. Add it later via a one-line provider\n * override.\n */\nexport interface FaqPublicPublisher {\n name: string;\n url?: string;\n logo?: string;\n}\n\nexport const FAQ_PUBLIC_PUBLISHER = new InjectionToken<FaqPublicPublisher>(\n 'FAQ_PUBLIC_PUBLISHER',\n { providedIn: 'root', factory: () => ({ name: '' }) },\n);\n","import { CommonModule } from '@angular/common';\nimport { Component, OnInit, computed, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { Meta, Title } from '@angular/platform-browser';\nimport { RouterLink } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { PublicFaqToc } from '../public-faq-toc/public-faq-toc';\nimport {\n FAQ_PUBLIC_PUBLISHER,\n FAQ_PUBLIC_SITE_BASE_URL,\n} from '../faq-seo.tokens';\nimport { FaqEntry } from '../faq.types';\n\ninterface CategoryGroup {\n category: string;\n entries: FaqEntry[];\n}\n\n/**\n * Public, SEO-targeted FAQ index. Prerendered at build time on the\n * consumer side (e.g. /help in broken-stock). Lists every manifest\n * entry where `audience === 'public' && seoReady === true`, grouped\n * by category and ordered by `order`.\n *\n * SEO (E17): sets <title>, meta description, OG, and Twitter tags.\n * JSON-LD (E18): emits a schema.org CollectionPage referencing\n * each child entry as an ItemList.\n */\n@Component({\n selector: 'public-faq-index',\n standalone: true,\n imports: [CommonModule, RouterLink, PublicFaqToc],\n template: `\n <div class=\"public-faq-layout\">\n <aside class=\"public-faq-sidebar\">\n <public-faq-toc />\n </aside>\n <article class=\"public-faq-index\">\n <header>\n <h1>Brokenstock Help</h1>\n <p class=\"lead\">Documentation and walkthroughs for the Brokenstock trade-journal platform.</p>\n </header>\n @if (loading()) {\n <p>Loading…</p>\n } @else if (groups().length === 0) {\n <p>No help pages are published yet.</p>\n } @else {\n @for (group of groups(); track group.category) {\n <section>\n <h2>{{ group.category }}</h2>\n <ul>\n @for (entry of group.entries; track entry.key) {\n <li>\n <a [routerLink]=\"['/help', entry.file]\">{{ entry.title }}</a>\n @if (entry.description) {\n <span class=\"desc\"> — {{ entry.description }}</span>\n }\n </li>\n }\n </ul>\n </section>\n }\n }\n @if (jsonLd(); as ld) {\n <script type=\"application/ld+json\">{{ ld }}</script>\n }\n </article>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-layout {\n display: grid;\n grid-template-columns: minmax(220px, 280px) 1fr;\n gap: 1.5rem;\n max-width: 1280px;\n margin: 0 auto;\n padding: 1.5rem 1.25rem 4rem;\n }\n .public-faq-sidebar {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n align-self: start;\n position: sticky;\n top: 1rem;\n max-height: calc(100vh - 2rem);\n overflow-y: auto;\n }\n .public-faq-index {\n max-width: 860px;\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n line-height: 1.55;\n }\n header h1 { font-size: 2.25rem; margin: 0 0 0.5rem; }\n .lead { color: #9aa3b3; margin: 0 0 2rem; font-size: 1.1rem; }\n h2 { font-size: 1.35rem; margin: 1.75rem 0 0.5rem; border-bottom: 1px solid rgba(255, 255, 255, 0.08); padding-bottom: 0.25rem; }\n ul { list-style: none; padding: 0; margin: 0; }\n li { padding: 0.4rem 0; }\n .public-faq-index a { color: #6ea8fe; text-decoration: none; font-weight: 500; }\n .public-faq-index a:hover { text-decoration: underline; }\n .desc { color: #8a93a3; font-weight: 400; }\n @media (max-width: 900px) {\n .public-faq-layout { grid-template-columns: 1fr; }\n .public-faq-sidebar {\n position: static;\n max-height: none;\n border-right: none;\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n }\n `],\n})\nexport class PublicFaqIndex implements OnInit {\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly title = inject(Title);\n private readonly meta = inject(Meta);\n private readonly siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);\n private readonly publisher = inject(FAQ_PUBLIC_PUBLISHER);\n\n private readonly _entries = signal<FaqEntry[]>([]);\n readonly loading = signal(true);\n\n readonly visibleEntries = computed(() =>\n this._entries().filter((e) => e.audience === 'public' && e.seoReady),\n );\n\n readonly groups = computed<CategoryGroup[]>(() => {\n const visible = this.visibleEntries();\n const byCategory = new Map<string, FaqEntry[]>();\n for (const entry of visible) {\n const list = byCategory.get(entry.category) ?? [];\n list.push(entry);\n byCategory.set(entry.category, list);\n }\n const groups: CategoryGroup[] = [];\n for (const [category, entries] of byCategory) {\n entries.sort((a, b) => a.order - b.order || a.title.localeCompare(b.title));\n groups.push({ category, entries });\n }\n groups.sort((a, b) => a.category.localeCompare(b.category));\n return groups;\n });\n\n readonly jsonLd = computed<string | null>(() => {\n const entries = this.visibleEntries();\n if (entries.length === 0) return null;\n const base = this.siteBase.replace(/\\/+$/, '');\n const indexUrl = `${base}/help`;\n const ld: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'CollectionPage',\n name: 'Brokenstock Help',\n url: indexUrl,\n mainEntity: {\n '@type': 'ItemList',\n itemListElement: entries.map((entry, idx) => ({\n '@type': 'ListItem',\n position: idx + 1,\n url: `${base}/help/${entry.file}`,\n name: entry.title,\n })),\n },\n };\n if (this.publisher.name) {\n const pub: Record<string, unknown> = {\n '@type': 'Organization',\n name: this.publisher.name,\n };\n if (this.publisher.url) pub['url'] = this.publisher.url;\n if (this.publisher.logo) pub['logo'] = this.publisher.logo;\n ld['publisher'] = pub;\n }\n return serializeJsonLd(ld);\n });\n\n async ngOnInit(): Promise<void> {\n try {\n const manifest = await this.loader.loadManifest();\n this._entries.set(manifest.entries);\n this.applyMeta();\n } finally {\n this.loading.set(false);\n }\n }\n\n private applyMeta(): void {\n const base = this.siteBase.replace(/\\/+$/, '');\n const url = `${base}/help`;\n const description =\n 'Documentation and walkthroughs for the Brokenstock trade-journal platform.';\n this.title.setTitle('Help — Brokenstock');\n this.meta.updateTag({ name: 'description', content: description });\n this.meta.updateTag({ property: 'og:type', content: 'website' });\n this.meta.updateTag({ property: 'og:title', content: 'Help — Brokenstock' });\n this.meta.updateTag({ property: 'og:description', content: description });\n this.meta.updateTag({ property: 'og:url', content: url });\n if (this.publisher.name) {\n this.meta.updateTag({ property: 'og:site_name', content: this.publisher.name });\n }\n this.meta.updateTag({ name: 'twitter:card', content: 'summary' });\n this.meta.updateTag({ name: 'twitter:title', content: 'Help — Brokenstock' });\n this.meta.updateTag({ name: 'twitter:description', content: description });\n }\n}\n\nfunction serializeJsonLd(obj: unknown): string {\n return JSON.stringify(obj).replace(/</g, '\\\\u003c');\n}\n","import { CommonModule } from '@angular/common';\nimport { Component, OnInit, computed, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { Meta, Title } from '@angular/platform-browser';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\nimport { FAQ_CONTENT_LOADER } from '../faq-content-loader.token';\nimport { FaqMarkdownRendererService } from '../faq-markdown-renderer.service';\nimport { PublicFaqToc } from '../public-faq-toc/public-faq-toc';\nimport {\n FAQ_PUBLIC_PUBLISHER,\n FAQ_PUBLIC_SITE_BASE_URL,\n} from '../faq-seo.tokens';\nimport { FaqEntry } from '../faq.types';\n\n/**\n * Public, SEO-targeted FAQ page. Prerendered at build time per\n * qualifying manifest entry (e.g. /help/landing, /help/trade/segments).\n *\n * The route is `help/**` so multi-segment file paths work; this\n * component reads the wildcard path off `ActivatedRoute.url`.\n *\n * SEO (E17): sets <title>, meta description, OpenGraph and Twitter\n * Card tags using Angular's Title + Meta services (SSR-compatible).\n * JSON-LD (E18): emits a schema.org Article (or BlogPosting) object\n * via an inline <script type=\"application/ld+json\"> element. The\n * raw JSON has `<` escaped to `<` so a stray `</script>` inside\n * data won't break the surrounding tag.\n */\n@Component({\n selector: 'public-faq-page',\n standalone: true,\n imports: [CommonModule, RouterLink, PublicFaqToc],\n template: `\n <div class=\"public-faq-layout\">\n <aside class=\"public-faq-sidebar\">\n <public-faq-toc [activeFile]=\"activeFile()\" />\n </aside>\n <article class=\"public-faq-page\">\n @if (loading()) {\n <p>Loading…</p>\n } @else if (!entry()) {\n <header>\n <h1>Page not found</h1>\n <p>That help page doesn't exist or isn't published. Try the <a routerLink=\"/help\">help index</a>.</p>\n </header>\n } @else {\n <header>\n <h1>{{ entry()!.title }}</h1>\n @if (entry()!.description) {\n <p class=\"lead\">{{ entry()!.description }}</p>\n }\n </header>\n <div class=\"body\" [innerHTML]=\"renderedHtml()\"></div>\n @if (jsonLd(); as ld) {\n <script type=\"application/ld+json\">{{ ld }}</script>\n }\n }\n </article>\n </div>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .public-faq-layout {\n display: grid;\n grid-template-columns: minmax(220px, 280px) 1fr;\n gap: 1.5rem;\n max-width: 1280px;\n margin: 0 auto;\n padding: 1.5rem 1.25rem 4rem;\n }\n .public-faq-sidebar {\n border-right: 1px solid rgba(255, 255, 255, 0.08);\n align-self: start;\n position: sticky;\n top: 1rem;\n max-height: calc(100vh - 2rem);\n overflow-y: auto;\n }\n .public-faq-page {\n font-family: system-ui, -apple-system, \"Segoe UI\", sans-serif;\n line-height: 1.6;\n max-width: 860px;\n }\n header h1 { font-size: 2.1rem; margin: 0 0 0.5rem; }\n .lead { color: #9aa3b3; font-size: 1.1rem; margin: 0 0 1.5rem; }\n .body :is(h1, h2, h3, h4) { margin-top: 2rem; }\n .body a { color: #6ea8fe; }\n .body img { max-width: 100%; height: auto; }\n .body pre { background: rgba(0, 0, 0, 0.35); padding: 0.75rem 1rem; border-radius: 6px; overflow-x: auto; }\n .body code { background: rgba(255, 255, 255, 0.08); padding: 0.1rem 0.3rem; border-radius: 3px; font-size: 0.9em; }\n .body pre code { background: transparent; padding: 0; }\n @media (max-width: 900px) {\n .public-faq-layout { grid-template-columns: 1fr; }\n .public-faq-sidebar {\n position: static;\n max-height: none;\n border-right: none;\n border-bottom: 1px solid rgba(255, 255, 255, 0.08);\n }\n }\n `],\n})\nexport class PublicFaqPage implements OnInit {\n private readonly route = inject(ActivatedRoute);\n private readonly loader = inject(FAQ_CONTENT_LOADER);\n private readonly renderer = inject(FaqMarkdownRendererService);\n private readonly title = inject(Title);\n private readonly meta = inject(Meta);\n private readonly siteBase = inject(FAQ_PUBLIC_SITE_BASE_URL);\n private readonly publisher = inject(FAQ_PUBLIC_PUBLISHER);\n\n readonly entry = signal<FaqEntry | null>(null);\n readonly body = signal<string>('');\n readonly loading = signal(true);\n\n readonly activeFile = computed(() => this.entry()?.file);\n\n readonly renderedHtml = computed(() => {\n const entry = this.entry();\n const body = this.body();\n if (!entry || !body) return '';\n return this.renderer.render(body, {\n context: 'page',\n imagePrefix: entry.imagePrefix\n ? `/assets/faq/${entry.imagePrefix}`\n : undefined,\n });\n });\n\n readonly jsonLd = computed<string | null>(() => {\n const entry = this.entry();\n if (!entry) return null;\n const url = this.canonicalUrl(entry);\n const ld: Record<string, unknown> = {\n '@context': 'https://schema.org',\n '@type': 'Article',\n headline: entry.title,\n url,\n mainEntityOfPage: url,\n };\n if (entry.description) ld['description'] = entry.description;\n if (this.publisher.name) {\n const pub: Record<string, unknown> = {\n '@type': 'Organization',\n name: this.publisher.name,\n };\n if (this.publisher.url) pub['url'] = this.publisher.url;\n if (this.publisher.logo) pub['logo'] = this.publisher.logo;\n ld['publisher'] = pub;\n ld['author'] = pub;\n }\n return serializeJsonLd(ld);\n });\n\n async ngOnInit(): Promise<void> {\n try {\n const segments = this.route.snapshot.url.map((s) => s.path);\n const filePath = segments.join('/');\n if (!filePath) {\n this.applyNotFoundMeta();\n return;\n }\n const manifest = await this.loader.loadManifest();\n const match = manifest.entries.find(\n (e) => e.file === filePath && e.audience === 'public' && e.seoReady,\n );\n if (!match) {\n this.applyNotFoundMeta();\n return;\n }\n const content = await this.loader.loadContent(match.key);\n if (content === null) {\n this.applyNotFoundMeta();\n return;\n }\n const parsed = this.renderer.parse(content);\n this.entry.set(match);\n this.body.set(parsed.body);\n this.applyMeta(match);\n } finally {\n this.loading.set(false);\n }\n }\n\n private applyMeta(entry: FaqEntry): void {\n const url = this.canonicalUrl(entry);\n const description = entry.description ?? '';\n const title = `${entry.title} — Help`;\n this.title.setTitle(title);\n this.meta.updateTag({ name: 'description', content: description });\n this.meta.updateTag({ property: 'og:type', content: 'article' });\n this.meta.updateTag({ property: 'og:title', content: entry.title });\n this.meta.updateTag({ property: 'og:description', content: description });\n this.meta.updateTag({ property: 'og:url', content: url });\n if (this.publisher.name) {\n this.meta.updateTag({ property: 'og:site_name', content: this.publisher.name });\n }\n this.meta.updateTag({ name: 'twitter:card', content: 'summary' });\n this.meta.updateTag({ name: 'twitter:title', content: entry.title });\n this.meta.updateTag({ name: 'twitter:description', content: description });\n }\n\n private applyNotFoundMeta(): void {\n this.title.setTitle('Page not found — Help');\n this.meta.updateTag({ name: 'robots', content: 'noindex' });\n }\n\n private canonicalUrl(entry: FaqEntry): string {\n const base = this.siteBase.replace(/\\/+$/, '');\n return `${base}/help/${entry.file}`;\n }\n}\n\n/**\n * Serializes a JSON-LD object for safe inclusion in a\n * `<script type=\"application/ld+json\">` element. Escapes `<` so a\n * stray `</script>` inside any string field cannot break out of the\n * script tag. (Browsers and crawlers parse the resulting `<`\n * back to `<` per JSON spec.)\n */\nfunction serializeJsonLd(obj: unknown): string {\n return JSON.stringify(obj).replace(/</g, '\\\\u003c');\n}\n","import { Injectable, signal, computed } from '@angular/core';\n\nexport type ThemeMode = 'dark';\n\n@Injectable({ providedIn: 'root' })\nexport class ThemeService {\n readonly mode = signal<ThemeMode>('dark');\n readonly isDark = computed(() => this.mode() === 'dark');\n}\n","/*\nCreated by Franz Zemen 2026-10-16\nLicense Type: UNLICENSED\n\nPhone layout of the app frame (broken-stock scanner-phone-display.prd.md D9 / E8).\n*/\n\nimport { DestroyRef, Injectable, Signal, inject, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\n\n/**\n * Below this width the frame is in its phone layout: no icon column, a ☰ menu\n * button in the top bar, a one-line top bar.\n *\n * The same 820px line broken-stock's screens use (scanner-filter-editor.prd.md\n * D11), written the same way. `819.98px` rather than `819px` so a fractional\n * width from browser zoom (819.5px) does not fall between the two layouts.\n *\n * ⚠ The CSS repeats this query in shell.css and status-bar.css —\n * a media query cannot read a TypeScript constant. phone-layout.service.spec.ts\n * fails if any of them drifts from this value.\n */\nexport const SHELL_PHONE_MEDIA_QUERY = '(max-width: 819.98px)';\n\n/**\n * Whether the frame is in its phone layout, and whether the phone menu is open.\n *\n * Desktop never sees any of this: `isPhone` is false there, the menu cannot open,\n * and the rail renders exactly as before.\n */\n@Injectable({ providedIn: 'root' })\nexport class PhoneLayoutService {\n readonly #window = inject(DOCUMENT).defaultView;\n readonly #isPhone = signal(false);\n readonly #menuOpen = signal(false);\n\n /** True below 820px. Always false where there is no window (server rendering). */\n readonly isPhone: Signal<boolean> = this.#isPhone.asReadonly();\n\n /** The ☰ menu's open state. Only ever true while `isPhone` is true. */\n readonly menuOpen: Signal<boolean> = this.#menuOpen.asReadonly();\n\n constructor() {\n const mql = this.#window?.matchMedia?.(SHELL_PHONE_MEDIA_QUERY);\n if (!mql) return;\n this.#isPhone.set(mql.matches);\n const onChange = (event: MediaQueryListEvent): void => {\n this.#isPhone.set(event.matches);\n // Rotating or widening past 820px brings the rail back; a menu left open\n // would then cover the screen with nothing on it to close it.\n if (!event.matches) this.#menuOpen.set(false);\n };\n mql.addEventListener('change', onChange);\n inject(DestroyRef).onDestroy(() => mql.removeEventListener('change', onChange));\n }\n\n toggleMenu(): void {\n this.#menuOpen.set(this.#isPhone() && !this.#menuOpen());\n }\n\n closeMenu(): void {\n this.#menuOpen.set(false);\n }\n}\n","import { Injectable, inject, signal } from '@angular/core';\nimport { PhoneLayoutService } from './phone-layout.service';\n\n/**\n * Asks the command box to take the cursor. Called by the shell after most\n * actions (rail choices, Log Out, ?, ⧉, Escape, sign-in) and by apps.\n *\n * ⚠ A NO-OP ON A PHONE (scanner-phone-display D10/E11). The console is shown\n * below 820px, but nothing may put the cursor in it there: focusing a text box\n * on a phone raises the on-screen keyboard over the screen the user just opened.\n * The one place every focus request passes through is here, so this is where it\n * is refused. Refusing it at the source also means a request made on a phone is\n * not left counted up, to be acted on after a rotation to a wider screen.\n */\n@Injectable({ providedIn: 'root' })\nexport class TerminalFocusService {\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly focusRequested = signal(0);\n\n requestFocus(): void {\n if (this.#phoneLayout.isPhone()) return;\n this.focusRequested.update(v => v + 1);\n }\n}\n","import { Injectable, Signal, signal } from '@angular/core';\n\n/**\n * The choice a NEW window starts with. Shared by the whole browser.\n * Written on every toggle, read only at construction.\n */\nconst DEFAULT_KEY = 'shell.commandTerminalVisible';\n\n/**\n * THIS window's current choice. Per-window by definition, so two windows cannot\n * fight over it.\n */\nconst WINDOW_KEY = 'shell.commandTerminalVisible.window';\n\n/**\n * Controls visibility of the command terminal at the bottom of the shell.\n *\n * ⚠ TWO KEYS, AND THE SPLIT IS THE POINT (multiple-windows F6).\n *\n * This used to be one `localStorage` value, read once at construction and\n * written on every change, with nothing listening for another window. That was\n * correct while the app could only be open once. It is not now: two windows\n * would each write the shared value on every toggle, so whichever you touched\n * last decided what BOTH windows got on their next start — a setting that\n * quietly refuses to stay put, which reads as a bug in the shell rather than in\n * storage.\n *\n * The resolution is not \"make them agree\". You genuinely may want the terminal\n * up on the scanner window and out of the way on the other, so forcing them into\n * step would be the wrong fix as well as a harder one. Instead:\n *\n * - the LIVE state is per-window (`sessionStorage`), so the two never collide\n * and a reload still restores what this window had;\n * - the DEFAULT for a brand-new window is shared (`localStorage`), so your\n * last choice anywhere still carries into the next window and across a\n * browser restart, which is the behaviour the single key was providing.\n *\n * Both writes are best-effort: losing a remembered layout must never break the\n * screen trying to remember it.\n *\n * ⚠ `visible` is READ-ONLY to the outside and `toggle()` is the only mutator.\n * It used to be a writable signal persisted by an `effect`, which meant any\n * caller could `set()` it — and whether that got remembered depended on an\n * effect firing somewhere else. Persisting inside the one mutator makes it\n * impossible to change this without persisting it.\n */\n@Injectable({ providedIn: 'root' })\nexport class TerminalVisibilityService {\n readonly #visible = signal(this.#readInitial());\n\n /** Read-only on purpose — see the header. */\n readonly visible: Signal<boolean> = this.#visible.asReadonly();\n\n toggle(): void {\n const next = !this.#visible();\n this.#visible.set(next);\n this.#write(sessionStorage, WINDOW_KEY, next);\n this.#write(localStorage, DEFAULT_KEY, next);\n }\n\n /**\n * This window's own choice wins; otherwise the last choice made anywhere;\n * otherwise visible.\n *\n * The order matters on a reload: a window that had hidden the terminal must\n * not have it reappear because another window showed one since.\n */\n #readInitial(): boolean {\n const own = this.#read(sessionStorage, WINDOW_KEY);\n if (own !== undefined) return own;\n const shared = this.#read(localStorage, DEFAULT_KEY);\n return shared ?? true;\n }\n\n #read(store: Storage, key: string): boolean | undefined {\n try {\n const raw = store.getItem(key);\n return raw === null ? undefined : raw === '1';\n } catch {\n // Storage unavailable (private mode / prerender) — fall through.\n return undefined;\n }\n }\n\n #write(store: Storage, key: string, value: boolean): void {\n try {\n store.setItem(key, value ? '1' : '0');\n } catch {\n // Non-fatal by policy: a lost layout preference must not break the screen.\n }\n }\n}\n","import { computed, inject, Injectable, NgZone, signal } from '@angular/core';\nimport { DOCUMENT } from '@angular/common';\nimport { TerminalFocusService } from './terminal-focus.service';\n\n/**\n * A key binding a screen registers while it is mounted.\n *\n * **`key` is what the help overlay shows and, by default, what is matched.**\n * `code` overrides the matching without changing the display, which matters more\n * than it sounds: on a US layout `shift`+1 delivers `event.key === '!'`, not\n * `'1'` with a shift flag. A screen binding shifted digits and comparing `key`\n * ships shortcuts that never fire — and registering `'!'` instead APPEARS to\n * work and then breaks on any non-US keyboard. `code: 'Digit1'` is the physical\n * key and is layout-independent.\n */\nexport interface ShortcutRegistration {\n /** Displayed in the help overlay, and matched against `event.key` unless `code` is set. */\n key: string;\n /**\n * Match `event.code` instead — the PHYSICAL key, independent of layout and of\n * what modifiers do to the character produced. Use for anything shifted.\n */\n code?: string;\n modifier?: 'Alt' | 'Shift';\n action: () => void;\n description: string;\n}\n\n/**\n * Elements that mean \"the user is typing\", where an unmodified shortcut must not fire.\n *\n * Kept as a set of tag names plus a `contenteditable` check rather than a\n * selector string, so it is greppable and so the reasoning stays attached to it.\n */\nconst TEXT_ENTRY_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT']);\n\n@Injectable({ providedIn: 'root' })\nexport class KeyboardShortcutService {\n readonly #groups = new Map<string, ShortcutRegistration[]>();\n readonly #activeGroupId = signal<string | null>(null);\n\n readonly #document = inject(DOCUMENT);\n readonly #zone = inject(NgZone);\n readonly #focusService = inject(TerminalFocusService);\n\n readonly helpVisible = signal(false);\n\n /**\n * True while unmodified shortcuts are being suppressed — the user is typing,\n * or a dialog is open.\n *\n * Exposed because a screen binding BARE keys needs to tell the user whether the\n * next keystroke acts or types, and that indicator must read the service's own\n * dispatch state. A screen keeping its own boolean will eventually disagree\n * with the service, and an indicator that lies about whether a keystroke sells\n * a thousand shares is worse than no indicator at all.\n */\n readonly suppressed = signal(false);\n\n readonly activeShortcuts = computed(() => {\n const groupId = this.#activeGroupId();\n if (!groupId) return null;\n const shortcuts = this.#groups.get(groupId);\n if (!shortcuts) return null;\n return { groupId, shortcuts };\n });\n\n constructor() {\n this.#zone.runOutsideAngular(() => {\n this.#document.addEventListener('keydown', (event: KeyboardEvent) => {\n this.#handleKeydown(event);\n });\n // ⚠ THE WRITE IS DEFERRED, AND THAT IS NOT AN OPTIMISATION.\n //\n // `element.focus()` dispatches `focusin` SYNCHRONOUSLY. Angular calls\n // `.focus()` from template-driven code — an autofocused input, the shell's\n // terminal reclaiming focus — so this listener can run in the middle of a\n // render, and a signal write there throws NG0600, \"writing to signals is\n // not allowed while Angular renders the template\".\n //\n // That throw shipped: it aborted the login transition, so the sign-in POST\n // returned 200 and the app still showed \"not logged in\", with every\n // authenticated request that followed answering 401. Nothing in the failure\n // pointed at the keyboard.\n //\n // A microtask runs after the render completes, which is soon enough for an\n // indicator a human reads and late enough to be outside the reactive\n // context. The value is compared first so an unchanged focus move writes\n // nothing at all.\n const refresh = (): void => {\n queueMicrotask(() => {\n const next = this.#isSuppressed();\n if (next !== this.suppressed()) this.suppressed.set(next);\n });\n };\n this.#document.addEventListener('focusin', refresh, true);\n this.#document.addEventListener('focusout', refresh, true);\n });\n }\n\n registerGroup(groupId: string, shortcuts: ShortcutRegistration[]): void {\n this.#groups.set(groupId, shortcuts);\n this.#activeGroupId.set(groupId);\n // Same hazard as the focus listener above: a screen registers from\n // `ngOnInit`, which Angular may run inside a render.\n queueMicrotask(() => {\n const next = this.#isSuppressed();\n if (next !== this.suppressed()) this.suppressed.set(next);\n });\n }\n\n unregisterGroup(groupId: string): void {\n this.#groups.delete(groupId);\n if (this.#activeGroupId() === groupId) {\n const keys = [...this.#groups.keys()];\n this.#activeGroupId.set(keys.length > 0 ? keys[keys.length - 1] : null);\n }\n }\n\n toggleHelp(): void {\n this.helpVisible.update(v => !v);\n }\n\n /**\n * Would an unmodified shortcut be ignored right now?\n *\n * Two cases: a text-entry element has focus, or a dialog is open. Alt\n * combinations are exempt — they do not collide with typing, which is why\n * every binding in the app before this guard existed used one.\n */\n #isSuppressed(): boolean {\n const active = this.#document.activeElement as HTMLElement | null;\n if (active) {\n if (TEXT_ENTRY_TAGS.has(active.tagName)) return true;\n if (active.isContentEditable) return true;\n }\n // Angular Material puts every dialog in this container. A shortcut firing\n // behind an open dialog acts on a screen the user cannot currently see.\n return this.#document.querySelector('.cdk-overlay-container .cdk-overlay-pane') !== null;\n }\n\n #matches(shortcut: ShortcutRegistration, event: KeyboardEvent): boolean {\n // The physical key when `code` is given, the produced character otherwise.\n const hit = shortcut.code ? shortcut.code === event.code : shortcut.key === event.key;\n if (!hit) return false;\n if (shortcut.modifier === 'Alt') return event.altKey;\n if (shortcut.modifier === 'Shift') {\n return event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;\n }\n // Unmodified. `ctrl`/`alt`/`meta` are excluded because the page still\n // receives a keystroke carrying the digit when the browser handles\n // `ctrl`+1 as a tab switch — without this, switching tabs would also fire\n // whatever a bare `1` is bound to.\n return !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;\n }\n\n #handleKeydown(event: KeyboardEvent): boolean {\n const activeId = this.#activeGroupId();\n if (activeId) {\n const shortcuts = this.#groups.get(activeId);\n if (shortcuts) {\n const match = shortcuts.find(s => this.#matches(s, event));\n if (match) {\n const alt = match.modifier === 'Alt';\n // Alt bindings are exempt from both guards below, so nothing that\n // existed before them changes behaviour: Alt does not collide with\n // typing, and holding Alt+ArrowDown to walk a list is wanted.\n if (!alt) {\n // A key held down repeats at roughly thirty a second. On a screen\n // where a bare key places an order, that is fifteen orders in half a\n // second, and a synchronous action path will run every one of them.\n if (event.repeat) return false;\n if (this.#isSuppressed()) return false;\n }\n event.preventDefault();\n this.#zone.run(() => match.action());\n return true;\n }\n }\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n this.#zone.run(() => {\n this.helpVisible.set(false);\n this.#focusService.requestFocus();\n });\n return true;\n }\n\n if (!event.altKey) return false;\n\n if (event.key === '?' || event.key === '/') {\n event.preventDefault();\n this.#zone.run(() => this.toggleHelp());\n return true;\n }\n\n return false;\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { z } from 'zod/v4';\nimport { CommandDefinition, CommandResult } from '../types/command.types';\nimport { FaqService } from '../faq/faq.service';\n\nconst FAQ_USAGE =\n 'faq\\n' +\n 'faq <key>\\n' +\n 'faq search <term>\\n' +\n 'faq index\\n' +\n 'faq help\\n\\n' +\n ' Opens the in-app FAQ help system. Does not require authentication.\\n\\n' +\n ' Subcommands:\\n' +\n ' (none) Open the FAQ at the current route\\'s resolved key.\\n' +\n ' <key> Open at a specific dot-notation key (e.g. trade.segments).\\n' +\n ' search <term> Open with the search field pre-filled.\\n' +\n ' index Open at the index table-of-contents.\\n' +\n ' help Show this help.';\n\n@Injectable({ providedIn: 'root' })\nexport class FaqCommand implements CommandDefinition {\n private readonly faqService = inject(FaqService);\n\n readonly name = 'faq';\n readonly description = 'Open the in-app FAQ help system';\n readonly usage = FAQ_USAGE;\n readonly requiresAuth = false;\n readonly scope = 'global' as const;\n readonly argsSchema = z.array(z.string()).max(50);\n\n execute(args: string[]): CommandResult {\n const ts = () => new Date();\n if (args.length === 0) {\n void this.faqService.openModal();\n return { success: true, message: '', timestamp: ts() };\n }\n const sub = args[0].toLowerCase();\n if (sub === 'index') {\n void this.faqService.openModal('index');\n return { success: true, message: '', timestamp: ts() };\n }\n if (sub === 'search') {\n const term = args.slice(1).join(' ').trim();\n if (!term) {\n return {\n success: false,\n message: 'Usage: faq search <term>',\n timestamp: ts(),\n };\n }\n void this.faqService.openModal(undefined, { searchTerm: term });\n return { success: true, message: '', timestamp: ts() };\n }\n void this.faqService.openModal(args[0]);\n return { success: true, message: '', timestamp: ts() };\n }\n}\n","import { inject, Injectable } from '@angular/core';\nimport { CommandAlias, CommandDefinition } from '../types/command.types';\nimport { SHELL_COMMANDS } from '../tokens/shell-tokens';\nimport { FaqCommand } from '../commands/faq.command';\n\n/**\n * What a typed word resolves to: the command it names, plus any words the\n * alternate name carries with it (see {@link CommandAlias}).\n */\nexport interface ResolvedCommand {\n readonly command: CommandDefinition;\n readonly prependArgs: readonly string[];\n}\n\n/**\n * Names the shell handles itself, ahead of the registry. A command taking one\n * of these would be registered and then never reachable, so registration\n * refuses them outright rather than leaving a command that silently never runs.\n */\nconst RESERVED_NAMES: readonly string[] = ['clear', 'help'];\n\n@Injectable({ providedIn: 'root' })\nexport class CommandRegistryService {\n private readonly commands = new Map<string, CommandDefinition>();\n private readonly aliases = new Map<string, ResolvedCommand>();\n\n constructor() {\n // Built-in shell commands registered ahead of app-provided commands so\n // an app cannot accidentally shadow them.\n this.register(inject(FaqCommand));\n\n const appCommands = inject(SHELL_COMMANDS, { optional: true }) ?? [];\n for (const cmd of appCommands) {\n this.register(cmd);\n }\n }\n\n /**\n * Register a command and claim its names.\n *\n * ⭐ THROWS on a name already taken — real name or alternate. It used to be a\n * bare `set`, which meant a clash silently overwrote whichever command\n * registered first, and the constructor's \"built-ins first so an app cannot\n * shadow them\" comment was not actually true of the map. A shadowed command\n * is indistinguishable from a broken one, and this is the map dispatch reads,\n * so the failure belongs at startup where it cannot be missed\n * (scanner-command-speed.prd.md D4).\n */\n register(command: CommandDefinition): void {\n this.#claim(command.name, `command '${command.name}'`);\n this.commands.set(command.name, command);\n for (const alias of command.aliases ?? []) {\n this.#claim(alias.name, `alias '${alias.name}' of '${command.name}'`);\n this.aliases.set(alias.name, { command, prependArgs: alias.prependArgs ?? [] });\n }\n }\n\n #claim(name: string, what: string): void {\n if (RESERVED_NAMES.includes(name)) {\n throw new Error(`${what} collides with a reserved command name`);\n }\n if (this.commands.has(name) || this.aliases.has(name)) {\n throw new Error(`${what} collides with a command name already registered`);\n }\n }\n\n /**\n * Resolve a word the user typed to the command it names — real name or\n * alternate. `prependArgs` is empty except for an alternate that carries a\n * subcommand.\n *\n * Use this wherever a TYPED word is being looked up. {@link get} deliberately\n * stays blind to alternates so callers that mean \"the command called X\" keep\n * meaning exactly that.\n */\n resolve(name: string): ResolvedCommand | undefined {\n const command = this.commands.get(name);\n if (command) return { command, prependArgs: [] };\n return this.aliases.get(name);\n }\n\n get(name: string): CommandDefinition | undefined {\n return this.commands.get(name);\n }\n\n getAll(): CommandDefinition[] {\n return Array.from(this.commands.values());\n }\n\n /**\n * Returns command name suggestions for tab-completion.\n * Built-ins (clear, help) are included when authenticated.\n */\n getSuggestions(prefix: string, isAuthenticated: boolean): string[] {\n if (!prefix) return [];\n if (!isAuthenticated) {\n const open = ['login', ...[...this.commands.values()]\n .filter(c => c.requiresAuth === false)\n .flatMap(c => [c.name, ...(c.aliases ?? []).map(a => a.name)])];\n return open.filter(name => name.startsWith(prefix) && name !== prefix).sort();\n }\n const builtIns = ['clear', 'help'];\n // Alternate names are offered too: typing `sca` and being offered nothing\n // is the exact failure that produced the ref/reference pair (D5).\n const registered = [...this.commands.keys(), ...this.aliases.keys()];\n return [...builtIns, ...registered]\n .filter(name => name.startsWith(prefix) && name !== prefix)\n .sort();\n }\n}\n","/**\n * Quote-aware command tokenizer. Treats \"...\" as single tokens and strips enclosing quotes.\n */\nexport function tokenize(input: string): string[] {\n return (input.match(/(?:\"[^\"]*\"|\\S)+/g) ?? []).map(t => t.replace(/\"([^\"]*)\"/g, '$1'));\n}\n\nexport const CLEAR_USAGE =\n 'clear\\n\\n' +\n ' Clears the terminal history.\\n' +\n ' No arguments required.';\n\nexport const HELP_USAGE =\n 'help [command]\\n\\n' +\n ' With no arguments, lists all available commands.\\n' +\n ' With a command name, shows detailed usage for that command.\\n\\n' +\n ' Arguments:\\n' +\n ' [command] Optional command name to show detailed help for';\n","/*\nCreated by Franz Zemen 2026-10-18\nLicense Type: UNLICENSED\n\nA question a command leaves open in the terminal (live-trading-foundation.prd.md D24).\n\nA command can ask instead of acting: \"Send SIM · Buy 100 NVDA? (Enter or yes to send, Esc to\ncancel)\". The next line typed — including a bare Enter — is the answer and goes to the command,\nnot to the command parser. Esc cancels. The arming code is asked the same way, with the input\nmasked so the code never appears on screen or in the terminal's history.\n\nPlain logic, no Angular: `CommandService` holds one of these and the terminal reads it.\n*/\n\nimport type { CommandResult } from '../types/command.types';\n\nexport interface PendingPrompt {\n /** The question, shown in the terminal and as the input's placeholder. */\n readonly question: string;\n /** Mask what is typed (a code), in the input and in the history. */\n readonly masked?: boolean;\n /**\n * The answer: the line typed, trimmed — `''` for a bare Enter. The command decides what counts\n * as yes. It may ask again by calling `ask` from inside.\n */\n answer(text: string): CommandResult | Promise<CommandResult>;\n /** Esc, or a new question replacing this one. */\n cancel?(): void;\n}\n\n/** True for the answers that mean yes: a bare Enter, `y`, `yes`. */\nexport function isYes(text: string): boolean {\n const t = text.trim().toLowerCase();\n return t === '' || t === 'y' || t === 'yes';\n}\n\n/** What the history shows for an answer: the text, a masked run, or \"(Enter)\". */\nexport function answerEcho(prompt: PendingPrompt, text: string): string {\n if (text === '') return '(Enter)';\n return prompt.masked ? '•'.repeat(text.length) : text;\n}\n\n/** Holds at most one open question. Asking again cancels the one before it. */\nexport class PendingPromptState {\n #current: PendingPrompt | null = null;\n\n get current(): PendingPrompt | null {\n return this.#current;\n }\n\n ask(prompt: PendingPrompt): void {\n const before = this.#current;\n this.#current = prompt;\n if (before && before !== prompt) before.cancel?.();\n }\n\n /**\n * Takes the open question and closes it, so an answer that asks again opens a fresh one rather\n * than being closed afterwards.\n */\n take(): PendingPrompt | null {\n const p = this.#current;\n this.#current = null;\n return p;\n }\n\n cancel(): boolean {\n const p = this.#current;\n if (!p) return false;\n this.#current = null;\n p.cancel?.();\n return true;\n }\n}\n","import { inject, Injectable, signal, computed, effect } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { z } from 'zod/v4';\nimport { CommandResult, CommandHistoryEntry, CommandScope, Severity, matchesRoute } from '../types/command.types';\nimport { tokenize, CLEAR_USAGE, HELP_USAGE } from '../commands/command.utils';\nimport { CommandRegistryService } from './command-registry.service';\nimport { AuthenticationService } from './authentication.service';\nimport { answerEcho, PendingPromptState, type PendingPrompt } from './pending-prompt';\n\nexport type { CommandResult, CommandHistoryEntry, Severity, PendingPrompt };\n\nconst CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');\n\n@Injectable({ providedIn: 'root' })\nexport class CommandService {\n readonly history = signal<CommandHistoryEntry[]>([]);\n readonly currentInput = signal('');\n readonly isProcessing = signal(false);\n readonly helpOverlay = signal<string | null>(null);\n\n /**\n * The question a command left open, or null (live-trading-foundation.prd.md D24). While set, the\n * next line — a bare Enter included — is its answer, not a command; Esc cancels.\n */\n readonly pending = signal<PendingPrompt | null>(null);\n readonly #prompts = new PendingPromptState();\n /**\n * True while a command (or an answer) runs. A question it asks is written to the history only\n * after the command's own lines, so it reads as the last thing said, under the preview it is about.\n */\n #running = false;\n #deferredQuestion: PendingPrompt | undefined;\n\n private readonly authService = inject(AuthenticationService);\n private readonly registry = inject(CommandRegistryService);\n private readonly router = inject(Router);\n\n constructor() {\n effect(() => {\n if (!this.authService.authenticated()) {\n this.history.set([]);\n // A question asked for a session that has ended must not be answerable by the next one.\n this.#prompts.cancel();\n this.pending.set(null);\n }\n });\n }\n\n readonly lastResult = computed(() => {\n const h = this.history();\n return h.length > 0 ? h[h.length - 1].result : null;\n });\n\n dismissHelp(): void {\n this.helpOverlay.set(null);\n }\n\n /** Leaves a question open; the next line typed answers it. A question already open is cancelled. */\n ask(prompt: PendingPrompt): void {\n this.#prompts.ask(prompt);\n this.pending.set(prompt);\n if (this.#running) this.#deferredQuestion = prompt;\n else this.#writeQuestion(prompt);\n }\n\n #writeQuestion(prompt: PendingPrompt): void {\n this.history.update(h => [...h, {\n input: '',\n result: { success: true, message: prompt.question, timestamp: new Date(), severity: 'info' },\n }]);\n }\n\n /** After a command's or an answer's own lines: the question it asked, if it is still open. */\n #finishRun(): void {\n this.#running = false;\n const q = this.#deferredQuestion;\n this.#deferredQuestion = undefined;\n if (q && this.#prompts.current === q) this.#writeQuestion(q);\n }\n\n /** Esc: closes the open question, if any. True when there was one. */\n cancelPending(): boolean {\n if (!this.#prompts.cancel()) return false;\n this.pending.set(null);\n this.currentInput.set('');\n this.history.update(h => [...h, {\n input: '',\n result: { success: true, message: 'Cancelled — nothing was sent.', timestamp: new Date(), severity: 'info' },\n }]);\n return true;\n }\n\n #answer(rawInput: string): void {\n const prompt = this.#prompts.take();\n if (!prompt) return;\n this.pending.set(null);\n const text = rawInput.trim();\n const echo = answerEcho(prompt, text);\n this.currentInput.set('');\n const record = (result: CommandResult) => {\n this.history.update(h => [...h, { input: echo, result }]);\n this.#finishRun();\n };\n this.#running = true;\n let out: CommandResult | Promise<CommandResult>;\n try {\n out = prompt.answer(text);\n } catch (err) {\n out = { success: false, message: (err as Error)?.message ?? String(err), timestamp: new Date() };\n }\n if (out instanceof Promise) {\n this.isProcessing.set(true);\n out\n .then(record, err => record({ success: false, message: (err as Error)?.message ?? String(err), timestamp: new Date() }))\n .finally(() => this.isProcessing.set(false));\n } else {\n record(out);\n }\n }\n\n echoCommand(input: string): void {\n if (this.#coalesce(input)) return;\n this.history.update(h => [...h, {\n input,\n result: { success: true, message: '', timestamp: new Date() },\n repeatCount: 1,\n }]);\n }\n\n pushNotification(notification: { message: string; severity: Severity }): void {\n this.history.update(h => [...h, {\n input: '',\n result: {\n success: notification.severity !== 'error',\n message: notification.message,\n timestamp: new Date(),\n severity: notification.severity,\n },\n }]);\n }\n\n execute(rawInput: string): void {\n // An open question takes the line, a bare Enter included (D24).\n if (this.#prompts.current) {\n this.#answer(rawInput);\n return;\n }\n const validation = CommandInputSchema.safeParse(rawInput);\n if (!validation.success) {\n this.history.update(h => [...h, {\n input: rawInput,\n result: { success: false, message: validation.error.issues[0].message, timestamp: new Date() },\n }]);\n this.currentInput.set('');\n return;\n }\n\n const input = validation.data;\n const parts = tokenize(input);\n const command = parts[0].toLowerCase();\n\n // Resolved rather than looked up by name: a command typed under an\n // alternate name must still get its own input sanitiser (a password line\n // masked under `login` stays masked under any other word for it).\n const def = this.registry.resolve(command)?.command;\n const displayInput = def?.sanitizeInput ? def.sanitizeInput(input) : input;\n\n this.#running = true;\n let resultOrPromise: CommandResult | Promise<CommandResult>;\n try {\n resultOrPromise = this.#dispatch(command, parts.slice(1));\n } catch (err) {\n resultOrPromise = { success: false, message: (err as Error)?.message ?? String(err), timestamp: new Date() };\n }\n this.currentInput.set('');\n\n if (resultOrPromise instanceof Promise) {\n this.isProcessing.set(true);\n resultOrPromise\n .then(result => {\n if (result.isHelp && result.message) {\n this.helpOverlay.set(result.message);\n }\n const historyResult = result.isHelp ? { ...result, message: '' } : result;\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: historyResult, repeatCount: 1 }]);\n }\n })\n .finally(() => {\n this.#finishRun();\n this.isProcessing.set(false);\n });\n } else {\n if (resultOrPromise.isHelp && resultOrPromise.message) {\n this.helpOverlay.set(resultOrPromise.message);\n }\n const historyResult = resultOrPromise.isHelp ? { ...resultOrPromise, message: '' } : resultOrPromise;\n if (!this.#coalesce(displayInput)) {\n this.history.update(h => [...h, { input: displayInput, result: historyResult, repeatCount: 1 }]);\n }\n this.#finishRun();\n }\n }\n\n #coalesce(input: string): boolean {\n if (!input) return false;\n const h = this.history();\n for (let i = h.length - 1; i >= 0; i--) {\n if (h[i].input) {\n if (h[i].input === input) {\n this.history.update(history => {\n const updated = [...history];\n updated[i] = { ...updated[i], repeatCount: (updated[i].repeatCount ?? 1) + 1 };\n return updated;\n });\n return true;\n }\n return false;\n }\n }\n return false;\n }\n\n #dispatch(command: string, args: string[]): CommandResult | Promise<CommandResult> {\n // Normalize \"help <command>\" → \"<command> help\" so auth and dispatch rules apply uniformly\n if (command === 'help' && args.length > 0 && args[0].toLowerCase() !== 'help') {\n [command, args] = [args[0].toLowerCase(), ['help']];\n }\n\n const hasHelp = args.some(a => a.toLowerCase() === 'help');\n const isAuthenticated = this.authService.authenticated();\n const notLoggedIn = (): CommandResult => ({\n success: false,\n message: 'Not logged in. Use \"login\" to authenticate.',\n timestamp: new Date(),\n });\n\n if (command === 'clear') {\n if (!isAuthenticated) return notLoggedIn();\n if (hasHelp) return { success: true, message: CLEAR_USAGE, timestamp: new Date(), isHelp: true };\n this.history.set([]);\n return { success: true, message: '', timestamp: new Date() };\n }\n\n if (command === 'help') {\n if (!isAuthenticated) return notLoggedIn();\n const target = args[0]?.toLowerCase();\n if (target) return this.#commandHelp(target);\n const registered = this.registry.getAll();\n const lines = [\n ' clear — Clear terminal history',\n ' help — List available commands',\n // Unavailable commands stay listed, annotated. Removing them would make\n // the CLI look broken rather than gated.\n // A command scoped to another screen stays listed too, with its screen\n // named rather than hidden (trades-tree.prd.md D31): hiding it would\n // read as a broken CLI.\n ...registered.map(c => {\n const availability = c.isAvailable?.();\n const suffix = availability && !availability.ok ? ` [unavailable — ${availability.reason}]` : this.#scopeSuffix(c.scope);\n return ` ${c.name} — ${c.description}${suffix}`;\n }),\n ];\n return {\n success: true,\n message: 'Available commands:\\n' + lines.join('\\n') + '\\n\\nType \"help <command>\" or \"<command> help\" for detailed usage.',\n timestamp: new Date(),\n isHelp: true,\n };\n }\n\n /*\n * Resolution, not a name lookup — `scan` and `scans` reach the scanner the\n * same way `scanner` does. An alternate may also carry leading words\n * (`scans NVDA` IS `scanner select NVDA`), which are inserted ahead of what\n * the user typed.\n *\n * ⭐ `command` keeps the word the USER typed. Every message below\n * interpolates it, and telling someone who typed `scan` that the arguments\n * of 'scanner' are wrong reads as though something else ran. The two-word\n * swap is the one deliberate exception, because there the typed first word\n * really was an argument.\n */\n let resolved = this.registry.resolve(command);\n if (resolved) {\n args = [...resolved.prependArgs, ...args];\n }\n let def = resolved?.command;\n if (!def) {\n // Try swapping the first two tokens: \"disable user foo\" → \"user disable foo\"\n const swapped = args[0]?.toLowerCase();\n const swappedResolved = swapped ? this.registry.resolve(swapped) : undefined;\n if (swappedResolved) {\n def = swappedResolved.command;\n args = [...swappedResolved.prependArgs, command, ...args.slice(1)];\n command = swapped!;\n } else {\n if (!isAuthenticated && command !== 'login') return notLoggedIn();\n return { success: false, message: `Unknown command: ${command}`, timestamp: new Date() };\n }\n }\n\n if (!isAuthenticated && command !== 'login' && def.requiresAuth !== false) {\n return notLoggedIn();\n }\n\n if (hasHelp) {\n // `help <command>` is normalised to `<command> help` above, so this is\n // the one place a command's usage is shown; the screen it works on goes\n // here (D31).\n return { success: true, message: def.usage + this.#whereNote(def.scope), timestamp: new Date(), isHelp: true };\n }\n\n // Screen gate (trades-tree.prd.md D30). A command bound to state only one\n // screen sets is refused off that screen with the screen named, the way\n // `tab` always did on its own. A command that navigates to its screen is\n // never refused here — declaring its routes is what lets `help` say where\n // it lives, and taking the user there is the handler's job (D32).\n if (def.scope !== 'global' && def.scope.elsewhere === 'refuse' && !matchesRoute(this.router.url, def.scope.routes)) {\n return {\n success: false,\n message: `'${command}' works on ${def.scope.screen}.`,\n severity: 'error',\n timestamp: new Date(),\n };\n }\n\n // Readiness gate. Deliberately ahead of argument validation: \"you can't use\n // this yet, here's why\" is more useful than a complaint about the arguments\n // of a command that wouldn't have run anyway.\n const availability = def.isAvailable?.();\n if (availability && !availability.ok) {\n return {\n success: false,\n message: availability.reason || `'${command}' is not available yet.`,\n severity: 'error',\n timestamp: new Date(),\n };\n }\n\n const validation = def.argsSchema.safeParse(args);\n if (!validation.success) {\n return { success: false, message: `Invalid arguments for '${command}': ${validation.error.issues[0].message}`, timestamp: new Date() };\n }\n\n return def.execute(args);\n }\n\n #commandHelp(name: string): CommandResult {\n if (name === 'clear') return { success: true, message: CLEAR_USAGE, timestamp: new Date(), isHelp: true };\n if (name === 'help') return { success: true, message: HELP_USAGE, timestamp: new Date(), isHelp: true };\n const def = this.registry.resolve(name)?.command;\n if (!def) return { success: false, message: `Unknown command: ${name}`, timestamp: new Date() };\n // Usage is still shown for a gated command — knowing how it works is how a\n // user decides whether it's worth unlocking. The gate is noted, not enforced.\n const availability = def.isAvailable?.();\n const note = availability && !availability.ok ? `\\n\\nCurrently unavailable — ${availability.reason}` : '';\n return { success: true, message: def.usage + this.#whereNote(def.scope) + note, timestamp: new Date(), isHelp: true };\n }\n\n /** \"Works on the Trades screen.\" — appended to a scoped command's usage. */\n #whereNote(scope: CommandScope): string {\n return scope === 'global' ? '' : `\\n\\nWorks on ${scope.screen}.`;\n }\n\n /** `help`'s annotation for a command scoped to a screen other than the current one. */\n #scopeSuffix(scope: CommandScope): string {\n if (scope === 'global' || matchesRoute(this.router.url, scope.routes)) return '';\n return ` [${scope.screen}]`;\n }\n}\n","import { Component, computed, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { SHELL_SHARED_SESSION } from '../../tokens/shell-tokens';\nimport { MatIconModule } from '@angular/material/icon';\n\n/** Roomy enough for the scanner beside a chart, small enough for a laptop. */\nconst POP_OUT_WIDTH = 1280;\nconst POP_OUT_HEIGHT = 900;\n\n@Component({\n selector: 'shell-status-bar',\n imports: [MatIconModule],\n templateUrl: './status-bar.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './status-bar.css',\n})\nexport class StatusBar {\n readonly #authService = inject(AuthenticationService);\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n\n readonly #sharedSession = inject(SHELL_SHARED_SESSION, { optional: true }) ?? false;\n\n readonly #phoneLayout = inject(PhoneLayoutService);\n\n readonly isAuthenticated = this.#authService.authenticated;\n\n /** The ☰ button: phones only, and only when there is a menu to open (signed in). */\n readonly showMenuButton = computed(() => this.#phoneLayout.isPhone() && this.isAuthenticated());\n readonly menuOpen = this.#phoneLayout.menuOpen;\n\n /**\n * Whether a second window is offered at all (multiple-windows PRD D14).\n *\n * ⚠ GATED ON SHARED SESSIONS, and this is a correctness gate rather than a\n * tidiness one. Without a session shared across windows, the new window starts\n * with no token, goes to the login screen, and signing in there ends the\n * session THIS window is using. A pop-out button in an app without sharing is\n * a button that signs you out — the exact failure the multiple-windows work\n * exists to remove.\n */\n readonly canPopOut = computed(() => this.#sharedSession && this.isAuthenticated());\n readonly loginStatus = computed(() =>\n this.#authService.authenticating()\n ? 'Authenticating...'\n : this.#authService.authenticated()\n ? 'Logged in'\n : 'Not logged in',\n );\n\n logout(): void {\n this.#authService.logout();\n this.#commandService.echoCommand('logout');\n this.#focusService.requestFocus();\n }\n\n /**\n * Open the screen you are on in a second, sized window.\n *\n * There is no mechanism by which this differs from the browser's own\n * \"Duplicate tab\": every window is a separate copy of the app started at some\n * address. It exists for the sizing and because it is discoverable — Ctrl+T,\n * a bookmark and dragging a tab out all work equally well once the session is\n * shared.\n *\n * `noopener` is deliberate. The new window needs nothing from this one — it\n * reads the session from storage — and leaving the opener reachable would give\n * two windows script access to each other for no purpose.\n */\n popOut(): void {\n if (typeof window === 'undefined') return;\n window.open(\n window.location.href,\n '_blank',\n `noopener,noreferrer,width=${POP_OUT_WIDTH},height=${POP_OUT_HEIGHT}`,\n );\n this.#focusService.requestFocus();\n }\n\n toggleMenu(): void {\n this.#phoneLayout.toggleMenu();\n }\n\n openFaq(): void {\n this.#commandService.execute('faq');\n this.#focusService.requestFocus();\n }\n}\n","<div class=\"status-bar\">\n @if (showMenuButton()) {\n <!-- Phone only (scanner-phone-display D9): the icon column is folded into this menu. -->\n <button\n type=\"button\"\n class=\"menu-button text-interactive\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"menuOpen()\"\n aria-controls=\"shell-phone-menu\"\n aria-label=\"Menu\"\n ><mat-icon>menu</mat-icon></button>\n }\n <div class=\"status-item status-item-own\">\n <span class=\"status-label text-secondary-info\">Status:</span>\n @if (isAuthenticated()) {\n <a class=\"status-value text-interactive logout-link\" (click)=\"logout()\">Log Out</a>\n } @else {\n <span class=\"status-value text-loss\">{{ loginStatus() }}</span>\n }\n </div>\n @if (isAuthenticated()) {\n <ng-content />\n }\n @if (canPopOut()) {\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"popOut()\"\n title=\"Open this screen in a second window\"\n aria-label=\"Open this screen in a second window\"\n >⧉</button>\n }\n <button\n type=\"button\"\n class=\"faq-button text-interactive\"\n (click)=\"openFaq()\"\n title=\"Open FAQ (or type `faq`)\"\n aria-label=\"Open FAQ\"\n >?</button>\n</div>\n","import { Component, computed, inject, input, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterLink, RouterLinkActive } from '@angular/router';\nimport { MatIconModule } from '@angular/material/icon';\nimport { MatTooltipModule } from '@angular/material/tooltip';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { CommandService } from '../../services/command.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\nimport { TerminalVisibilityService } from '../../services/terminal-visibility.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { SHELL_MENU_ITEMS } from '../../tokens/shell-tokens';\nimport { MenuItem } from '../../types/menu.types';\n\nexport { MenuItem };\n\n@Component({\n selector: 'shell-side-menu',\n imports: [RouterLink, RouterLinkActive, MatIconModule, MatTooltipModule],\n templateUrl: './side-menu.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './side-menu.css',\n})\nexport class SideMenu {\n readonly #focusService = inject(TerminalFocusService);\n readonly #commandService = inject(CommandService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly #terminalVisibility = inject(TerminalVisibilityService);\n readonly hasShortcuts = this.#shortcutService.activeShortcuts;\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly terminalVisible = this.#terminalVisibility.visible;\n\n /**\n * Phone-menu rendering (scanner-phone-display D9): the same items as the icon\n * column, each with its label as visible text — a tooltip needs a hover a\n * touch screen does not have.\n *\n * ⚠ The keyboard-shortcuts button (Alt+?) is left out here. It opens a list of\n * Alt-key bindings, and a phone has no Alt key. The shortcuts themselves are\n * untouched — they are document-level listeners and work from a hardware\n * keyboard whatever the layout.\n *\n * The console show/hide button stays (Franz, 2026-10-17: the console is back\n * on phones, reversing 0.8.1). Turning the console ON from here does not put\n * the cursor in the command box on a phone — see CommandTerminal.focusOnAppear.\n */\n readonly drawer = input(false);\n\n readonly #allMenuItems: MenuItem[] = inject(SHELL_MENU_ITEMS, { optional: true }) ?? [];\n\n readonly menuItems = computed(() =>\n this.#allMenuItems.filter(item => !item.visible || item.visible()),\n );\n\n /**\n * Readiness, not entitlement — an unentitled item never reaches here, having\n * been filtered out by `visible` above. Read from the template so the\n * predicate's signal reads are tracked and the strip regreys live when the\n * user's state changes.\n */\n isEnabled(item: MenuItem): boolean {\n return !item.enabled || item.enabled();\n }\n\n disabledReasonFor(item: MenuItem): string {\n return item.disabledReason?.() ?? item.label;\n }\n\n onMenuClick(item: MenuItem): void {\n if (item.command) {\n this.#commandService.echoCommand(item.command);\n }\n if (this.drawer()) {\n // ⚠ No terminal focus from the phone menu. Focusing the command box on a\n // phone raises the on-screen keyboard over half the screen you just\n // navigated to.\n this.#phoneLayout.closeMenu();\n return;\n }\n this.#focusService.requestFocus();\n }\n\n toggleHelp(): void {\n this.#shortcutService.toggleHelp();\n }\n\n toggleTerminal(): void {\n this.#terminalVisibility.toggle();\n // ⚠ No terminal focus here either: on a phone, showing the console is not a\n // request to type. The menu closes so the user sees the console appear.\n if (this.drawer()) this.#phoneLayout.closeMenu();\n }\n}\n","<nav class=\"side-menu\" [class.drawer]=\"drawer()\" [attr.aria-label]=\"drawer() ? 'Menu' : null\">\n @for (item of menuItems(); track item.route) {\n @if (isEnabled(item)) {\n <a\n class=\"menu-item\"\n [routerLink]=\"item.route\"\n routerLinkActive=\"active\"\n [matTooltip]=\"item.label\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n (click)=\"onMenuClick(item)\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">{{ item.label }}</span>\n }\n </a>\n } @else {\n <!-- No routerLink: the item is inert. Pointer events stay live (see the\n .disabled rule) so the tooltip still fires — it carries the only\n explanation the user gets. In the phone menu the explanation is shown\n as text instead, since there is no hover to fire it. -->\n <span\n class=\"menu-item disabled\"\n [matTooltip]=\"disabledReasonFor(item)\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n aria-disabled=\"true\"\n >\n <mat-icon>{{ item.icon }}</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">\n {{ item.label }}\n <span class=\"menu-reason\">{{ disabledReasonFor(item) }}</span>\n </span>\n }\n </span>\n }\n }\n <div class=\"menu-spacer\"></div>\n <button\n class=\"menu-item terminal-toggle\"\n type=\"button\"\n [class.active]=\"terminalVisible()\"\n [matTooltip]=\"terminalVisible() ? 'Hide command console' : 'Show command console'\"\n matTooltipPosition=\"right\"\n [matTooltipDisabled]=\"drawer()\"\n [attr.aria-pressed]=\"terminalVisible()\"\n (click)=\"toggleTerminal()\"\n >\n <mat-icon>terminal</mat-icon>\n @if (drawer()) {\n <span class=\"menu-label\">{{ terminalVisible() ? 'Hide command console' : 'Show command console' }}</span>\n }\n </button>\n @if (hasShortcuts() && !drawer()) {\n <button\n class=\"help-button\"\n matTooltip=\"Keyboard shortcuts\"\n matTooltipPosition=\"right\"\n (click)=\"toggleHelp()\"\n >\n <span class=\"help-modifier\">Alt+</span><span class=\"help-key\">?</span>\n </button>\n }\n</nav>\n","import { Component, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { MatProgressSpinnerModule } from '@angular/material/progress-spinner';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { KeyboardShortcutService } from '../../services/keyboard-shortcut.service';\n\n@Component({\n selector: 'shell-main-content',\n imports: [RouterOutlet, MatProgressSpinnerModule],\n templateUrl: './main-content.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './main-content.css',\n})\nexport class MainContent {\n readonly #thinkingService = inject(ThinkingService);\n readonly #shortcutService = inject(KeyboardShortcutService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly shortcutHelpVisible = this.#shortcutService.helpVisible;\n readonly activeShortcuts = this.#shortcutService.activeShortcuts;\n\n formatKey(key: string): string {\n const keyMap: Record<string, string> = {\n ArrowUp: '↑', ArrowDown: '↓', ArrowLeft: '←', ArrowRight: '→',\n PageUp: 'PgUp', PageDown: 'PgDn',\n };\n return keyMap[key] ?? key;\n }\n\n closeShortcutHelp(): void {\n this.#shortcutService.helpVisible.set(false);\n }\n}\n","<div class=\"main-content\">\n <div class=\"content-area\">\n <router-outlet />\n </div>\n @if (shortcutHelpVisible() && activeShortcuts()) {\n <div class=\"shortcut-overlay\" (click)=\"closeShortcutHelp()\">\n <div class=\"shortcut-panel\" (click)=\"$event.stopPropagation()\">\n <div class=\"shortcut-title text-secondary-info\">{{ activeShortcuts()!.groupId }} shortcuts</div>\n @for (s of activeShortcuts()!.shortcuts; track s.key) {\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Alt+{{ formatKey(s.key) }}</kbd>\n <span class=\"shortcut-desc text-text-primary\">{{ s.description }}</span>\n </div>\n }\n <!--\n Esc is documented rather than added (scanner-command-speed.prd.md D24/E4).\n It has always put the cursor in the command box, from anywhere and even\n while typing in a field — it was simply never written down, which is why\n it read as a missing feature. Worded for what it actually does: it also\n closes this panel, and it does not check whether a dialog is open.\n -->\n <div class=\"shortcut-row\">\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-text-primary\">Put the cursor in the command box, from anywhere</span>\n </div>\n <div class=\"shortcut-row shortcut-dismiss\">\n <kbd class=\"shortcut-key\">Alt+?</kbd>\n <span class=\"shortcut-desc text-secondary-info\">or</span>\n <kbd class=\"shortcut-key\">Esc</kbd>\n <span class=\"shortcut-desc text-secondary-info\">dismiss</span>\n </div>\n </div>\n </div>\n }\n @if (isThinking()) {\n <div class=\"thinking-overlay\">\n <mat-spinner diameter=\"48\" />\n </div>\n }\n</div>\n","import { Component, inject, input, ElementRef, viewChild, effect, afterNextRender, computed, ChangeDetectionStrategy } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { CommandService } from '../../services/command.service';\nimport { CommandRegistryService } from '../../services/command-registry.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { CommandResult } from '../../types/command.types';\n\n@Component({\n selector: 'shell-command-terminal',\n imports: [FormsModule],\n templateUrl: './command-terminal.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './command-terminal.css',\n})\nexport class CommandTerminal {\n private readonly commandService = inject(CommandService);\n private readonly registry = inject(CommandRegistryService);\n private readonly authService = inject(AuthenticationService);\n private readonly terminalFocusService = inject(TerminalFocusService);\n readonly #phoneLayout = inject(PhoneLayoutService);\n\n /**\n * Whether the command box takes the cursor when the console first appears.\n *\n * True for a standalone console. The shell passes false on a phone (below\n * 820px), including when the user turns the console on from the ☰ menu:\n * showing the console is not a request to type, and focusing the box would\n * raise the on-screen keyboard over it (scanner-phone-display D10). On a\n * phone, focusInput() refuses anyway; this keeps the intent explicit.\n */\n readonly focusOnAppear = input(true);\n\n readonly history = computed(() => [...this.commandService.history()].reverse());\n readonly currentInput = this.commandService.currentInput;\n readonly isProcessing = this.commandService.isProcessing;\n /** The question a command left open (D24): the input answers it; Esc cancels. */\n readonly pending = this.commandService.pending;\n\n private readonly inputEl = viewChild<ElementRef<HTMLInputElement>>('terminalInput');\n\n private tabCycleIndex = -1;\n private lastTabPrefix = '';\n\n readonly ghostText = computed(() => {\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return '';\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n return suggestions.length > 0 ? suggestions[0] : '';\n });\n\n constructor() {\n afterNextRender(() => {\n if (this.focusOnAppear()) this.focusInput();\n });\n\n // Both effects below skip their first run. An effect runs once when it is\n // created, so without the skip each would focus the box on appearance a\n // second and third time — after `focusOnAppear` had said not to. Appearance\n // is the afterNextRender above's job alone; these react to CHANGES.\n let firstProcessingRun = true;\n effect(() => {\n const busy = this.isProcessing();\n if (firstProcessingRun) {\n firstProcessingRun = false;\n return;\n }\n if (!busy) {\n setTimeout(() => this.focusInput());\n }\n });\n\n let firstRequestRun = true;\n effect(() => {\n this.terminalFocusService.focusRequested();\n if (firstRequestRun) {\n firstRequestRun = false;\n return;\n }\n setTimeout(() => this.focusInput());\n });\n }\n\n onSubmit(): void {\n const input = this.currentInput();\n // With a question open, a bare Enter is an answer.\n if (!input.trim() && !this.pending()) return;\n this.commandService.execute(input);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n this.focusInput();\n }\n\n onInputChange(value: string): void {\n this.currentInput.set(value);\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n if (this.commandService.helpOverlay()) {\n this.commandService.dismissHelp();\n }\n }\n\n dismissHelp(): void {\n this.commandService.dismissHelp();\n }\n\n /** Esc: cancels an open question first, otherwise closes the help overlay. */\n onEscape(): void {\n if (!this.commandService.cancelPending()) this.dismissHelp();\n }\n\n onTab(event: KeyboardEvent): void {\n event.preventDefault();\n const input = this.currentInput().trim();\n if (!input || input.includes(' ')) return;\n\n const prefix = input.toLowerCase();\n const suggestions = this.registry.getSuggestions(prefix, this.authService.authenticated());\n if (suggestions.length === 0) return;\n\n if (suggestions.length === 1) {\n this.currentInput.set(suggestions[0] + ' ');\n this.tabCycleIndex = -1;\n this.lastTabPrefix = '';\n return;\n }\n\n if (this.lastTabPrefix !== prefix) {\n this.lastTabPrefix = prefix;\n this.tabCycleIndex = -1;\n }\n\n if (event.shiftKey) {\n this.tabCycleIndex = this.tabCycleIndex <= 0 ? suggestions.length - 1 : this.tabCycleIndex - 1;\n } else {\n this.tabCycleIndex = (this.tabCycleIndex + 1) % suggestions.length;\n }\n\n this.currentInput.set(suggestions[this.tabCycleIndex]);\n }\n\n getSeverityClass(result: CommandResult): string {\n if (result.severity === 'info') return 'info';\n if (result.severity === 'warning') return 'warning';\n if (result.severity === 'error' || !result.success) return 'error';\n return '';\n }\n\n /**\n * ⚠ A no-op on a phone (scanner-phone-display D10/E11). The console is shown\n * there, but only the user tapping the box may give it the cursor; every\n * programmatic path (first appearance, a finished command, a focus request,\n * an app calling this) ends here and is refused, so nothing on a phone can\n * raise the on-screen keyboard unasked.\n */\n focusInput(): void {\n if (this.#phoneLayout.isPhone()) return;\n this.inputEl()?.nativeElement.focus();\n }\n}\n","<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText() && !pending()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n [type]=\"pending()?.masked ? 'password' : 'text'\"\n [class.answering]=\"!!pending()\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"onEscape()\"\n [placeholder]=\"pending()?.question ?? 'Type a command...'\"\n [attr.autocomplete]=\"pending()?.masked ? 'one-time-code' : 'off'\"\n [disabled]=\"isProcessing()\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(×{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n","import { Component, computed, effect, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { StatusBar } from '../status-bar/status-bar';\nimport { SideMenu } from '../side-menu/side-menu';\nimport { MainContent } from '../main-content/main-content';\nimport { CommandTerminal } from '../command-terminal/command-terminal';\nimport { FaqModal } from '../../faq/faq-modal/faq-modal';\nimport { ThinkingService } from '../../services/thinking.service';\nimport { CommandService } from '../../services/command.service';\nimport { AuthenticationService } from '../../services/authentication.service';\nimport { TerminalVisibilityService } from '../../services/terminal-visibility.service';\nimport { PhoneLayoutService } from '../../services/phone-layout.service';\nimport { CdkTrapFocus } from '@angular/cdk/a11y';\n\nconst MIN_TERMINAL_HEIGHT = 80;\nconst MAX_TERMINAL_RATIO = 0.6;\nconst DEFAULT_TERMINAL_HEIGHT = 160;\n/**\n * How often a signed-in window re-reads whether the AWS-set bypass is on\n * (authenticator-sign-in.prd.md D12). The server never says when it ends, so the\n * banner goes away on the first read after it has.\n */\nconst BYPASS_RECHECK_MS = 2 * 60 * 1000;\n\n@Component({\n selector: 'shell-root',\n imports: [StatusBar, SideMenu, MainContent, CommandTerminal, FaqModal, CdkTrapFocus],\n templateUrl: './shell.html',\n changeDetection: ChangeDetectionStrategy.Eager,\n styleUrl: './shell.css',\n})\nexport class Shell {\n readonly #thinkingService = inject(ThinkingService);\n readonly #commandService = inject(CommandService);\n readonly #authService = inject(AuthenticationService);\n readonly #terminalVisibility = inject(TerminalVisibilityService);\n readonly isThinking = this.#thinkingService.isThinking;\n readonly isAuthenticated = this.#authService.authenticated;\n readonly helpOverlay = this.#commandService.helpOverlay;\n readonly #phoneLayout = inject(PhoneLayoutService);\n readonly terminalVisible = this.#terminalVisibility.visible;\n /** Below 820px the icon column is replaced by the ☰ menu (scanner-phone-display D9). */\n readonly isPhone = this.#phoneLayout.isPhone;\n readonly phoneMenuOpen = this.#phoneLayout.menuOpen;\n\n /**\n * Whether the command box takes the cursor when the console appears: on a\n * desktop yes, on a phone never (scanner-phone-display D10, Franz 2026-10-17).\n *\n * The console is shown on a phone again (reversing 0.8.1), but nothing may\n * put the cursor in its box there — the on-screen keyboard would cover the\n * screen. That includes the user turning the console ON from the ☰ menu: a\n * show is not a request to type, and the keyboard rising over the console the\n * moment it appears would hide the output the user wanted to see. Tapping the\n * box is the only way it gets the cursor on a phone.\n *\n * Rotating across 820px never mounts or unmounts the console (its visibility\n * is the user's choice alone), so this is only read when the user turns it on\n * or at start-up. CommandTerminal.focusInput also refuses on a phone, as a\n * second guard.\n */\n readonly consoleFocusOnAppear = computed(() => !this.isPhone());\n\n /** \"Sign-in code check is off.\" on every screen while the bypass is on (D12). */\n readonly bypassActive = this.#authService.bypassActive;\n\n /**\n * Keeps `bypassActive` current while signed in: once now (a window restored from\n * storage never saw the sign-in response) and then every two minutes.\n */\n readonly #bypassWatch = effect(onCleanup => {\n if (!this.isAuthenticated()) return;\n const read = () => { this.#authService.authenticatorStatus().catch(() => undefined); };\n read();\n const timer = setInterval(read, BYPASS_RECHECK_MS);\n onCleanup(() => clearInterval(timer));\n });\n\n closePhoneMenu(): void {\n this.#phoneLayout.closeMenu();\n }\n\n dismissHelp(): void {\n this.#commandService.dismissHelp();\n }\n readonly terminalHeight = signal(`${DEFAULT_TERMINAL_HEIGHT}px`);\n readonly isDragging = signal(false);\n\n #startY = 0;\n #startHeight = DEFAULT_TERMINAL_HEIGHT;\n\n #resizeTo(clientY: number): void {\n const deltaY = clientY - this.#startY;\n const maxHeight = Math.floor(window.innerHeight * MAX_TERMINAL_RATIO);\n const newHeight = Math.min(maxHeight, Math.max(MIN_TERMINAL_HEIGHT, this.#startHeight - deltaY));\n this.terminalHeight.set(`${newHeight}px`);\n }\n\n readonly #onMouseMove = (event: MouseEvent) => this.#resizeTo(event.clientY);\n\n readonly #onMouseUp = () => {\n this.isDragging.set(false);\n document.removeEventListener('mousemove', this.#onMouseMove);\n document.removeEventListener('mouseup', this.#onMouseUp);\n };\n\n onResizeStart(event: MouseEvent): void {\n event.preventDefault();\n this.#startY = event.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('mousemove', this.#onMouseMove);\n document.addEventListener('mouseup', this.#onMouseUp);\n }\n\n // Touch drag for the resize bar (scanner-phone-display E12): tablets and,\n // since the console is back there (D10, 2026-10-17), phones. Kept separate from the mouse path so the desktop's behaviour is unchanged;\n // the bar's `touch-action: none` stops the page scrolling under the finger.\n readonly #onTouchMove = (event: TouchEvent) => {\n const touch = event.touches[0];\n if (touch) this.#resizeTo(touch.clientY);\n };\n\n readonly #onTouchEnd = () => {\n this.isDragging.set(false);\n document.removeEventListener('touchmove', this.#onTouchMove);\n document.removeEventListener('touchend', this.#onTouchEnd);\n document.removeEventListener('touchcancel', this.#onTouchEnd);\n };\n\n onResizeTouchStart(event: TouchEvent): void {\n const touch = event.touches[0];\n if (!touch || event.touches.length > 1) return;\n this.#startY = touch.clientY;\n this.#startHeight = parseInt(this.terminalHeight(), 10);\n this.isDragging.set(true);\n document.addEventListener('touchmove', this.#onTouchMove);\n document.addEventListener('touchend', this.#onTouchEnd);\n document.addEventListener('touchcancel', this.#onTouchEnd);\n }\n}\n","<div class=\"shell\" [style.--terminal-height]=\"terminalHeight()\" [class.is-dragging]=\"isDragging()\" [class.terminal-hidden]=\"!terminalVisible()\">\n <shell-status-bar class=\"shell-status\" [class.disabled-zone]=\"isThinking()\">\n <ng-content />\n </shell-status-bar>\n @if (isAuthenticated() && !isPhone()) {\n <shell-side-menu class=\"shell-menu\" [class.disabled-zone]=\"isThinking()\" />\n }\n <shell-main-content class=\"shell-main\" [class.full-width]=\"!isAuthenticated()\" />\n @if (terminalVisible()) {\n <!-- On a phone too (scanner-phone-display D10), but never given the cursor there: see Shell.consoleFocusOnAppear. -->\n <div class=\"shell-resize\" [class.dragging]=\"isDragging()\" (mousedown)=\"onResizeStart($event)\" (touchstart)=\"onResizeTouchStart($event)\"></div>\n <shell-command-terminal class=\"shell-terminal\" [class.disabled-zone]=\"isThinking()\" [focusOnAppear]=\"consoleFocusOnAppear()\" />\n }\n @if (isAuthenticated() && phoneMenuOpen()) {\n <!-- Phone menu (scanner-phone-display D9): the icon column's items, opened from the ☰ button. -->\n <div class=\"phone-menu-backdrop\" (click)=\"closePhoneMenu()\"></div>\n <shell-side-menu\n id=\"shell-phone-menu\"\n class=\"phone-menu\"\n [class.disabled-zone]=\"isThinking()\"\n [drawer]=\"true\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Menu\"\n cdkTrapFocus\n [cdkTrapFocusAutoCapture]=\"true\"\n (keydown.escape)=\"closePhoneMenu()\"\n />\n }\n @if (isAuthenticated() && bypassActive()) {\n <!-- authenticator-sign-in.prd.md D12: cannot be dismissed; no end time (the server never sends one). -->\n <div class=\"bypass-banner\" role=\"status\">Sign-in code check is off.</div>\n }\n <faq-modal />\n\n @if (helpOverlay(); as helpText) {\n <div class=\"help-backdrop\" (click)=\"dismissHelp()\">\n <div class=\"help-panel\" (click)=\"$event.stopPropagation()\" role=\"dialog\" aria-label=\"Command help\">\n <div class=\"help-panel-header\">\n <span class=\"help-panel-title\">Help</span>\n <button class=\"help-panel-close\" type=\"button\" (click)=\"dismissHelp()\" aria-label=\"Close help\">✕</button>\n </div>\n <div class=\"help-panel-content\">{{ helpText }}</div>\n <div class=\"help-panel-footer\">\n <span>Tip: for most commands you can swap the first and second words — e.g. \"disable user\" works the same as \"user disable\"</span>\n <span class=\"help-panel-footer-dismiss\">Press Escape, click outside, or start typing to close</span>\n </div>\n </div>\n </div>\n }\n</div>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nThe 10 recovery codes, shown ONCE (authenticator-sign-in.prd.md D7), with Download (a text file made\nin the browser — nothing is stored on the server as a file) and Copy. \"Continue\" is the only way on,\nso the codes cannot scroll past unseen.\n*/\n\nimport { ChangeDetectionStrategy, Component, input, output, signal } from '@angular/core';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatIconModule } from '@angular/material/icon';\nimport { recoveryCodesFile } from '../../services/authenticator.types';\n\n@Component({\n selector: 'shell-recovery-codes',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [MatButtonModule, MatIconModule],\n template: `\n <div class=\"recovery-codes\">\n <p class=\"recovery-codes-lead text-text-primary\"><strong>Save your recovery codes.</strong></p>\n <p class=\"text-secondary-info\">\n Each one works once, in place of the 6-digit code, if you lose your phone.\n They will not be shown again.\n </p>\n <ol class=\"recovery-codes-list\">\n @for (code of codes(); track code) {\n <li><code>{{ code }}</code></li>\n }\n </ol>\n <div class=\"recovery-codes-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"download()\">\n <mat-icon>download</mat-icon> Download\n </button>\n <button mat-stroked-button type=\"button\" (click)=\"copy()\">\n <mat-icon>content_copy</mat-icon> {{ copied() ? 'Copied' : 'Copy' }}\n </button>\n <button mat-flat-button type=\"button\" (click)=\"done.emit()\">I have saved them — continue</button>\n </div>\n </div>\n `,\n styles: [`\n .recovery-codes { max-width: 360px; padding: 12px 16px; border-radius: 4px; background-color: var(--color-surface-light); text-align: left; font-size: 0.9rem; }\n .recovery-codes p { margin: 0 0 8px 0; }\n .recovery-codes-list { columns: 2; margin: 8px 0 12px 0; padding-left: 1.5em; font-family: var(--shell-mono, monospace); }\n .recovery-codes-list li { margin: 2px 0; }\n .recovery-codes-actions { display: flex; flex-wrap: wrap; gap: 8px; }\n `],\n})\nexport class RecoveryCodes {\n readonly codes = input.required<readonly string[]>();\n readonly appName = input('BrokenStock');\n readonly username = input<string | undefined>(undefined);\n readonly done = output<void>();\n protected readonly copied = signal(false);\n\n download(): void {\n const text = recoveryCodesFile(this.appName(), this.username(), this.codes());\n const url = URL.createObjectURL(new Blob([text], {type: 'text/plain'}));\n const a = document.createElement('a');\n a.href = url;\n a.download = `${this.appName().toLowerCase().replace(/[^a-z0-9]+/g, '-')}-recovery-codes.txt`;\n a.click();\n setTimeout(() => URL.revokeObjectURL(url));\n }\n\n copy(): void {\n navigator.clipboard?.writeText(this.codes().join('\\n')).then(() => this.copied.set(true)).catch(() => undefined);\n }\n}\n","import { Component, inject, signal, ChangeDetectionStrategy } from '@angular/core';\nimport { AutofillEvent, TextFieldModule } from '@angular/cdk/text-field';\nimport { Credentials, SessionSummary, validateCredentials } from '@franzzemen/identity';\nimport { PASSWORD_REGEX, USERNAME_REGEX } from '@franzzemen/utility';\nimport { MatFormField, MatLabel } from '@angular/material/form-field';\nimport { MatInput, MatInputModule } from '@angular/material/input';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatCheckboxModule } from '@angular/material/checkbox';\nimport { MatIconModule } from '@angular/material/icon';\nimport { ActivatedRoute, Router } from '@angular/router';\nimport { DatePipe } from '@angular/common';\nimport { AuthenticationService, CODE_STEP, LoginChoice } from '../../services/authentication.service';\nimport { RecoveryCodes } from '../recovery-codes/recovery-codes';\nimport { CommandService } from '../../services/command.service';\nimport { TerminalFocusService } from '../../services/terminal-focus.service';\nimport { RegexValidatorDirective } from '../../directives/regex-validator.directive';\nimport { SHELL_APP_NAME, SHELL_POST_LOGIN_ROUTE } from '../../tokens/shell-tokens';\n\n@Component({\n selector: 'shell-login',\n templateUrl: './login.html',\n styleUrl: './login.css',\n changeDetection: ChangeDetectionStrategy.Eager,\n imports: [\n FormsModule,\n MatFormField,\n MatLabel,\n MatInput,\n MatInputModule,\n MatButtonModule,\n MatCheckboxModule,\n MatIconModule,\n RegexValidatorDirective,\n TextFieldModule,\n DatePipe,\n RecoveryCodes,\n ],\n})\nexport class Login {\n model: Credentials = { username: '', password: '' };\n submitted = false;\n hide = signal(true);\n errors: { ndx: number; message: string }[] = [];\n\n /**\n * Session identifiers the user has ticked for ending (multiple-devices D7).\n *\n * ⚠ THE TAKEOVER CHECKBOX THAT USED TO LIVE ON THIS FORM IS GONE, and its\n * removal is the point rather than a tidy-up. It defaulted to ON and sat on\n * the FIRST form, before anything was known about what was live — so once a\n * user deliberately holds sessions on two machines, one absent-minded submit\n * ended the session on the machine in the other room. The choice belongs\n * here, on the screen that lists what is actually running.\n */\n readonly selected = signal<ReadonlySet<string>>(new Set());\n\n /** The code or recovery code typed on the code step (authenticator-sign-in.prd.md). */\n codeText = '';\n /** Typing a recovery code instead of the 6-digit code. */\n readonly useRecovery = signal(false);\n\n protected readonly USERNAME_REGEX = USERNAME_REGEX;\n protected readonly PASSWORD_REGEX = PASSWORD_REGEX;\n protected readonly appName = inject(SHELL_APP_NAME, { optional: true }) ?? 'Application';\n readonly #postLoginRoute = inject(SHELL_POST_LOGIN_ROUTE, { optional: true }) ?? '/';\n\n readonly #commandService = inject(CommandService);\n readonly #terminalFocusService = inject(TerminalFocusService);\n\n readonly #activatedRoute = inject(ActivatedRoute);\n\n constructor(\n protected authenticationService: AuthenticationService,\n protected router: Router,\n ) {}\n\n /**\n * Returns the post-login destination. Honors a `returnUrl` query param if\n * present and safe (same-origin, leading `/`, not protocol-relative);\n * otherwise falls back to `SHELL_POST_LOGIN_ROUTE`.\n */\n #resolvePostLoginUrl(): string {\n const candidate = this.#activatedRoute.snapshot.queryParamMap.get('returnUrl');\n if (!candidate) return this.#postLoginRoute;\n if (!candidate.startsWith('/')) return this.#postLoginRoute;\n if (candidate.startsWith('//')) return this.#postLoginRoute;\n if (/^https?:\\/\\//i.test(candidate)) return this.#postLoginRoute;\n return candidate;\n }\n\n onAutofill(event: AutofillEvent, inputEl: HTMLInputElement): void {\n if (event.isAutofilled) {\n setTimeout(() => {\n const length = inputEl.value.length;\n inputEl.setSelectionRange(length, length);\n });\n }\n }\n\n clickEvent(event: MouseEvent): void {\n this.hide.set(!this.hide());\n event.stopPropagation();\n }\n\n onSubmit(event: Event): void {\n this.errors = [];\n event.preventDefault();\n this.submitted = true;\n const result = validateCredentials(this.model);\n if (result === true) {\n // A first attempt makes no claim about other sessions. If any exist the\n // server refuses, and the conflict panel below is where the decision is\n // made — with the sessions on screen.\n this.#doLogin(false);\n } else {\n for (let ndx = 0; ndx < result.length; ndx++) {\n this.errors.push({\n ndx,\n message: `${result[ndx].message ?? 'Unknown error'}: ${result[ndx].field ?? 'Unknown field'} ${result[ndx].type ?? 'Unknown type'} Expected: ${result[ndx].expected} Actual: ${result[ndx].actual}`,\n });\n }\n this.submitted = false;\n }\n }\n\n /** Whether individual sessions can be ticked: only when the server named them. */\n canEndIndividually(): boolean {\n return (this.authenticationService.conflictSessions() ?? []).some(s => !!s.sessionId);\n }\n\n isSelected(session: SessionSummary): boolean {\n return !!session.sessionId && this.selected().has(session.sessionId);\n }\n\n toggleSelected(session: SessionSummary, checked: boolean): void {\n if (!session.sessionId) return;\n const next = new Set(this.selected());\n if (checked) next.add(session.sessionId); else next.delete(session.sessionId);\n this.selected.set(next);\n }\n\n selectedCount(): number {\n return this.selected().size;\n }\n\n /**\n * What to call a session on screen.\n *\n * Falls back to the application name, which is what this screen showed before\n * devices were recorded, and then to something plainly non-committal. It never\n * invents a device: a session that predates the column genuinely has none, and\n * guessing would make two machines look like one.\n */\n deviceLabel(session: SessionSummary): string {\n return session.deviceDescription ?? session.appContext ?? 'Another session';\n }\n\n onTakeOver(): void {\n this.errors = [];\n this.selected.set(new Set());\n // ⚠ This used to hand the terminal `login --force`, with no username or\n // password on it — the terminal's login command reads its credentials from\n // the words typed after it, found none, and answered \"Invalid syntax\". The\n // credentials the user already typed are on this form; sign in with them,\n // the same way the other two buttons here do.\n this.#doLogin(true);\n }\n\n onSignInAsWell(): void {\n this.errors = [];\n this.selected.set(new Set());\n this.#doLogin(false, {additional: true});\n }\n\n onEndSelected(): void {\n this.errors = [];\n const ids = [...this.selected()];\n this.selected.set(new Set());\n this.#doLogin(false, {endSessionIds: ids});\n }\n\n /** The code step: the 6-digit code (or a recovery code), with the credentials already accepted. */\n onSubmitCode(event: Event): void {\n event.preventDefault();\n this.errors = [];\n const typed = this.codeText.trim();\n if (!typed) return;\n this.submitted = true;\n this.#doLogin(false, this.useRecovery() ? {recoveryCode: typed} : {code: typed});\n }\n\n onToggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.codeText = '';\n this.errors = [];\n }\n\n /** Back to the password form. */\n onCancelCode(): void {\n this.authenticationService.cancelCodeStep();\n this.codeText = '';\n this.useRecovery.set(false);\n this.errors = [];\n this.submitted = false;\n }\n\n /** New recovery codes were shown after sign-in; now go where sign-in was going. */\n onRecoveryCodesSaved(): void {\n this.authenticationService.acknowledgeRecoveryCodes();\n // Setup can finish on an attempt that then stops at \"already signed in\n // elsewhere\": the codes are shown first, and the session choice is still open.\n if (this.authenticationService.authenticated()) this.#navigateAfterLogin();\n }\n\n onCancelConflict(): void {\n this.authenticationService.clearConflict();\n this.selected.set(new Set());\n this.submitted = false;\n }\n\n #doLogin(force: boolean, choice: LoginChoice = {}): void {\n this.authenticationService\n .login(this.model, force, choice)\n .then(() => {\n this.#commandService.echoCommand(`login ${this.model.username}`);\n this.codeText = '';\n this.useRecovery.set(false);\n // Setup finished during this sign-in: the codes are on screen and must be\n // seen before the app takes over the page.\n if (this.authenticationService.recoveryCodesToShow()) {\n this.submitted = false;\n return;\n }\n this.#navigateAfterLogin();\n })\n .catch((err) => {\n if (err !== 'conflict' && err !== CODE_STEP) {\n this.errors.push({ ndx: 0, message: typeof err === 'string' ? err : 'Unable to login' });\n }\n this.codeText = '';\n this.submitted = false;\n });\n }\n\n #navigateAfterLogin(): void {\n this.router.navigateByUrl(this.#resolvePostLoginUrl()).then(() => {\n setTimeout(() => this.#terminalFocusService.requestFocus());\n }).catch(console.error);\n }\n}\n","@let usernameRegex = USERNAME_REGEX;\n@let passwordRegex = PASSWORD_REGEX;\n<div class=\"login-container\">\n <div class=\"login-header\">\n <h2 class=\"text-text-primary\">{{ appName }}</h2>\n <p class=\"text-secondary-info\">Sign in to continue</p>\n </div>\n @let step = authenticationService.codeStep();\n @if (authenticationService.recoveryCodesToShow(); as codes) {\n <shell-recovery-codes [codes]=\"codes\" [appName]=\"appName\" [username]=\"model.username\" (done)=\"onRecoveryCodesSaved()\" />\n } @else if (step !== 'none') {\n <form (submit)=\"onSubmitCode($event)\" class=\"login-form\" aria-label=\"Authenticator code\">\n @if (step === 'setup' && authenticationService.setupChallenge(); as challenge) {\n <p class=\"text-secondary-info login-code-lead\">\n Set up your authenticator: scan this with Google Authenticator (or Authy, 1Password),\n then enter the 6-digit code it shows.\n </p>\n <img class=\"login-qr\" [src]=\"challenge.qr\" alt=\"QR code for your authenticator app\" width=\"200\" height=\"200\" />\n <p class=\"text-secondary-info login-key\">Can't scan? Enter this key: <code>{{ challenge.key }}</code></p>\n } @else {\n <p class=\"text-secondary-info login-code-lead\">\n @if (useRecovery()) {\n Enter one of your recovery codes.\n } @else {\n Enter the 6-digit code from your authenticator app.\n }\n </p>\n }\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Code' }}</mat-label>\n <input\n matInput\n name=\"code\"\n [(ngModel)]=\"codeText\"\n [disabled]=\"submitted\"\n [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\"\n [attr.maxlength]=\"useRecovery() ? 16 : 7\"\n [placeholder]=\"useRecovery() ? 'xxxxx-xxxxx' : '123456'\"\n autofocus\n />\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n {{ step === 'setup' ? 'Finish setup and sign in' : 'Sign in' }}\n </button>\n <div class=\"login-code-links\">\n @if (step === 'code') {\n <button mat-button type=\"button\" (click)=\"onToggleRecovery()\">\n {{ useRecovery() ? 'Use the 6-digit code' : 'Use a recovery code' }}\n </button>\n }\n <button mat-button type=\"button\" (click)=\"onCancelCode()\">Back</button>\n </div>\n </form>\n } @else {\n <form #loginForm=\"ngForm\" (ngSubmit)=\"onSubmit($event)\" class=\"login-form\">\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Username</mat-label>\n <input\n #usernameInput\n matInput\n placeholder=\"Enter username\"\n [(ngModel)]=\"model.username\"\n name=\"username\"\n [disabled]=\"submitted\"\n required\n regexValidator\n [regex]=\"usernameRegex\"\n (cdkAutofill)=\"onAutofill($event, usernameInput)\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\" class=\"login-field\">\n <mat-label>Password</mat-label>\n <input\n #passwordInput\n matInput\n placeholder=\"Enter password\"\n [type]=\"hide() ? 'password' : 'text'\"\n [(ngModel)]=\"model.password\"\n name=\"password\"\n [disabled]=\"submitted\"\n regexValidator\n [regex]=\"passwordRegex\"\n (cdkAutofill)=\"onAutofill($event, passwordInput)\"\n />\n <button\n mat-icon-button\n matSuffix\n type=\"button\"\n (click)=\"clickEvent($event)\"\n [attr.aria-label]=\"'Hide password'\"\n [attr.aria-pressed]=\"hide()\"\n >\n <mat-icon>{{ hide() ? 'visibility_off' : 'visibility' }}</mat-icon>\n </button>\n </mat-form-field>\n <button mat-flat-button type=\"submit\" [disabled]=\"submitted\" class=\"login-button\">\n Login\n </button>\n </form>\n }\n @if (errors.length > 0) {\n <div class=\"login-errors\">\n @for (error of errors; track error.ndx) {\n <div class=\"login-error text-loss\">{{ error.message }}</div>\n }\n </div>\n }\n @if (authenticationService.conflictSessions(); as sessions) {\n <div class=\"login-conflict\">\n <p class=\"text-secondary-info\">\n You are already signed in {{ sessions.length === 1 ? 'somewhere else' : 'on other devices' }}:\n </p>\n @for (session of sessions; track session.sessionId ?? $index) {\n <div class=\"login-conflict-session\">\n @if (canEndIndividually()) {\n <mat-checkbox\n [checked]=\"isSelected(session)\"\n [disabled]=\"!session.sessionId\"\n (change)=\"toggleSelected(session, $event.checked)\"\n [attr.aria-label]=\"'End ' + deviceLabel(session)\"\n ></mat-checkbox>\n }\n <span class=\"text-secondary-info\">\n <strong>{{ deviceLabel(session) }}</strong>\n <!-- signedInAtEpoch is when the password was typed. startEpoch is\n when the row was written, which renewal resets — so it is shown\n only when there is nothing better, and labelled for what it is. -->\n @if (session.signedInAtEpoch) {\n — since {{ session.signedInAtEpoch | date:'short' }}\n } @else {\n — last active {{ session.startEpoch | date:'short' }}\n }\n </span>\n </div>\n }\n <div class=\"login-conflict-actions\">\n <button mat-stroked-button type=\"button\" (click)=\"onCancelConflict()\">Cancel</button>\n @if (selectedCount() > 0) {\n <button mat-stroked-button type=\"button\" (click)=\"onEndSelected()\">\n End {{ selectedCount() === 1 ? 'that one' : selectedCount() + ' of them' }} and sign in\n </button>\n }\n <button mat-stroked-button type=\"button\" (click)=\"onTakeOver()\">\n {{ sessions.length === 1 ? 'End it and sign in' : 'End them all and sign in' }}\n </button>\n @if (authenticationService.additionalSignInAllowed()) {\n <button mat-flat-button type=\"button\" (click)=\"onSignInAsWell()\">Sign in here as well</button>\n }\n </div>\n </div>\n }\n</div>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\nSettings → Sign-in code (authenticator-sign-in.prd.md D5, D7). Shared by every app: each routes to\n`AuthenticatorSettings` wherever its settings live.\n\n - Set up an authenticator (or replace one): the password again, plus a current code or a\n recovery code when replacing → QR + typed-in key → the first code → 10 recovery codes.\n - New recovery codes: a current code → 10 new ones; the old ones stop working.\n\n⛔ There is deliberately no \"remove\" and no \"turn off\" here (D13). Those are AWS-only; the screen\nsays how to get them done.\n*/\n\nimport { ChangeDetectionStrategy, Component, inject, OnInit, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { AuthenticationService, AuthenticatorError } from '../../services/authentication.service';\nimport { AuthenticatorStatus, SetupChallenge } from '../../services/authenticator.types';\nimport { SHELL_APP_NAME } from '../../tokens/shell-tokens';\nimport { RecoveryCodes } from '../recovery-codes/recovery-codes';\n\ntype Mode = 'view' | 'password' | 'scan' | 'reissue' | 'codes';\n\n@Component({\n selector: 'shell-authenticator-settings',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, MatButtonModule, MatFormFieldModule, MatInputModule, RecoveryCodes],\n templateUrl: './authenticator-settings.html',\n styleUrl: './authenticator-settings.css',\n})\nexport class AuthenticatorSettings implements OnInit {\n readonly #auth = inject(AuthenticationService);\n protected readonly appName = inject(SHELL_APP_NAME, {optional: true}) ?? 'BrokenStock';\n\n protected readonly status = signal<AuthenticatorStatus | undefined>(undefined);\n protected readonly mode = signal<Mode>('view');\n protected readonly busy = signal(false);\n protected readonly error = signal<string | undefined>(undefined);\n protected readonly challenge = signal<SetupChallenge | undefined>(undefined);\n protected readonly codes = signal<string[] | undefined>(undefined);\n protected readonly useRecovery = signal(false);\n\n password = '';\n code = '';\n\n ngOnInit(): void {\n void this.#load();\n }\n\n async #load(): Promise<void> {\n try {\n this.status.set(await this.#auth.authenticatorStatus());\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Could not load your sign-in code settings.');\n }\n }\n\n begin(mode: 'password' | 'reissue'): void {\n this.#reset();\n this.mode.set(mode);\n }\n\n cancel(): void {\n this.#reset();\n this.mode.set('view');\n }\n\n toggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.code = '';\n }\n\n /** Password (and current code when replacing) → QR. */\n async start(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n const current = this.status()?.enrolled\n ? (this.useRecovery() ? {recoveryCode: this.code.trim()} : {code: this.code.trim()})\n : {};\n this.challenge.set(await this.#auth.startAuthenticatorSetup(this.password, current));\n this.password = '';\n this.code = '';\n this.useRecovery.set(false);\n this.mode.set('scan');\n });\n }\n\n /** The first code from the newly scanned app → recovery codes. */\n async confirm(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n this.codes.set(await this.#auth.confirmAuthenticatorSetup(this.code.trim()));\n this.challenge.set(undefined);\n this.code = '';\n this.mode.set('codes');\n });\n }\n\n async reissue(event: Event): Promise<void> {\n event.preventDefault();\n await this.#run(async () => {\n this.codes.set(await this.#auth.reissueRecoveryCodes(this.code.trim()));\n this.code = '';\n this.mode.set('codes');\n });\n }\n\n async codesSaved(): Promise<void> {\n this.#reset();\n this.mode.set('view');\n await this.#load();\n }\n\n async #run(work: () => Promise<void>): Promise<void> {\n this.busy.set(true);\n this.error.set(undefined);\n try {\n await work();\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Something went wrong');\n this.code = '';\n } finally {\n this.busy.set(false);\n }\n }\n\n #reset(): void {\n this.password = '';\n this.code = '';\n this.error.set(undefined);\n this.challenge.set(undefined);\n this.codes.set(undefined);\n this.useRecovery.set(false);\n }\n}\n","<section class=\"authenticator-settings\">\n <h2 class=\"text-text-primary\">Sign-in code</h2>\n <p class=\"text-secondary-info\">\n Signing in asks for your password and a 6-digit code from an authenticator app on your phone\n (Google Authenticator, Authy, 1Password).\n </p>\n\n @if (status(); as s) {\n @switch (mode()) {\n @case ('view') {\n <dl class=\"authenticator-facts\">\n <dt>Authenticator</dt>\n <dd>{{ s.enrolled ? 'Set up' : 'Not set up' }}</dd>\n @if (s.enrolled) {\n <dt>Recovery codes left</dt>\n <dd [class.text-loss]=\"s.recoveryCodesLeft <= 2\">{{ s.recoveryCodesLeft }} of 10</dd>\n }\n <dt>Code required at sign-in</dt>\n <dd>{{ s.enrolled ? 'Yes' : (s.codeRequired ? 'Yes' : 'Not yet — set one up') }}</dd>\n </dl>\n <div class=\"authenticator-actions\">\n <button mat-flat-button type=\"button\" (click)=\"begin('password')\">\n {{ s.enrolled ? 'Replace authenticator' : 'Set up authenticator' }}\n </button>\n @if (s.enrolled) {\n <button mat-stroked-button type=\"button\" (click)=\"begin('reissue')\">New recovery codes</button>\n }\n </div>\n <p class=\"text-secondary-info authenticator-note\">\n Lost your phone? Sign in with a recovery code, then replace the authenticator here.\n No recovery codes left? Only the administrator can reset it, from AWS — there is no way\n to switch the code off from inside the app.\n </p>\n }\n\n @case ('password') {\n <form class=\"authenticator-form\" (submit)=\"start($event)\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Password</mat-label>\n <input matInput type=\"password\" name=\"password\" [(ngModel)]=\"password\" autocomplete=\"current-password\" [disabled]=\"busy()\" />\n </mat-form-field>\n @if (s.enrolled) {\n <mat-form-field appearance=\"outline\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Current 6-digit code' }}</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\" [disabled]=\"busy()\" />\n </mat-form-field>\n <button mat-button type=\"button\" class=\"authenticator-link\" (click)=\"toggleRecovery()\">\n {{ useRecovery() ? 'Use the 6-digit code' : 'Lost the phone? Use a recovery code' }}\n </button>\n }\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !password || (s.enrolled && !code.trim())\">Continue</button>\n </div>\n </form>\n }\n\n @case ('scan') {\n @if (challenge(); as c) {\n <form class=\"authenticator-form\" (submit)=\"confirm($event)\">\n <p class=\"text-secondary-info\">Scan this with your authenticator app, then enter the 6-digit code it shows.</p>\n <img class=\"authenticator-qr\" [src]=\"c.qr\" alt=\"QR code for your authenticator app\" width=\"200\" height=\"200\" />\n <p class=\"text-secondary-info authenticator-key\">Can't scan? Enter this key: <code>{{ c.key }}</code></p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Code</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" inputmode=\"numeric\" autocomplete=\"one-time-code\" [disabled]=\"busy()\" />\n </mat-form-field>\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !code.trim()\">Finish setup</button>\n </div>\n @if (s.enrolled) {\n <p class=\"text-secondary-info authenticator-note\">Your old authenticator keeps working until you finish.</p>\n }\n </form>\n }\n }\n\n @case ('reissue') {\n <form class=\"authenticator-form\" (submit)=\"reissue($event)\">\n <p class=\"text-secondary-info\">Ten new recovery codes. The ones you have now will stop working.</p>\n <mat-form-field appearance=\"outline\">\n <mat-label>Current 6-digit code</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"code\" inputmode=\"numeric\" autocomplete=\"one-time-code\" [disabled]=\"busy()\" />\n </mat-form-field>\n <div class=\"authenticator-actions\">\n <button mat-button type=\"button\" (click)=\"cancel()\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !code.trim()\">Make new codes</button>\n </div>\n </form>\n }\n\n @case ('codes') {\n @if (codes(); as list) {\n <shell-recovery-codes [codes]=\"list\" [appName]=\"appName\" (done)=\"codesSaved()\" />\n }\n }\n }\n }\n\n @if (error(); as message) {\n <p class=\"text-loss authenticator-error\" role=\"alert\">{{ message }}</p>\n }\n</section>\n","/*\nCreated by Franz Zemen 2026-10-17\nLicense Type: UNLICENSED\n\n\"Enter your code\" — the reusable dialog for the on-demand check (authenticator-sign-in.prd.md D15).\nLive Trading opens it to arm trading; anything else that needs the code again can too.\n\nCloses with the time the server recorded (epoch ms), or `undefined` if cancelled. Wrong codes keep\nthe dialog open with the reason in plain words; after five, \"Too many attempts.\" and nothing more.\n\n const at = await openCodeDialog(dialog, {title: 'Arm live trading', purpose: 'arm-live-trading'});\n*/\n\nimport { ChangeDetectionStrategy, Component, inject, signal } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { MAT_DIALOG_DATA, MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatFormFieldModule } from '@angular/material/form-field';\nimport { MatInputModule } from '@angular/material/input';\nimport { firstValueFrom } from 'rxjs';\nimport { AuthenticationService, AuthenticatorError } from '../../services/authentication.service';\n\nexport interface CodeDialogData {\n title: string;\n /** One line under the title saying what the code is for. */\n message?: string;\n /** Short lowercase label for the log, e.g. 'arm-live-trading' (D17). Changes nothing. */\n purpose?: string;\n confirmLabel?: string;\n}\n\n@Component({\n selector: 'shell-code-dialog',\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [FormsModule, MatDialogModule, MatButtonModule, MatFormFieldModule, MatInputModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <form (submit)=\"submit($event)\">\n <mat-dialog-content>\n <p>{{ data.message ?? (useRecovery() ? 'Enter one of your recovery codes.' : 'Enter the 6-digit code from your authenticator app.') }}</p>\n <mat-form-field appearance=\"outline\" class=\"code-field\">\n <mat-label>{{ useRecovery() ? 'Recovery code' : 'Code' }}</mat-label>\n <input matInput name=\"code\" [(ngModel)]=\"text\" [disabled]=\"busy()\"\n [attr.inputmode]=\"useRecovery() ? 'text' : 'numeric'\"\n [attr.autocomplete]=\"useRecovery() ? 'off' : 'one-time-code'\" cdkFocusInitial />\n </mat-form-field>\n @if (error(); as message) {\n <p class=\"code-error text-loss\" role=\"alert\">{{ message }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button type=\"button\" (click)=\"toggleRecovery()\">{{ useRecovery() ? 'Use the 6-digit code' : 'Use a recovery code' }}</button>\n <button mat-button type=\"button\" (click)=\"dialogRef.close(undefined)\">Cancel</button>\n <button mat-flat-button type=\"submit\" [disabled]=\"busy() || !text.trim()\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n </form>\n `,\n styles: [`\n :host { display: block; }\n .code-field { width: 100%; }\n .code-error { margin: 0; }\n `],\n})\nexport class CodeDialog {\n readonly data = inject<CodeDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<CodeDialog, number | undefined>);\n readonly #auth = inject(AuthenticationService);\n text = '';\n protected readonly useRecovery = signal(false);\n protected readonly busy = signal(false);\n protected readonly error = signal<string | undefined>(undefined);\n\n toggleRecovery(): void {\n this.useRecovery.set(!this.useRecovery());\n this.text = '';\n this.error.set(undefined);\n }\n\n async submit(event: Event): Promise<void> {\n event.preventDefault();\n const typed = this.text.trim();\n if (!typed) return;\n this.busy.set(true);\n this.error.set(undefined);\n try {\n const at = await this.#auth.verifyCode(this.useRecovery() ? {recoveryCode: typed} : {code: typed}, this.data.purpose);\n this.dialogRef.close(at);\n } catch (err) {\n this.error.set(err instanceof AuthenticatorError ? err.message : 'Something went wrong');\n this.text = '';\n } finally {\n this.busy.set(false);\n }\n }\n}\n\n/** Opens the dialog; resolves with the recorded time (epoch ms), or undefined when cancelled. */\nexport function openCodeDialog(dialog: MatDialog, data: CodeDialogData): Promise<number | undefined> {\n return firstValueFrom(dialog.open<CodeDialog, CodeDialogData, number | undefined>(CodeDialog, {data, width: '360px'}).afterClosed());\n}\n","import { Component, inject, ChangeDetectionStrategy } from '@angular/core';\nimport { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';\nimport { MatButtonModule } from '@angular/material/button';\n\nexport interface ConfirmDialogData {\n title: string;\n message: string;\n warningMessage?: string;\n confirmLabel?: string;\n cancelLabel?: string;\n}\n\n@Component({\n selector: 'shell-confirm-dialog',\n imports: [MatDialogModule, MatButtonModule],\n template: `\n <h2 mat-dialog-title>{{ data.title }}</h2>\n <mat-dialog-content>\n <p>{{ data.message }}</p>\n @if (data.warningMessage) {\n <p class=\"warning-message\">{{ data.warningMessage }}</p>\n }\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <button mat-button (click)=\"dialogRef.close(false)\">{{ data.cancelLabel ?? 'Cancel' }}</button>\n <button mat-flat-button color=\"warn\" (click)=\"dialogRef.close(true)\">{{ data.confirmLabel ?? 'Confirm' }}</button>\n </mat-dialog-actions>\n `,\n changeDetection: ChangeDetectionStrategy.Eager,\n styles: [`\n :host { display: block; }\n .warning-message { color: var(--color-warning); margin-top: 8px; }\n `],\n})\nexport class ConfirmDialog {\n readonly data = inject<ConfirmDialogData>(MAT_DIALOG_DATA);\n readonly dialogRef = inject(MatDialogRef<ConfirmDialog>);\n}\n","/*\n * Public API surface for @franzzemen/brokenstock-shell\n */\n\n// Types\nexport * from './lib/types/command.types';\nexport * from './lib/types/menu.types';\n\n// Tokens & config\nexport * from './lib/tokens/shell-tokens';\nexport * from './lib/provide-shell-config';\n\n// Guards\nexport * from './lib/guards/auth.guard';\nexport * from './lib/guards/guest.guard';\n\n// Interceptors\nexport * from './lib/interceptors/auth.interceptor';\n\n// Directives\nexport * from './lib/directives/regex-validator.directive';\n\n// FAQ help system\nexport * from './lib/faq/faq.types';\nexport * from './lib/faq/faq-content-loader.token';\nexport * from './lib/faq/faq-markdown-renderer.service';\nexport * from './lib/faq/http-faq-content-loader.service';\nexport * from './lib/faq/faq.service';\nexport * from './lib/faq/faq-history.service';\nexport * from './lib/faq/faq-modal/faq-modal';\nexport * from './lib/faq/faq-dev-mode.token';\nexport * from './lib/faq/faq-authoring-panel/faq-authoring-panel';\nexport * from './lib/faq/public-faq-index/public-faq-index';\nexport * from './lib/faq/public-faq-page/public-faq-page';\nexport * from './lib/faq/public-faq-toc/public-faq-toc';\nexport * from './lib/faq/faq-seo.tokens';\n\n// Services\nexport * from './lib/services/thinking.service';\nexport * from './lib/services/session-token-store';\nexport * from './lib/services/renewal-decision';\nexport * from './lib/services/theme.service';\nexport * from './lib/services/terminal-focus.service';\nexport * from './lib/services/terminal-visibility.service';\nexport * from './lib/services/phone-layout.service';\nexport * from './lib/services/keyboard-shortcut.service';\nexport * from './lib/services/authentication.service';\nexport * from './lib/services/authenticator.types';\nexport * from './lib/services/command-registry.service';\nexport * from './lib/services/command.service';\nexport * from './lib/services/pending-prompt';\n\n// Commands\nexport * from './lib/commands/command.utils';\n\n// Components\nexport * from './lib/components/shell/shell';\nexport * from './lib/components/side-menu/side-menu';\nexport * from './lib/components/status-bar/status-bar';\nexport * from './lib/components/main-content/main-content';\nexport * from './lib/components/command-terminal/command-terminal';\nexport * from './lib/components/login/login';\nexport * from './lib/components/recovery-codes/recovery-codes';\nexport * from './lib/components/authenticator-settings/authenticator-settings';\nexport * from './lib/components/code-dialog/code-dialog';\nexport * from './lib/components/confirm-dialog/confirm-dialog';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["serializeJsonLd","i1","i2","i1.AuthenticationService","i3","i8"],"mappings":"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"}
|