{"version":3,"sources":["../../src/gen/cli.ts","../../src/gen/generate.ts","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/_dnt.shims.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/consts.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/kems/dhkemPrimitives/ec.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/utils/noble.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/hash/hash.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/hash/hmac.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/hash/u64.js","../../../node_modules/.pnpm/@hpke+common@1.10.1/node_modules/@hpke/common/esm/src/hash/sha3.js","../../../node_modules/.pnpm/@hpke+chacha20poly1305@1.8.0/node_modules/@hpke/chacha20poly1305/esm/src/chacha/utils.js","../../../node_modules/.pnpm/@hpke+chacha20poly1305@1.8.0/node_modules/@hpke/chacha20poly1305/esm/src/chacha/_arx.js","../../../node_modules/.pnpm/@hpke+chacha20poly1305@1.8.0/node_modules/@hpke/chacha20poly1305/esm/src/chacha/_poly1305.js","../../../node_modules/.pnpm/@hpke+chacha20poly1305@1.8.0/node_modules/@hpke/chacha20poly1305/esm/src/chacha/chacha.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/exporterContext.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/mutex.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/recipientContext.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/senderContext.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/cipherSuiteNative.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x25519.js","../../../node_modules/.pnpm/@hpke+core@1.9.0/node_modules/@hpke/core/esm/src/kems/dhkemPrimitives/x448.js","../../../core/src/config.ts","../../../core/src/errors.ts","../../../core/src/platform.ts","../../../core/src/pow.ts","../../../core/src/sealed.ts","../../../core/src/sealed-json.ts","../../../core/src/sealed-keys.ts","../../../core/src/url.ts","../../../core/src/http.ts","../../../core/src/token.ts","../../../modules/auth/src/auth-client.ts","../../../modules/auth/src/device-client.ts","../../../modules/auth/src/oauth.ts","../../src/api-key.ts","../../src/gen/emitter.ts","../../src/gen/parser.ts"],"sourcesContent":["#!/usr/bin/env node\n// palbe-gen — SDK-owned typed-client codegen for @palbase/web.\n// Reads app-bound artifacts written by `palbase link`, or fetches the spec\n// from an origin passed with --url, and writes the typed palbe.gen.ts module.\nimport process from 'node:process';\nimport { main } from './generate.js';\n\nmain(process.argv.slice(2)).then(\n  (code) => process.exit(code),\n  (err) => {\n    process.stderr.write(`error: ${err instanceof Error ? err.message : String(err)}\\n`);\n    process.exit(1);\n  },\n);\n","// palbe-gen command logic: read the committed Palbase/ spec (or fetch it from\n// the origin passed with --url), run the parser+emitter, and write palbe.gen.ts.\n// Ports the CLI's Go semantics (internal/backend: pullTSTypes zero-op guard,\n// --soft policy, tswatch.go watch loop).\n\nimport { createHash } from 'node:crypto';\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';\nimport process from 'node:process';\nimport { parseArgs } from 'node:util';\nimport { parseOAuthConfig } from '@palbase/auth';\nimport { environmentRefFromPublishableApiKey } from '../api-key.js';\nimport { emitEnvironmentConfigModule, emitTypeScript, type GeneratedConfig } from './emitter.js';\nimport { type Op, parseOpenAPI, parseRooms, type RoomDecl, readSpecDeploy } from './parser.js';\n\nexport type Writer = (line: string) => void;\n\nconst USAGE = `Usage: palbe-gen [--dir palbase/environments] [--out palbe.gen.ts] [--url <specOrigin>] [--soft] [--watch]\n\nGenerate the typed palbe.gen.ts web client for the @palbase/web SDK.\n\nThe environment is chosen by the PALBASE_ENV environment variable; unset means\n\\`local\\`, the stack every checkout gets for free. Inputs are read from that\nenvironment's own directory, and \\`palbase/client.ts\\` is written as the one line\nyour application imports — so switching environments never edits your source.\n\n  --dir <dir>    Directory holding the per-environment artifacts written by\n                 \\`palbase link\\`: <dir>/<env>/{openapi.json, web-config.json}\n                 (default: palbase/environments). Role definitions travel\n                 inside openapi.json as \\`x-palbase-roles\\`.\n  --out <file>   Output file name, written inside the environment's directory;\n                 an absolute path is used as given (default: palbe.gen.ts)\n  --url <origin> Fetch the spec from <origin>/openapi.json instead of --dir\n                 (e.g. a deployed Environment's origin)\n  --soft         Never fail: print a warning and exit 0 on any error\n                 (for predev/prebuild hooks)\n  --watch        Poll the --url origin every second and regenerate whenever\n                 the spec changes. Without --url, polls the linked\n                 checkout's own Environment (the base_url committed to\n                 <dir>/<env>/web-config.json by \\`palbase link\\`)\n  -h, --help     Show this help`;\n\nfunction errMsg(e: unknown): string {\n  return e instanceof Error ? e.message : String(e);\n}\n\nexport class HttpStatusError extends Error {\n  readonly status: number;\n  constructor(status: number, url: string) {\n    super(`GET ${url}: HTTP ${status}`);\n    this.status = status;\n  }\n}\n\nexport async function fetchSpec(url: string): Promise<string> {\n  let res: Response;\n  try {\n    res = await fetch(url, { signal: AbortSignal.timeout(3000) });\n  } catch (e) {\n    throw new Error(`GET ${url}: ${errMsg(e)}`);\n  }\n  if (!res.ok) throw new HttpStatusError(res.status, url);\n  return res.text();\n}\n\n// readWebConfig reads the required canonical app-bound\n// {envDir}/web-config.json shape.\n//\n// The name carries the platform because one checkout can serve more than one\n// (an RN app has web AND android beside each other in the same environment\n// directory), and the environment directory is FLAT — the platform lives in the\n// file name, not in a subdirectory. That flatness is load-bearing elsewhere:\n// Xcode's exclusion pattern is written against a fixed number of path levels.\nexport function readWebConfig(dir: string): GeneratedConfig {\n  const path = join(dir, 'web-config.json');\n  let text: string;\n  try {\n    text = readFileSync(path, 'utf8');\n  } catch {\n    throw new Error(`${path} is required in dir mode — run \\`palbase link\\``);\n  }\n  let raw: unknown;\n  try {\n    raw = parseConfigJSON(text);\n  } catch (e) {\n    throw new Error(`${path} is not valid JSON: ${errMsg(e)}`);\n  }\n  const obj = (raw ?? {}) as Record<string, unknown>;\n  const str = (v: unknown) => (typeof v === 'string' ? v : '');\n  const required = (field: 'app_id' | 'base_url' | 'api_key'): string => {\n    const value = str(obj[field]);\n    if (value.trim() === '') {\n      throw new Error(`${path} is missing nonempty required field ${field}`);\n    }\n    return value.trim();\n  };\n  const cfg: GeneratedConfig = {\n    url: required('base_url'),\n    apiKey: required('api_key'),\n    appId: required('app_id'),\n  };\n  if (obj.sealed_root !== undefined) {\n    const root = str(obj.sealed_root).trim();\n    if (\n      !/^[A-Za-z0-9+/]{43}=$/.test(root) ||\n      Buffer.from(root, 'base64').toString('base64') !== root\n    ) {\n      throw new Error(`${path} sealed_root must be a base64 Ed25519 public key (32 bytes)`);\n    }\n    cfg.sealedRoot = root;\n  }\n  // The project identity comes from the key and from nowhere else. This file\n  // used to require an `environment_ref` field beside it and refuse when the two\n  // disagreed — and on 2026-08-16 they did: `palbase link` wrote one value while\n  // minting a key carrying another, so linking a web app to a project produced a\n  // config this generator would not read. A copy that must equal its original is\n  // not a second fact, it is a second chance to be wrong.\n  const projectRef = environmentRefFromPublishableApiKey(cfg.apiKey);\n  if (projectRef === '') {\n    throw new Error(`${path} api_key does not contain a valid publishable project identity`);\n  }\n  let configURL: URL;\n  try {\n    configURL = new URL(cfg.url);\n  } catch {\n    throw new Error(`${path} base_url must be a valid HTTPS URL`);\n  }\n  // A LOCAL STACK IS PLAIN HTTP ON LOOPBACK, and refusing it made two shipped\n  // parts contradict each other: `palbase link http://127.0.0.1:PORT` succeeds and\n  // docs/cli/local-stack says the local stack serves plain HTTP, while this threw\n  // \"base_url must be a valid HTTPS URL\" — so `palbase link` could not generate\n  // a client against the stack a person had just started (measured 2026-08-29).\n  // Loopback carries no transport risk: the bytes never leave the machine.\n  const isLoopback =\n    configURL.hostname === '127.0.0.1' ||\n    configURL.hostname === 'localhost' ||\n    configURL.hostname === '[::1]' ||\n    configURL.hostname === '::1';\n  if (configURL.protocol !== 'https:' && !(configURL.protocol === 'http:' && isLoopback)) {\n    throw new Error(\n      `${path} base_url must be an HTTPS URL (plain http is accepted only for a loopback host such as 127.0.0.1 or localhost)`,\n    );\n  }\n  // THE HOST IS NOT DERIVABLE FROM THE KEY, and a check that pretends otherwise\n  // refuses every correct config.\n  //\n  // This used to require the first label of a *.palbase.studio host to equal the\n  // ref inside the key, on the premise that a publishable key names its own\n  // address. That premise was v1's. On v2 a stack's identity is a COMPILE-TIME\n  // constant — every tenant's key reads `pb_project_…` (cloud\n  // tenant-stack/main.go: bootStackRef, and palsvc panics at boot if a key\n  // disagrees with it) — while the address is the tenant's own ref. So the two\n  // never match, for any project, and the rule turned `palbe-gen` into something\n  // that could not run against v2 at all.\n  //\n  // Nothing replaces it: there is no fact in the key to check the host against.\n  // What DOES catch a config pointed at the wrong project is the generator's\n  // next step — it fetches that host's contract with that key, and a mismatch\n  // answers 401.\n  if (Object.hasOwn(obj, 'auth') || Object.hasOwn(obj, 'socialAuth'))\n    throw new Error(`${path} must use the oauth configuration emitted by palbase link`);\n  if (Object.hasOwn(obj, 'oauth')) cfg.oauth = parseOAuthConfig(obj.oauth, projectRef);\n  return cfg;\n}\n\n// JSON.parse keeps the last duplicate field. Validate the original document\n// first so hand-edited config cannot hide a second client, target or revision.\nfunction parseConfigJSON(raw: string): unknown {\n  if (raw.length > 256 * 1024) throw new Error('App config exceeds 256 KiB');\n  const value: unknown = JSON.parse(raw);\n  let i = 0;\n  const space = () => {\n    while (/\\s/.test(raw[i] ?? '') && i < raw.length) i++;\n  };\n  const string = () => {\n    const start = i++;\n    while (i < raw.length) {\n      if (raw[i] === '\\\\') i += 2;\n      else if (raw[i++] === '\"') break;\n    }\n    return JSON.parse(raw.slice(start, i)) as string;\n  };\n  const visit = (depth: number) => {\n    if (depth > 32) throw new Error('App config nesting exceeds 32 levels');\n    space();\n    if (raw[i] === '\"') {\n      string();\n      return;\n    }\n    if (raw[i] === '{') {\n      i++;\n      const fields = new Set<string>();\n      space();\n      while (raw[i] !== '}') {\n        const name = string();\n        if (fields.has(name)) throw new Error(`Duplicate config field: ${name}`);\n        fields.add(name);\n        space();\n        i++; // colon; syntax already checked by JSON.parse\n        visit(depth + 1);\n        space();\n        if (raw[i] !== ',') break;\n        i++;\n        space();\n      }\n      i++;\n      return;\n    }\n    if (raw[i] === '[') {\n      i++;\n      space();\n      while (raw[i] !== ']') {\n        visit(depth + 1);\n        space();\n        if (raw[i] !== ',') break;\n        i++;\n        space();\n      }\n      i++;\n      return;\n    }\n    while (i < raw.length && !/[\\s,}\\]]/.test(raw[i] ?? '')) i++;\n  };\n  visit(0);\n  return value;\n}\n\nfunction emitAndWrite(\n  ops: Op[],\n  cfg: GeneratedConfig,\n  outFile: string,\n  rooms: RoomDecl[],\n  rolesArtifact: string,\n): void {\n  const dir = dirname(outFile);\n  if (dir !== '.' && dir !== '') {\n    mkdirSync(dir, { recursive: true });\n  }\n  writeFileSync(outFile, emitTypeScript(ops, cfg, rooms, rolesArtifact));\n}\n\n// readRolesFromSpec takes the role definitions out of the CONTRACT, where the\n// stack now puts them (`x-palbase-roles`). There is no sibling file to find any\n// more, so there is no path rule to get wrong.\n//\n// ABSENT IS NO LONGER AN ANSWER. It used to be: a missing sibling file returned\n// '' and the module generated without role types, silently. That was tolerable\n// only while the file was optional. Now a contract fetched by a CLI carrying\n// this change ALWAYS has the field, so one without it is STALE — and emitting\n// nothing for it would drop constants somebody's code already names, which is a\n// build that keeps working while the permission behind it is gone.\n//\n// The two faults get two sentences, because they have two different cures.\nexport function readRolesFromSpec(specJson: string): string {\n  const doc = JSON.parse(specJson) as Record<string, unknown>;\n  const field = doc['x-palbase-roles'];\n  if (field === undefined) {\n    throw new Error(\n      'this contract carries no `x-palbase-roles`, so it predates roles travelling inside ' +\n        'the document. Two steps, in this order: upgrade `@palbase/backend` and push the ' +\n        'project, then run `palbase link` to refresh the contract.',\n    );\n  }\n  // PRESENT BUT BODILESS is the other fault: the producer answered about roles\n  // without listing any. `{\"roles\": []}` is NOT this — that is a stack with no\n  // roles, which is a known answer and generates empty constants.\n  const body = field as { roles?: unknown };\n  if (body === null || typeof body !== 'object' || !Array.isArray(body.roles)) {\n    throw new Error(\n      \"this contract's `x-palbase-roles` carries no roles list, so what the stack defines \" +\n        'cannot be read from it. Refresh the contract; if it comes back the same, the stack ' +\n        'is serving a malformed document.',\n    );\n  }\n  return JSON.stringify(field);\n}\n\nfunction existingNonEmpty(outFile: string): boolean {\n  try {\n    return readFileSync(outFile).length > 0;\n  } catch {\n    return false;\n  }\n}\n\n// writeGenerated applies the zero-op overwrite guard, then emits. A live spec\n// with 0 operations almost always means the backend's controller metadata\n// extraction broke (the \"zero endpoints collected\" failure class), not that\n// the app has no endpoints. Never clobber a previously good palbe.gen.ts with\n// an empty client; warn and exit 0 so a predev hook doesn't fail the build.\n// With nothing to protect, write the (empty) module anyway — a fresh project\n// still gets a compilable file — but warn loudly.\nexport function writeGenerated(\n  ops: Op[],\n  cfg: GeneratedConfig,\n  outFile: string,\n  out: Writer,\n  specDeploy = '',\n  rooms: RoomDecl[] = [],\n  rolesArtifact = '',\n): void {\n  // THE ENVIRONMENT IS WRITTEN BEFORE THE ZERO-OP GUARD, because a config is an\n  // IDENTITY, not an inventory: an environment with no endpoints is still that\n  // environment. Below this point a zero-op run RETURNS to preserve an existing\n  // palbe.gen.ts, and a config written after it would never happen.\n  writeEnvironmentConfig(outFile, cfg);\n  if (ops.length === 0) {\n    if (existingNonEmpty(outFile)) {\n      out(\n        `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n      );\n      return;\n    }\n    out(\n      `warning: live spec has 0 operations — ${outFile} registers no calls (fix your controllers and rerun)`,\n    );\n  }\n  emitAndWrite(ops, cfg, outFile, rooms, rolesArtifact);\n  out(`✓ wrote ${outFile} (${ops.length} operations${provenance(specDeploy)})`);\n}\n\n// provenance renders the deploy clause the success lines carry. Empty for a spec\n// with no identity — an artifact built before the stamp existed. Saying nothing\n// there is deliberate: a fabricated or guessed identity would read as verified.\nfunction provenance(specDeploy: string): string {\n  return specDeploy === '' ? '' : `, deploy ${specDeploy}`;\n}\n\n// resolveEnvironment picks the environment this run generates for.\n//\n// ONE KEY, AND ITS DEFAULT IS `local`. The customer writes `PALBASE_ENV` in\n// whatever they already use (an npm script, a `.env`, their CI) and nothing else\n// is asked of them — the CLI writes nothing into their build system.\n//\n// A blank value counts as UNSET, and that is not a nicety: a shell that exports\n// `PALBASE_ENV=` sends an empty string, and reading that as a real name would\n// look for an environment directory called \"\" and fail with a path nobody typed.\nexport function resolveEnvironment(value: string | undefined): string {\n  const trimmed = (value ?? '').trim();\n  return trimmed === '' ? 'local' : trimmed;\n}\n\n// environmentDir is where ONE environment's committed artifacts live.\nexport function environmentDir(dir: string, environment: string): string {\n  return join(dir, environment);\n}\n\n// barrelRootFor is the checkout root implied by --dir.\n//\n// `--dir` names the environments directory (`<root>/palbase/environments`), so\n// the root is two levels up. Deriving it here rather than reading the process's\n// working directory is what keeps the barrel beside the environments it points\n// at — one visible `palbase/` per checkout, which is the whole rule.\nexport function barrelRootFor(dir: string): string {\n  return resolve(dir, '..', '..');\n}\n\n// writeClientBarrel writes the ONE line the application imports.\n//\n// Every environment's generated client is committed, side by side. If the app\n// imported one of them directly, its import path would carry the environment\n// name — and switching environments would mean editing the app's own source.\n// The barrel makes the import stable: the only thing that changes is this file's\n// single re-export line.\n//\n// Measured (research.md): a bundler follows the re-export and pulls in ONLY the\n// named environment's code — the unselected one leaves no trace in the bundle.\nexport function writeClientBarrel(root: string, outFile: string): void {\n  const from = join(root, 'palbase');\n  // POSIX separators: `relative` yields `\\` on win32 and a backslash in an\n  // ESM specifier is not a path separator, it is an escape.\n  const rel = relative(from, resolve(outFile)).split(sep).join('/').replace(/\\.ts$/, '');\n  const target = rel.startsWith('.') ? rel : `./${rel}`;\n  const body =\n    `// GENERATED by \\`palbase link\\` / \\`palbe-gen\\` — do not edit.\\n` +\n    `// The environment is chosen by PALBASE_ENV (default: local).\\n` +\n    `export * from '${target}';\\n`;\n  mkdirSync(join(root, 'palbase'), { recursive: true });\n  writeFileSync(join(root, 'palbase', 'client.ts'), body);\n}\n\n// writeEnvironmentConfig writes the leaf config module NEXT TO the generated\n// client — derived from outFile, never from the environment directory.\n//\n// WHY NOT <envDir>: `--out` is honoured as given when it is absolute (main()),\n// so the client can land outside the environment directory entirely. A config\n// written to <envDir> would then not be the client's sibling, and the\n// `./palbe.config` specifier palbe.gen.ts re-exports would resolve to nothing.\n//\n// IT PRINTS NOTHING. The watch tests assert the emitted line list with\n// toEqual([...]), so an extra out() call here would break them — and there is\n// nothing to announce: this file is a detail of the client beside it.\nexport function writeEnvironmentConfig(outFile: string, cfg: GeneratedConfig): string {\n  const target = join(dirname(resolve(outFile)), 'palbe.config.ts');\n  mkdirSync(dirname(target), { recursive: true });\n  writeFileSync(target, emitEnvironmentConfigModule(cfg));\n  return target;\n}\n\n// writeConfigBarrel is writeClientBarrel's twin for the config module.\n//\n// It derives its target from outFile rather than from writeEnvironmentConfig's\n// return value, so the caller need not order the two: main() writes both\n// barrels before it even knows whether this run is one-shot or a watch.\nexport function writeConfigBarrel(root: string, outFile: string): void {\n  const configFile = join(dirname(resolve(outFile)), 'palbe.config.ts');\n  const from = join(root, 'palbase');\n  const rel = relative(from, configFile).split(sep).join('/').replace(/\\.ts$/, '');\n  const target = rel.startsWith('.') ? rel : `./${rel}`;\n  const body =\n    `// GENERATED by \\`palbase link\\` / \\`palbe-gen\\` — do not edit.\\n` +\n    `// The environment is chosen by PALBASE_ENV (default: local).\\n` +\n    `export * from '${target}';\\n`;\n  mkdirSync(from, { recursive: true });\n  writeFileSync(join(from, 'config.ts'), body);\n}\n\n// generateOnce is the single-shot generation path.\n//   - default: read {envDir}/openapi.json + required {envDir}/web-config.json\n//   - --url:   fetch <origin>/openapi.json while retaining the canonical linked\n//              Environment identity; only the runtime URL points at the origin.\nexport async function generateOnce(\n  dir: string,\n  outFile: string,\n  url: string | undefined,\n  out: Writer,\n): Promise<void> {\n  let specText: string;\n  let cfg: GeneratedConfig;\n  if (url !== undefined) {\n    const origin = url.replace(/\\/+$/, '');\n    specText = await fetchSpec(`${origin}/openapi.json`);\n    cfg = { ...readWebConfig(dir), url: origin };\n  } else {\n    cfg = readWebConfig(dir);\n    const specPath = join(dir, 'openapi.json');\n    try {\n      specText = readFileSync(specPath, 'utf8');\n    } catch {\n      throw new Error(\n        `no OpenAPI spec at ${specPath} — run \\`palbase spec\\` first, or pass --url to fetch it from an origin`,\n      );\n    }\n  }\n  // THE ROLES FOLLOW THE CONTRACT, in both modes. They used to come from the\n  // linked directory while --url redirected only where the contract was read\n  // from — so a remote contract could be generated against a LOCAL checkout's\n  // role list, and the two could disagree. Now there is one source and no way\n  // for them to drift apart.\n  writeGenerated(\n    parseOpenAPI(specText),\n    cfg,\n    outFile,\n    out,\n    readSpecDeploy(specText),\n    parseRooms(specText),\n    readRolesFromSpec(specText),\n  );\n}\n\n// --- Watch mode (tswatch.go port) --------------------------------------------\n\nexport type FetchFn = (url: string) => Promise<string>;\n\n// watchLoop polls specURL on each tick:\n//   - Fetch fails: print a down message ONCE per transition — a waiting line\n//     when nothing is listening, or the HTTP-error variant when the origin\n//     answered with an error status.\n//   - Fetch succeeds: SHA-256 the body. Same hash as the last EMIT → skip.\n//     Same hash as the last WARNED-bad body → stay silent. Otherwise parse +\n//     emit + write; a bad body (unparseable, or 0 ops with an existing file to\n//     protect) warns once and records its hash. A successful emit resets the\n//     bad-hash state.\n// Hash state starts EMPTY intentionally: the first successful fetch always\n// regenerates. Returns (printing \"watch stopped\") when the tick source ends.\nexport async function watchLoop(\n  specURL: string,\n  cfg: GeneratedConfig,\n  outFile: string,\n  fetchFn: FetchFn,\n  ticks: AsyncIterable<void>,\n  out: Writer,\n): Promise<void> {\n  let lastEmittedHash = ''; // '' = nothing emitted yet\n  let lastBadHash = ''; // '' = no standing bad-body warning\n  let lastDownMsg = ''; // last printed down message; '' = the origin was up\n\n  for await (const _ of ticks) {\n    let specText: string;\n    try {\n      specText = await fetchFn(specURL);\n    } catch (err) {\n      let m = `waiting for ${specURL}…`;\n      if (err instanceof HttpStatusError) {\n        m = `${specURL} responded with an error (HTTP ${err.status})`;\n      }\n      if (m !== lastDownMsg) {\n        out(m);\n        lastDownMsg = m;\n      }\n      continue;\n    }\n\n    // The origin is (back) up.\n    lastDownMsg = '';\n\n    const h = createHash('sha256').update(specText).digest('hex');\n    if (lastEmittedHash !== '' && h === lastEmittedHash) continue; // no change\n    if (lastBadHash !== '' && h === lastBadHash) continue; // already warned\n\n    let ops: Op[];\n    let rooms: RoomDecl[];\n    try {\n      ops = parseOpenAPI(specText);\n      rooms = parseRooms(specText);\n    } catch (err) {\n      out(`warning: failed to parse spec: ${errMsg(err)}`);\n      lastBadHash = h;\n      continue;\n    }\n    if (ops.length === 0 && existingNonEmpty(outFile)) {\n      out(\n        `warning: live spec has 0 operations — keeping existing ${outFile} (fix your controllers and rerun)`,\n      );\n      lastBadHash = h;\n      continue;\n    }\n\n    try {\n      // FROM THIS TICK'S OWN CONTRACT. The loop used to take a `() => string`\n      // provider that defaulted to '' — a caller that omitted it generated\n      // role-less modules in silence, and the loop re-read a file on every emit\n      // to stay current. Both problems go away when the roles are in the\n      // document the tick already fetched.\n      emitAndWrite(ops, cfg, outFile, rooms, readRolesFromSpec(specText));\n    } catch (err) {\n      // Environmental write failure (disk) — not spec-dependent, so do not\n      // record a bad hash; the next tick retries.\n      out(`warning: codegen error: ${errMsg(err)}`);\n      continue;\n    }\n\n    lastEmittedHash = h;\n    lastBadHash = ''; // a good emit resets the warn-dedup state\n    out(`regenerated ${outFile} (${ops.length} operations${provenance(readSpecDeploy(specText))})`);\n  }\n  out('watch stopped');\n}\n\nfunction delay(ms: number, signal: AbortSignal): Promise<void> {\n  return new Promise((resolve) => {\n    if (signal.aborted) {\n      resolve();\n      return;\n    }\n    const onAbort = () => {\n      clearTimeout(t);\n      resolve();\n    };\n    const t = setTimeout(() => {\n      signal.removeEventListener('abort', onAbort);\n      resolve();\n    }, ms);\n    signal.addEventListener('abort', onAbort, { once: true });\n  });\n}\n\nasync function* intervalTicks(ms: number, signal: AbortSignal): AsyncGenerator<void> {\n  while (!signal.aborted) {\n    await delay(ms, signal);\n    if (signal.aborted) return;\n    yield;\n  }\n}\n\nasync function runWatch(\n  dir: string,\n  outFile: string,\n  url: string | undefined,\n  out: Writer,\n): Promise<void> {\n  // readWebConfig throws a clear, actionable error when {dir} was never\n  // linked — that's the same \"run `palbase link`\" failure every other\n  // dir-mode path already has, so an unlinked --watch fails loudly here, not\n  // by silently retrying an address nothing answers.\n  const linked = readWebConfig(dir);\n\n  // No --url: watch the linked checkout's OWN Environment. `palbase serve`\n  // (retired) used to expose the spec on http://localhost:4003; nothing\n  // replaces that local server today, so defaulting to it just polled a dead\n  // address forever with a misleading \"waiting for...\" message. base_url —\n  // already read and validated above — is a real, currently-serving origin.\n  const origin = (url ?? linked.url).replace(/\\/+$/, '');\n  const specURL = `${origin}/openapi.json`;\n\n  // The spec comes from the resolved origin, while identity remains bound to\n  // the linked Environment. Initial fetch failure is soft because the loop\n  // exists to wait for that origin to answer.\n  const cfg: GeneratedConfig = { ...linked, url: origin };\n  // WRITTEN BEFORE THE FIRST FETCH, and this is not a nicety: watchLoop does\n  // NOT go through writeGenerated (it calls emitAndWrite directly) and skips\n  // emit entirely on a zero-op tick, so a config wired only into writeGenerated\n  // would never be written in a watch session at all. Placing it before the try\n  // also means an origin that never answers still leaves a correct config.\n  // `cfg` is const and never reassigned for the life of the session, so there\n  // is nothing to refresh per tick.\n  writeEnvironmentConfig(outFile, cfg);\n  try {\n    const initial = await fetchSpec(specURL);\n    writeGenerated(\n      parseOpenAPI(initial),\n      cfg,\n      outFile,\n      out,\n      readSpecDeploy(initial),\n      parseRooms(initial),\n      readRolesFromSpec(initial),\n    );\n  } catch (err) {\n    out(`warning: codegen skipped (${errMsg(err)})`);\n  }\n\n  // A real Ctrl-C aborts the tick source → clean \"watch stopped\" exit 0\n  // instead of a hard kill that could truncate palbe.gen.ts mid-write.\n  const ctrl = new AbortController();\n  const stop = () => ctrl.abort();\n  process.once('SIGINT', stop);\n  process.once('SIGTERM', stop);\n  try {\n    await watchLoop(specURL, cfg, outFile, fetchSpec, intervalTicks(1000, ctrl.signal), out);\n  } finally {\n    process.removeListener('SIGINT', stop);\n    process.removeListener('SIGTERM', stop);\n  }\n}\n\n// --- Entry -------------------------------------------------------------------\n\nconst stdoutWriter: Writer = (line) => {\n  process.stdout.write(`${line}\\n`);\n};\nconst stderrWriter: Writer = (line) => {\n  process.stderr.write(`${line}\\n`);\n};\n\nfunction parseCliArgs(argv: string[]) {\n  return parseArgs({\n    args: argv,\n    options: {\n      dir: { type: 'string', default: 'palbase/environments' },\n      out: { type: 'string', default: 'palbe.gen.ts' },\n      url: { type: 'string' },\n      soft: { type: 'boolean', default: false },\n      watch: { type: 'boolean', default: false },\n      help: { type: 'boolean', short: 'h', default: false },\n    },\n  }).values;\n}\n\nexport async function main(\n  argv: string[],\n  out: Writer = stdoutWriter,\n  errOut: Writer = stderrWriter,\n): Promise<number> {\n  let values: ReturnType<typeof parseCliArgs>;\n  try {\n    values = parseCliArgs(argv);\n  } catch (e) {\n    errOut(`error: ${errMsg(e)}`);\n    errOut(USAGE);\n    return 1;\n  }\n  if (values.help) {\n    out(USAGE);\n    return 0;\n  }\n  try {\n    const environment = resolveEnvironment(process.env.PALBASE_ENV);\n    const envDir = environmentDir(values.dir, environment);\n    // `--out` is a NAME resolved inside the environment's directory; an explicit\n    // path is honoured as given, because a caller that spells one out means it.\n    const outFile = isAbsolute(values.out) ? values.out : join(envDir, values.out);\n    // THE BARREL GOES FIRST, and in watch mode that is the whole point.\n    //\n    // `runWatch` does not return until Ctrl-C. Writing the barrel after it meant\n    // a fresh checkout running `palbe-gen --watch` produced the client but never\n    // the one line the application imports — and worse, switching PALBASE_ENV\n    // and re-watching left the barrel naming the OLD environment for the whole\n    // session, so the app talked to the wrong stack. That is precisely the\n    // defect this layout exists to remove.\n    //\n    // It is derived from --dir, NOT from the process's working directory: a\n    // `palbe-gen --dir apps/web/palbase/environments` run from the repository\n    // root used to write a SECOND visible `palbase/` at the root while the app's\n    // own barrel was never written at all.\n    //\n    // AMA ÖNCE DOĞRULA. \"Barrel önce gider\" watch DÖNGÜSÜNDEN önce demek,\n    // KONFİGÜRASYON DOĞRULAMASINDAN önce değil — ve ikisini karıştırmak bu\n    // dosyanın kendi testlerini düşürdü: `dir mode` bloğunun on iki vakası da\n    // konfigürasyon hatasını bekliyor, yani sıra zaten testlerde yazılı.\n    //\n    // ÖLÇÜLDÜ: `--dir` yazılabilir bir kökün iki seviye altında değilse\n    // `barrelRootFor` erişilemez bir dizine çıkıyor ve mkdir konfigürasyon\n    // hiç okunmadan patlıyor — `--dir /tmp/x` verildiğinde kök `/private` olup\n    // `error: EACCES: permission denied, mkdir '/private/palbase'` geliyordu.\n    // Kusur `TMPDIR` sayesinde GİZLİYDİ (iki seviye yukarısı yazılabilir bir\n    // kullanıcı dizini oluyordu); turbo 2 STRICT env kipinde onu sildiği için\n    // `npm test` 915/915 yeşilken `turbo run test` aynı dosyada 12 vaka\n    // düşürüyordu — ve CI yalnız turbo yolunu koşuyor.\n    //\n    // Konfigürasyon burada BİR KEZ FAZLADAN okunuyor (asıl okuma\n    // generateOnce/runWatch içinde). Bir JSON okumasının bedeli, yazmadan önce\n    // doğrulamanın karşılığında ucuz.\n    // THE LEAF GOES WITH THE BARRELS, not later with the client.\n    //\n    // The barrels are written here, unconditionally, before anything can fail.\n    // The leaf used to be written only inside writeGenerated/runWatch, so a run\n    // that ended early — `--soft` with no spec in the selected environment, the\n    // exact shape `predev` produces on a fresh environment — left\n    // `palbase/config.ts` re-exporting a file that was never created. Measured:\n    // `PALBASE_ENV=staging … --soft` exits 0 and the app then fails to build on\n    // an import the generator itself emitted. `client.ts` can dangle the same\n    // way, but checkouts COMMIT `<env>/palbe.gen.ts` and do not commit\n    // `palbe.config.ts`, so this one dangles alone — on projects that built\n    // yesterday.\n    //\n    // `readWebConfig` is the same call this path already made to validate\n    // before writing; `--url` runs let generateOnce/runWatch overwrite the leaf\n    // with the resolved origin.\n    const linked = readWebConfig(envDir);\n    writeEnvironmentConfig(outFile, linked);\n    writeClientBarrel(barrelRootFor(values.dir), outFile);\n    writeConfigBarrel(barrelRootFor(values.dir), outFile);\n    out(\n      `environment ${environment} → ${join(barrelRootFor(values.dir), 'palbase', 'client.ts')}` +\n        ` + ${join(barrelRootFor(values.dir), 'palbase', 'config.ts')}`,\n    );\n    if (values.watch) {\n      await runWatch(envDir, outFile, values.url, out);\n    } else {\n      await generateOnce(envDir, outFile, values.url, out);\n    }\n    return 0;\n  } catch (err) {\n    // --soft turns ANY failure into a warning + exit 0, so a predev/prebuild\n    // hook never blocks a machine without the spec or a running serve.\n    if (values.soft) {\n      out(`warning: codegen skipped (${errMsg(err)})`);\n      return 0;\n    }\n    errOut(`error: ${errMsg(err)}`);\n    return 1;\n  }\n}\n","const dntGlobals = {};\nexport const dntGlobalThis = createMergeProxy(globalThis, dntGlobals);\nfunction createMergeProxy(baseObj, extObj) {\n    return new Proxy(baseObj, {\n        get(_target, prop, _receiver) {\n            if (prop in extObj) {\n                return extObj[prop];\n            }\n            else {\n                return baseObj[prop];\n            }\n        },\n        set(_target, prop, value) {\n            if (prop in extObj) {\n                delete extObj[prop];\n            }\n            baseObj[prop] = value;\n            return true;\n        },\n        deleteProperty(_target, prop) {\n            let success = false;\n            if (prop in extObj) {\n                delete extObj[prop];\n                success = true;\n            }\n            if (prop in baseObj) {\n                delete baseObj[prop];\n                success = true;\n            }\n            return success;\n        },\n        ownKeys(_target) {\n            const baseKeys = Reflect.ownKeys(baseObj);\n            const extKeys = Reflect.ownKeys(extObj);\n            const extKeysSet = new Set(extKeys);\n            return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];\n        },\n        defineProperty(_target, prop, desc) {\n            if (prop in extObj) {\n                delete extObj[prop];\n            }\n            Reflect.defineProperty(baseObj, prop, desc);\n            return true;\n        },\n        getOwnPropertyDescriptor(_target, prop) {\n            if (prop in extObj) {\n                return Reflect.getOwnPropertyDescriptor(extObj, prop);\n            }\n            else {\n                return Reflect.getOwnPropertyDescriptor(baseObj, prop);\n            }\n        },\n        has(_target, prop) {\n            return prop in extObj || prop in baseObj;\n        },\n    });\n}\n","// The input length limit (psk, psk_id, info, exporter_context, ikm).\nexport const INPUT_LENGTH_LIMIT = 8192;\nexport const INFO_LENGTH_LIMIT = 268435456;\n// The minimum length of a PSK.\nexport const MINIMUM_PSK_LENGTH = 32;\n// b\"\"\nexport const EMPTY = /* @__PURE__ */ new Uint8Array(0);\n// Common BigInt constants\nexport const N_0 = 0n;\nexport const N_1 = 1n;\nexport const N_2 = 2n;\nexport const N_7 = 7n;\nexport const N_32 = 32n;\nexport const N_256 = 256n;\nexport const N_0x71 = 0x71n;\nexport const BYTE_TO_BIGINT_256 = /* @__PURE__ */ (() => {\n    const out = new Array(256);\n    let i = 0;\n    let value = 0n;\n    while (i < 256) {\n        out[i] = value;\n        i++;\n        value += 1n;\n    }\n    return out;\n})();\n","import { NativeAlgorithm } from \"../../algorithm.js\";\nimport { BYTE_TO_BIGINT_256, EMPTY } from \"../../consts.js\";\nimport { toArrayBuffer } from \"../../kdfs/hkdf.js\";\nimport { DeriveKeyPairError, DeserializeError, NotSupportedError, SerializeError, } from \"../../errors.js\";\nimport { KemId } from \"../../identifiers.js\";\nimport { KEM_USAGES, LABEL_DKP_PRK } from \"../../interfaces/dhkemPrimitives.js\";\nimport { Bignum } from \"../../utils/bignum.js\";\nimport { base64UrlToBytes, i2Osp } from \"../../utils/misc.js\";\n// b\"candidate\"\n// deno-fmt-ignore\nconst LABEL_CANDIDATE = /* @__PURE__ */ new Uint8Array([\n    99, 97, 110, 100, 105, 100, 97, 116, 101,\n]);\n// the order of the curve being used.\n// deno-fmt-ignore\nconst ORDER_P_256 = /* @__PURE__ */ new Uint8Array([\n    0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84,\n    0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,\n]);\n// deno-fmt-ignore\nconst ORDER_P_384 = /* @__PURE__ */ new Uint8Array([\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xc7, 0x63, 0x4d, 0x81, 0xf4, 0x37, 0x2d, 0xdf,\n    0x58, 0x1a, 0x0d, 0xb2, 0x48, 0xb0, 0xa7, 0x7a,\n    0xec, 0xec, 0x19, 0x6a, 0xcc, 0xc5, 0x29, 0x73,\n]);\n// deno-fmt-ignore\nconst ORDER_P_521 = /* @__PURE__ */ new Uint8Array([\n    0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,\n    0xff, 0xfa, 0x51, 0x86, 0x87, 0x83, 0xbf, 0x2f,\n    0x96, 0x6b, 0x7f, 0xcc, 0x01, 0x48, 0xf7, 0x09,\n    0xa5, 0xd0, 0x3b, 0xb5, 0xc9, 0xb8, 0x89, 0x9c,\n    0x47, 0xae, 0xbb, 0x6f, 0xb7, 0x1e, 0x91, 0x38,\n    0x64, 0x09,\n]);\n// deno-fmt-ignore\nconst PKCS8_ALG_ID_P_256 = /* @__PURE__ */ new Uint8Array([\n    48, 65, 2, 1, 0, 48, 19, 6, 7, 42,\n    134, 72, 206, 61, 2, 1, 6, 8, 42, 134,\n    72, 206, 61, 3, 1, 7, 4, 39, 48, 37,\n    2, 1, 1, 4, 32,\n]);\n// deno-fmt-ignore\nconst PKCS8_ALG_ID_P_384 = /* @__PURE__ */ new Uint8Array([\n    48, 78, 2, 1, 0, 48, 16, 6, 7, 42,\n    134, 72, 206, 61, 2, 1, 6, 5, 43, 129,\n    4, 0, 34, 4, 55, 48, 53, 2, 1, 1,\n    4, 48,\n]);\n// deno-fmt-ignore\nconst PKCS8_ALG_ID_P_521 = /* @__PURE__ */ new Uint8Array([\n    48, 96, 2, 1, 0, 48, 16, 6, 7, 42,\n    134, 72, 206, 61, 2, 1, 6, 5, 43, 129,\n    4, 0, 35, 4, 73, 48, 71, 2, 1, 1,\n    4, 66,\n]);\nconst EC_P_256_PARAMS = {\n    p: 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn,\n    b: 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn,\n    gx: 0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296n,\n    gy: 0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5n,\n    coordinateSize: 32,\n};\nconst EC_P_384_PARAMS = {\n    p: 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffffn,\n    b: 0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aefn,\n    gx: 0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7n,\n    gy: 0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5fn,\n    coordinateSize: 48,\n};\nconst EC_P_521_PARAMS = {\n    p: (1n << 521n) - 1n,\n    b: 0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00n,\n    gx: 0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66n,\n    gy: 0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650n,\n    coordinateSize: 66,\n};\nfunction mod(a, p) {\n    const r = a % p;\n    return r >= 0n ? r : r + p;\n}\nfunction modPow(base, exponent, p) {\n    let result = 1n;\n    let b = mod(base, p);\n    let e = exponent;\n    while (e > 0n) {\n        if ((e & 1n) === 1n) {\n            result = mod(result * b, p);\n        }\n        b = mod(b * b, p);\n        e >>= 1n;\n    }\n    return result;\n}\nfunction modSqrt(rhs, p) {\n    // P-256/P-384/P-521 primes satisfy p % 4 == 3.\n    const y = modPow(rhs, (p + 1n) >> 2n, p);\n    if (mod(y * y, p) !== mod(rhs, p)) {\n        throw new Error(\"Invalid ECDH point\");\n    }\n    return y;\n}\nfunction bytesToBigInt(bytes) {\n    let v = 0n;\n    for (const b of bytes) {\n        v = (v << 8n) | BYTE_TO_BIGINT_256[b];\n    }\n    return v;\n}\nfunction bigIntToBytes(v, len) {\n    const out = new Uint8Array(len);\n    let n = v;\n    for (let i = len - 1; i >= 0; i--) {\n        out[i] = Number(n & 0xffn);\n        n >>= 8n;\n    }\n    if (n !== 0n) {\n        throw new Error(\"Invalid coordinate length\");\n    }\n    return out;\n}\nfunction buildRawUncompressedPublicKey(x, y, coordinateSize) {\n    const out = new Uint8Array(1 + coordinateSize * 2);\n    out[0] = 0x04;\n    out.set(bigIntToBytes(x, coordinateSize), 1);\n    out.set(bigIntToBytes(y, coordinateSize), 1 + coordinateSize);\n    return out;\n}\nexport class Ec extends NativeAlgorithm {\n    constructor(kem, hkdf) {\n        super();\n        Object.defineProperty(this, \"_hkdf\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_alg\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nPk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nSk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nDh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // EC specific arguments for deriving key pair.\n        Object.defineProperty(this, \"_order\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_bitmask\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_pkcs8AlgId\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_curveParams\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this._hkdf = hkdf;\n        switch (kem) {\n            case KemId.DhkemP256HkdfSha256:\n                this._alg = { name: \"ECDH\", namedCurve: \"P-256\" };\n                this._nPk = 65;\n                this._nSk = 32;\n                this._nDh = 32;\n                this._order = ORDER_P_256;\n                this._bitmask = 0xFF;\n                this._pkcs8AlgId = PKCS8_ALG_ID_P_256;\n                this._curveParams = EC_P_256_PARAMS;\n                break;\n            case KemId.DhkemP384HkdfSha384:\n                this._alg = { name: \"ECDH\", namedCurve: \"P-384\" };\n                this._nPk = 97;\n                this._nSk = 48;\n                this._nDh = 48;\n                this._order = ORDER_P_384;\n                this._bitmask = 0xFF;\n                this._pkcs8AlgId = PKCS8_ALG_ID_P_384;\n                this._curveParams = EC_P_384_PARAMS;\n                break;\n            default:\n                // case KemId.DhkemP521HkdfSha512:\n                this._alg = { name: \"ECDH\", namedCurve: \"P-521\" };\n                this._nPk = 133;\n                this._nSk = 66;\n                this._nDh = 66;\n                this._order = ORDER_P_521;\n                this._bitmask = 0x01;\n                this._pkcs8AlgId = PKCS8_ALG_ID_P_521;\n                this._curveParams = EC_P_521_PARAMS;\n                break;\n        }\n    }\n    async serializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._api.exportKey(\"raw\", key);\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), true);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async serializePrivateKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            if (!(\"d\" in jwk)) {\n                throw new Error(\"Not private key\");\n            }\n            return base64UrlToBytes(jwk[\"d\"]).buffer;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePrivateKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), false);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async importKey(format, key, isPublic) {\n        await this._setup();\n        try {\n            if (format === \"raw\") {\n                return await this._importRawKey(key, isPublic);\n            }\n            // jwk\n            if (key instanceof ArrayBuffer) {\n                throw new Error(\"Invalid jwk key format\");\n            }\n            return await this._importJWK(key, isPublic);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async generateKeyPair() {\n        await this._setup();\n        try {\n            return await this._api.generateKey(this._alg, true, KEM_USAGES);\n        }\n        catch (e) {\n            throw new NotSupportedError(e);\n        }\n    }\n    async deriveKeyPair(ikm) {\n        await this._setup();\n        try {\n            const rawIkm = toArrayBuffer(ikm);\n            const dkpPrk = await this._hkdf.labeledExtract(EMPTY, LABEL_DKP_PRK, new Uint8Array(rawIkm));\n            const bn = new Bignum(this._nSk);\n            for (let counter = 0; bn.isZero() || !bn.lessThan(this._order); counter++) {\n                if (counter > 255) {\n                    throw new Error(\"Faild to derive a key pair\");\n                }\n                const bytes = new Uint8Array(await this._hkdf.labeledExpand(dkpPrk, LABEL_CANDIDATE, i2Osp(counter, 1), this._nSk));\n                bytes[0] = bytes[0] & this._bitmask;\n                bn.set(bytes);\n            }\n            const sk = await this._deserializePkcs8Key(bn.val());\n            bn.reset();\n            return {\n                privateKey: sk,\n                publicKey: await this.derivePublicKey(sk),\n            };\n        }\n        catch (e) {\n            throw new DeriveKeyPairError(e);\n        }\n    }\n    async derivePublicKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            delete jwk[\"d\"];\n            delete jwk[\"key_ops\"];\n            return await this._api.importKey(\"jwk\", jwk, this._alg, true, []);\n        }\n        catch {\n            try {\n                // Firefox fails to export JWK from some imported ECDH private keys.\n                return await this._derivePublicKeyWithoutJwkExport(key);\n            }\n            catch (e) {\n                throw new DeserializeError(e);\n            }\n        }\n    }\n    async dh(sk, pk) {\n        try {\n            await this._setup();\n            const bits = await this._api.deriveBits({\n                name: \"ECDH\",\n                public: pk,\n            }, sk, this._nDh * 8);\n            return bits;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async _importRawKey(key, isPublic) {\n        if (isPublic && key.byteLength !== this._nPk) {\n            throw new Error(\"Invalid public key for the ciphersuite\");\n        }\n        if (!isPublic && key.byteLength !== this._nSk) {\n            throw new Error(\"Invalid private key for the ciphersuite\");\n        }\n        if (isPublic) {\n            return await this._api.importKey(\"raw\", key, this._alg, true, []);\n        }\n        return await this._deserializePkcs8Key(new Uint8Array(key));\n    }\n    async _importJWK(key, isPublic) {\n        if (typeof key.crv === \"undefined\" || key.crv !== this._alg.namedCurve) {\n            throw new Error(`Invalid crv: ${key.crv}`);\n        }\n        if (isPublic) {\n            if (typeof key.d !== \"undefined\") {\n                throw new Error(\"Invalid key: `d` should not be set\");\n            }\n            return await this._api.importKey(\"jwk\", key, this._alg, true, []);\n        }\n        if (typeof key.d === \"undefined\") {\n            throw new Error(\"Invalid key: `d` not found\");\n        }\n        return await this._api.importKey(\"jwk\", key, this._alg, true, KEM_USAGES);\n    }\n    async _deserializePkcs8Key(k) {\n        const pkcs8Key = new Uint8Array(this._pkcs8AlgId.length + k.length);\n        pkcs8Key.set(this._pkcs8AlgId, 0);\n        pkcs8Key.set(k, this._pkcs8AlgId.length);\n        return await this._api.importKey(\"pkcs8\", pkcs8Key, this._alg, true, KEM_USAGES);\n    }\n    async _derivePublicKeyWithoutJwkExport(key) {\n        const basePointRaw = buildRawUncompressedPublicKey(this._curveParams.gx, this._curveParams.gy, this._curveParams.coordinateSize);\n        const basePoint = await this._api.importKey(\"raw\", basePointRaw.buffer, this._alg, true, []);\n        const xBytes = new Uint8Array(await this._api.deriveBits({\n            name: \"ECDH\",\n            public: basePoint,\n        }, key, this._nDh * 8));\n        const p = this._curveParams.p;\n        const x = bytesToBigInt(xBytes);\n        const rhs = mod(modPow(x, 3n, p) - 3n * x + this._curveParams.b, p);\n        let y = modSqrt(rhs, p);\n        // Canonicalize sign so the encoded point is deterministic.\n        if ((y & 1n) === 1n) {\n            y = p - y;\n        }\n        const pubRaw = buildRawUncompressedPublicKey(x, y, this._curveParams.coordinateSize);\n        return await this._api.importKey(\"raw\", pubRaw.buffer, this._alg, true, []);\n    }\n}\n","// deno-lint-ignore-file no-explicit-any\n/**\n * This file is based on noble-curves (https://github.com/paulmillr/noble-curves).\n *\n * noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-curves/blob/b9d49d2b41d550571a0c5be443ecb62109fa3373/src/utils.ts\n */\n/**\n * Hex, bytes and number utilities.\n * @module\n */\nimport { loadCrypto } from \"./misc.js\";\nimport { N_0 } from \"../consts.js\";\n/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */\nexport function isBytes(a) {\n    return a instanceof Uint8Array ||\n        (ArrayBuffer.isView(a) && a.constructor.name === \"Uint8Array\");\n}\n/** Asserts something is positive integer. */\nexport function anumber(n, title = \"\") {\n    if (!Number.isSafeInteger(n) || n < 0) {\n        const prefix = title && `\"${title}\" `;\n        throw new Error(`${prefix}expected integer >0, got ${n}`);\n    }\n}\n/** Asserts something is Uint8Array. */\nexport function abytes(value, length, title = \"\") {\n    const bytes = isBytes(value);\n    const len = value?.length;\n    const needsLen = length !== undefined;\n    if (!bytes || (needsLen && len !== length)) {\n        const prefix = title && `\"${title}\" `;\n        const ofLen = needsLen ? ` of length ${length}` : \"\";\n        const got = bytes ? `length=${len}` : `type=${typeof value}`;\n        throw new Error(prefix + \"expected Uint8Array\" + ofLen + \", got \" + got);\n    }\n    return value;\n}\n// ahash function is now imported from ../hash/hash.ts\n/** Asserts a hash instance has not been destroyed / finished */\nexport function aexists(instance, checkFinished = true) {\n    if (instance.destroyed)\n        throw new Error(\"Hash instance has been destroyed\");\n    if (checkFinished && instance.finished) {\n        throw new Error(\"Hash#digest() has already been called\");\n    }\n}\n/** Asserts output is properly-sized byte array */\nexport function aoutput(out, instance) {\n    abytes(out, undefined, \"digestInto() output\");\n    const min = instance.outputLen;\n    if (out.length < min) {\n        throw new Error('\"digestInto() output\" expected to be of length >=' + min);\n    }\n}\n// Used in weierstrass, der\nfunction abignumer(n) {\n    if (typeof n === \"bigint\") {\n        if (!isPosBig(n))\n            throw new Error(\"positive bigint expected, got \" + n);\n    }\n    else\n        anumber(n);\n    return n;\n}\n/** Cast u8 / u16 / u32 to u32. */\nexport function u32(arr) {\n    return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));\n}\n/** Zeroize a byte array. Warning: JS provides no guarantees. */\nexport function clean(...arrays) {\n    for (let i = 0; i < arrays.length; i++) {\n        arrays[i].fill(0);\n    }\n}\n/** Pre-computed buffer for endianness detection */\nconst _endianTestBuffer = /* @__PURE__ */ new Uint32Array([0x11223344]);\nconst _endianTestBytes = /* @__PURE__ */ new Uint8Array(_endianTestBuffer.buffer);\n/** Is current platform little-endian? Most are. Big-Endian platform: IBM */\nexport const isLE = /* @__PURE__ */ _endianTestBytes[0] === 0x44;\n/** The byte swap operation for uint32 */\nexport function byteSwap(word) {\n    return (((word << 24) & 0xff000000) |\n        ((word << 8) & 0xff0000) |\n        ((word >>> 8) & 0xff00) |\n        ((word >>> 24) & 0xff));\n}\n/** Conditionally byte swap if on a big-endian platform */\nexport function swap8IfBE(n) {\n    return isLE ? n : byteSwap(n);\n}\n/** @deprecated */\nexport const byteSwapIfBE = swap8IfBE;\n/** In place byte swap for Uint32Array */\nexport function byteSwap32(arr) {\n    for (let i = 0; i < arr.length; i++) {\n        arr[i] = byteSwap(arr[i]);\n    }\n    return arr;\n}\nexport function swap32IfBE(u) {\n    return isLE ? u : byteSwap32(u);\n}\n/** Create DataView of an array for easy byte-level manipulation. */\nexport function createView(arr) {\n    return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n/** The rotate right (circular right shift) operation for uint32 */\nexport function rotr(word, shift) {\n    return (word << (32 - shift)) | (word >>> shift);\n}\n// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex\nconst hasHexBuiltin = /* @__PURE__ */ (() => \n// @ts-ignore: to use toHex\ntypeof Uint8Array.from([]).toHex === \"function\" &&\n    // @ts-ignore: to use fromHex\n    typeof Uint8Array.fromHex === \"function\")();\n// Array where index 0xf0 (240) is mapped to string 'f0'\nconst hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, \"0\"));\nconst HEX_TO_BIGINT = /* @__PURE__ */ [\n    0n,\n    1n,\n    2n,\n    3n,\n    4n,\n    5n,\n    6n,\n    7n,\n    8n,\n    9n,\n    10n,\n    11n,\n    12n,\n    13n,\n    14n,\n    15n,\n];\n/**\n * Convert byte array to hex string. Uses built-in function, when available.\n * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'\n */\nexport function bytesToHex(bytes) {\n    abytes(bytes);\n    // @ts-ignore: to use toHex\n    if (hasHexBuiltin)\n        return bytes.toHex();\n    // pre-caching improves the speed 6x\n    let hex = \"\";\n    for (let i = 0; i < bytes.length; i++) {\n        hex += hexes[bytes[i]];\n    }\n    return hex;\n}\n// We use optimized technique to convert hex string to byte array\nconst asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };\nfunction asciiToBase16(ch) {\n    if (ch >= asciis._0 && ch <= asciis._9)\n        return ch - asciis._0; // '2' => 50-48\n    if (ch >= asciis.A && ch <= asciis.F)\n        return ch - (asciis.A - 10); // 'B' => 66-(65-10)\n    if (ch >= asciis.a && ch <= asciis.f)\n        return ch - (asciis.a - 10); // 'b' => 98-(97-10)\n    return;\n}\n/**\n * Convert hex string to byte array. Uses built-in function, when available.\n * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])\n */\nexport function hexToBytes(hex) {\n    if (typeof hex !== \"string\") {\n        throw new Error(\"hex string expected, got \" + typeof hex);\n    }\n    // @ts-ignore: to use fromHex\n    if (hasHexBuiltin)\n        return Uint8Array.fromHex(hex);\n    const hl = hex.length;\n    const al = hl / 2;\n    if (hl % 2) {\n        throw new Error(\"hex string expected, got unpadded hex of length \" + hl);\n    }\n    const array = new Uint8Array(al);\n    for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {\n        const n1 = asciiToBase16(hex.charCodeAt(hi));\n        const n2 = asciiToBase16(hex.charCodeAt(hi + 1));\n        if (n1 === undefined || n2 === undefined) {\n            const char = hex[hi] + hex[hi + 1];\n            throw new Error('hex string expected, got non-hex character \"' + char + '\" at index ' +\n                hi);\n        }\n        array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163\n    }\n    return array;\n}\n/**\n * Converts string to bytes using UTF8 encoding.\n * @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])\n */\nexport function utf8ToBytes(str) {\n    if (typeof str !== \"string\")\n        throw new Error(\"string expected\");\n    return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809\n}\n/**\n * Converts bytes to string using UTF8 encoding.\n * @example bytesToUtf8(Uint8Array.from([97, 98, 99])) // 'abc'\n */\nexport function bytesToUtf8(bytes) {\n    return new TextDecoder().decode(bytes);\n}\nexport function numberToHexUnpadded(num) {\n    const hex = abignumer(num).toString(16);\n    return hex.length & 1 ? \"0\" + hex : hex;\n}\nexport function hexToNumber(hex) {\n    if (typeof hex !== \"string\") {\n        throw new Error(\"hex string expected, got \" + typeof hex);\n    }\n    let out = N_0;\n    for (let i = 0; i < hex.length; i++) {\n        const n = asciiToBase16(hex.charCodeAt(i));\n        if (n === undefined) {\n            throw new Error('hex string expected, got non-hex character \"' + hex[i] +\n                '\" at index ' + i);\n        }\n        out = (out << 4n) | HEX_TO_BIGINT[n];\n    }\n    return out; // Big Endian\n}\nexport function numberToBigint(num) {\n    anumber(num, \"numberToBigint\");\n    let n = num;\n    let out = N_0;\n    let bit = 1n;\n    while (n > 0) {\n        if (n % 2 === 1)\n            out += bit;\n        n = Math.floor(n / 2);\n        bit <<= 1n;\n    }\n    return out;\n}\n// BE: Big Endian, LE: Little Endian\nexport function bytesToNumberBE(bytes) {\n    return hexToNumber(bytesToHex(bytes));\n}\nexport function bytesToNumberLE(bytes) {\n    return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse()));\n}\nexport function numberToBytesBE(n, len) {\n    anumber(len);\n    n = abignumer(n);\n    const res = hexToBytes(n.toString(16).padStart(len * 2, \"0\"));\n    if (res.length !== len)\n        throw new Error(\"number too large\");\n    return res;\n}\nexport function numberToBytesLE(n, len) {\n    return numberToBytesBE(n, len).reverse();\n}\n/**\n * Copies Uint8Array. We can't use u8a.slice(), because u8a can be Buffer,\n * and Buffer#slice creates mutable copy. Never use Buffers!\n */\nexport function copyBytes(bytes) {\n    return Uint8Array.from(bytes);\n}\n/** Copies several Uint8Arrays into one. */\nexport function concatBytes(...arrays) {\n    let sum = 0;\n    for (let i = 0; i < arrays.length; i++) {\n        const a = arrays[i];\n        abytes(a);\n        sum += a.length;\n    }\n    const res = new Uint8Array(sum);\n    for (let i = 0, pad = 0; i < arrays.length; i++) {\n        const a = arrays[i];\n        res.set(a, pad);\n        pad += a.length;\n    }\n    return res;\n}\n/**\n * Decodes 7-bit ASCII string to Uint8Array, throws on non-ascii symbols\n * Should be safe to use for things expected to be ASCII.\n * Returns exact same result as utf8ToBytes for ASCII or throws.\n */\nexport function asciiToBytes(ascii) {\n    return Uint8Array.from(ascii, (c, i) => {\n        const charCode = c.charCodeAt(0);\n        if (c.length !== 1 || charCode > 127) {\n            throw new Error(`string contains non-ASCII character \"${ascii[i]}\" with code ${charCode} at position ${i}`);\n        }\n        return charCode;\n    });\n}\n// Is positive bigint\nfunction isPosBig(n) {\n    return typeof n === \"bigint\" && N_0 <= n;\n}\nexport function inRange(n, min, max) {\n    return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;\n}\n/**\n * Asserts min <= n < max. NOTE: It's < max and not <= max.\n * @example\n * aInRange('x', x, 1n, 256n); // would assume x is in (1n..255n)\n */\nexport function aInRange(title, n, min, max) {\n    // Why min <= n < max and not a (min < n < max) OR b (min <= n <= max)?\n    // consider P=256n, min=0n, max=P\n    // - a for min=0 would require -1:          `inRange('x', x, -1n, P)`\n    // - b would commonly require subtraction:  `inRange('x', x, 0n, P - 1n)`\n    // - our way is the cleanest:               `inRange('x', x, 0n, P)\n    if (!inRange(n, min, max)) {\n        throw new Error(\"expected valid \" + title + \": \" + min + \" <= n < \" + max + \", got \" + n);\n    }\n}\nexport function validateObject(object, fields = {}, optFields = {}) {\n    if (!object || typeof object !== \"object\") {\n        throw new Error(\"expected valid options object\");\n    }\n    function checkField(fieldName, expectedType, isOpt) {\n        const val = object[fieldName];\n        if (isOpt && val === undefined)\n            return;\n        const current = typeof val;\n        if (current !== expectedType || val === null) {\n            throw new Error(`param \"${fieldName}\" is invalid: expected ${expectedType}, got ${current}`);\n        }\n    }\n    const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));\n    iter(fields, false);\n    iter(optFields, true);\n}\n// createHasher function is now exported above with ahash\n// /** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\n// export function randomBytes(bytesLength = 32): Uint8Array {\n//   const cr = typeof globalThis != null && (globalThis as any).crypto;\n//   if (!cr || typeof cr.getRandomValues !== \"function\") {\n//     throw new Error(\"crypto.getRandomValues must be defined\");\n//   }\n//   return cr.getRandomValues(new Uint8Array(bytesLength));\n// }\n/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */\nexport async function randomBytesAsync(bytesLength = 32) {\n    const api = await loadCrypto();\n    const rnd = new Uint8Array(bytesLength);\n    api.getRandomValues(rnd);\n    return rnd;\n}\n// 06 09 60 86 48 01 65 03 04 02\nexport function oidNist(suffix) {\n    return {\n        oid: Uint8Array.from([\n            0x06,\n            0x09,\n            0x60,\n            0x86,\n            0x48,\n            0x01,\n            0x65,\n            0x03,\n            0x04,\n            0x02,\n            suffix,\n        ]),\n    };\n}\n","/**\n * This file is based on noble-curves (https://github.com/paulmillr/noble-curves).\n *\n * noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-curves/blob/b9d49d2b41d550571a0c5be443ecb62109fa3373/src/utils.ts\n */\n/**\n * Hash utilities and type definitions extracted from noble.ts\n * @module\n */\nimport { anumber } from \"../utils/noble.js\";\n/** Asserts something is hash */\nexport function ahash(h) {\n    if (typeof h !== \"function\" || typeof h.create !== \"function\") {\n        throw new Error(\"Hash must wrapped by utils.createHasher\");\n    }\n    anumber(h.outputLen);\n    anumber(h.blockLen);\n}\nexport function createHasher(hashCons, info = {}) {\n    const hashFn = (msg, opts) => hashCons(opts).update(msg).digest();\n    const tmp = hashCons(undefined);\n    const hashC = Object.assign(hashFn, {\n        outputLen: tmp.outputLen,\n        blockLen: tmp.blockLen,\n        create: (opts) => hashCons(opts),\n        ...info,\n    });\n    return Object.freeze(hashC);\n}\n","// deno-lint-ignore-file no-explicit-any\n/**\n * This file is based on noble-hashes (https://github.com/paulmillr/noble-hashes).\n *\n * noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-hashes/blob/2e0c00e1aa134082ba1380bf3afb8b1641f60fed/src/hmac.ts\n */\n/**\n * HMAC: RFC2104 message authentication code.\n * @module\n */\nimport { abytes, aexists, clean } from \"../utils/noble.js\";\nimport { ahash } from \"./hash.js\";\nexport class _HMAC {\n    constructor(hash, key) {\n        Object.defineProperty(this, \"oHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"iHash\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"blockLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"outputLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"finished\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        Object.defineProperty(this, \"destroyed\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        ahash(hash);\n        abytes(key, undefined, \"key\");\n        this.iHash = hash.create();\n        if (typeof this.iHash.update !== \"function\") {\n            throw new Error(\"Expected instance of class which extends utils.Hash\");\n        }\n        this.blockLen = this.iHash.blockLen;\n        this.outputLen = this.iHash.outputLen;\n        const blockLen = this.blockLen;\n        const pad = new Uint8Array(blockLen);\n        // blockLen can be bigger than outputLen\n        pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);\n        for (let i = 0; i < pad.length; i++)\n            pad[i] ^= 0x36;\n        this.iHash.update(pad);\n        // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone\n        this.oHash = hash.create();\n        // Undo internal XOR && apply outer XOR\n        for (let i = 0; i < pad.length; i++)\n            pad[i] ^= 0x36 ^ 0x5c;\n        this.oHash.update(pad);\n        clean(pad);\n    }\n    update(buf) {\n        aexists(this);\n        this.iHash.update(buf);\n        return this;\n    }\n    digestInto(out) {\n        aexists(this);\n        abytes(out, this.outputLen, \"output\");\n        this.finished = true;\n        this.iHash.digestInto(out);\n        this.oHash.update(out);\n        this.oHash.digestInto(out);\n        this.destroy();\n    }\n    digest() {\n        const out = new Uint8Array(this.oHash.outputLen);\n        this.digestInto(out);\n        return out;\n    }\n    _cloneInto(to) {\n        // Create new instance without calling constructor since key already in state and we don't know it.\n        to ||= Object.create(Object.getPrototypeOf(this), {});\n        const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;\n        to = to;\n        to.finished = finished;\n        to.destroyed = destroyed;\n        to.blockLen = blockLen;\n        to.outputLen = outputLen;\n        to.oHash = oHash._cloneInto(to.oHash);\n        to.iHash = iHash._cloneInto(to.iHash);\n        return to;\n    }\n    clone() {\n        return this._cloneInto();\n    }\n    destroy() {\n        this.destroyed = true;\n        this.oHash.destroy();\n        this.iHash.destroy();\n    }\n}\n/**\n * HMAC: RFC2104 message authentication code.\n * @param hash - function that would be used e.g. sha256\n * @param key - message key\n * @param message - message data\n * @example\n * import { hmac } from '@noble/hashes/hmac';\n * import { sha256 } from '@noble/hashes/sha2';\n * const mac1 = hmac(sha256, 'key', 'message');\n */\nexport const hmac = (hash, key, message) => new _HMAC(hash, key).update(message).digest();\nhmac.create = (hash, key) => new _HMAC(hash, key);\n","/**\n * This file is based on noble-hashes (https://github.com/paulmillr/noble-hashes).\n *\n * noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-hashes/blob/4e358a46d682adfb005ae6314ec999f2513086b9/src/_u64.ts\n */\n/**\n * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.\n * @todo re-check https://issues.chromium.org/issues/42212588\n * @module\n */\nconst U32_MASK64 = 0xffffffffn;\nconst _32n = 32n;\nfunction fromBig(n, le = false) {\n    if (le) {\n        return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };\n    }\n    return {\n        h: Number((n >> _32n) & U32_MASK64) | 0,\n        l: Number(n & U32_MASK64) | 0,\n    };\n}\nfunction split(lst, le = false) {\n    const len = lst.length;\n    const Ah = new Uint32Array(len);\n    const Al = new Uint32Array(len);\n    for (let i = 0; i < len; i++) {\n        const { h, l } = fromBig(lst[i], le);\n        [Ah[i], Al[i]] = [h, l];\n    }\n    return [Ah, Al];\n}\nconst toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);\n// for Shift in [0, 32)\nconst shrSH = (h, _l, s) => h >>> s;\nconst shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in [1, 32)\nconst rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));\nconst rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);\n// Right rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));\nconst rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));\n// Right rotate for shift===32 (just swaps l&h)\nconst rotr32H = (_h, l) => l;\nconst rotr32L = (h, _l) => h;\n// Left rotate for Shift in [1, 32)\nconst rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));\nconst rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));\n// Left rotate for Shift in (32, 64), NOTE: 32 is special case.\nconst rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));\nconst rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));\n// JS uses 32-bit signed integers for bitwise operations which means we cannot\n// simple take carry out of low bit sum by shift, we need to use division.\nfunction add(Ah, Al, Bh, Bl) {\n    const l = (Al >>> 0) + (Bl >>> 0);\n    return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };\n}\n// Addition with more than 2 elements\nconst add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);\nconst add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;\nconst add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);\nconst add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;\nconst add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);\nconst add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;\n// prettier-ignore\nexport { add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig, };\n// prettier-ignore\nconst u64 = {\n    fromBig,\n    split,\n    toBig,\n    shrSH,\n    shrSL,\n    rotrSH,\n    rotrSL,\n    rotrBH,\n    rotrBL,\n    rotr32H,\n    rotr32L,\n    rotlSH,\n    rotlSL,\n    rotlBH,\n    rotlBL,\n    add,\n    add3L,\n    add3H,\n    add4L,\n    add4H,\n    add5H,\n    add5L,\n};\nexport default u64;\n","/**\n * This file is based on noble-hashes (https://github.com/paulmillr/noble-hashes).\n *\n * noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-hashes/blob/4e358a46d682adfb005ae6314ec999f2513086b9/src/sha3.ts\n */\n/**\n * SHA3 (keccak) hash function, based on a new \"Sponge function\" design.\n * Different from older hashes, the internal state is bigger than output size.\n *\n * Check out [FIPS-202](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf),\n * [Website](https://keccak.team/keccak.html),\n * [the differences between SHA-3 and Keccak](https://crypto.stackexchange.com/questions/15727/what-are-the-key-differences-between-the-draft-sha-3-standard-and-the-keccak-sub).\n *\n * Check out `sha3-addons` module for cSHAKE, k12, and others.\n * @module\n */\nimport { rotlBH, rotlBL, rotlSH, rotlSL, split } from \"./u64.js\";\nimport { abytes, aexists, anumber, aoutput, clean, oidNist, swap32IfBE, u32, } from \"../utils/noble.js\";\nimport { createHasher, } from \"./hash.js\";\n// No __PURE__ annotations in sha3 header:\n// EVERYTHING is in fact used on every export.\n// Various per round constants calculations\nconst _0n = 0n;\nconst _1n = 1n;\nconst _2n = 2n;\nconst _7n = 7n;\nconst _256n = 256n;\nconst _0x71n = 0x71n;\nconst SHA3_PI = [];\nconst SHA3_ROTL = [];\nconst _SHA3_IOTA = []; // no pure annotation: var is always used\nfor (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {\n    // Pi\n    [x, y] = [y, (2 * x + 3 * y) % 5];\n    SHA3_PI.push(2 * (5 * y + x));\n    // Rotational\n    SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);\n    // Iota\n    let t = _0n;\n    for (let j = 0; j < 7; j++) {\n        R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;\n        if (R & _2n)\n            t ^= _1n << ((_1n << BigInt(j)) - _1n);\n    }\n    _SHA3_IOTA.push(t);\n}\nconst IOTAS = split(_SHA3_IOTA, true);\nconst SHA3_IOTA_H = IOTAS[0];\nconst SHA3_IOTA_L = IOTAS[1];\n// Left rotation (without 0, 32, 64)\nconst rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));\nconst rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));\n/** `keccakf1600` internal function, additionally allows to adjust round count. */\nexport function keccakP(s, rounds = 24, B) {\n    if (!B)\n        B = new Uint32Array(10);\n    // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)\n    for (let round = 24 - rounds; round < 24; round++) {\n        // Theta θ\n        for (let x = 0; x < 10; x++) {\n            B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];\n        }\n        // for (let x = 0; x < 10; x += 2) {\n        //   const idx1 = (x + 8) % 10;\n        //   const idx0 = (x + 2) % 10;\n        //   const B0 = B[idx0];\n        //   const B1 = B[idx0 + 1];\n        //   const Th = rotlH(B0, B1, 1) ^ B[idx1];\n        //   const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];\n        //   for (let y = 0; y < 50; y += 10) {\n        //     s[x + y] ^= Th;\n        //     s[x + y + 1] ^= Tl;\n        //   }\n        // }\n        { // x=0: idx0=2, idx1=8\n            const Th = rotlH(B[2], B[3], 1) ^ B[8];\n            const Tl = rotlL(B[2], B[3], 1) ^ B[9];\n            s[0] ^= Th;\n            s[1] ^= Tl;\n            s[10] ^= Th;\n            s[11] ^= Tl;\n            s[20] ^= Th;\n            s[21] ^= Tl;\n            s[30] ^= Th;\n            s[31] ^= Tl;\n            s[40] ^= Th;\n            s[41] ^= Tl;\n        }\n        { // x=2: idx0=4, idx1=0\n            const Th = rotlH(B[4], B[5], 1) ^ B[0];\n            const Tl = rotlL(B[4], B[5], 1) ^ B[1];\n            s[2] ^= Th;\n            s[3] ^= Tl;\n            s[12] ^= Th;\n            s[13] ^= Tl;\n            s[22] ^= Th;\n            s[23] ^= Tl;\n            s[32] ^= Th;\n            s[33] ^= Tl;\n            s[42] ^= Th;\n            s[43] ^= Tl;\n        }\n        { // x=4: idx0=6, idx1=2\n            const Th = rotlH(B[6], B[7], 1) ^ B[2];\n            const Tl = rotlL(B[6], B[7], 1) ^ B[3];\n            s[4] ^= Th;\n            s[5] ^= Tl;\n            s[14] ^= Th;\n            s[15] ^= Tl;\n            s[24] ^= Th;\n            s[25] ^= Tl;\n            s[34] ^= Th;\n            s[35] ^= Tl;\n            s[44] ^= Th;\n            s[45] ^= Tl;\n        }\n        { // x=6: idx0=8, idx1=4\n            const Th = rotlH(B[8], B[9], 1) ^ B[4];\n            const Tl = rotlL(B[8], B[9], 1) ^ B[5];\n            s[6] ^= Th;\n            s[7] ^= Tl;\n            s[16] ^= Th;\n            s[17] ^= Tl;\n            s[26] ^= Th;\n            s[27] ^= Tl;\n            s[36] ^= Th;\n            s[37] ^= Tl;\n            s[46] ^= Th;\n            s[47] ^= Tl;\n        }\n        { // x=8: idx0=0, idx1=6\n            const Th = rotlH(B[0], B[1], 1) ^ B[6];\n            const Tl = rotlL(B[0], B[1], 1) ^ B[7];\n            s[8] ^= Th;\n            s[9] ^= Tl;\n            s[18] ^= Th;\n            s[19] ^= Tl;\n            s[28] ^= Th;\n            s[29] ^= Tl;\n            s[38] ^= Th;\n            s[39] ^= Tl;\n            s[48] ^= Th;\n            s[49] ^= Tl;\n        }\n        // Rho (ρ) and Pi (π) — fully unrolled\n        let curH = s[2];\n        let curL = s[3];\n        // for (let t = 0; t < 24; t++) {\n        //   const shift = SHA3_ROTL[t];\n        //   const Th = rotlH(curH, curL, shift);\n        //   const Tl = rotlL(curH, curL, shift);\n        //   const PI = SHA3_PI[t];\n        //   curH = s[PI];\n        //   curL = s[PI + 1];\n        //   s[PI] = Th;\n        //   s[PI + 1] = Tl;\n        // }\n        let Th, Tl;\n        // t=0: shift=1(S), PI=20\n        Th = rotlSH(curH, curL, 1);\n        Tl = rotlSL(curH, curL, 1);\n        curH = s[20];\n        curL = s[21];\n        s[20] = Th;\n        s[21] = Tl;\n        // t=1: shift=3(S), PI=14\n        Th = rotlSH(curH, curL, 3);\n        Tl = rotlSL(curH, curL, 3);\n        curH = s[14];\n        curL = s[15];\n        s[14] = Th;\n        s[15] = Tl;\n        // t=2: shift=6(S), PI=22\n        Th = rotlSH(curH, curL, 6);\n        Tl = rotlSL(curH, curL, 6);\n        curH = s[22];\n        curL = s[23];\n        s[22] = Th;\n        s[23] = Tl;\n        // t=3: shift=10(S), PI=34\n        Th = rotlSH(curH, curL, 10);\n        Tl = rotlSL(curH, curL, 10);\n        curH = s[34];\n        curL = s[35];\n        s[34] = Th;\n        s[35] = Tl;\n        // t=4: shift=15(S), PI=36\n        Th = rotlSH(curH, curL, 15);\n        Tl = rotlSL(curH, curL, 15);\n        curH = s[36];\n        curL = s[37];\n        s[36] = Th;\n        s[37] = Tl;\n        // t=5: shift=21(S), PI=6\n        Th = rotlSH(curH, curL, 21);\n        Tl = rotlSL(curH, curL, 21);\n        curH = s[6];\n        curL = s[7];\n        s[6] = Th;\n        s[7] = Tl;\n        // t=6: shift=28(S), PI=10\n        Th = rotlSH(curH, curL, 28);\n        Tl = rotlSL(curH, curL, 28);\n        curH = s[10];\n        curL = s[11];\n        s[10] = Th;\n        s[11] = Tl;\n        // t=7: shift=36(B), PI=32\n        Th = rotlBH(curH, curL, 36);\n        Tl = rotlBL(curH, curL, 36);\n        curH = s[32];\n        curL = s[33];\n        s[32] = Th;\n        s[33] = Tl;\n        // t=8: shift=45(B), PI=16\n        Th = rotlBH(curH, curL, 45);\n        Tl = rotlBL(curH, curL, 45);\n        curH = s[16];\n        curL = s[17];\n        s[16] = Th;\n        s[17] = Tl;\n        // t=9: shift=55(B), PI=42\n        Th = rotlBH(curH, curL, 55);\n        Tl = rotlBL(curH, curL, 55);\n        curH = s[42];\n        curL = s[43];\n        s[42] = Th;\n        s[43] = Tl;\n        // t=10: shift=2(S), PI=48\n        Th = rotlSH(curH, curL, 2);\n        Tl = rotlSL(curH, curL, 2);\n        curH = s[48];\n        curL = s[49];\n        s[48] = Th;\n        s[49] = Tl;\n        // t=11: shift=14(S), PI=8\n        Th = rotlSH(curH, curL, 14);\n        Tl = rotlSL(curH, curL, 14);\n        curH = s[8];\n        curL = s[9];\n        s[8] = Th;\n        s[9] = Tl;\n        // t=12: shift=27(S), PI=30\n        Th = rotlSH(curH, curL, 27);\n        Tl = rotlSL(curH, curL, 27);\n        curH = s[30];\n        curL = s[31];\n        s[30] = Th;\n        s[31] = Tl;\n        // t=13: shift=41(B), PI=46\n        Th = rotlBH(curH, curL, 41);\n        Tl = rotlBL(curH, curL, 41);\n        curH = s[46];\n        curL = s[47];\n        s[46] = Th;\n        s[47] = Tl;\n        // t=14: shift=56(B), PI=38\n        Th = rotlBH(curH, curL, 56);\n        Tl = rotlBL(curH, curL, 56);\n        curH = s[38];\n        curL = s[39];\n        s[38] = Th;\n        s[39] = Tl;\n        // t=15: shift=8(S), PI=26\n        Th = rotlSH(curH, curL, 8);\n        Tl = rotlSL(curH, curL, 8);\n        curH = s[26];\n        curL = s[27];\n        s[26] = Th;\n        s[27] = Tl;\n        // t=16: shift=25(S), PI=24\n        Th = rotlSH(curH, curL, 25);\n        Tl = rotlSL(curH, curL, 25);\n        curH = s[24];\n        curL = s[25];\n        s[24] = Th;\n        s[25] = Tl;\n        // t=17: shift=43(B), PI=4\n        Th = rotlBH(curH, curL, 43);\n        Tl = rotlBL(curH, curL, 43);\n        curH = s[4];\n        curL = s[5];\n        s[4] = Th;\n        s[5] = Tl;\n        // t=18: shift=62(B), PI=40\n        Th = rotlBH(curH, curL, 62);\n        Tl = rotlBL(curH, curL, 62);\n        curH = s[40];\n        curL = s[41];\n        s[40] = Th;\n        s[41] = Tl;\n        // t=19: shift=18(S), PI=28\n        Th = rotlSH(curH, curL, 18);\n        Tl = rotlSL(curH, curL, 18);\n        curH = s[28];\n        curL = s[29];\n        s[28] = Th;\n        s[29] = Tl;\n        // t=20: shift=39(B), PI=44\n        Th = rotlBH(curH, curL, 39);\n        Tl = rotlBL(curH, curL, 39);\n        curH = s[44];\n        curL = s[45];\n        s[44] = Th;\n        s[45] = Tl;\n        // t=21: shift=61(B), PI=18\n        Th = rotlBH(curH, curL, 61);\n        Tl = rotlBL(curH, curL, 61);\n        curH = s[18];\n        curL = s[19];\n        s[18] = Th;\n        s[19] = Tl;\n        // t=22: shift=20(S), PI=12\n        Th = rotlSH(curH, curL, 20);\n        Tl = rotlSL(curH, curL, 20);\n        curH = s[12];\n        curL = s[13];\n        s[12] = Th;\n        s[13] = Tl;\n        // t=23: shift=44(B), PI=2\n        Th = rotlBH(curH, curL, 44);\n        Tl = rotlBL(curH, curL, 44);\n        s[2] = Th;\n        s[3] = Tl;\n        // Chi (χ)\n        for (let y = 0; y < 50; y += 10) {\n            B[0] = s[y];\n            B[1] = s[y + 1];\n            B[2] = s[y + 2];\n            B[3] = s[y + 3];\n            B[4] = s[y + 4];\n            B[5] = s[y + 5];\n            B[6] = s[y + 6];\n            B[7] = s[y + 7];\n            B[8] = s[y + 8];\n            B[9] = s[y + 9];\n            s[y + 0] ^= ~B[2] & B[4];\n            s[y + 1] ^= ~B[3] & B[5];\n            s[y + 2] ^= ~B[4] & B[6];\n            s[y + 3] ^= ~B[5] & B[7];\n            s[y + 4] ^= ~B[6] & B[8];\n            s[y + 5] ^= ~B[7] & B[9];\n            s[y + 6] ^= ~B[8] & B[0];\n            s[y + 7] ^= ~B[9] & B[1];\n            s[y + 8] ^= ~B[0] & B[2];\n            s[y + 9] ^= ~B[1] & B[3];\n        }\n        // Iota (ι)\n        s[0] ^= SHA3_IOTA_H[round];\n        s[1] ^= SHA3_IOTA_L[round];\n    }\n}\n/** Keccak sponge function. */\nexport class Keccak {\n    // NOTE: we accept arguments in bytes instead of bits here.\n    constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {\n        Object.defineProperty(this, \"state\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"pos\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"posOut\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"finished\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        Object.defineProperty(this, \"state32\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"destroyed\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        Object.defineProperty(this, \"_B\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: new Uint32Array(10)\n        });\n        Object.defineProperty(this, \"blockLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"suffix\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"outputLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"enableXOF\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        Object.defineProperty(this, \"rounds\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this.blockLen = blockLen;\n        this.suffix = suffix;\n        this.outputLen = outputLen;\n        this.enableXOF = enableXOF;\n        this.rounds = rounds;\n        // Can be passed from user as dkLen\n        anumber(outputLen, \"outputLen\");\n        // 1600 = 5x5 matrix of 64bit.  1600 bits === 200 bytes\n        // 0 < blockLen < 200\n        if (!(0 < blockLen && blockLen < 200)) {\n            throw new Error(\"only keccak-f1600 function is supported\");\n        }\n        this.state = new Uint8Array(200);\n        this.state32 = u32(this.state);\n    }\n    clone() {\n        return this._cloneInto();\n    }\n    /** Resets instance to initial (empty) state for reuse. */\n    reset() {\n        this.state.fill(0);\n        this.pos = 0;\n        this.posOut = 0;\n        this.finished = false;\n        this.destroyed = false;\n    }\n    keccak() {\n        swap32IfBE(this.state32);\n        keccakP(this.state32, this.rounds, this._B);\n        swap32IfBE(this.state32);\n        this.posOut = 0;\n        this.pos = 0;\n    }\n    update(data) {\n        aexists(this);\n        abytes(data);\n        return this.updateUnsafe(data);\n    }\n    /** Like update(), but skips validation. Caller must ensure valid state and input. */\n    updateUnsafe(data) {\n        const { blockLen, state } = this;\n        const len = data.length;\n        for (let pos = 0; pos < len;) {\n            const take = Math.min(blockLen - this.pos, len - pos);\n            for (let i = 0; i < take; i++)\n                state[this.pos++] ^= data[pos++];\n            if (this.pos === blockLen)\n                this.keccak();\n        }\n        return this;\n    }\n    finish() {\n        if (this.finished)\n            return;\n        this.finished = true;\n        const { state, suffix, pos, blockLen } = this;\n        // Do the padding\n        state[pos] ^= suffix;\n        if ((suffix & 0x80) !== 0 && pos === blockLen - 1)\n            this.keccak();\n        state[blockLen - 1] ^= 0x80;\n        this.keccak();\n    }\n    writeInto(out) {\n        aexists(this, false);\n        abytes(out);\n        return this.writeIntoUnsafe(out);\n    }\n    /** Like writeInto(), but skips validation. Caller must ensure valid state and output. */\n    writeIntoUnsafe(out) {\n        this.finish();\n        const bufferOut = this.state;\n        const { blockLen } = this;\n        for (let pos = 0, len = out.length; pos < len;) {\n            if (this.posOut >= blockLen)\n                this.keccak();\n            const take = Math.min(blockLen - this.posOut, len - pos);\n            out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);\n            this.posOut += take;\n            pos += take;\n        }\n        return out;\n    }\n    xofInto(out) {\n        // Sha3/Keccak usage with XOF is probably mistake, only SHAKE instances can do XOF\n        if (!this.enableXOF) {\n            throw new Error(\"XOF is not possible for this instance\");\n        }\n        return this.writeInto(out);\n    }\n    xof(bytes) {\n        anumber(bytes);\n        return this.xofInto(new Uint8Array(bytes));\n    }\n    digestInto(out) {\n        aoutput(out, this);\n        if (this.finished)\n            throw new Error(\"digest() was already called\");\n        this.writeInto(out);\n        this.destroy();\n        return out;\n    }\n    digest() {\n        return this.digestInto(new Uint8Array(this.outputLen));\n    }\n    destroy() {\n        this.destroyed = true;\n        clean(this.state);\n    }\n    _cloneInto(to) {\n        const { blockLen, suffix, outputLen, rounds, enableXOF } = this;\n        to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds);\n        to.state32.set(this.state32);\n        to.pos = this.pos;\n        to.posOut = this.posOut;\n        to.finished = this.finished;\n        to.rounds = rounds;\n        // Suffix can change in cSHAKE\n        to.suffix = suffix;\n        to.outputLen = outputLen;\n        to.enableXOF = enableXOF;\n        to.destroyed = this.destroyed;\n        return to;\n    }\n}\nconst genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info);\n// /** SHA3-224 hash function. */\n// export const sha3_224: CHash = /* @__PURE__ */ genKeccak(\n//   0x06,\n//   144,\n//   28,\n//   /* @__PURE__ */ oidNist(0x07),\n// );\n/** SHA3-256 hash function. Different from keccak-256. */\nexport const sha3_256 = /* @__PURE__ */ genKeccak(0x06, 136, 32, \n/* @__PURE__ */ oidNist(0x08));\n/** SHA3-384 hash function. */\nexport const sha3_384 = /* @__PURE__ */ genKeccak(0x06, 104, 48, \n/* @__PURE__ */ oidNist(0x09));\n/** SHA3-512 hash function. */\nexport const sha3_512 = /* @__PURE__ */ genKeccak(0x06, 72, 64, \n/* @__PURE__ */ oidNist(0x0a));\n/** keccak-224 hash function. */\nexport const keccak_224 = /* @__PURE__ */ genKeccak(0x01, 144, 28);\n/** keccak-256 hash function. Different from SHA3-256. */\nexport const keccak_256 = /* @__PURE__ */ genKeccak(0x01, 136, 32);\n/** keccak-384 hash function. */\nexport const keccak_384 = /* @__PURE__ */ genKeccak(0x01, 104, 48);\n/** keccak-512 hash function. */\nexport const keccak_512 = /* @__PURE__ */ genKeccak(0x01, 72, 64);\nconst genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true), info);\n/** SHAKE128 XOF with 128-bit security. */\nexport const shake128 = \n/* @__PURE__ */\ngenShake(0x1f, 168, 16, /* @__PURE__ */ oidNist(0x0b));\n/** SHAKE256 XOF with 256-bit security. */\nexport const shake256 = \n/* @__PURE__ */\ngenShake(0x1f, 136, 32, /* @__PURE__ */ oidNist(0x0c));\n// /** SHAKE128 XOF with 256-bit output (NIST version). */\n// export const shake128_32: CHashXOF<Keccak, ShakeOpts> =\n//   /* @__PURE__ */\n//   genShake(0x1f, 168, 32, /* @__PURE__ */ oidNist(0x0b));\n// /** SHAKE256 XOF with 512-bit output (NIST version). */\n// export const shake256_64: CHashXOF<Keccak, ShakeOpts> =\n//   /* @__PURE__ */\n//   genShake(0x1f, 136, 64, /* @__PURE__ */ oidNist(0x0c));\n","/**\n * This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).\n *\n * noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/utils.ts\n */\n/**\n * Utilities for hex, bytes, CSPRNG.\n * @module\n */\nimport { abytes, aexists, anumber, aoutput, clean, copyBytes, createView, isLE, numberToBigint, u32, } from \"@hpke/common\";\nexport { abytes, aexists, anumber, aoutput, clean, copyBytes, createView, isLE, u32, };\n/** Asserts something is boolean. */\nexport function abool(b) {\n    if (typeof b !== \"boolean\")\n        throw new Error(`boolean expected, not ${b}`);\n}\n/** Cast u8 / u16 / u32 to u8. */\nexport function u8(arr) {\n    return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);\n}\n/**\n * Wraps a cipher: validates args, ensures encrypt() can only be called once.\n * @__NO_SIDE_EFFECTS__\n */\n// deno-lint-ignore no-explicit-any\nexport const wrapCipher = (params, constructor) => {\n    // deno-lint-ignore no-explicit-any\n    function wrappedCipher(key, ...args) {\n        // Validate key\n        abytes(key, undefined, \"key\");\n        // Big-Endian hardware is rare. Just in case someone still decides to run ciphers:\n        if (!isLE) {\n            throw new Error(\"Non little-endian hardware is not yet supported\");\n        }\n        // Validate nonce if nonceLength is present\n        if (params.nonceLength !== undefined) {\n            const nonce = args[0];\n            abytes(nonce, params.varSizeNonce ? undefined : params.nonceLength, \"nonce\");\n        }\n        // Validate AAD if tagLength present\n        const tagl = params.tagLength;\n        if (tagl && args[1] !== undefined)\n            abytes(args[1], undefined, \"AAD\");\n        const cipher = constructor(key, ...args);\n        const checkOutput = (fnLength, output) => {\n            if (output !== undefined) {\n                if (fnLength !== 2)\n                    throw new Error(\"cipher output not supported\");\n                abytes(output, undefined, \"output\");\n            }\n        };\n        // Create wrapped cipher with validation and single-use encryption\n        let called = false;\n        const wrCipher = {\n            encrypt(data, output) {\n                if (called) {\n                    throw new Error(\"cannot encrypt() twice with same key + nonce\");\n                }\n                called = true;\n                abytes(data);\n                checkOutput(cipher.encrypt.length, output);\n                return cipher.encrypt(data, output);\n            },\n            decrypt(data, output) {\n                abytes(data);\n                if (tagl && data.length < tagl) {\n                    throw new Error('\"ciphertext\" expected length bigger than tagLength=' + tagl);\n                }\n                checkOutput(cipher.decrypt.length, output);\n                return cipher.decrypt(data, output);\n            },\n        };\n        return wrCipher;\n    }\n    Object.assign(wrappedCipher, params);\n    return wrappedCipher;\n};\nexport function checkOpts(defaults, opts) {\n    if (opts == null || typeof opts !== \"object\") {\n        throw new Error(\"options must be defined\");\n    }\n    const merged = Object.assign(defaults, opts);\n    return merged;\n}\n/** Compares 2 uint8array-s in kinda constant time. */\nexport function equalBytes(a, b) {\n    if (a.length !== b.length)\n        return false;\n    let diff = 0;\n    for (let i = 0; i < a.length; i++)\n        diff |= a[i] ^ b[i];\n    return diff === 0;\n}\n/**\n * By default, returns u8a of length.\n * When out is available, it checks it for validity and uses it.\n */\nexport function getOutput(expectedLength, out, onlyAligned = true) {\n    if (out === undefined)\n        return new Uint8Array(expectedLength);\n    if (out.length !== expectedLength) {\n        throw new Error('\"output\" expected Uint8Array of length ' + expectedLength + \", got: \" +\n            out.length);\n    }\n    if (onlyAligned && !isAligned32(out)) {\n        throw new Error(\"invalid output, must be aligned\");\n    }\n    return out;\n}\nexport function u64Lengths(dataLength, aadLength, isLE) {\n    abool(isLE);\n    const num = new Uint8Array(16);\n    const view = createView(num);\n    view.setBigUint64(0, numberToBigint(aadLength), isLE);\n    view.setBigUint64(8, numberToBigint(dataLength), isLE);\n    return num;\n}\n// Is byte array aligned to 4 byte offset (u32)?\nexport function isAligned32(bytes) {\n    return bytes.byteOffset % 4 === 0;\n}\n// copy bytes to new u8a (aligned). Because Buffer.slice is broken.\n// Re-exported from @hpke/common.\n","/**\n * This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).\n *\n * noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/_arx.ts\n */\n/**\n * Basic utils for ARX (add-rotate-xor) salsa and chacha ciphers.\n\nRFC8439 requires multi-step cipher stream, where\nauthKey starts with counter: 0, actual msg with counter: 1.\n\nFor this, we need a way to re-use nonce / counter:\n\n    const counter = new Uint8Array(4);\n    chacha(..., counter, ...); // counter is now 1\n    chacha(..., counter, ...); // counter is now 2\n\nThis is complicated:\n\n- 32-bit counters are enough, no need for 64-bit: max ArrayBuffer size in JS is 4GB\n- Original papers don't allow mutating counters\n- Counter overflow is undefined [^1]\n- Idea A: allow providing (nonce | counter) instead of just nonce, re-use it\n- Caveat: Cannot be re-used through all cases:\n- * chacha has (counter | nonce)\n- * xchacha has (nonce16 | counter | nonce16)\n- Idea B: separate nonce / counter and provide separate API for counter re-use\n- Caveat: there are different counter sizes depending on an algorithm.\n- salsa & chacha also differ in structures of key & sigma:\n  salsa20:      s[0] | k(4) | s[1] | nonce(2) | cnt(2) | s[2] | k(4) | s[3]\n  chacha:       s(4) | k(8) | cnt(1) | nonce(3)\n  chacha20orig: s(4) | k(8) | cnt(2) | nonce(2)\n- Idea C: helper method such as `setSalsaState(key, nonce, sigma, data)`\n- Caveat: we can't re-use counter array\n\nxchacha [^2] uses the subkey and remaining 8 byte nonce with ChaCha20 as normal\n(prefixed by 4 NUL bytes, since [RFC8439] specifies a 12-byte nonce).\n\n[^1]: https://mailarchive.ietf.org/arch/msg/cfrg/gsOnTJzcbgG6OqD8Sc0GO5aR_tU/\n[^2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha#appendix-A.2\n\n * @module\n */\nimport { abool, abytes, anumber, checkOpts, clean, copyBytes, u32, } from \"./utils.js\";\n// Can't use similar utils.utf8ToBytes, because it uses `TextEncoder` - not available in all envs\nconst _utf8ToBytes = (str) => Uint8Array.from(str.split(\"\").map((c) => c.charCodeAt(0)));\nconst sigma16 = _utf8ToBytes(\"expand 16-byte k\");\nconst sigma32 = _utf8ToBytes(\"expand 32-byte k\");\nconst sigma16_32 = u32(sigma16);\nconst sigma32_32 = u32(sigma32);\n/** Rotate left. */\nexport function rotl(a, b) {\n    return (a << b) | (a >>> (32 - b));\n}\n// Is byte array aligned to 4 byte offset (u32)?\nfunction isAligned32(b) {\n    return b.byteOffset % 4 === 0;\n}\n// Salsa and Chacha block length is always 512-bit\nconst BLOCK_LEN = 64;\nconst BLOCK_LEN32 = 16;\n// new Uint32Array([2**32])   // => Uint32Array(1) [ 0 ]\n// new Uint32Array([2**32-1]) // => Uint32Array(1) [ 4294967295 ]\nconst MAX_COUNTER = 2 ** 32 - 1;\nconst U32_EMPTY = Uint32Array.of();\nfunction runCipher(core, sigma, key, nonce, data, output, counter, rounds) {\n    const len = data.length;\n    const block = new Uint8Array(BLOCK_LEN);\n    const b32 = u32(block);\n    // Make sure that buffers aligned to 4 bytes\n    const isAligned = isAligned32(data) && isAligned32(output);\n    const d32 = isAligned ? u32(data) : U32_EMPTY;\n    const o32 = isAligned ? u32(output) : U32_EMPTY;\n    for (let pos = 0; pos < len; counter++) {\n        core(sigma, key, nonce, b32, counter, rounds);\n        if (counter >= MAX_COUNTER)\n            throw new Error(\"arx: counter overflow\");\n        const take = Math.min(BLOCK_LEN, len - pos);\n        // aligned to 4 bytes\n        if (isAligned && take === BLOCK_LEN) {\n            const pos32 = pos / 4;\n            if (pos % 4 !== 0)\n                throw new Error(\"arx: invalid block position\");\n            for (let j = 0, posj; j < BLOCK_LEN32; j++) {\n                posj = pos32 + j;\n                o32[posj] = d32[posj] ^ b32[j];\n            }\n            pos += BLOCK_LEN;\n            continue;\n        }\n        for (let j = 0, posj; j < take; j++) {\n            posj = pos + j;\n            output[posj] = data[posj] ^ block[j];\n        }\n        pos += take;\n    }\n}\n/** Creates ARX-like (ChaCha, Salsa) cipher stream from core function. */\nexport function createCipher(core, opts) {\n    const { allowShortKeys, extendNonceFn, counterLength, counterRight, rounds } = checkOpts({\n        allowShortKeys: false,\n        counterLength: 8,\n        counterRight: false,\n        rounds: 20,\n    }, opts);\n    if (typeof core !== \"function\")\n        throw new Error(\"core must be a function\");\n    anumber(counterLength);\n    anumber(rounds);\n    abool(counterRight);\n    abool(allowShortKeys);\n    return (key, nonce, data, output, counter = 0) => {\n        abytes(key, undefined, \"key\");\n        abytes(nonce, undefined, \"nonce\");\n        abytes(data, undefined, \"data\");\n        const len = data.length;\n        if (output === undefined)\n            output = new Uint8Array(len);\n        abytes(output, undefined, \"output\");\n        anumber(counter);\n        if (counter < 0 || counter >= MAX_COUNTER) {\n            throw new Error(\"arx: counter overflow\");\n        }\n        if (output.length < len) {\n            throw new Error(`arx: output (${output.length}) is shorter than data (${len})`);\n        }\n        const toClean = [];\n        // Key & sigma\n        // key=16 -> sigma16, k=key|key\n        // key=32 -> sigma32, k=key\n        const l = key.length;\n        let k;\n        let sigma;\n        if (l === 32) {\n            toClean.push(k = copyBytes(key));\n            sigma = sigma32_32;\n        }\n        else if (l === 16 && allowShortKeys) {\n            k = new Uint8Array(32);\n            k.set(key);\n            k.set(key, 16);\n            sigma = sigma16_32;\n            toClean.push(k);\n        }\n        else {\n            abytes(key, 32, \"arx key\");\n            throw new Error(\"invalid key size\");\n            // throw new Error(`\"arx key\" expected Uint8Array of length 32, got length=${l}`);\n        }\n        // Nonce\n        // salsa20:      8   (8-byte counter)\n        // chacha20orig: 8   (8-byte counter)\n        // chacha20:     12  (4-byte counter)\n        // xsalsa20:     24  (16 -> hsalsa,  8 -> old nonce)\n        // xchacha20:    24  (16 -> hchacha, 8 -> old nonce)\n        // Align nonce to 4 bytes\n        if (!isAligned32(nonce))\n            toClean.push(nonce = copyBytes(nonce));\n        const k32 = u32(k);\n        // hsalsa & hchacha: handle extended nonce\n        if (extendNonceFn) {\n            if (nonce.length !== 24) {\n                throw new Error(`arx: extended nonce must be 24 bytes`);\n            }\n            extendNonceFn(sigma, k32, u32(nonce.subarray(0, 16)), k32);\n            nonce = nonce.subarray(16);\n        }\n        // Handle nonce counter\n        const nonceNcLen = 16 - counterLength;\n        if (nonceNcLen !== nonce.length) {\n            throw new Error(`arx: nonce must be ${nonceNcLen} or 16 bytes`);\n        }\n        // Pad counter when nonce is 64 bit\n        if (nonceNcLen !== 12) {\n            const nc = new Uint8Array(12);\n            nc.set(nonce, counterRight ? 0 : 12 - nonce.length);\n            nonce = nc;\n            toClean.push(nonce);\n        }\n        const n32 = u32(nonce);\n        runCipher(core, sigma, k32, n32, data, output, counter, rounds);\n        clean(...toClean);\n        return output;\n    };\n}\n","/**\n * This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).\n *\n * noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/_poly1305.ts\n */\n/**\n * Poly1305 ([PDF](https://cr.yp.to/mac/poly1305-20050329.pdf),\n * [wiki](https://en.wikipedia.org/wiki/Poly1305))\n * is a fast and parallel secret-key message-authentication code suitable for\n * a wide variety of applications. It was standardized in\n * [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439) and is now used in TLS 1.3.\n *\n * Polynomial MACs are not perfect for every situation:\n * they lack Random Key Robustness: the MAC can be forged, and can't be used in PAKE schemes.\n * See [invisible salamanders attack](https://keymaterial.net/2020/09/07/invisible-salamanders-in-aes-gcm-siv/).\n * To combat invisible salamanders, `hash(key)` can be included in ciphertext,\n * however, this would violate ciphertext indistinguishability:\n * an attacker would know which key was used - so `HKDF(key, i)`\n * could be used instead.\n *\n * Check out [original website](https://cr.yp.to/mac.html).\n * Based on Public Domain [poly1305-donna](https://github.com/floodyberry/poly1305-donna).\n * @module\n */\nimport { abytes, aexists, aoutput, clean, copyBytes, } from \"./utils.js\";\nfunction u8to16(a, i) {\n    return (a[i++] & 0xff) | ((a[i++] & 0xff) << 8);\n}\n// function bytesToNumberLE(bytes: Uint8Array): bigint {\n//   return hexToNumber(bytesToHex(Uint8Array.from(bytes).reverse()));\n// }\n// /** Small version of `poly1305` without loop unrolling. Unused, provided for auditability. */\n// function poly1305_small(msg: Uint8Array, key: Uint8Array): Uint8Array {\n//   abytes(msg);\n//   abytes(key, 32, \"key\");\n//   const POW_2_130_5 = 2n ** 130n - 5n; // 2^130-5\n//   const POW_2_128_1 = 2n ** 128n - 1n; // 2^128-1\n//   const CLAMP_R = 0x0ffffffc0ffffffc0ffffffc0fffffffn;\n//   const r = bytesToNumberLE(key.subarray(0, 16)) & CLAMP_R;\n//   const s = bytesToNumberLE(key.subarray(16));\n//   // Process by 16 byte chunks\n//   let acc = 0n;\n//   for (let i = 0; i < msg.length; i += 16) {\n//     const m = msg.subarray(i, i + 16);\n//     const n = bytesToNumberLE(m) | (1n << (8n * mLen)); // mLen: bigint\n//     acc = ((acc + n) * r) % POW_2_130_5;\n//   }\n//   const res = (acc + s) & POW_2_128_1;\n//   return numberToBytesBE(res, 16).reverse(); // LE\n// }\n// Can be used to replace `computeTag` in chacha.ts. Unused, provided for auditability.\n// function poly1305_computeTag_small(\n//   authKey: Uint8Array,\n//   lengths: Uint8Array,\n//   ciphertext: Uint8Array,\n//   AAD?: Uint8Array,\n// ): Uint8Array {\n//   const res = [];\n//   const updatePadded2 = (msg: Uint8Array) => {\n//     res.push(msg);\n//     const leftover = msg.length % 16;\n//     if (leftover) res.push(new Uint8Array(16).slice(leftover));\n//   };\n//   if (AAD) updatePadded2(AAD);\n//   updatePadded2(ciphertext);\n//   res.push(lengths);\n//   return poly1305_small(concatBytes(...res), authKey);\n// }\n/** Poly1305 class. Prefer poly1305() function instead. */\nexport class Poly1305 {\n    // Can be speed-up using BigUint64Array, at the cost of complexity\n    constructor(key) {\n        Object.defineProperty(this, \"blockLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 16\n        });\n        Object.defineProperty(this, \"outputLen\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 16\n        });\n        Object.defineProperty(this, \"buffer\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: new Uint8Array(16)\n        });\n        Object.defineProperty(this, \"r\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: new Uint16Array(10)\n        }); // Allocating 1 array with .subarray() here is slower than 3\n        Object.defineProperty(this, \"h\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: new Uint16Array(10)\n        });\n        Object.defineProperty(this, \"pad\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: new Uint16Array(8)\n        });\n        Object.defineProperty(this, \"pos\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: 0\n        });\n        Object.defineProperty(this, \"finished\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: false\n        });\n        key = copyBytes(abytes(key, 32, \"key\"));\n        const t0 = u8to16(key, 0);\n        const t1 = u8to16(key, 2);\n        const t2 = u8to16(key, 4);\n        const t3 = u8to16(key, 6);\n        const t4 = u8to16(key, 8);\n        const t5 = u8to16(key, 10);\n        const t6 = u8to16(key, 12);\n        const t7 = u8to16(key, 14);\n        // https://github.com/floodyberry/poly1305-donna/blob/e6ad6e091d30d7f4ec2d4f978be1fcfcbce72781/poly1305-donna-16.h#L47\n        this.r[0] = t0 & 0x1fff;\n        this.r[1] = ((t0 >>> 13) | (t1 << 3)) & 0x1fff;\n        this.r[2] = ((t1 >>> 10) | (t2 << 6)) & 0x1f03;\n        this.r[3] = ((t2 >>> 7) | (t3 << 9)) & 0x1fff;\n        this.r[4] = ((t3 >>> 4) | (t4 << 12)) & 0x00ff;\n        this.r[5] = (t4 >>> 1) & 0x1ffe;\n        this.r[6] = ((t4 >>> 14) | (t5 << 2)) & 0x1fff;\n        this.r[7] = ((t5 >>> 11) | (t6 << 5)) & 0x1f81;\n        this.r[8] = ((t6 >>> 8) | (t7 << 8)) & 0x1fff;\n        this.r[9] = (t7 >>> 5) & 0x007f;\n        for (let i = 0; i < 8; i++)\n            this.pad[i] = u8to16(key, 16 + 2 * i);\n    }\n    process(data, offset, isLast = false) {\n        const hibit = isLast ? 0 : 1 << 11;\n        const { h, r } = this;\n        const r0 = r[0];\n        const r1 = r[1];\n        const r2 = r[2];\n        const r3 = r[3];\n        const r4 = r[4];\n        const r5 = r[5];\n        const r6 = r[6];\n        const r7 = r[7];\n        const r8 = r[8];\n        const r9 = r[9];\n        const t0 = u8to16(data, offset + 0);\n        const t1 = u8to16(data, offset + 2);\n        const t2 = u8to16(data, offset + 4);\n        const t3 = u8to16(data, offset + 6);\n        const t4 = u8to16(data, offset + 8);\n        const t5 = u8to16(data, offset + 10);\n        const t6 = u8to16(data, offset + 12);\n        const t7 = u8to16(data, offset + 14);\n        const h0 = h[0] + (t0 & 0x1fff);\n        const h1 = h[1] + (((t0 >>> 13) | (t1 << 3)) & 0x1fff);\n        const h2 = h[2] + (((t1 >>> 10) | (t2 << 6)) & 0x1fff);\n        const h3 = h[3] + (((t2 >>> 7) | (t3 << 9)) & 0x1fff);\n        const h4 = h[4] + (((t3 >>> 4) | (t4 << 12)) & 0x1fff);\n        const h5 = h[5] + ((t4 >>> 1) & 0x1fff);\n        const h6 = h[6] + (((t4 >>> 14) | (t5 << 2)) & 0x1fff);\n        const h7 = h[7] + (((t5 >>> 11) | (t6 << 5)) & 0x1fff);\n        const h8 = h[8] + (((t6 >>> 8) | (t7 << 8)) & 0x1fff);\n        const h9 = h[9] + ((t7 >>> 5) | hibit);\n        let c = 0;\n        let d0 = c + h0 * r0 + h1 * (5 * r9) + h2 * (5 * r8) + h3 * (5 * r7) +\n            h4 * (5 * r6);\n        c = d0 >>> 13;\n        d0 &= 0x1fff;\n        d0 += h5 * (5 * r5) + h6 * (5 * r4) + h7 * (5 * r3) + h8 * (5 * r2) +\n            h9 * (5 * r1);\n        c += d0 >>> 13;\n        d0 &= 0x1fff;\n        let d1 = c + h0 * r1 + h1 * r0 + h2 * (5 * r9) + h3 * (5 * r8) +\n            h4 * (5 * r7);\n        c = d1 >>> 13;\n        d1 &= 0x1fff;\n        d1 += h5 * (5 * r6) + h6 * (5 * r5) + h7 * (5 * r4) + h8 * (5 * r3) +\n            h9 * (5 * r2);\n        c += d1 >>> 13;\n        d1 &= 0x1fff;\n        let d2 = c + h0 * r2 + h1 * r1 + h2 * r0 + h3 * (5 * r9) + h4 * (5 * r8);\n        c = d2 >>> 13;\n        d2 &= 0x1fff;\n        d2 += h5 * (5 * r7) + h6 * (5 * r6) + h7 * (5 * r5) + h8 * (5 * r4) +\n            h9 * (5 * r3);\n        c += d2 >>> 13;\n        d2 &= 0x1fff;\n        let d3 = c + h0 * r3 + h1 * r2 + h2 * r1 + h3 * r0 + h4 * (5 * r9);\n        c = d3 >>> 13;\n        d3 &= 0x1fff;\n        d3 += h5 * (5 * r8) + h6 * (5 * r7) + h7 * (5 * r6) + h8 * (5 * r5) +\n            h9 * (5 * r4);\n        c += d3 >>> 13;\n        d3 &= 0x1fff;\n        let d4 = c + h0 * r4 + h1 * r3 + h2 * r2 + h3 * r1 + h4 * r0;\n        c = d4 >>> 13;\n        d4 &= 0x1fff;\n        d4 += h5 * (5 * r9) + h6 * (5 * r8) + h7 * (5 * r7) + h8 * (5 * r6) +\n            h9 * (5 * r5);\n        c += d4 >>> 13;\n        d4 &= 0x1fff;\n        let d5 = c + h0 * r5 + h1 * r4 + h2 * r3 + h3 * r2 + h4 * r1;\n        c = d5 >>> 13;\n        d5 &= 0x1fff;\n        d5 += h5 * r0 + h6 * (5 * r9) + h7 * (5 * r8) + h8 * (5 * r7) +\n            h9 * (5 * r6);\n        c += d5 >>> 13;\n        d5 &= 0x1fff;\n        let d6 = c + h0 * r6 + h1 * r5 + h2 * r4 + h3 * r3 + h4 * r2;\n        c = d6 >>> 13;\n        d6 &= 0x1fff;\n        d6 += h5 * r1 + h6 * r0 + h7 * (5 * r9) + h8 * (5 * r8) + h9 * (5 * r7);\n        c += d6 >>> 13;\n        d6 &= 0x1fff;\n        let d7 = c + h0 * r7 + h1 * r6 + h2 * r5 + h3 * r4 + h4 * r3;\n        c = d7 >>> 13;\n        d7 &= 0x1fff;\n        d7 += h5 * r2 + h6 * r1 + h7 * r0 + h8 * (5 * r9) + h9 * (5 * r8);\n        c += d7 >>> 13;\n        d7 &= 0x1fff;\n        let d8 = c + h0 * r8 + h1 * r7 + h2 * r6 + h3 * r5 + h4 * r4;\n        c = d8 >>> 13;\n        d8 &= 0x1fff;\n        d8 += h5 * r3 + h6 * r2 + h7 * r1 + h8 * r0 + h9 * (5 * r9);\n        c += d8 >>> 13;\n        d8 &= 0x1fff;\n        let d9 = c + h0 * r9 + h1 * r8 + h2 * r7 + h3 * r6 + h4 * r5;\n        c = d9 >>> 13;\n        d9 &= 0x1fff;\n        d9 += h5 * r4 + h6 * r3 + h7 * r2 + h8 * r1 + h9 * r0;\n        c += d9 >>> 13;\n        d9 &= 0x1fff;\n        c = ((c << 2) + c) | 0;\n        c = (c + d0) | 0;\n        d0 = c & 0x1fff;\n        c = c >>> 13;\n        d1 += c;\n        h[0] = d0;\n        h[1] = d1;\n        h[2] = d2;\n        h[3] = d3;\n        h[4] = d4;\n        h[5] = d5;\n        h[6] = d6;\n        h[7] = d7;\n        h[8] = d8;\n        h[9] = d9;\n    }\n    finalize() {\n        const { h, pad } = this;\n        const g = new Uint16Array(10);\n        let c = h[1] >>> 13;\n        h[1] &= 0x1fff;\n        for (let i = 2; i < 10; i++) {\n            h[i] += c;\n            c = h[i] >>> 13;\n            h[i] &= 0x1fff;\n        }\n        h[0] += c * 5;\n        c = h[0] >>> 13;\n        h[0] &= 0x1fff;\n        h[1] += c;\n        c = h[1] >>> 13;\n        h[1] &= 0x1fff;\n        h[2] += c;\n        g[0] = h[0] + 5;\n        c = g[0] >>> 13;\n        g[0] &= 0x1fff;\n        for (let i = 1; i < 10; i++) {\n            g[i] = h[i] + c;\n            c = g[i] >>> 13;\n            g[i] &= 0x1fff;\n        }\n        g[9] -= 1 << 13;\n        let mask = (c ^ 1) - 1;\n        for (let i = 0; i < 10; i++)\n            g[i] &= mask;\n        mask = ~mask;\n        for (let i = 0; i < 10; i++)\n            h[i] = (h[i] & mask) | g[i];\n        h[0] = (h[0] | (h[1] << 13)) & 0xffff;\n        h[1] = ((h[1] >>> 3) | (h[2] << 10)) & 0xffff;\n        h[2] = ((h[2] >>> 6) | (h[3] << 7)) & 0xffff;\n        h[3] = ((h[3] >>> 9) | (h[4] << 4)) & 0xffff;\n        h[4] = ((h[4] >>> 12) | (h[5] << 1) | (h[6] << 14)) & 0xffff;\n        h[5] = ((h[6] >>> 2) | (h[7] << 11)) & 0xffff;\n        h[6] = ((h[7] >>> 5) | (h[8] << 8)) & 0xffff;\n        h[7] = ((h[8] >>> 8) | (h[9] << 5)) & 0xffff;\n        let f = h[0] + pad[0];\n        h[0] = f & 0xffff;\n        for (let i = 1; i < 8; i++) {\n            f = (((h[i] + pad[i]) | 0) + (f >>> 16)) | 0;\n            h[i] = f & 0xffff;\n        }\n        clean(g);\n    }\n    update(data) {\n        aexists(this);\n        abytes(data);\n        data = copyBytes(data);\n        const { buffer, blockLen } = this;\n        const len = data.length;\n        for (let pos = 0; pos < len;) {\n            const take = Math.min(blockLen - this.pos, len - pos);\n            // Fast path: we have at least one block in input\n            if (take === blockLen) {\n                for (; blockLen <= len - pos; pos += blockLen)\n                    this.process(data, pos);\n                continue;\n            }\n            buffer.set(data.subarray(pos, pos + take), this.pos);\n            this.pos += take;\n            pos += take;\n            if (this.pos === blockLen) {\n                this.process(buffer, 0, false);\n                this.pos = 0;\n            }\n        }\n        return this;\n    }\n    destroy() {\n        clean(this.h, this.r, this.buffer, this.pad);\n    }\n    digestInto(out) {\n        aexists(this);\n        aoutput(out, this);\n        this.finished = true;\n        const { buffer, h } = this;\n        let { pos } = this;\n        if (pos) {\n            buffer[pos++] = 1;\n            for (; pos < 16; pos++)\n                buffer[pos] = 0;\n            this.process(buffer, 0, true);\n        }\n        this.finalize();\n        let opos = 0;\n        for (let i = 0; i < 8; i++) {\n            out[opos++] = h[i] >>> 0;\n            out[opos++] = h[i] >>> 8;\n        }\n        return out;\n    }\n    digest() {\n        const { buffer, outputLen } = this;\n        this.digestInto(buffer);\n        const res = buffer.slice(0, outputLen);\n        this.destroy();\n        return res;\n    }\n}\nexport function wrapConstructorWithKey(hashCons) {\n    const hashC = (msg, key) => hashCons(key).update(msg).digest();\n    const tmp = hashCons(new Uint8Array(32)); // tmp array, used just once below\n    hashC.outputLen = tmp.outputLen;\n    hashC.blockLen = tmp.blockLen;\n    hashC.create = (key) => hashCons(key);\n    return hashC;\n}\n/** Poly1305 MAC from RFC 8439. */\nexport const poly1305 = \n/** @__PURE__ */ (() => wrapConstructorWithKey((key) => new Poly1305(key)))();\n","/**\n * This file is based on noble-ciphers (https://github.com/paulmillr/noble-ciphers).\n *\n * noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com)\n *\n * The original file is located at:\n * https://github.com/paulmillr/noble-ciphers/blob/749cdf9cd07ebdd19e9b957d0f172f1045179695/src/chacha.ts\n */\n/**\n * ChaCha stream cipher, released\n * in 2008. Developed after Salsa20, ChaCha aims to increase diffusion per round.\n * It was standardized in [RFC 8439](https://www.rfc-editor.org/rfc/rfc8439) and\n * is now used in TLS 1.3.\n *\n * [XChaCha20](https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha)\n * extended-nonce variant is also provided. Similar to XSalsa, it's safe to use with\n * randomly-generated nonces.\n *\n * Check out [PDF](http://cr.yp.to/chacha/chacha-20080128.pdf) and\n * [wiki](https://en.wikipedia.org/wiki/Salsa20) and\n * [website](https://cr.yp.to/chacha.html).\n *\n * @module\n */\nimport { createCipher, rotl } from \"./_arx.js\";\nimport { poly1305 } from \"./_poly1305.js\";\nimport { abytes, clean, equalBytes, getOutput, u64Lengths, wrapCipher, } from \"./utils.js\";\n/**\n * ChaCha core function. It is implemented twice:\n * 1. Simple loop (chachaCore_small, hchacha_small)\n * 2. Unrolled loop (chachaCore, hchacha) - 4x faster, but larger & harder to read\n * The specific implementation is selected in `createCipher` below.\n */\nfunction chachaCore(s, k, n, out, cnt, rounds = 20) {\n    const y00 = s[0], y01 = s[1], y02 = s[2], y03 = s[3], // \"expa\"   \"nd 3\"  \"2-by\"  \"te k\"\n    y04 = k[0], y05 = k[1], y06 = k[2], y07 = k[3], // Key      Key     Key     Key\n    y08 = k[4], y09 = k[5], y10 = k[6], y11 = k[7], // Key      Key     Key     Key\n    y12 = cnt, y13 = n[0], y14 = n[1], y15 = n[2]; // Counter  Counter\tNonce   Nonce\n    // Save state to temporary variables\n    let x00 = y00, x01 = y01, x02 = y02, x03 = y03, x04 = y04, x05 = y05, x06 = y06, x07 = y07, x08 = y08, x09 = y09, x10 = y10, x11 = y11, x12 = y12, x13 = y13, x14 = y14, x15 = y15;\n    for (let r = 0; r < rounds; r += 2) {\n        x00 = (x00 + x04) | 0;\n        x12 = rotl(x12 ^ x00, 16);\n        x08 = (x08 + x12) | 0;\n        x04 = rotl(x04 ^ x08, 12);\n        x00 = (x00 + x04) | 0;\n        x12 = rotl(x12 ^ x00, 8);\n        x08 = (x08 + x12) | 0;\n        x04 = rotl(x04 ^ x08, 7);\n        x01 = (x01 + x05) | 0;\n        x13 = rotl(x13 ^ x01, 16);\n        x09 = (x09 + x13) | 0;\n        x05 = rotl(x05 ^ x09, 12);\n        x01 = (x01 + x05) | 0;\n        x13 = rotl(x13 ^ x01, 8);\n        x09 = (x09 + x13) | 0;\n        x05 = rotl(x05 ^ x09, 7);\n        x02 = (x02 + x06) | 0;\n        x14 = rotl(x14 ^ x02, 16);\n        x10 = (x10 + x14) | 0;\n        x06 = rotl(x06 ^ x10, 12);\n        x02 = (x02 + x06) | 0;\n        x14 = rotl(x14 ^ x02, 8);\n        x10 = (x10 + x14) | 0;\n        x06 = rotl(x06 ^ x10, 7);\n        x03 = (x03 + x07) | 0;\n        x15 = rotl(x15 ^ x03, 16);\n        x11 = (x11 + x15) | 0;\n        x07 = rotl(x07 ^ x11, 12);\n        x03 = (x03 + x07) | 0;\n        x15 = rotl(x15 ^ x03, 8);\n        x11 = (x11 + x15) | 0;\n        x07 = rotl(x07 ^ x11, 7);\n        x00 = (x00 + x05) | 0;\n        x15 = rotl(x15 ^ x00, 16);\n        x10 = (x10 + x15) | 0;\n        x05 = rotl(x05 ^ x10, 12);\n        x00 = (x00 + x05) | 0;\n        x15 = rotl(x15 ^ x00, 8);\n        x10 = (x10 + x15) | 0;\n        x05 = rotl(x05 ^ x10, 7);\n        x01 = (x01 + x06) | 0;\n        x12 = rotl(x12 ^ x01, 16);\n        x11 = (x11 + x12) | 0;\n        x06 = rotl(x06 ^ x11, 12);\n        x01 = (x01 + x06) | 0;\n        x12 = rotl(x12 ^ x01, 8);\n        x11 = (x11 + x12) | 0;\n        x06 = rotl(x06 ^ x11, 7);\n        x02 = (x02 + x07) | 0;\n        x13 = rotl(x13 ^ x02, 16);\n        x08 = (x08 + x13) | 0;\n        x07 = rotl(x07 ^ x08, 12);\n        x02 = (x02 + x07) | 0;\n        x13 = rotl(x13 ^ x02, 8);\n        x08 = (x08 + x13) | 0;\n        x07 = rotl(x07 ^ x08, 7);\n        x03 = (x03 + x04) | 0;\n        x14 = rotl(x14 ^ x03, 16);\n        x09 = (x09 + x14) | 0;\n        x04 = rotl(x04 ^ x09, 12);\n        x03 = (x03 + x04) | 0;\n        x14 = rotl(x14 ^ x03, 8);\n        x09 = (x09 + x14) | 0;\n        x04 = rotl(x04 ^ x09, 7);\n    }\n    // Write output\n    let oi = 0;\n    out[oi++] = (y00 + x00) | 0;\n    out[oi++] = (y01 + x01) | 0;\n    out[oi++] = (y02 + x02) | 0;\n    out[oi++] = (y03 + x03) | 0;\n    out[oi++] = (y04 + x04) | 0;\n    out[oi++] = (y05 + x05) | 0;\n    out[oi++] = (y06 + x06) | 0;\n    out[oi++] = (y07 + x07) | 0;\n    out[oi++] = (y08 + x08) | 0;\n    out[oi++] = (y09 + x09) | 0;\n    out[oi++] = (y10 + x10) | 0;\n    out[oi++] = (y11 + x11) | 0;\n    out[oi++] = (y12 + x12) | 0;\n    out[oi++] = (y13 + x13) | 0;\n    out[oi++] = (y14 + x14) | 0;\n    out[oi++] = (y15 + x15) | 0;\n}\n/**\n * ChaCha stream cipher. Conforms to RFC 8439 (IETF, TLS). 12-byte nonce, 4-byte counter.\n * With smaller nonce, it's not safe to make it random (CSPRNG), due to collision chance.\n */\nexport const chacha20 = /* @__PURE__ */ createCipher(chachaCore, {\n    counterRight: false,\n    counterLength: 4,\n    allowShortKeys: false,\n});\nconst ZEROS16 = /* @__PURE__ */ new Uint8Array(16);\n// Pad to digest size with zeros\nconst updatePadded = (h, msg) => {\n    h.update(msg);\n    const leftover = msg.length % 16;\n    if (leftover)\n        h.update(ZEROS16.subarray(leftover));\n};\nconst ZEROS32 = /* @__PURE__ */ new Uint8Array(32);\nfunction computeTag(fn, key, nonce, ciphertext, AAD) {\n    if (AAD !== undefined)\n        abytes(AAD, undefined, \"AAD\");\n    const authKey = fn(key, nonce, ZEROS32);\n    const lengths = u64Lengths(ciphertext.length, AAD ? AAD.length : 0, true);\n    // Methods below can be replaced with\n    // return poly1305_computeTag_small(authKey, lengths, ciphertext, AAD)\n    const h = poly1305.create(authKey);\n    if (AAD)\n        updatePadded(h, AAD);\n    updatePadded(h, ciphertext);\n    h.update(lengths);\n    const res = h.digest();\n    clean(authKey, lengths);\n    return res;\n}\n/**\n * AEAD algorithm from RFC 8439.\n * Salsa20 and chacha (RFC 8439) use poly1305 differently.\n * We could have composed them, but it's hard because of authKey:\n * In salsa20, authKey changes position in salsa stream.\n * In chacha, authKey can't be computed inside computeTag, it modifies the counter.\n */\nexport const _poly1305_aead = (xorStream) => (key, nonce, AAD) => {\n    const tagLength = 16;\n    return {\n        encrypt(plaintext, output) {\n            const plength = plaintext.length;\n            output = getOutput(plength + tagLength, output, false);\n            output.set(plaintext);\n            const oPlain = output.subarray(0, -tagLength);\n            // Actual encryption\n            xorStream(key, nonce, oPlain, oPlain, 1);\n            const tag = computeTag(xorStream, key, nonce, oPlain, AAD);\n            output.set(tag, plength); // append tag\n            clean(tag);\n            return output;\n        },\n        decrypt(ciphertext, output) {\n            output = getOutput(ciphertext.length - tagLength, output, false);\n            const data = ciphertext.subarray(0, -tagLength);\n            const passedTag = ciphertext.subarray(-tagLength);\n            const tag = computeTag(xorStream, key, nonce, data, AAD);\n            if (!equalBytes(passedTag, tag))\n                throw new Error(\"invalid tag\");\n            output.set(ciphertext.subarray(0, -tagLength));\n            // Actual decryption\n            xorStream(key, nonce, output, output, 1); // start stream with i=1\n            clean(tag);\n            return output;\n        },\n    };\n};\n/**\n * ChaCha20-Poly1305 from RFC 8439.\n *\n * Unsafe to use random nonces under the same key, due to collision chance.\n * Prefer XChaCha instead.\n */\nexport const chacha20poly1305 = /* @__PURE__ */ wrapCipher({ blockSize: 64, nonceLength: 12, tagLength: 16 }, _poly1305_aead(chacha20));\n","import { ExportError, INPUT_LENGTH_LIMIT, InvalidParamError, toArrayBuffer, } from \"@hpke/common\";\nimport { emitNotSupported } from \"./utils/emitNotSupported.js\";\n// b\"sec\"\nconst LABEL_SEC = new Uint8Array([115, 101, 99]);\nexport class ExporterContextImpl {\n    constructor(api, kdf, exporterSecret) {\n        Object.defineProperty(this, \"_api\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"exporterSecret\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_kdf\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this._api = api;\n        this._kdf = kdf;\n        this.exporterSecret = exporterSecret;\n    }\n    async seal(_data, _aad) {\n        return await emitNotSupported();\n    }\n    async open(_data, _aad) {\n        return await emitNotSupported();\n    }\n    async export(exporterContext, len) {\n        const rawExporterContext = toArrayBuffer(exporterContext);\n        if (rawExporterContext.byteLength > INPUT_LENGTH_LIMIT) {\n            throw new InvalidParamError(\"Too long exporter context\");\n        }\n        try {\n            return await this._kdf.labeledExpand(this.exporterSecret, LABEL_SEC, new Uint8Array(rawExporterContext), len);\n        }\n        catch (e) {\n            throw new ExportError(e);\n        }\n    }\n}\nexport class RecipientExporterContextImpl extends ExporterContextImpl {\n}\nexport class SenderExporterContextImpl extends ExporterContextImpl {\n    constructor(api, kdf, exporterSecret, enc) {\n        super(api, kdf, exporterSecret);\n        Object.defineProperty(this, \"enc\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this.enc = enc;\n        return;\n    }\n}\n","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n};\nvar _Mutex_locked;\nexport class Mutex {\n    constructor() {\n        _Mutex_locked.set(this, Promise.resolve());\n    }\n    async lock() {\n        let releaseLock;\n        const nextLock = new Promise((resolve) => {\n            releaseLock = resolve;\n        });\n        const previousLock = __classPrivateFieldGet(this, _Mutex_locked, \"f\");\n        __classPrivateFieldSet(this, _Mutex_locked, nextLock, \"f\");\n        await previousLock;\n        return releaseLock;\n    }\n}\n_Mutex_locked = new WeakMap();\n","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n};\nvar _RecipientContextImpl_mutex;\nimport { EMPTY, OpenError, toArrayBuffer } from \"@hpke/common\";\nimport { EncryptionContextImpl } from \"./encryptionContext.js\";\nimport { Mutex } from \"./mutex.js\";\nexport class RecipientContextImpl extends EncryptionContextImpl {\n    constructor() {\n        super(...arguments);\n        _RecipientContextImpl_mutex.set(this, void 0);\n    }\n    async open(data, aad = EMPTY.buffer) {\n        __classPrivateFieldSet(this, _RecipientContextImpl_mutex, __classPrivateFieldGet(this, _RecipientContextImpl_mutex, \"f\") ?? new Mutex(), \"f\");\n        const release = await __classPrivateFieldGet(this, _RecipientContextImpl_mutex, \"f\").lock();\n        let pt;\n        try {\n            pt = await this._ctx.key.open(this.computeNonce(this._ctx), toArrayBuffer(data), toArrayBuffer(aad));\n        }\n        catch (e) {\n            throw new OpenError(e);\n        }\n        finally {\n            release();\n        }\n        this.incrementSeq(this._ctx);\n        return pt;\n    }\n}\n_RecipientContextImpl_mutex = new WeakMap();\n","var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\n    return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\n};\nvar __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {\n    if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\n    if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\n    if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\n    return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\n};\nvar _SenderContextImpl_mutex;\nimport { EMPTY, SealError, toArrayBuffer } from \"@hpke/common\";\nimport { EncryptionContextImpl } from \"./encryptionContext.js\";\nimport { Mutex } from \"./mutex.js\";\nexport class SenderContextImpl extends EncryptionContextImpl {\n    constructor(api, kdf, params, enc) {\n        super(api, kdf, params);\n        Object.defineProperty(this, \"enc\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        _SenderContextImpl_mutex.set(this, void 0);\n        this.enc = enc;\n    }\n    async seal(data, aad = EMPTY.buffer) {\n        __classPrivateFieldSet(this, _SenderContextImpl_mutex, __classPrivateFieldGet(this, _SenderContextImpl_mutex, \"f\") ?? new Mutex(), \"f\");\n        const release = await __classPrivateFieldGet(this, _SenderContextImpl_mutex, \"f\").lock();\n        let ct;\n        try {\n            ct = await this._ctx.key.seal(this.computeNonce(this._ctx), toArrayBuffer(data), toArrayBuffer(aad));\n        }\n        catch (e) {\n            throw new SealError(e);\n        }\n        finally {\n            release();\n        }\n        this.incrementSeq(this._ctx);\n        return ct;\n    }\n}\n_SenderContextImpl_mutex = new WeakMap();\n","import { AeadId, EMPTY, i2Osp, INFO_LENGTH_LIMIT, INPUT_LENGTH_LIMIT, InvalidParamError, MINIMUM_PSK_LENGTH, Mode, NativeAlgorithm, toUint8Array, } from \"@hpke/common\";\nimport { RecipientExporterContextImpl, SenderExporterContextImpl, } from \"./exporterContext.js\";\nimport { RecipientContextImpl } from \"./recipientContext.js\";\nimport { SenderContextImpl } from \"./senderContext.js\";\n// b\"base_nonce\"\n// deno-fmt-ignore\nconst LABEL_BASE_NONCE = new Uint8Array([\n    98, 97, 115, 101, 95, 110, 111, 110, 99, 101,\n]);\n// b\"exp\"\nconst LABEL_EXP = new Uint8Array([101, 120, 112]);\n// b\"info_hash\"\n// deno-fmt-ignore\nconst LABEL_INFO_HASH = new Uint8Array([\n    105, 110, 102, 111, 95, 104, 97, 115, 104,\n]);\n// b\"key\"\nconst LABEL_KEY = new Uint8Array([107, 101, 121]);\n// b\"psk_id_hash\"\n// deno-fmt-ignore\nconst LABEL_PSK_ID_HASH = new Uint8Array([\n    112, 115, 107, 95, 105, 100, 95, 104, 97, 115, 104,\n]);\n// b\"secret\"\nconst LABEL_SECRET = new Uint8Array([115, 101, 99, 114, 101, 116]);\n// b\"HPKE\"\n// deno-fmt-ignore\nconst SUITE_ID_HEADER_HPKE = new Uint8Array([\n    72, 80, 75, 69, 0, 0, 0, 0, 0, 0,\n]);\n/**\n * The Hybrid Public Key Encryption (HPKE) ciphersuite,\n * which is implemented using only\n * {@link https://www.w3.org/TR/WebCryptoAPI/ | Web Cryptography API}.\n *\n * This is the super class of {@link CipherSuite} and the same as\n * {@link https://jsr.io/@hpke/core/doc/~/CipherSuite | @hpke/core#CipherSuite} as follows:\n * which supports only the ciphersuites that can be implemented on the native\n * {@link https://www.w3.org/TR/WebCryptoAPI/ | Web Cryptography API}.\n * Therefore, the following cryptographic algorithms are not supported for now:\n *   - DHKEM(X25519, HKDF-SHA256)\n *   - DHKEM(X448, HKDF-SHA512)\n *   - ChaCha20Poly1305\n *\n * In addtion, the HKDF functions contained in this class can only derive\n * keys of the same length as the `hashSize`.\n *\n * If you want to use the unsupported cryptographic algorithms\n * above or derive keys longer than the `hashSize`,\n * please use {@link CipherSuite}.\n *\n * This class provides following functions:\n *\n * - Creates encryption contexts both for senders and recipients.\n *   - {@link createSenderContext}\n *   - {@link createRecipientContext}\n * - Provides single-shot encryption API.\n *   - {@link seal}\n *   - {@link open}\n *\n * The calling of the constructor of this class is the starting\n * point for HPKE operations for both senders and recipients.\n *\n * @example Use only ciphersuites supported by Web Cryptography API.\n *\n * ```ts\n * import {\n *   Aes128Gcm,\n *   DhkemP256HkdfSha256,\n *   HkdfSha256,\n *   CipherSuite,\n * } from \"@hpke/core\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemP256HkdfSha256(),\n *   kdf: new HkdfSha256(),\n *   aead: new Aes128Gcm(),\n * });\n * ```\n *\n * @example Use a ciphersuite which is currently not supported by Web Cryptography API.\n *\n * ```ts\n * import { Aes128Gcm, HkdfSha256, CipherSuite } from \"@hpke/core\";\n * // Use an extension module.\n * import { DhkemX25519HkdfSha256 } from \"@hpke/dhkem-x25519\";\n *\n * const suite = new CipherSuite({\n *   kem: new DhkemX25519HkdfSha256(),\n *   kdf: new HkdfSha256(),\n *   aead: new Aes128Gcm(),\n * });\n * ```\n */\nexport class CipherSuiteNative extends NativeAlgorithm {\n    /**\n     * @param params A set of parameters for building a cipher suite.\n     *\n     * If the error occurred, throws {@link InvalidParamError}.\n     *\n     * @throws {@link InvalidParamError}\n     */\n    constructor(params) {\n        super();\n        Object.defineProperty(this, \"_kem\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_kdf\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_aead\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_suiteId\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        // KEM\n        if (typeof params.kem === \"number\") {\n            throw new InvalidParamError(\"KemId cannot be used\");\n        }\n        this._kem = params.kem;\n        // KDF\n        if (typeof params.kdf === \"number\") {\n            throw new InvalidParamError(\"KdfId cannot be used\");\n        }\n        this._kdf = params.kdf;\n        // AEAD\n        if (typeof params.aead === \"number\") {\n            throw new InvalidParamError(\"AeadId cannot be used\");\n        }\n        this._aead = params.aead;\n        this._suiteId = new Uint8Array(SUITE_ID_HEADER_HPKE);\n        this._suiteId.set(i2Osp(this._kem.id, 2), 4);\n        this._suiteId.set(i2Osp(this._kdf.id, 2), 6);\n        this._suiteId.set(i2Osp(this._aead.id, 2), 8);\n        this._kdf.init(this._suiteId);\n    }\n    /**\n     * Gets the KEM context of the ciphersuite.\n     */\n    get kem() {\n        return this._kem;\n    }\n    /**\n     * Gets the KDF context of the ciphersuite.\n     */\n    get kdf() {\n        return this._kdf;\n    }\n    /**\n     * Gets the AEAD context of the ciphersuite.\n     */\n    get aead() {\n        return this._aead;\n    }\n    /**\n     * Creates an encryption context for a sender.\n     *\n     * If the error occurred, throws {@link DecapError} | {@link ValidationError}.\n     *\n     * @param params A set of parameters for the sender encryption context.\n     * @returns A sender encryption context.\n     * @throws {@link EncapError}, {@link ValidationError}\n     */\n    async createSenderContext(params) {\n        this._validateInputLength(params);\n        await this._setup();\n        const dh = await this._kem.encap(params);\n        let mode;\n        if (params.psk !== undefined) {\n            mode = params.senderKey !== undefined ? Mode.AuthPsk : Mode.Psk;\n        }\n        else {\n            mode = params.senderKey !== undefined ? Mode.Auth : Mode.Base;\n        }\n        return await this._keyScheduleS(mode, dh.sharedSecret, dh.enc, params);\n    }\n    /**\n     * Creates an encryption context for a recipient.\n     *\n     * If the error occurred, throws {@link DecapError}\n     * | {@link DeserializeError} | {@link ValidationError}.\n     *\n     * @param params A set of parameters for the recipient encryption context.\n     * @returns A recipient encryption context.\n     * @throws {@link DecapError}, {@link DeserializeError}, {@link ValidationError}\n     */\n    async createRecipientContext(params) {\n        this._validateInputLength(params);\n        await this._setup();\n        const sharedSecret = await this._kem.decap(params);\n        let mode;\n        if (params.psk !== undefined) {\n            mode = params.senderPublicKey !== undefined ? Mode.AuthPsk : Mode.Psk;\n        }\n        else {\n            mode = params.senderPublicKey !== undefined ? Mode.Auth : Mode.Base;\n        }\n        return await this._keyScheduleR(mode, sharedSecret, params);\n    }\n    /**\n     * Encrypts a message to a recipient.\n     *\n     * If the error occurred, throws `EncapError` | `MessageLimitReachedError` | `SealError` | `ValidationError`.\n     *\n     * @param params A set of parameters for building a sender encryption context.\n     * @param pt A plain text as bytes to be encrypted.\n     * @param aad Additional authenticated data as bytes fed by an application.\n     * @returns A cipher text and an encapsulated key as bytes.\n     * @throws {@link EncapError}, {@link MessageLimitReachedError}, {@link SealError}, {@link ValidationError}\n     */\n    async seal(params, pt, aad = EMPTY.buffer) {\n        const ctx = await this.createSenderContext(params);\n        return {\n            ct: await ctx.seal(pt, aad),\n            enc: ctx.enc,\n        };\n    }\n    /**\n     * Decrypts a message from a sender.\n     *\n     * If the error occurred, throws `DecapError` | `DeserializeError` | `OpenError` | `ValidationError`.\n     *\n     * @param params A set of parameters for building a recipient encryption context.\n     * @param ct An encrypted text as bytes to be decrypted.\n     * @param aad Additional authenticated data as bytes fed by an application.\n     * @returns A decrypted plain text as bytes.\n     * @throws {@link DecapError}, {@link DeserializeError}, {@link OpenError}, {@link ValidationError}\n     */\n    async open(params, ct, aad = EMPTY.buffer) {\n        const ctx = await this.createRecipientContext(params);\n        return await ctx.open(ct, aad);\n    }\n    // private verifyPskInputs(mode: Mode, params: KeyScheduleParams) {\n    //   const gotPsk = (params.psk !== undefined);\n    //   const gotPskId = (params.psk !== undefined && params.psk.id.byteLength > 0);\n    //   if (gotPsk !== gotPskId) {\n    //     throw new Error('Inconsistent PSK inputs');\n    //   }\n    //   if (gotPsk && (mode === Mode.Base || mode === Mode.Auth)) {\n    //     throw new Error('PSK input provided when not needed');\n    //   }\n    //   if (!gotPsk && (mode === Mode.Psk || mode === Mode.AuthPsk)) {\n    //     throw new Error('Missing required PSK input');\n    //   }\n    //   return;\n    // }\n    async _keySchedule(mode, sharedSecret, params) {\n        // Currently, there is no point in executing this function\n        // because this hpke library does not allow users to explicitly specify the mode.\n        //\n        // this.verifyPskInputs(mode, params);\n        const pskId = params.psk === undefined\n            ? EMPTY\n            : toUint8Array(params.psk.id);\n        const pskIdHash = await this._kdf.labeledExtract(EMPTY, LABEL_PSK_ID_HASH, pskId);\n        const info = params.info === undefined ? EMPTY : toUint8Array(params.info);\n        const infoHash = await this._kdf.labeledExtract(EMPTY, LABEL_INFO_HASH, info);\n        const keyScheduleContext = new Uint8Array(1 + pskIdHash.byteLength + infoHash.byteLength);\n        keyScheduleContext.set(new Uint8Array([mode]), 0);\n        keyScheduleContext.set(new Uint8Array(pskIdHash), 1);\n        keyScheduleContext.set(new Uint8Array(infoHash), 1 + pskIdHash.byteLength);\n        const psk = params.psk === undefined ? EMPTY : toUint8Array(params.psk.key);\n        const ikm = this._kdf.buildLabeledIkm(LABEL_SECRET, psk);\n        const exporterSecretInfo = this._kdf.buildLabeledInfo(LABEL_EXP, keyScheduleContext, this._kdf.hashSize);\n        const exporterSecret = await this._kdf.extractAndExpand(sharedSecret, ikm, exporterSecretInfo, this._kdf.hashSize);\n        if (this._aead.id === AeadId.ExportOnly) {\n            return { aead: this._aead, exporterSecret: exporterSecret };\n        }\n        const keyInfo = this._kdf.buildLabeledInfo(LABEL_KEY, keyScheduleContext, this._aead.keySize);\n        const key = await this._kdf.extractAndExpand(sharedSecret, ikm, keyInfo, this._aead.keySize);\n        const baseNonceInfo = this._kdf.buildLabeledInfo(LABEL_BASE_NONCE, keyScheduleContext, this._aead.nonceSize);\n        const baseNonce = await this._kdf.extractAndExpand(sharedSecret, ikm, baseNonceInfo, this._aead.nonceSize);\n        return {\n            aead: this._aead,\n            exporterSecret: exporterSecret,\n            key: key,\n            baseNonce: new Uint8Array(baseNonce),\n            seq: 0,\n        };\n    }\n    async _keyScheduleS(mode, sharedSecret, enc, params) {\n        const res = await this._keySchedule(mode, sharedSecret, params);\n        if (res.key === undefined) {\n            return new SenderExporterContextImpl(this._api, this._kdf, res.exporterSecret, enc);\n        }\n        return new SenderContextImpl(this._api, this._kdf, res, enc);\n    }\n    async _keyScheduleR(mode, sharedSecret, params) {\n        const res = await this._keySchedule(mode, sharedSecret, params);\n        if (res.key === undefined) {\n            return new RecipientExporterContextImpl(this._api, this._kdf, res.exporterSecret);\n        }\n        return new RecipientContextImpl(this._api, this._kdf, res);\n    }\n    _validateInputLength(params) {\n        if (params.info !== undefined &&\n            params.info.byteLength > INFO_LENGTH_LIMIT) {\n            throw new InvalidParamError(\"Too long info\");\n        }\n        if (params.psk !== undefined) {\n            if (params.psk.key.byteLength < MINIMUM_PSK_LENGTH) {\n                throw new InvalidParamError(`PSK must have at least ${MINIMUM_PSK_LENGTH} bytes`);\n            }\n            if (params.psk.key.byteLength > INPUT_LENGTH_LIMIT) {\n                throw new InvalidParamError(\"Too long psk.key\");\n            }\n            if (params.psk.id.byteLength > INPUT_LENGTH_LIMIT) {\n                throw new InvalidParamError(\"Too long psk.id\");\n            }\n        }\n        return;\n    }\n}\n","import { base64UrlToBytes, DeriveKeyPairError, DeserializeError, EMPTY, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, NativeAlgorithm, NotSupportedError, SerializeError, toArrayBuffer, } from \"@hpke/common\";\nconst ALG_NAME = \"X25519\";\n// deno-fmt-ignore\nconst PKCS8_ALG_ID_X25519 = new Uint8Array([\n    0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,\n    0x03, 0x2b, 0x65, 0x6e, 0x04, 0x22, 0x04, 0x20,\n]);\nconst BASE_POINT_X25519 = /* @__PURE__ */ (() => {\n    const p = new Uint8Array(32);\n    p[0] = 9;\n    return p;\n})();\nexport class X25519 extends NativeAlgorithm {\n    constructor(hkdf) {\n        super();\n        Object.defineProperty(this, \"_hkdf\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_alg\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nPk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nSk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nDh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_pkcs8AlgId\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this._alg = { name: ALG_NAME };\n        this._hkdf = hkdf;\n        this._nPk = 32;\n        this._nSk = 32;\n        this._nDh = 32;\n        this._pkcs8AlgId = PKCS8_ALG_ID_X25519;\n    }\n    async serializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._api.exportKey(\"raw\", key);\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), true);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async serializePrivateKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            if (!(\"d\" in jwk)) {\n                throw new Error(\"Not private key\");\n            }\n            return base64UrlToBytes(jwk[\"d\"]).buffer;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePrivateKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), false);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async importKey(format, key, isPublic) {\n        await this._setup();\n        try {\n            if (format === \"raw\") {\n                return await this._importRawKey(key, isPublic);\n            }\n            // jwk\n            if (key instanceof ArrayBuffer) {\n                throw new Error(\"Invalid jwk key format\");\n            }\n            return await this._importJWK(key, isPublic);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async generateKeyPair() {\n        await this._setup();\n        try {\n            return await this._api.generateKey(ALG_NAME, true, KEM_USAGES);\n        }\n        catch (e) {\n            throw new NotSupportedError(e);\n        }\n    }\n    async deriveKeyPair(ikm) {\n        await this._setup();\n        try {\n            const rawIkm = toArrayBuffer(ikm);\n            const dkpPrk = await this._hkdf.labeledExtract(EMPTY, LABEL_DKP_PRK, new Uint8Array(rawIkm));\n            const rawSk = await this._hkdf.labeledExpand(dkpPrk, LABEL_SK, EMPTY, this._nSk);\n            const rawSkBytes = new Uint8Array(rawSk);\n            const sk = await this._deserializePkcs8Key(rawSkBytes);\n            rawSkBytes.fill(0);\n            return {\n                privateKey: sk,\n                publicKey: await this.derivePublicKey(sk),\n            };\n        }\n        catch (e) {\n            throw new DeriveKeyPairError(e);\n        }\n    }\n    async derivePublicKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            delete jwk[\"d\"];\n            delete jwk[\"key_ops\"];\n            return await this._api.importKey(\"jwk\", jwk, this._alg, true, []);\n        }\n        catch {\n            try {\n                // Firefox fails to export JWK from some imported X25519 private keys.\n                const bp = await this._api.importKey(\"raw\", BASE_POINT_X25519.buffer, this._alg, true, []);\n                const bits = await this._api.deriveBits({\n                    name: ALG_NAME,\n                    public: bp,\n                }, key, this._nPk * 8);\n                return await this._api.importKey(\"raw\", bits, this._alg, true, []);\n            }\n            catch (e) {\n                throw new DeserializeError(e);\n            }\n        }\n    }\n    async dh(sk, pk) {\n        await this._setup();\n        try {\n            const bits = await this._api.deriveBits({\n                name: ALG_NAME,\n                public: pk,\n            }, sk, this._nDh * 8);\n            return bits;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async _importRawKey(key, isPublic) {\n        if (isPublic && key.byteLength !== this._nPk) {\n            throw new Error(\"Invalid public key for the ciphersuite\");\n        }\n        if (!isPublic && key.byteLength !== this._nSk) {\n            throw new Error(\"Invalid private key for the ciphersuite\");\n        }\n        if (isPublic) {\n            return await this._api.importKey(\"raw\", key, this._alg, true, []);\n        }\n        return await this._deserializePkcs8Key(new Uint8Array(key));\n    }\n    async _importJWK(key, isPublic) {\n        if (typeof key.kty === \"undefined\" || key.kty !== \"OKP\") {\n            throw new Error(`Invalid kty: ${key.crv}`);\n        }\n        if (typeof key.crv === \"undefined\" || key.crv !== ALG_NAME) {\n            throw new Error(`Invalid crv: ${key.crv}`);\n        }\n        if (isPublic) {\n            if (typeof key.d !== \"undefined\") {\n                throw new Error(\"Invalid key: `d` should not be set\");\n            }\n            return await this._api.importKey(\"jwk\", key, this._alg, true, []);\n        }\n        if (typeof key.d === \"undefined\") {\n            throw new Error(\"Invalid key: `d` not found\");\n        }\n        return await this._api.importKey(\"jwk\", key, this._alg, true, KEM_USAGES);\n    }\n    async _deserializePkcs8Key(k) {\n        const pkcs8Key = new Uint8Array(this._pkcs8AlgId.length + k.length);\n        pkcs8Key.set(this._pkcs8AlgId, 0);\n        pkcs8Key.set(k, this._pkcs8AlgId.length);\n        return await this._api.importKey(\"pkcs8\", pkcs8Key, this._alg, true, KEM_USAGES);\n    }\n}\n","import { base64UrlToBytes, DeriveKeyPairError, DeserializeError, EMPTY, KEM_USAGES, LABEL_DKP_PRK, LABEL_SK, NativeAlgorithm, NotSupportedError, SerializeError, toArrayBuffer, } from \"@hpke/common\";\nconst ALG_NAME = \"X448\";\n// deno-fmt-ignore\nconst PKCS8_ALG_ID_X448 = new Uint8Array([\n    0x30, 0x46, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06,\n    0x03, 0x2b, 0x65, 0x6f, 0x04, 0x3a, 0x04, 0x38,\n]);\nconst BASE_POINT_X448 = /* @__PURE__ */ (() => {\n    const p = new Uint8Array(56);\n    p[0] = 5;\n    return p;\n})();\nexport class X448 extends NativeAlgorithm {\n    constructor(hkdf) {\n        super();\n        Object.defineProperty(this, \"_hkdf\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_alg\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nPk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nSk\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_nDh\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        Object.defineProperty(this, \"_pkcs8AlgId\", {\n            enumerable: true,\n            configurable: true,\n            writable: true,\n            value: void 0\n        });\n        this._alg = { name: ALG_NAME };\n        this._hkdf = hkdf;\n        this._nPk = 56;\n        this._nSk = 56;\n        this._nDh = 56;\n        this._pkcs8AlgId = PKCS8_ALG_ID_X448;\n    }\n    async serializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._api.exportKey(\"raw\", key);\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePublicKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), true);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async serializePrivateKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            if (!(\"d\" in jwk)) {\n                throw new Error(\"Not private key\");\n            }\n            return base64UrlToBytes(jwk[\"d\"]).buffer;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async deserializePrivateKey(key) {\n        await this._setup();\n        try {\n            return await this._importRawKey(toArrayBuffer(key), false);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async importKey(format, key, isPublic) {\n        await this._setup();\n        try {\n            if (format === \"raw\") {\n                return await this._importRawKey(key, isPublic);\n            }\n            // jwk\n            if (key instanceof ArrayBuffer) {\n                throw new Error(\"Invalid jwk key format\");\n            }\n            return await this._importJWK(key, isPublic);\n        }\n        catch (e) {\n            throw new DeserializeError(e);\n        }\n    }\n    async generateKeyPair() {\n        await this._setup();\n        try {\n            return await this._api.generateKey(ALG_NAME, true, KEM_USAGES);\n        }\n        catch (e) {\n            throw new NotSupportedError(e);\n        }\n    }\n    async deriveKeyPair(ikm) {\n        await this._setup();\n        try {\n            const rawIkm = toArrayBuffer(ikm);\n            const dkpPrk = await this._hkdf.labeledExtract(EMPTY, LABEL_DKP_PRK, new Uint8Array(rawIkm));\n            const rawSk = await this._hkdf.labeledExpand(dkpPrk, LABEL_SK, EMPTY, this._nSk);\n            const rawSkBytes = new Uint8Array(rawSk);\n            const sk = await this._deserializePkcs8Key(rawSkBytes);\n            rawSkBytes.fill(0);\n            return {\n                privateKey: sk,\n                publicKey: await this.derivePublicKey(sk),\n            };\n        }\n        catch (e) {\n            throw new DeriveKeyPairError(e);\n        }\n    }\n    async derivePublicKey(key) {\n        await this._setup();\n        try {\n            const jwk = await this._api.exportKey(\"jwk\", key);\n            delete jwk[\"d\"];\n            delete jwk[\"key_ops\"];\n            return await this._api.importKey(\"jwk\", jwk, this._alg, true, []);\n        }\n        catch {\n            try {\n                // Some runtimes cannot export JWK from imported X448 private keys.\n                const bp = await this._api.importKey(\"raw\", BASE_POINT_X448.buffer, this._alg, true, []);\n                const bits = await this._api.deriveBits({\n                    name: ALG_NAME,\n                    public: bp,\n                }, key, this._nPk * 8);\n                return await this._api.importKey(\"raw\", bits, this._alg, true, []);\n            }\n            catch (e) {\n                throw new DeserializeError(e);\n            }\n        }\n    }\n    async dh(sk, pk) {\n        await this._setup();\n        try {\n            const bits = await this._api.deriveBits({\n                name: ALG_NAME,\n                public: pk,\n            }, sk, this._nDh * 8);\n            return bits;\n        }\n        catch (e) {\n            throw new SerializeError(e);\n        }\n    }\n    async _importRawKey(key, isPublic) {\n        if (isPublic && key.byteLength !== this._nPk) {\n            throw new Error(\"Invalid public key for the ciphersuite\");\n        }\n        if (!isPublic && key.byteLength !== this._nSk) {\n            throw new Error(\"Invalid private key for the ciphersuite\");\n        }\n        if (isPublic) {\n            return await this._api.importKey(\"raw\", key, this._alg, true, []);\n        }\n        return await this._deserializePkcs8Key(new Uint8Array(key));\n    }\n    async _importJWK(key, isPublic) {\n        if (typeof key.kty === \"undefined\" || key.kty !== \"OKP\") {\n            throw new Error(`Invalid kty: ${key.crv}`);\n        }\n        if (typeof key.crv === \"undefined\" || key.crv !== ALG_NAME) {\n            throw new Error(`Invalid crv: ${key.crv}`);\n        }\n        if (isPublic) {\n            if (typeof key.d !== \"undefined\") {\n                throw new Error(\"Invalid key: `d` should not be set\");\n            }\n            return await this._api.importKey(\"jwk\", key, this._alg, true, []);\n        }\n        if (typeof key.d === \"undefined\") {\n            throw new Error(\"Invalid key: `d` not found\");\n        }\n        return await this._api.importKey(\"jwk\", key, this._alg, true, KEM_USAGES);\n    }\n    async _deserializePkcs8Key(k) {\n        const pkcs8Key = new Uint8Array(this._pkcs8AlgId.length + k.length);\n        pkcs8Key.set(this._pkcs8AlgId, 0);\n        pkcs8Key.set(k, this._pkcs8AlgId.length);\n        return await this._api.importKey(\"pkcs8\", pkcs8Key, this._alg, true, KEM_USAGES);\n    }\n}\n","import type { HttpClient } from './http.js';\nimport type { ProjectConfig } from './types.js';\n\nconst CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\nexport class ConfigFetcher {\n  protected readonly httpClient: HttpClient;\n  private cachedConfig: ProjectConfig | null = null;\n  private cacheTimestamp = 0;\n\n  constructor(httpClient: HttpClient) {\n    this.httpClient = httpClient;\n  }\n\n  async getConfig(): Promise<ProjectConfig | null> {\n    const now = Date.now();\n\n    if (this.cachedConfig && now - this.cacheTimestamp < CACHE_TTL_MS) {\n      return this.cachedConfig;\n    }\n\n    try {\n      const response = await this.httpClient.request<ProjectConfig>('GET', '/v1/config');\n\n      if (response.error || !response.data) {\n        return null;\n      }\n\n      this.cachedConfig = response.data;\n      this.cacheTimestamp = now;\n\n      return this.cachedConfig;\n    } catch {\n      return null;\n    }\n  }\n}\n","export class PalbaseError extends Error {\n  readonly code: string;\n  readonly status: number;\n  readonly details?: unknown;\n\n  constructor(code: string, message: string, status: number, details?: unknown) {\n    super(message);\n    this.name = 'PalbaseError';\n    this.code = code;\n    this.status = status;\n    this.details = details;\n  }\n}\n","export type Platform = 'browser' | 'node' | 'react-native' | 'deno' | 'bun';\n\ndeclare const Deno: unknown;\n\nexport function detectPlatform(): Platform {\n  if (typeof Deno !== 'undefined') {\n    return 'deno';\n  }\n\n  const runtime = globalThis as typeof globalThis & {\n    process?: { versions?: Record<string, string> };\n  };\n  if (runtime.process?.versions) {\n    if ('bun' in runtime.process.versions) {\n      return 'bun';\n    }\n    if ('node' in runtime.process.versions) {\n      return 'node';\n    }\n  }\n\n  if (typeof navigator !== 'undefined' && navigator.product === 'ReactNative') {\n    return 'react-native';\n  }\n\n  return 'browser';\n}\n\n/**\n * The platform word this SDK puts on the wire (`X-Platform`), which the server\n * reads to target flags and to label telemetry.\n *\n * It is NOT `detectPlatform()`'s value verbatim: that reports the JS host\n * (\"browser\"), while the wire wants the platform. iOS sends \"ios\", not the name\n * of its runtime, and a condition author writes `client.platform == 'web'` —\n * the word every other flag vendor uses too. Server hosts keep their own names,\n * where the distinction is the useful part.\n */\nexport function wirePlatform(): string {\n  const host = detectPlatform();\n  return host === 'browser' ? 'web' : host;\n}\n","// Proof-of-work: the bot gate in front of /auth/signup and /auth/login.\n//\n// The server answers an unsolved request with 403 and a challenge in the body:\n//\n//   { \"error\": \"pow_required\", \"challenge\": { \"id\", \"prefix\", \"difficulty\" } }\n//\n// A client finds any nonce whose SHA-256(prefix + nonce) begins with\n// `difficulty` zero bits, then repeats the request carrying the id and nonce as\n// headers. The work is the point: a person signing up pays it once and does not\n// notice, a script signing up ten thousand times pays it ten thousand times.\n//\n// # Why this lives in core, and not one layer up\n//\n// Until 2026-08-14 nothing shipped could solve it: the gate was written with the\n// server and its own integration harness, and every real client sent requests\n// without the headers and got 403. It was then solved in @palbase/web's own\n// request path — which covers `pb.call` and the module facades and NOT\n// `pb.auth.*`, because those go through @palbase/auth's client and from there\n// into core's HttpClient. So the fix landed everywhere except the two endpoints\n// the gate actually guards, and `npm i @palbase/web` still could not sign a\n// person in. Measured 2026-08-18 against a real stack, on the published 7.3.0.\n//\n// The lesson is where a retry belongs: at the layer that ISSUES the request.\n// Core owns fetch for every client in this repo, so core owns the challenge.\n//\n// WebCrypto rather than a hashing dependency: `crypto.subtle` is present in\n// browsers and in Node 18+, which is the same floor the rest of the SDK sets.\n// Measured at the server's default difficulty of 16: ~330ms, ~65k digests.\n\n/** The challenge a `pow_required` response carries. */\nexport interface PowChallenge {\n  id: string;\n  prefix: string;\n  difficulty: number;\n}\n\n/** Header names the retry must carry. Mirrors the server's constants. */\nexport const POW_CHALLENGE_ID_HEADER = 'X-PoW-Challenge-ID';\nexport const POW_NONCE_HEADER = 'X-PoW-Nonce';\n\n/**\n * Reads a challenge out of an error envelope, or returns null when the envelope\n * is not a `pow_required` one.\n *\n * The whole wire envelope is stored on the error, so the challenge arrives\n * without the HTTP layer having to know about proof-of-work at all.\n */\nexport function asPowChallenge(details: unknown): PowChallenge | null {\n  if (typeof details !== 'object' || details === null) return null;\n  const env = details as Record<string, unknown>;\n  if (env.error !== 'pow_required') return null;\n  const c = env.challenge;\n  if (typeof c !== 'object' || c === null) return null;\n  const { id, prefix, difficulty } = c as Record<string, unknown>;\n  if (typeof id !== 'string' || typeof prefix !== 'string') return null;\n  if (typeof difficulty !== 'number' || !Number.isInteger(difficulty) || difficulty < 0)\n    return null;\n  return { id, prefix, difficulty };\n}\n\nconst encoder = new TextEncoder();\n\n/**\n * One SHA-256, by the fastest route this runtime offers.\n *\n * Awaiting `crypto.subtle.digest` once per nonce is what made this expensive,\n * and the cost is the await rather than the hashing. Measured on one machine,\n * 200k digests of a 40-byte input:\n *\n *\tawaited crypto.subtle.digest     105,597 digests/s\n *\tsync node:crypto createHash    1,324,503 digests/s   — 12.5x\n *\n * That is the difference between difficulty 24 taking 159 seconds and taking\n * 13. Node, Bun and Deno all have the sync one; a browser has only WebCrypto,\n * and there it stays async.\n *\n * The specifier is assembled at runtime so a browser bundler does not try to\n * resolve `node:crypto` and fail the build over a branch that never runs there.\n */\ntype Hasher = (input: string) => Uint8Array | Promise<Uint8Array>;\n\nlet hasher: Hasher | null = null;\n\nasync function digester(): Promise<Hasher> {\n  if (hasher) return hasher;\n  // Read off globalThis with an inline shape rather than by naming `process`,\n  // which needs @types/node — a dependency this package does not have and should\n  // not grow for one branch. It typechecked locally only because those types\n  // were hoisted into node_modules by a sibling package; the publish workflow's\n  // clean checkout is what said so, which is exactly what it is for.\n  const runtime = globalThis as {\n    process?: { versions?: { node?: string; bun?: string } };\n  };\n  const nodeish =\n    runtime.process?.versions?.node !== undefined || runtime.process?.versions?.bun !== undefined;\n  if (nodeish) {\n    try {\n      const mod = (await import(/* @vite-ignore */ `${'node:'}crypto`)) as {\n        createHash?: (alg: string) => { update(s: string): { digest(): Uint8Array } };\n      };\n      if (typeof mod.createHash === 'function') {\n        const createHash = mod.createHash;\n        hasher = (input: string) => new Uint8Array(createHash('sha256').update(input).digest());\n        return hasher;\n      }\n    } catch {\n      // No node:crypto here. WebCrypto below is not a fallback in the apologetic\n      // sense — it is the only hash a browser has, and it is correct.\n    }\n  }\n  hasher = async (input: string) =>\n    new Uint8Array(await crypto.subtle.digest('SHA-256', encoder.encode(input)));\n  return hasher;\n}\n\n/** Monotonic where it exists, wall-clock where it does not. */\nconst now = (): number =>\n  typeof performance !== 'undefined' && typeof performance.now === 'function'\n    ? performance.now()\n    : Date.now();\n\n/** Counts leading zero bits, stopping at the first byte that has a one. */\nfunction leadingZeroBits(hash: Uint8Array): number {\n  let bits = 0;\n  for (const byte of hash) {\n    if (byte === 0) {\n      bits += 8;\n      continue;\n    }\n    // clz32 counts across 32 bits; a byte occupies the low 8, so the first 24\n    // are always zero and get subtracted back off.\n    return bits + Math.clz32(byte) - 24;\n  }\n  return bits;\n}\n\n/**\n * The hardest challenge this client will attempt.\n *\n * Not a taste: it is the server's own ceiling. palauth maps a risk score to a\n * difficulty and its worst case is 24 (`DifficultyForRisk`, bot/pow.go:156-166).\n * Anything above that cannot have come from a stack behaving as designed, and\n * the cost of humouring it falls entirely on this side — each step up DOUBLES\n * the work, so difficulty 30 is sixty-four times a legitimate worst case and, on\n * the web, sixty-four times a frozen main thread. Refused immediately, by name.\n */\nexport const MAX_POW_DIFFICULTY = 24;\n\n/**\n * Finds a nonce satisfying the challenge and returns the headers a retry needs.\n *\n * THE BUDGET SCALES WITH THE CHALLENGE, and the first version of this did not.\n * It bounded the search at a flat `1 << 24` — which is not a generous bound for\n * difficulty 24, it is the EXPECTED number of attempts. Finding a nonce is a\n * geometric process: the chance of needing more than 2^d attempts is 1/e, so a\n * flat 2^24 would have failed roughly 37% of legitimate hardest-risk challenges,\n * and failed them for precisely the users the gate exists to slow down — who\n * would have been unable to sign in at all rather than made to wait.\n *\n * Eight times expected puts that at e^-8, about three in ten thousand, while\n * leaving the common case (the server's default 16, and 12 for an unremarkable\n * caller) exactly as cheap as it was.\n *\n * `powBudget` is exported and separate so the RELATIONSHIP can be asserted\n * directly. A test that only watches a cheap challenge succeed cannot tell this\n * budget from the flat one it replaced — measured: reinstating `1 << 24` left\n * such a test green.\n */\nexport function powBudget(difficulty: number): number {\n  return 8 * 2 ** difficulty;\n}\n\n/**\n * The longest a solve may be ALLOWED to take, and the difference from a\n * deadline is the whole point.\n *\n * The first version of this was a flat 120s deadline, and it was measured to be\n * worse than the flat iteration budget it was meant to backstop: at ~105k\n * digests/s, difficulty 24 EXPECTS 159 seconds, so a 120s clock killed the\n * majority of legitimate hardest-risk solves — reintroducing, larger, exactly\n * the class of defect that replacing `1 << 24` had removed. Guessing a number\n * for an unknown machine cannot work: the same difficulty is 13 seconds on a\n * runtime with a sync hasher and 159 on one without.\n *\n * So the machine is MEASURED, and the decision moves to the front. A short\n * calibration gives the rate this process actually hashes at; if the whole\n * iteration budget cannot fit in this window at that rate, the solve is refused\n * IMMEDIATELY, naming the numbers. A caller then learns in milliseconds that\n * this difficulty is unpayable here, instead of after two minutes of work\n * thrown away.\n *\n * What remains after that is a guarantee rather than a gamble: a solve that\n * starts can always finish inside its budget, so the only failure left is the\n * budget's own e^-8.\n */\nexport const POW_TIME_BUDGET_MS = 120_000;\n\n/**\n * The window the rate is measured over, and the warm-up it deliberately skips.\n *\n * All of these are REAL attempts — the search starts at nonce 0 and never\n * restarts — so calibration costs nothing but the reading. The first 1024 are\n * excluded from the timing because they include this loop's own JIT warm-up:\n * measured, timing from zero reported 747k digests/s on a machine whose steady\n * rate is 1.32M, and the decision below would have refused a difficulty this\n * machine can pay in half the allowance.\n */\nconst CALIBRATION_WARMUP = 1024;\nconst CALIBRATION_END = 9216;\n\nexport async function solvePowChallenge(\n  challenge: PowChallenge,\n  maxIterations = powBudget(challenge.difficulty),\n  // The caller's AbortSignal, honoured INSIDE the loop rather than only around\n  // the fetch it precedes — for the callers that have one. `pb.auth.signIn` does\n  // NOT: it reaches the network through @palbase/auth's client, which takes\n  // credentials and nothing else. So it is the extra a caller can opt into, and\n  // POW_TIME_BUDGET_MS below is what actually bounds the work.\n  signal?: AbortSignal,\n): Promise<Record<string, string>> {\n  if (challenge.difficulty > MAX_POW_DIFFICULTY) {\n    throw new Error(\n      `proof-of-work: refusing difficulty ${challenge.difficulty}; this client attempts at most ${MAX_POW_DIFFICULTY}, which is the highest a Palbase stack issues`,\n    );\n  }\n\n  const digest = await digester();\n  let warmedAt = 0;\n  let calibrated = false;\n  // Armed by the calibration below, never before it: until the rate is known\n  // there is no honest number to put here.\n  let deadline = Number.POSITIVE_INFINITY;\n\n  for (let nonce = 0; nonce < maxIterations; nonce++) {\n    // Checked in batches: reading them is cheap but not free, and a\n    // 1024-digest granularity bounds the delay at a few milliseconds.\n    if ((nonce & 1023) === 0) {\n      if (signal?.aborted) {\n        throw new DOMException('proof-of-work solve aborted', 'AbortError');\n      }\n      if (now() > deadline) {\n        throw new Error(\n          `proof-of-work: gave up on difficulty ${challenge.difficulty} after ${POW_TIME_BUDGET_MS / 1000}s ` +\n            `and ${nonce.toLocaleString()} attempts — the tail this run drew is longer than the allowance`,\n        );\n      }\n    }\n\n    // THE DECISION, TAKEN ONCE AND TAKEN EARLY.\n    //\n    // After CALIBRATION_DIGESTS real attempts the rate of THIS process is\n    // known, so the question \"can this machine pay this difficulty\" has an\n    // answer instead of an assumption. If the whole budget cannot fit in the\n    // time budget, refuse here — milliseconds in, with the numbers — rather\n    // than spend two minutes and throw them away. If it fits, everything after\n    // this point is guaranteed to finish inside the window, so the only\n    // remaining failure is the budget's own e^-8.\n    if (nonce === CALIBRATION_WARMUP) {\n      warmedAt = now();\n    }\n    if (!calibrated && nonce === CALIBRATION_END) {\n      calibrated = true;\n      const elapsed = Math.max(now() - warmedAt, 0.001);\n      const rate = (CALIBRATION_END - CALIBRATION_WARMUP) / (elapsed / 1000);\n      // EXPECTED, not worst case, and the difference is the whole judgement.\n      //\n      // Finding a nonce is geometric: 2^difficulty attempts on average, with a\n      // long tail the 8x budget covers. Refusing because the TAIL will not fit\n      // would turn away work whose expected cost is seventeen seconds — measured\n      // exactly that on this machine at difficulty 24. Refusing on the EXPECTED\n      // cost turns away only what is genuinely unpayable here, and what it lets\n      // through is then cut by the clock with probability e^-(budget/expected):\n      // at 120s against a 17s expectation that is one run in a thousand, and at\n      // difficulty 20 on a browser it is one in a hundred and fifty thousand.\n      const expectedMs = (2 ** challenge.difficulty / rate) * 1000;\n      if (expectedMs > POW_TIME_BUDGET_MS) {\n        throw new Error(\n          `proof-of-work: difficulty ${challenge.difficulty} needs about ${Math.round(expectedMs / 1000)}s here ` +\n            `(${Math.round(rate).toLocaleString()} digests/s) and this client allows ${POW_TIME_BUDGET_MS / 1000}s; ` +\n            `refusing before spending the time rather than after`,\n        );\n      }\n      deadline = now() + (POW_TIME_BUDGET_MS - (now() - warmedAt));\n    }\n\n    const hash = await digest(challenge.prefix + nonce);\n    if (leadingZeroBits(hash) >= challenge.difficulty) {\n      return {\n        [POW_CHALLENGE_ID_HEADER]: challenge.id,\n        [POW_NONCE_HEADER]: String(nonce),\n      };\n    }\n  }\n  throw new Error(\n    `proof-of-work: no nonce found for difficulty ${challenge.difficulty} within ${maxIterations} attempts`,\n  );\n}\n","import { Chacha20Poly1305 } from '@hpke/chacha20poly1305';\nimport { CipherSuite, HkdfSha256 } from '@hpke/core';\nimport { DhkemX25519HkdfSha256 } from '@hpke/dhkem-x25519';\nimport { PalbaseError } from './errors.js';\nimport { fromBase64, toBase64 } from './sealed-json.js';\nimport type { SealingKey } from './sealed-keys.js';\n\nexport const SEALED_CONTENT_TYPE = 'application/palbase-sealed+json';\nexport const SEALED_HEADER = 'X-Palbase-Sealed';\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder('utf-8', { fatal: true });\nconst responseLabel = 'palbase-sealed/response/v1';\n\nexport function sealingRequired(path: string): boolean {\n  // Mirrors v2/internal/server/sealed.go. Tenant/runtime routes cannot unseal.\n  return new URL(path, 'https://unused.invalid').pathname.startsWith('/auth/');\n}\n\nexport function requestAAD(\n  host: string,\n  method: string,\n  path: string,\n  ict: string,\n  ts: number,\n  idem: string,\n): Uint8Array<ArrayBuffer> {\n  const fields = [host, method, path, ict, idem].map((field) => encoder.encode(field));\n  const bytes = new Uint8Array(fields.reduce((size, field) => size + 4 + field.length, 8));\n  const view = new DataView(bytes.buffer);\n  let offset = 0;\n  for (const [index, field] of fields.entries()) {\n    if (index === 4) {\n      view.setBigUint64(offset, BigInt(ts));\n      offset += 8;\n    }\n    view.setUint32(offset, field.length);\n    offset += 4;\n    bytes.set(field, offset);\n    offset += field.length;\n  }\n  return bytes;\n}\n\nexport function sealingSuite(): CipherSuite {\n  return new CipherSuite({\n    kem: new DhkemX25519HkdfSha256(),\n    kdf: new HkdfSha256(),\n    aead: new Chacha20Poly1305(),\n  });\n}\n\nexport async function sealRequest(\n  key: SealingKey,\n  url: string,\n  init: RequestInit,\n): Promise<Uint8Array<ArrayBuffer>> {\n  const suite = sealingSuite();\n  const sender = await suite.createSenderContext({\n    recipientPublicKey: await suite.kem.importKey('raw', key.publicKey.buffer),\n  });\n  const headers = new Headers(init.headers);\n  const ict = headers.get('content-type') ?? 'application/json';\n  const ts = Math.floor(Date.now() / 1000);\n  const target = new URL(url);\n  const method = init.method ?? 'GET';\n  // Go binds r.URL.Path (decoded, without the query), not RequestURI.\n  const aad = requestAAD(\n    target.host,\n    method,\n    decodeURIComponent(target.pathname),\n    ict,\n    ts,\n    headers.get('idempotency-key') ?? '',\n  );\n  const ct = await sender.seal(encoder.encode(typeof init.body === 'string' ? init.body : ''), aad);\n  const envelope = JSON.stringify({\n    v: 2,\n    kid: key.kid,\n    enc: toBase64(new Uint8Array(sender.enc)),\n    ct: toBase64(new Uint8Array(ct)),\n    ict,\n    ts,\n  });\n  if (method === 'GET' || method === 'HEAD' || init.body === undefined) {\n    headers.set(\n      SEALED_HEADER,\n      toBase64(encoder.encode(envelope)).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, ''),\n    );\n    delete init.body;\n  } else {\n    headers.delete(SEALED_HEADER);\n    headers.set('Content-Type', SEALED_CONTENT_TYPE);\n    init.body = envelope;\n  }\n  headers.delete('Content-Length');\n  init.headers = Object.fromEntries(headers.entries());\n  // Do not redirect a credential-bearing envelope to a different endpoint.\n  init.redirect = 'error';\n  return new Uint8Array(await sender.export(encoder.encode(responseLabel), 32));\n}\n\nexport async function openSealedResponse(\n  response: Response,\n  exporter: Uint8Array | undefined,\n  method: string,\n): Promise<Response> {\n  if (\n    response.headers.get('content-type')?.split(';')[0]?.trim().toLowerCase() !==\n    SEALED_CONTENT_TYPE\n  ) {\n    // Edge/middleware errors are plaintext. A successful auth result cannot be.\n    if (exporter && response.ok && method !== 'HEAD') {\n      throw new PalbaseError(\n        'sealed_response_invalid',\n        'The server returned an unencrypted response.',\n        response.status,\n      );\n    }\n    return response;\n  }\n  // HTTP HEAD has no response body, including when the handler sealed it.\n  if (method === 'HEAD') return response;\n  try {\n    if (!exporter) throw new Error('No sealing context');\n    const envelope = (await response.json()) as {\n      v: number;\n      n: string;\n      ct: string;\n      ict: string;\n      st: number;\n    };\n    if (\n      envelope.v !== 2 ||\n      !Number.isInteger(envelope.st) ||\n      envelope.st < 200 ||\n      envelope.st > 599 ||\n      typeof envelope.ict !== 'string'\n    ) {\n      throw new Error('Invalid response envelope');\n    }\n    const plaintext = await new Chacha20Poly1305()\n      .createEncryptionContext(exporter)\n      .open(\n        fromBase64(envelope.n),\n        fromBase64(envelope.ct),\n        encoder.encode(`${responseLabel}\\n${envelope.ict}\\n${envelope.st}`),\n      );\n    const headers = new Headers(response.headers);\n    headers.set('Content-Type', envelope.ict);\n    headers.delete('Content-Length');\n    headers.delete('Content-Encoding');\n    // The outer status is always 200; auth failures and PoW live inside the seal.\n    return new Response([204, 205, 304].includes(envelope.st) ? null : decoder.decode(plaintext), {\n      status: envelope.st,\n      headers,\n    });\n  } catch {\n    throw new PalbaseError(\n      'sealed_response_invalid',\n      'The encrypted server response could not be verified.',\n      response.status,\n    );\n  }\n}\n","// Signatures cover the original JSON bytes, not JSON.stringify(JSON.parse(raw)).\n// Go's encoder preserves struct field order and escapes characters differently.\nexport function rawObjectFields(raw: string): Map<string, string> {\n  const parsed: unknown = JSON.parse(raw);\n  if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n    throw new Error('Expected a JSON object');\n  }\n  const fields = new Map<string, string>();\n  let i = 0;\n  const space = () => {\n    while (/\\s/.test(raw[i] ?? '') && i < raw.length) i++;\n  };\n  const stringEnd = (start: number) => {\n    let end = start + 1;\n    while (end < raw.length) {\n      if (raw[end] === '\\\\') end += 2;\n      else if (raw[end++] === '\"') return end;\n    }\n    throw new Error('Unterminated JSON string');\n  };\n  space();\n  i++; // opening object, already validated by JSON.parse\n  while (true) {\n    space();\n    if (raw[i] === '}') return fields;\n    const nameEnd = stringEnd(i);\n    const name = JSON.parse(raw.slice(i, nameEnd)) as string;\n    i = nameEnd;\n    space();\n    i++; // colon\n    space();\n    const start = i;\n    if (raw[i] === '\"') i = stringEnd(i);\n    else if (raw[i] === '{' || raw[i] === '[') {\n      let depth = 0;\n      do {\n        const c = raw[i];\n        if (c === '\"') {\n          i = stringEnd(i);\n          continue;\n        }\n        if (c === '{' || c === '[') depth++;\n        if (c === '}' || c === ']') depth--;\n        i++;\n      } while (depth > 0 && i < raw.length);\n    } else {\n      while (i < raw.length && !/[\\s,}]/.test(raw[i] ?? '')) i++;\n    }\n    // A first-match slice and JSON.parse's last-match value must never disagree.\n    if (fields.has(name)) throw new Error('Duplicate JSON field');\n    fields.set(name, raw.slice(start, i));\n    space();\n    if (raw[i] === ',') i++;\n  }\n}\n\nexport function fromBase64(value: string): Uint8Array<ArrayBuffer> {\n  return Uint8Array.from(atob(value), (c) => c.charCodeAt(0));\n}\n\nexport function toBase64(bytes: Uint8Array): string {\n  // Avoid a spread: envelopes can exceed the engine's argument-count limit.\n  let binary = '';\n  for (const byte of bytes) binary += String.fromCharCode(byte);\n  return btoa(binary);\n}\n","import { ed25519 } from '@noble/curves/ed25519.js';\nimport { PalbaseError } from './errors.js';\nimport { fromBase64, rawObjectFields } from './sealed-json.js';\nimport type { HttpClientOptions } from './types.js';\nimport { endpointUrl } from './url.js';\n\nexport const SEALED_KEYSET_PATH = '/palbase-sealed-keys.json';\nexport const SEALED_SUITE = 'DHKEM-X25519-HKDF-SHA256/HKDF-SHA256/ChaCha20Poly1305';\n// Fleet PUBLIC key, identical to the iOS SDK pin. Never learned from a response.\nconst FLEET_ROOT = 'mRDTIWzhW0JCk0e2Jvkn679VeZBB38zOOfPTMO6vBpU=';\nconst REFRESH_MS = 5 * 60_000;\nconst FAILURE_COOLDOWN_MS = 60_000;\nconst encoder = new TextEncoder();\n\nexport interface SealingKey {\n  kid: string;\n  publicKey: Uint8Array<ArrayBuffer>;\n  expires: number;\n  version: number;\n}\n\nexport function expectedSealedStack(baseUrl: string, apiKey: string): string {\n  // Fleet tenant hosts name the stack even when a legacy key says pb_project_.\n  // Apex/custom/self-host URLs instead need the key's ref (or an explicit pin).\n  const host = new URL(baseUrl).hostname;\n  return (\n    /^([a-z0-9]{4,24})\\.(?:(?:dev|staging)\\.)?palbase\\.studio$/.exec(host)?.[1] ??\n    /^pb_([^_]+)_/.exec(apiKey)?.[1] ??\n    ''\n  );\n}\n\nfunction record(raw: string | undefined): Record<string, unknown> {\n  if (!raw) throw new Error('Missing signed object');\n  rawObjectFields(raw); // also refuses duplicate fields\n  return JSON.parse(raw) as Record<string, unknown>;\n}\n\nfunction string(value: unknown): string {\n  if (typeof value !== 'string' || !value) throw new Error('Missing string');\n  return value;\n}\n\nfunction integer(value: unknown): number {\n  if (typeof value !== 'number' || !Number.isSafeInteger(value) || value < 0) {\n    throw new Error('Invalid integer');\n  }\n  return value;\n}\n\nfunction verifySignature(raw: string, signed: Record<string, unknown>, publicKey: Uint8Array) {\n  if (\n    signed.alg !== 'ed25519' ||\n    publicKey.length !== 32 ||\n    !ed25519.verify(fromBase64(string(signed.sig)), encoder.encode(raw), publicKey, {\n      zip215: false,\n    })\n  )\n    throw new Error('Invalid sealed key signature');\n}\n\n/** Verify fleet → expected stack → keyset, retaining the exact signed bytes. */\nexport function verifySealingKey(\n  raw: string,\n  expectedRef: string,\n  root: string,\n  lastVersion: number,\n  now: number,\n): SealingKey {\n  const fields = rawObjectFields(raw);\n  const signed = record(raw);\n  const statementRaw = fields.get('binding');\n  const statement = record(statementRaw);\n  const bindingRaw = rawObjectFields(statementRaw ?? '').get('binding');\n  if (!bindingRaw || statement.rootKid !== 'sealed-root-v1') {\n    throw new Error('Unknown sealed trust root');\n  }\n  verifySignature(bindingRaw, statement, fromBase64(root));\n  const binding = record(bindingRaw);\n  if (\n    binding.v !== 1 ||\n    !expectedRef ||\n    string(binding.stackRef).trim().toLowerCase() !== expectedRef.toLowerCase()\n  ) {\n    throw new Error('Sealed binding belongs to another stack');\n  }\n  const bindingExpiry = integer(binding.expires);\n  if (bindingExpiry * 1000 <= now) throw new Error('Expired sealed binding');\n  const keysetRaw = fields.get('keyset');\n  if (!keysetRaw) throw new Error('Missing sealed keyset');\n  verifySignature(keysetRaw, signed, fromBase64(string(binding.signingKey)));\n  const keyset = record(keysetRaw);\n  const version = integer(keyset.version);\n  const expires = Math.min(integer(keyset.expires), bindingExpiry);\n  if (version < lastVersion) throw new Error('Sealed keyset version went backwards');\n  if (expires * 1000 <= now) throw new Error('Expired sealed keyset');\n  if (keyset.v !== 1 || !Array.isArray(keyset.keys)) throw new Error('Invalid sealed keyset');\n  for (const item of keyset.keys) {\n    if (item === null || typeof item !== 'object') continue;\n    const entry = item as Record<string, unknown>;\n    if (entry.alg !== SEALED_SUITE) continue;\n    const publicKey = fromBase64(string(entry.pub));\n    if (publicKey.length !== 32) throw new Error('Invalid sealing public key');\n    return { kid: string(entry.kid), publicKey, expires, version };\n  }\n  throw new Error('No supported sealing key');\n}\n\nexport class SealedKeyStore {\n  private cached?: SealingKey;\n  private pending?: Promise<SealingKey>;\n  private fetchedAt = 0;\n  private retryAfter = 0;\n  private lastVersion = 0;\n  private lastError?: PalbaseError;\n  private rotationRefreshAt = 0;\n\n  constructor(\n    private readonly baseUrl: string,\n    private readonly apiKey: string,\n    private readonly options?: Exclude<HttpClientOptions['sealed'], false>,\n  ) {}\n\n  async current(signal?: AbortSignal, rotate = false): Promise<SealingKey> {\n    signal?.throwIfAborted();\n    const now = Date.now();\n    const valid = this.cached && this.cached.expires * 1000 > now ? this.cached : undefined;\n    if (this.pending) return this.waitFor(this.pending, signal);\n    // A forged unknown-kid response cannot turn every request into a key fetch.\n    if (rotate && now - this.rotationRefreshAt >= FAILURE_COOLDOWN_MS) {\n      this.fetchedAt = 0;\n      this.retryAfter = 0;\n      this.rotationRefreshAt = now;\n    }\n    if (valid && now - this.fetchedAt < REFRESH_MS) return valid;\n    if (now < this.retryAfter) {\n      if (valid) return valid;\n      throw this.lastError;\n    }\n    const pending = this.fetchKey()\n      .then((key) => {\n        this.cached = key;\n        this.lastVersion = key.version;\n        this.fetchedAt = Date.now();\n        this.retryAfter = 0;\n        return key;\n      })\n      .catch((error: unknown) => {\n        this.retryAfter = Date.now() + FAILURE_COOLDOWN_MS;\n        this.lastError =\n          error instanceof PalbaseError\n            ? error\n            : new PalbaseError(\n                'sealed_key_unavailable',\n                'The server encryption key could not be verified. Please try again later.',\n                0,\n              );\n        // A transient refresh failure may reuse a verified, unexpired key only.\n        if (this.cached && this.cached.expires * 1000 > Date.now()) return this.cached;\n        throw this.lastError;\n      })\n      .finally(() => {\n        this.pending = undefined;\n      });\n    this.pending = pending;\n    return this.waitFor(pending, signal);\n  }\n\n  private async fetchKey(): Promise<SealingKey> {\n    const controller = new AbortController();\n    const timer = setTimeout(() => controller.abort(), 15_000);\n    try {\n      const response = await fetch(endpointUrl(this.baseUrl, SEALED_KEYSET_PATH), {\n        headers: this.apiKey ? { apikey: this.apiKey } : {},\n        signal: controller.signal,\n        cache: 'no-store',\n        redirect: 'error',\n      });\n      if (!response.ok) throw new Error('Sealed keyset unavailable');\n      const raw = await response.text();\n      if (raw.length > 64 * 1024) throw new Error('Sealed keyset too large');\n      const expectedRef = this.options?.stackRef ?? expectedSealedStack(this.baseUrl, this.apiKey);\n      return verifySealingKey(\n        raw,\n        expectedRef,\n        this.options?.root ?? FLEET_ROOT,\n        this.lastVersion,\n        Date.now(),\n      );\n    } finally {\n      clearTimeout(timer);\n    }\n  }\n\n  // One caller's cancellation must not abort a shared key fetch for other calls.\n  private waitFor(pending: Promise<SealingKey>, signal?: AbortSignal): Promise<SealingKey> {\n    if (!signal) return pending;\n    return new Promise((resolve, reject) => {\n      const aborted = () => reject(signal.reason);\n      signal.addEventListener('abort', aborted, { once: true });\n      pending.then(resolve, reject).finally(() => signal.removeEventListener('abort', aborted));\n      if (signal.aborted) aborted();\n    });\n  }\n}\n","/**\n * Join the configured base URL with an SDK path.\n *\n * A BASE URL MAY CARRY A PATH, NOT JUST AN ORIGIN — a self-host published\n * under `https://api.example.com/palbase`, or an app that routes the browser\n * through its own server (`<origin>/pb`, rewritten upstream) because the\n * Environment's edge does not answer its origin with CORS headers.\n *\n * `new URL('/palbase-sealed-keys.json', base)` reads as the careful way to do\n * this and is the one form that DROPS that path: the leading slash makes the\n * path absolute against the base's ORIGIN. The sealed key store used it while\n * every ordinary request concatenated, so one request in the client asked a\n * different server than all the others — measured live 2026-09-11, the keyset\n * fetch landed on the app's own 404 page and every sealed call failed with\n * `sealed_key_unavailable`. The other two SDK surfaces never had the split:\n * iOS appends (`SealedKeyStore.swift`), Android concatenates onto a\n * slash-trimmed base (`SealedKeyStore.kt`) — this is their shape.\n */\nexport function endpointUrl(base: string, path: string): string {\n  return `${base.replace(/\\/+$/, '')}${path}`;\n}\n","import { PalbaseError } from './errors.js';\nimport { wirePlatform } from './platform.js';\nimport { asPowChallenge, solvePowChallenge } from './pow.js';\nimport { openSealedResponse, sealingRequired, sealRequest } from './sealed.js';\nimport { SealedKeyStore } from './sealed-keys.js';\nimport type { TokenManager } from './token.js';\nimport type { HttpClientOptions, PalbaseResponse, RequestOptions } from './types.js';\nimport { endpointUrl } from './url.js';\n\n/**\n * Default production host. Dev / staging / local callers override via\n * `options.url`. Apex-style routing is the only supported production path;\n * Kong resolves Environment identity from the API key.\n */\nconst PALBASE_DEFAULT_HOST = 'api.palbase.studio';\n\n/**\n * Parse the Environment ref from a Palbase API key.\n *\n * Canonical shape: `pb_{environment_ref}_c{random}`, where the Environment ref\n * is 4-24 lowercase ASCII alphanumeric characters and random is AT LEAST 20\n * base62 chars.\n *\n * The length is a floor, not an equality. The stack's own minter writes 20\n * (v2/cmd/palsvc/initenv.go) and the cloud control plane writes 32\n * (cloud/platform/server/services/keys.ts), and the door that admits the\n * request refuses to rule on the difference: *\"a shorter or longer secret is\n * not a security property this door can rule on\"*\n * (v2/internal/platform/identitymw.go: parseAPIKey). A client that is stricter\n * than the server does not add safety — it just refuses working keys, which is\n * exactly what this one did to every cloud project until 2026-08-25.\n *\n * Returns the Environment ref on match; `null` otherwise.\n */\nconst API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20,}$/;\n\nfunction parseEnvironmentRef(apiKey: string): string | null {\n  return API_KEY_RE.exec(apiKey)?.[1] ?? null;\n}\nconst MAX_RETRIES = 3;\nconst INITIAL_BACKOFF_MS = 200;\n/**\n * Upper bound on a single 429 retry sleep. A server may return a long\n * Retry-After (a locked account can send minutes/hours); honoring it verbatim\n * would HANG the request for that whole window. Cap each retry at 10s — after\n * MAX_RETRIES the 429 envelope surfaces to the caller (fail fast, don't sleep\n * minutes). The clamp never skips a retry; it only bounds how long each waits.\n */\nconst MAX_RETRY_DELAY_MS = 10_000;\n\n/**\n * The edge's refusals this client is allowed to WAIT for — an ALLOWLIST.\n *\n * NEVER a denylist. Enumerating the exceptions cannot see the set GROW: a name\n * added at the edge tomorrow would be waited for by a client that never heard\n * of it. The client waits only for what it was taught.\n *\n * `request_too_large` is absent on purpose — the same body earns the same\n * refusal, so waiting cannot help. `handoff_failed` is absent because the\n * project may ALREADY have applied the request: the edge counts a hand-off\n * ATTEMPT before it knows the outcome, and a connection can break after the\n * body was fully delivered. A silent retry there writes an insert twice.\n */\nconst RETRYABLE_HOLD_REFUSALS: ReadonlySet<string> = new Set([\n  'holder_full',\n  'wake_budget_exceeded',\n]);\n\n/**\n * How long to wait for a held-request refusal, or null when it must surface.\n *\n * READS THE NAME, NEVER THE STATUS: an unnamed 503 is Envoy's `no healthy\n * upstream` and this client keeps surfacing it exactly as it does today.\n *\n * READS THE HINT FROM THE PARSED BODY, never from the header alone. A browser\n * cannot see `Retry-After` unless CORS exposes it, and the edge does not — it\n * was measured live on an AWAKE project, whose expose list carries\n * `x-request-id, palbase-auth-contract, etag` and not `Retry-After`. A\n * header-only read is inert exactly where this fix matters.\n */\nfunction heldRefusalWait(\n  status: number,\n  body: { error?: string; retry_after?: number } | undefined,\n): number | null {\n  if (status !== 503) return null;\n  if (body?.error === undefined || !RETRYABLE_HOLD_REFUSALS.has(body.error)) return null;\n  const seconds = body.retry_after;\n  const advertised =\n    typeof seconds === 'number' && Number.isFinite(seconds) && seconds > 0\n      ? seconds * 1000\n      : INITIAL_BACKOFF_MS;\n  // The 429 path's own ceiling — no second backoff is invented.\n  return Math.min(advertised, MAX_RETRY_DELAY_MS);\n}\n\n/**\n * Carry a 429's retry hint into the error envelope when only the header has it.\n *\n * A REFUSAL FROM THE EDGE CARRIES NOTHING BUT THE HEADER. Envoy and the\n * gateway limiter answer before any Palbase service is reached, so their 429\n * has no `retry_after` and no `data.retryAfter` — and every reader above this\n * layer (`@palbase/web`'s BackendError, the iOS SDK) looks in the BODY. The\n * seconds were on the wire and unreachable to all of them.\n *\n * Lifted under `retry_after`, the platform's own name for it (palauth's\n * rate-limit envelope), never overwriting a hint the service itself sent — a\n * service knows its window, the edge only knows its own.\n */\nfunction withRetryHint(\n  body: Record<string, unknown> | undefined,\n  response: Response,\n): Record<string, unknown> | undefined {\n  // 429, OR a 503 the edge NAMED as a held request. NOT \"any 503\": an unnamed\n  // 503 is Envoy's `no healthy upstream` and FR-006 keeps it exactly as it is\n  // today — gaining a hint would already be a behaviour change.\n  const namedHold =\n    response.status === 503 &&\n    typeof body?.error === 'string' &&\n    RETRYABLE_HOLD_REFUSALS.has(body.error);\n  if (response.status !== 429 && !namedHold) return body;\n  const data = body?.data;\n  const alreadyStated =\n    typeof body?.retry_after === 'number' ||\n    (typeof data === 'object' && data !== null && 'retryAfter' in data);\n  if (alreadyStated) return body;\n  const seconds = Number.parseInt(response.headers.get('Retry-After') ?? '', 10);\n  if (Number.isNaN(seconds) || seconds <= 0) return body;\n  return { ...body, retry_after: seconds };\n}\n\n/**\n * Request interceptor. Runs before every HTTP request.\n * Can modify headers, body, or reject the request.\n */\nexport type RequestInterceptor = (request: {\n  headers: Record<string, string>;\n  method: string;\n  path: string;\n}) => void | Promise<void>;\n\nexport class HttpClient {\n  protected readonly apiKey: string;\n  protected readonly options?: HttpClientOptions;\n\n  tokenManager: TokenManager | null = null;\n\n  /**\n   * Admin JWT used for platform admin endpoints (/admin/*).\n   * When set, takes precedence over tokenManager access token in the\n   * Authorization header.\n   */\n  adminToken: string | null = null;\n\n  private readonly interceptors: RequestInterceptor[] = [];\n  private readonly forbiddenListeners = new Set<(body: Record<string, unknown>) => void>();\n  private sealedKeys?: SealedKeyStore;\n\n  constructor(apiKey: string, options?: HttpClientOptions) {\n    this.apiKey = apiKey;\n    this.options = options;\n  }\n\n  /** Set (or clear) the admin JWT used on admin endpoints. */\n  setAdminToken(token: string | null): void {\n    this.adminToken = token;\n  }\n\n  /**\n   * Called with the RAW body of every 403 this client receives (FR-010). Core\n   * does not know the envelope's fields — the layer that does (palbe) reads\n   * `required` out of it. Nothing is retried or swallowed: the error still\n   * returns to the caller.\n   */\n  onForbidden(handler: (body: Record<string, unknown>) => void): () => void {\n    this.forbiddenListeners.add(handler);\n    return () => {\n      this.forbiddenListeners.delete(handler);\n    };\n  }\n\n  /**\n   * Create a scoped HttpClient that adds the given extra headers to every\n   * request. The returned client shares the admin token and token manager\n   * with the parent at runtime — later changes on the parent propagate to\n   * the scope and vice versa.\n   *\n   * Typical use: adding an Environment-routing header for an admin call.\n   */\n  withHeaders(extra: Record<string, string>): HttpClient {\n    const mergedHeaders = { ...(this.options?.headers ?? {}), ...extra };\n\n    const scoped: HttpClient = new HttpClient(this.apiKey, {\n      ...this.options,\n      headers: mergedHeaders,\n    });\n    scoped.tokenManager = this.tokenManager;\n    // Delegate adminToken reads + writes to the parent so the scope always\n    // sees the latest token, and setAdminToken on the scope affects the parent.\n    // The scope shares the parent's 403 listeners: a refusal is a refusal\n    // whichever header set the request carried.\n    Object.defineProperty(scoped, 'forbiddenListeners', {\n      get: () => this.forbiddenListeners,\n    });\n    Object.defineProperty(scoped, 'adminToken', {\n      get: () => this.adminToken,\n      set: (v: string | null) => {\n        this.adminToken = v;\n      },\n      configurable: true,\n    });\n    Object.defineProperty(scoped, 'sealedKeys', {\n      get: () => this.sealedKeys,\n      set: (v: SealedKeyStore | undefined) => {\n        this.sealedKeys = v;\n      },\n    });\n    return scoped;\n  }\n\n  /** Add a request interceptor. Runs before every request. */\n  addInterceptor(interceptor: RequestInterceptor): void {\n    this.interceptors.push(interceptor);\n  }\n\n  async request<T>(\n    method: string,\n    path: string,\n    options?: RequestOptions,\n  ): Promise<PalbaseResponse<T>> {\n    // If token is expired and refresh is available, refresh before making the request\n    if (\n      !options?.skipSessionRefresh &&\n      this.tokenManager?.isExpired() &&\n      this.tokenManager.getRefreshToken() &&\n      this.tokenManager.refreshFunction\n    ) {\n      try {\n        await this.tokenManager.refreshSession();\n      } catch (e) {\n        const status = e instanceof PalbaseError ? e.status : 0;\n        if (status === 400 || status === 401 || status === 403) {\n          // Terminal: the refresh token is dead (revoked/expired/forbidden).\n          // Clear the session (listeners persist the sign-out) and proceed\n          // unauthenticated — the endpoint will 401 into the normal error\n          // envelope instead of bricking every subsequent call including\n          // the recovery sign-in.\n          this.tokenManager.clearSession();\n        } else {\n          throw e; // network/5xx: transient, stay loud\n        }\n      }\n    }\n\n    return this.executeWithRetry<T>(method.toUpperCase(), path, options, 0);\n  }\n\n  /**\n   * A response read as it arrives, for `text/event-stream` routes.\n   *\n   * Deliberately NOT `executeWithRetry`: a retry replays the request, and a\n   * stream the caller has already begun reading cannot be replayed — the frames\n   * it handed over would arrive a second time. A stream that fails to open fails\n   * to the caller, once, with its status.\n   *\n   * The buffered path's headers, base URL and interceptors are reused verbatim,\n   * so a streaming call is authenticated exactly like every other call; only the\n   * body handling differs. `Accept` says what the caller wants, and the status\n   * is returned beside the body because the CALLER decides what a non-2xx means\n   * (an error envelope arrives as an ordinary buffered body).\n   */\n  async requestStream(\n    method: string,\n    path: string,\n    options?: RequestOptions,\n  ): Promise<{ status: number; body: ReadableStream<Uint8Array> | null; contentType: string }> {\n    method = method.toUpperCase();\n    if (\n      !options?.skipSessionRefresh &&\n      this.tokenManager?.isExpired() &&\n      this.tokenManager.getRefreshToken() &&\n      this.tokenManager.refreshFunction\n    ) {\n      try {\n        await this.tokenManager.refreshSession();\n      } catch (e) {\n        const status = e instanceof PalbaseError ? e.status : 0;\n        if (status === 400 || status === 401 || status === 403) {\n          this.tokenManager.clearSession();\n        } else {\n          throw e;\n        }\n      }\n    }\n\n    const url = endpointUrl(this.getBaseUrl(), path);\n    const headers = { ...this.buildHeaders(options), Accept: 'text/event-stream' };\n    for (const interceptor of this.interceptors) {\n      await interceptor({ headers, method, path });\n    }\n\n    const fetchOptions: RequestInit = { method, headers, signal: options?.signal };\n    if (options?.body !== undefined) fetchOptions.body = JSON.stringify(options.body);\n    const exporter = await this.prepareSealed(url, path, fetchOptions);\n\n    const response = await openSealedResponse(await fetch(url, fetchOptions), exporter, method);\n    return {\n      status: response.status,\n      body: response.body,\n      contentType: response.headers.get('content-type') ?? '',\n    };\n  }\n\n  private async prepareSealed(\n    url: string,\n    path: string,\n    init: RequestInit,\n  ): Promise<Uint8Array<ArrayBuffer> | undefined> {\n    if (this.options?.sealed === false || !sealingRequired(path)) return undefined;\n    this.sealedKeys ??= new SealedKeyStore(this.getBaseUrl(), this.apiKey, this.options?.sealed);\n    const key = await this.sealedKeys.current(init.signal ?? undefined);\n    init.signal?.throwIfAborted();\n    try {\n      return await sealRequest(key, url, init);\n    } catch (error) {\n      init.signal?.throwIfAborted();\n      if (error instanceof PalbaseError) throw error;\n      throw new PalbaseError('sealed_request_failed', 'The request could not be encrypted.', 0);\n    }\n  }\n\n  private getBaseUrl(): string {\n    // Explicit URL always wins (local dev, staging, test rigs).\n    if (this.options?.url) {\n      return this.options.url;\n    }\n\n    // Validate the key shape up front so apex-routed callers still\n    // fail loud on a malformed key instead of hitting the gateway\n    // with bad credentials.\n    if (this.apiKey && parseEnvironmentRef(this.apiKey) === null) {\n      throw new PalbaseError(\n        'invalid_api_key',\n        'Invalid API key format. Expected pb_{environment_ref}_c{at least 20 base62 chars}. For dev/staging pass `url: \"https://api.dev.palbase.studio\"` via options.',\n        0,\n      );\n    }\n\n    return `https://${PALBASE_DEFAULT_HOST}`;\n  }\n\n  private buildHeaders(options?: RequestOptions): Record<string, string> {\n    const headers: Record<string, string> = {\n      'Content-Type': 'application/json',\n      // Client identity, the web counterpart of the iOS SDK's\n      // ClientInfo.augment(). The server reads these to resolve flag targeting\n      // conditions and to label telemetry, so an app declares nothing and calls\n      // nothing — whatever the SDK can know, it sends.\n      'X-Platform': wirePlatform(),\n    };\n    // The host app's own version is not knowable on the web (no bundle to read\n    // it from), so it is opt-in; when given it fills the same header iOS fills\n    // from CFBundleShortVersionString.\n    const appVersion = this.options?.appVersion?.trim();\n    if (appVersion) {\n      headers['X-Palbase-Client-Version'] = appVersion;\n    }\n\n    // Palbase Environment keys live in the `apikey` header — never in\n    // `Authorization` — because Kong's key-auth resolves them on that\n    // header and the gateway's pre-function plugin stamps the downstream\n    // identity.\n    const effectiveKey = this.apiKey;\n    if (effectiveKey) {\n      headers['apikey'] = effectiveKey;\n    }\n\n    // User session token, if any. Kong's pre-function plugin strips\n    // Authorization on /v1/* routes anyway (PostgREST has no JWT\n    // secret and would crash on a Bearer it can't decode), but\n    // sending it preserves the contract for /auth/* endpoints that\n    // do consume the bearer (e.g. session refresh).\n    const token = this.tokenManager?.getAccessToken();\n    if (token) {\n      headers['Authorization'] = `Bearer ${token}`;\n    }\n\n    // adminToken (platform admin JWT) takes precedence — used by the\n    // @palbase/admin internal flows that hit /admin/* routes; those\n    // routes verify the bearer themselves and aren't subject to the\n    // /v1/* Authorization-strip rule.\n    if (this.adminToken) {\n      headers['Authorization'] = `Bearer ${this.adminToken}`;\n    }\n\n    // Merge global custom headers\n    if (this.options?.headers) {\n      Object.assign(headers, this.options.headers);\n    }\n\n    // Merge per-request headers\n    if (options?.headers) {\n      Object.assign(headers, options.headers);\n    }\n\n    return headers;\n  }\n\n  private async executeWithRetry<T>(\n    method: string,\n    path: string,\n    options: RequestOptions | undefined,\n    attempt: number,\n    // Headers a PREVIOUS attempt earned and this one has to carry. Today that\n    // is only the solved proof-of-work pair; it is a parameter rather than a\n    // field because it belongs to one request's second try, and a field would\n    // leak it onto every later call made through this client.\n    earned?: Record<string, string>,\n    rotated = false,\n  ): Promise<PalbaseResponse<T>> {\n    const url = endpointUrl(this.getBaseUrl(), path);\n    const headers = { ...this.buildHeaders(options), ...earned };\n\n    // Run interceptors\n    for (const interceptor of this.interceptors) {\n      await interceptor({ headers, method, path });\n    }\n\n    const fetchOptions: RequestInit = {\n      method,\n      headers,\n      signal: options?.signal,\n    };\n\n    if (options?.body !== undefined) {\n      fetchOptions.body = JSON.stringify(options.body);\n    }\n    // A fresh HPKE encapsulation on EVERY attempt: reusing an envelope trips\n    // the server replay guard, even when the first response was lost.\n    const exporter = await this.prepareSealed(url, path, fetchOptions);\n\n    let response: Response;\n    try {\n      response = await fetch(url, fetchOptions);\n    } catch (error) {\n      options?.signal?.throwIfAborted();\n      // Network error — retry with backoff\n      if (options?.retry !== false && attempt < MAX_RETRIES - 1) {\n        const backoff = INITIAL_BACKOFF_MS * 2 ** attempt;\n        await this.delay(backoff);\n        // WITHOUT `earned`, and that is the whole point of this line.\n        //\n        // A network error means the response was lost, not that the request\n        // was. If it reached the server, the challenge is already SPENT —\n        // palauth's VerifyChallenge reads and deletes in one step\n        // (bot/pow.go:96-104), deliberately, because a proof presented twice is\n        // not proof. Replaying the nonce would then answer `pow_invalid`, and\n        // the one-solve guard below would refuse to try again: a request one\n        // fresh solve away from succeeding, failed. Dropping it costs nothing\n        // in the other case — if the server never saw the request, a fresh\n        // challenge works exactly as well as the old one.\n        return this.executeWithRetry<T>(method, path, options, attempt + 1, undefined, rotated);\n      }\n\n      // All retries exhausted — throw PalbaseError\n      throw new PalbaseError(\n        'network_error',\n        error instanceof Error ? error.message : 'Network request failed',\n        0,\n      );\n    }\n    response = await openSealedResponse(response, exporter, method);\n\n    // Handle 429 Too Many Requests — retry with Retry-After or backoff;\n    // if retries exhausted, fall through to normal error response handling below\n    if (response.status === 429) {\n      if (options?.retry !== false && attempt < MAX_RETRIES - 1) {\n        const retryAfter = response.headers.get('Retry-After');\n        const parsed = retryAfter ? Number.parseInt(retryAfter, 10) : Number.NaN;\n        // Clamp the server-requested wait: a long Retry-After (locked account)\n        // must not hang the request — cap each sleep, exhaust MAX_RETRIES, then\n        // fall through to surface the 429 envelope below.\n        const delayMs = Number.isNaN(parsed)\n          ? INITIAL_BACKOFF_MS * 2 ** attempt\n          : Math.min(parsed * 1000, MAX_RETRY_DELAY_MS);\n        await this.delay(delayMs);\n        // WITH `earned`, unlike the network path above: a 429 is a refusal the\n        // server issued INSTEAD of doing the work, so the challenge was never\n        // consumed. The edge's rate limiter answers before palsvc, and on the\n        // auth routes palauth's own limiter runs BEFORE the proof-of-work\n        // middleware (auth/internal/server/server.go: rl.LoginByIP, then powMW).\n        return this.executeWithRetry<T>(method, path, options, attempt + 1, earned, rotated);\n      }\n    }\n\n    // Parse response body\n    let data: T | null = null;\n    let errorBody:\n      | {\n          error?: string;\n          error_description?: string;\n          status?: number;\n          required?: string;\n          retry_after?: number;\n        }\n      | undefined;\n\n    // HEAD responses have no body by spec — skip parsing.\n    const contentType = response.headers.get('Content-Type');\n    if (\n      method !== 'HEAD' &&\n      ![204, 205, 304].includes(response.status) &&\n      contentType?.includes('json')\n    ) {\n      if (response.ok) {\n        data = (await response.json()) as T;\n      } else {\n        // A REFUSAL WHOSE BODY DID NOT ARRIVE WHOLE IS STILL A REFUSAL.\n        //\n        // This path became REACHABLE with the edge's named envelope: before it,\n        // a held-request refusal was `text/plain` and was never parsed, so a\n        // truncated body could not surface. Now the edge answers 503 with\n        // `application/json`, and a body cut short mid-flight would throw a\n        // bare `SyntaxError` straight out of this client — no `PalbaseError`,\n        // no status, nothing the application can read. That is exactly the\n        // failure this whole change exists to remove, re-entering through the\n        // door it opened.\n        //\n        // The refusal keeps its status and surfaces as `unknown_error` below;\n        // an unreadable body costs the NAME, not the answer.\n        //\n        // Only on the error path: a SUCCESS body that cannot be parsed is a\n        // real failure and must keep throwing — swallowing it would hand the\n        // caller `{ data: null, error: null }`, which is a silent lie.\n        errorBody = (await response.json().catch(() => undefined)) as typeof errorBody;\n      }\n    }\n\n    // A HELD REQUEST IS NOT AN ERROR — the edge is starting a sleeping project.\n    //\n    // This sits AFTER the body parse, and not beside the 429 check above, on\n    // purpose: the name and the hint live in the BODY, and the body does not\n    // exist yet where the 429 block runs.\n    if (options?.retry !== false && attempt < MAX_RETRIES - 1) {\n      const heldWait = heldRefusalWait(response.status, errorBody);\n      if (heldWait !== null) {\n        await this.delay(heldWait);\n        // WITH `earned`, like the 429 path: the edge refused INSTEAD of doing\n        // the work, so the challenge was never consumed.\n        return this.executeWithRetry<T>(method, path, options, attempt + 1, earned, rotated);\n      }\n    }\n\n    if (\n      exporter &&\n      !rotated &&\n      response.status === 400 &&\n      errorBody?.error === 'sealed_unknown_kid'\n    ) {\n      await this.sealedKeys?.current(options?.signal, true);\n      return this.executeWithRetry<T>(method, path, options, attempt, earned, true);\n    }\n\n    // Proof-of-work: /auth/signup and /auth/token sit behind a bot gate that\n    // answers an unsolved request with 403 and the challenge in the body. Solve\n    // it and repeat the request carrying the two headers; the caller never\n    // learns the gate is there.\n    //\n    // HERE, in core, because this is the layer that issues the request for every\n    // client in the repo — @palbase/auth's sign-in, @palbase/web's facades, the\n    // server SDK. The same retry lived one layer up in @palbase/web until\n    // 2026-08-18 and covered everything EXCEPT `pb.auth.*`, which reaches the\n    // network through this method; so the gate stayed unsatisfiable on exactly\n    // the two endpoints it guards.\n    //\n    // ONE retry, and only when the body really carries a challenge: `earned`\n    // being set already means this IS the second try. A 403 that says\n    // pow_required without a challenge is a server the client cannot satisfy,\n    // and looping on it would turn a broken gate into a hang.\n    if (response.status === 403 && !earned) {\n      const challenge = asPowChallenge(errorBody);\n      if (challenge) {\n        return this.executeWithRetry<T>(\n          method,\n          path,\n          options,\n          attempt,\n          await solvePowChallenge(challenge, undefined, options?.signal),\n          rotated,\n        );\n      }\n    }\n\n    if (!response.ok) {\n      if (response.status === 403 && errorBody !== undefined) {\n        const body: Record<string, unknown> = errorBody;\n        for (const listener of this.forbiddenListeners) {\n          try {\n            listener(body);\n          } catch {\n            // A consumer's handler must not turn a well-formed refusal into a\n            // thrown error, nor stop the listeners after it (same rule as\n            // internal.ts' configured listeners).\n          }\n        }\n      }\n      return {\n        data: null,\n        error: new PalbaseError(\n          errorBody?.error ?? 'unknown_error',\n          errorBody?.error_description ?? response.statusText,\n          response.status,\n          withRetryHint(errorBody, response),\n        ),\n        status: response.status,\n      };\n    }\n\n    // Parse PostgREST Content-Range for count queries (e.g. \"0-9/42\" or \"*/42\").\n    const contentRange = response.headers.get('Content-Range');\n    let count: number | undefined;\n    if (contentRange) {\n      const slash = contentRange.lastIndexOf('/');\n      if (slash >= 0) {\n        const totalPart = contentRange.slice(slash + 1);\n        if (totalPart !== '*') {\n          const parsed = Number.parseInt(totalPart, 10);\n          if (!Number.isNaN(parsed)) {\n            count = parsed;\n          }\n        }\n      }\n    }\n\n    // Header names are case-insensitive and `Headers.get` already honours that;\n    // the wire spells this one lowercase.\n    const etag = response.headers.get('etag');\n\n    return {\n      data,\n      error: null,\n      status: response.status,\n      ...(count !== undefined ? { count } : {}),\n      ...(etag ? { etag } : {}),\n    };\n  }\n\n  private delay(ms: number): Promise<void> {\n    return new Promise((resolve) => setTimeout(resolve, ms));\n  }\n}\n","import type { AuthStateCallback, Session, Unsubscribe } from './types.js';\n\nexport class TokenManager {\n  private session: Session | null = null;\n  private listeners: Set<AuthStateCallback> = new Set();\n  private refreshPromise: Promise<void> | null = null;\n  private refreshing = false;\n\n  refreshFunction: ((refreshToken: string) => Promise<Session>) | null = null;\n\n  setSession(session: Session): void {\n    this.session = session;\n    this.notify('SESSION_SET', session);\n  }\n\n  getAccessToken(): string | null {\n    return this.session?.accessToken ?? null;\n  }\n\n  getRefreshToken(): string | null {\n    return this.session?.refreshToken ?? null;\n  }\n\n  clearSession(): void {\n    this.session = null;\n    this.notify('SESSION_CLEARED', null);\n  }\n\n  isExpired(): boolean {\n    if (!this.session) return true;\n    return Date.now() >= this.session.expiresAt;\n  }\n\n  async refreshSession(): Promise<void> {\n    if (!this.session?.refreshToken || !this.refreshFunction) {\n      return;\n    }\n\n    // Collapse concurrent refresh calls into a single request\n    if (this.refreshPromise) {\n      return this.refreshPromise;\n    }\n\n    // Re-entrancy guard: the wired refreshFunction issues its own HTTP request\n    // (POST /auth/token/refresh) through HttpClient, whose pre-flight calls\n    // refreshSession() again SYNCHRONOUSLY — before `refreshPromise` below is\n    // assigned (the whole chain runs before the first real await). Without\n    // this flag that recursion is unbounded (stack overflow). Returning early\n    // lets the refresh request itself proceed unauthenticated — it carries\n    // the refresh token in its body, not the Bearer header.\n    if (this.refreshing) {\n      return;\n    }\n\n    this.refreshing = true;\n    this.refreshPromise = this.executeRefresh(this.session.refreshToken);\n\n    try {\n      await this.refreshPromise;\n    } finally {\n      this.refreshPromise = null;\n      this.refreshing = false;\n    }\n  }\n\n  onAuthStateChange(callback: AuthStateCallback): Unsubscribe {\n    this.listeners.add(callback);\n    return () => {\n      this.listeners.delete(callback);\n    };\n  }\n\n  private async executeRefresh(refreshToken: string): Promise<void> {\n    if (!this.refreshFunction) return;\n    const startedSession = this.session;\n    try {\n      const newSession = await this.refreshFunction(refreshToken);\n      // Sign-out, a new sign-in, or another session adoption takes precedence\n      // over a refresh that started against an older session.\n      if (this.session === startedSession) this.setSession(newSession);\n    } catch (error) {\n      // The caller would clear its session on a terminal refresh error. An\n      // error from an older session must not clear a newer one.\n      if (this.session === startedSession) throw error;\n    }\n  }\n\n  private notify(event: 'SESSION_SET' | 'SESSION_CLEARED', session: Session | null): void {\n    for (const listener of this.listeners) {\n      listener(event, session);\n    }\n  }\n}\n","import type { HttpClient, PalbaseResponse, Session, TokenManager } from '@palbase/core';\nimport { PalbaseError } from '@palbase/core';\nimport { DeviceClient } from './device-client.js';\nimport {\n  type OAuthConfig,\n  OAuthFlow,\n  type OAuthOptions,\n  type OAuthResult,\n  type OAuthTransaction,\n  type OAuthTransactionStorage,\n} from './oauth.js';\nimport type {\n  AuthEvent,\n  AuthResult,\n  AuthSession,\n  AuthStateChangeCallback,\n  Identity,\n  MagicLinkParams,\n  MagicLinkVerifyParams,\n  MFAChallengeParams,\n  MFAEmailChallengeParams,\n  MFAEmailVerifyParams,\n  MFAEnrollParams,\n  MFAEnrollResult,\n  MFAFactor,\n  MFARecoveryParams,\n  PasswordChangeParams,\n  PasswordResetConfirmParams,\n  PasswordResetParams,\n  PasswordSetParams,\n  RegisterTrustedDeviceParams,\n  SignInCredentials,\n  SignUpCredentials,\n  TokenResponse,\n  TrustedDevice,\n  User,\n  VerifyEmailParams,\n} from './types.js';\n\nexport interface AuthClientOptions {\n  oauth?: OAuthConfig;\n  oauthStorage?: OAuthTransactionStorage;\n  /** Coordinate rotating credentials with the runtime's shared session store. */\n  coordinateRefresh?: (\n    refreshToken: string,\n    exchange: (refreshToken: string) => Promise<Session>,\n  ) => Promise<Session>;\n}\n\n/** Validates that a path parameter does not contain path traversal characters. */\nfunction validatePathParam(name: string, value: string): void {\n  if (value.includes('/') || value.includes('..') || value.includes('%')) {\n    throw new Error(`Invalid ${name}: must not contain path separators`);\n  }\n}\n\n/** Convert AuthResult from the real API into the SDK Session shape. */\nfunction toSession(result: AuthResult): Session {\n  return {\n    accessToken: result.access_token,\n    refreshToken: result.refresh_token,\n    expiresAt: Date.now() + result.expires_in * 1000,\n  };\n}\n\n/** Convert AuthResult UserInfo into the SDK User shape. */\nfunction toUser(result: AuthResult): User {\n  return {\n    id: result.user.id,\n    email: result.user.email,\n    emailVerified: result.user.email_verified,\n    createdAt: result.user.created_at,\n    updatedAt: result.user.created_at,\n    // Bir stack roller yüzeyinden eskiyse anahtarı hiç göndermez; orada `[]`\n    // dürüst okumadır — taşıyacağı rol yoktur.\n    roles: result.user.roles ?? [],\n  };\n}\n\nexport class AuthClient {\n  private readonly httpClient: HttpClient;\n  private readonly tokenManager: TokenManager;\n  private readonly apiKey: string;\n  private readonly baseUrl: string;\n  private currentSession: Session | null = null;\n  private hasSession = false;\n  private _mfa: ReturnType<AuthClient['buildMfa']> | null = null;\n  private readonly oauthFlow: OAuthFlow;\n  private readonly coordinateRefresh: AuthClientOptions['coordinateRefresh'];\n\n  /** Device attestation */\n  readonly device: DeviceClient;\n\n  constructor(\n    httpClient: HttpClient,\n    tokenManager: TokenManager,\n    apiKey?: string,\n    baseUrl?: string,\n    options?: AuthClientOptions,\n  ) {\n    this.httpClient = httpClient;\n    this.tokenManager = tokenManager;\n    this.apiKey = apiKey ?? '';\n    this.baseUrl = baseUrl ?? '';\n    this.coordinateRefresh = options?.coordinateRefresh;\n    this.device = new DeviceClient(httpClient);\n    this.oauthFlow = new OAuthFlow(\n      httpClient,\n      options?.oauth,\n      options?.oauthStorage,\n      ({ session }) => {\n        if (this.currentSession?.accessToken !== session.accessToken)\n          this.setSessionAndWireRefresh(session);\n      },\n      this.baseUrl,\n    );\n\n    this.tokenManager.onAuthStateChange((event, session) => {\n      if (event === 'SESSION_SET') {\n        this.currentSession = session;\n      } else {\n        this.currentSession = null;\n      }\n    });\n  }\n\n  // ── Core Auth ───────────────────────────────────────────\n\n  async signUp(\n    credentials: SignUpCredentials,\n    options?: { headers?: Record<string, string> },\n  ): Promise<PalbaseResponse<{ user: User; session: Session }>> {\n    const response = await this.httpClient.request<AuthResult>('POST', '/auth/signup', {\n      body: credentials,\n      retry: false,\n      skipSessionRefresh: true,\n      ...(options?.headers ? { headers: options.headers } : {}),\n    });\n\n    if (response.data) {\n      const session = toSession(response.data);\n      const user = toUser(response.data);\n      this.setSessionAndWireRefresh(session);\n      return { data: { user, session }, error: null, status: response.status };\n    }\n\n    return { data: null, error: response.error, status: response.status };\n  }\n\n  async signIn(\n    credentials: SignInCredentials,\n  ): Promise<PalbaseResponse<{ user: User; session: Session }>> {\n    const response = await this.httpClient.request<AuthResult>('POST', '/auth/login', {\n      body: credentials,\n      retry: false,\n      skipSessionRefresh: true,\n    });\n\n    if (response.data) {\n      const session = toSession(response.data);\n      const user = toUser(response.data);\n      this.setSessionAndWireRefresh(session);\n      return { data: { user, session }, error: null, status: response.status };\n    }\n\n    return { data: null, error: response.error, status: response.status };\n  }\n\n  async signOut(): Promise<PalbaseResponse<void>> {\n    const response = await this.httpClient.request<void>('POST', '/auth/logout');\n    this.tokenManager.clearSession();\n    this.hasSession = false;\n    return response;\n  }\n\n  // ── Email Verification ──────────────────────────────────\n\n  async verifyEmail(params: VerifyEmailParams): Promise<PalbaseResponse<{ status: string }>> {\n    return this.httpClient.request<{ status: string }>('POST', '/auth/verify-email', {\n      body: params,\n    });\n  }\n\n  async resendVerification(\n    email: string,\n  ): Promise<PalbaseResponse<{ verification_token?: string; verification_code?: string }>> {\n    return this.httpClient.request<{ verification_token?: string; verification_code?: string }>(\n      'POST',\n      '/auth/resend-verification',\n      { body: { email } },\n    );\n  }\n\n  // ── Password ────────────────────────────────────────────\n\n  async requestPasswordReset(\n    params: PasswordResetParams,\n  ): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/password/reset', {\n      body: params,\n    });\n  }\n\n  async confirmPasswordReset(\n    params: PasswordResetConfirmParams,\n  ): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/password/reset/confirm', {\n      body: params,\n    });\n  }\n\n  async changePassword(\n    params: PasswordChangeParams,\n  ): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/password/change', {\n      body: params,\n    });\n  }\n\n  /**\n   * Give a PASSWORDLESS account its first password.\n   *\n   * Separate from `changePassword` because that one cannot serve the case: it\n   * sends a current password and palauth answers an account that has none with\n   * 401. Requires a RECENT sign-in (403 `reauthentication_required` otherwise,\n   * the same gate passkey enrollment carries); an account that already has a\n   * password gets 409 `password_already_set`.\n   */\n  async setPassword(params: PasswordSetParams): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/password/set', {\n      body: params,\n    });\n  }\n\n  // ── Token ───────────────────────────────────────────────\n\n  async refresh(): Promise<PalbaseResponse<TokenResponse>> {\n    const refreshToken = this.tokenManager.getRefreshToken();\n    if (!refreshToken) {\n      return {\n        data: null,\n        error: new PalbaseError('no_refresh_token', 'No refresh token available', 0),\n        status: 0,\n      };\n    }\n\n    // Explicit refresh shares the same flight as request preflight/reactive\n    // refresh. Calling HTTP directly here consumed an expired token twice:\n    // once in preflight, then again in the explicit request body.\n    this.tokenManager.refreshFunction ??= (token) => this.refreshToken(token);\n    try {\n      await this.tokenManager.refreshSession();\n      const session = this.currentSession;\n      if (!session) {\n        return {\n          data: null,\n          error: new PalbaseError('no_refresh_token', 'Session ended during refresh', 0),\n          status: 0,\n        };\n      }\n      return {\n        data: {\n          access_token: session.accessToken,\n          refresh_token: session.refreshToken,\n          expires_in: Math.max(0, Math.floor((session.expiresAt - Date.now()) / 1000)),\n          token_type: 'Bearer',\n        },\n        error: null,\n        status: 200,\n      };\n    } catch (error) {\n      const failure =\n        error instanceof PalbaseError\n          ? error\n          : new PalbaseError(\n              'refresh_failed',\n              error instanceof Error ? error.message : 'Failed to refresh token',\n              0,\n            );\n      return { data: null, error: failure, status: failure.status };\n    }\n  }\n\n  getAccessToken(): string | null {\n    return this.tokenManager.getAccessToken();\n  }\n\n  onTokenChange(\n    callback: (tokens: { accessToken: string | null; refreshToken: string | null }) => void,\n  ): () => void {\n    return this.tokenManager.onAuthStateChange((event, session) => {\n      if (event === 'SESSION_SET' && session) {\n        callback({ accessToken: session.accessToken, refreshToken: session.refreshToken });\n      } else {\n        callback({ accessToken: null, refreshToken: null });\n      }\n    });\n  }\n\n  setTokens(accessToken: string, refreshToken: string, expiresIn = 3600): void {\n    const session: Session = {\n      accessToken,\n      refreshToken,\n      // Default 1h when the caller has no TTL; corrected on next refresh anyway.\n      expiresAt: Date.now() + expiresIn * 1000,\n    };\n    this.setSessionAndWireRefresh(session);\n  }\n\n  // ── Sessions ────────────────────────────────────────────\n\n  async listSessions(): Promise<PalbaseResponse<AuthSession[]>> {\n    const response = await this.httpClient.request<{ sessions: AuthSession[] }>(\n      'GET',\n      '/auth/sessions',\n    );\n\n    if (response.data) {\n      return { data: response.data.sessions, error: null, status: response.status };\n    }\n\n    return { data: null, error: response.error, status: response.status };\n  }\n\n  async revokeSession(sessionId: string): Promise<PalbaseResponse<void>> {\n    validatePathParam('sessionId', sessionId);\n    return this.httpClient.request<void>('DELETE', `/auth/sessions/${sessionId}`);\n  }\n\n  async revokeAllSessions(): Promise<PalbaseResponse<void>> {\n    return this.httpClient.request<void>('DELETE', '/auth/sessions');\n  }\n\n  // ── MFA ─────────────────────────────────────────────────\n\n  get mfa() {\n    this._mfa ??= this.buildMfa();\n    return this._mfa;\n  }\n\n  private buildMfa() {\n    return {\n      enroll: (params: MFAEnrollParams): Promise<PalbaseResponse<MFAEnrollResult>> =>\n        this.httpClient.request('POST', '/auth/mfa/enroll', { body: params }),\n\n      verifyEnrollment: (code: string): Promise<PalbaseResponse<{ status: string }>> =>\n        this.httpClient.request('POST', '/auth/mfa/verify', { body: { code } }),\n\n      challenge: (params: MFAChallengeParams): Promise<PalbaseResponse<TokenResponse>> =>\n        this.httpClient.request('POST', '/auth/mfa/challenge', { body: params }),\n\n      recovery: (params: MFARecoveryParams): Promise<PalbaseResponse<TokenResponse>> =>\n        this.httpClient.request('POST', '/auth/mfa/recovery', { body: params }),\n\n      listFactors: (): Promise<PalbaseResponse<{ factors: MFAFactor[] }>> =>\n        this.httpClient.request('GET', '/auth/mfa/factors'),\n\n      removeFactor: (\n        factorId: string,\n        currentPassword: string,\n      ): Promise<PalbaseResponse<{ status: string }>> => {\n        validatePathParam('factorId', factorId);\n        return this.httpClient.request('DELETE', `/auth/mfa/factors/${factorId}`, {\n          body: { current_password: currentPassword },\n        });\n      },\n\n      regenerateRecoveryCodes: (): Promise<PalbaseResponse<{ recovery_codes: string[] }>> =>\n        this.httpClient.request('POST', '/auth/mfa/recovery-codes/regenerate'),\n\n      emailEnroll: (): Promise<PalbaseResponse<{ status: string }>> =>\n        this.httpClient.request('POST', '/auth/mfa/email/enroll'),\n\n      emailChallenge: (\n        params: MFAEmailChallengeParams,\n      ): Promise<PalbaseResponse<{ status: string }>> =>\n        this.httpClient.request('POST', '/auth/mfa/email/challenge', { body: params }),\n\n      emailVerify: (params: MFAEmailVerifyParams): Promise<PalbaseResponse<TokenResponse>> =>\n        this.httpClient.request('POST', '/auth/mfa/email/verify', { body: params }),\n    };\n  }\n\n  // ── OAuth / Social ──────────────────────────────────────\n\n  async getOAuthURL(options: OAuthOptions): Promise<PalbaseResponse<{ url: string }>> {\n    const response = await this.beginOAuth(options);\n    return { ...response, data: response.data ? { url: response.data.authorizationURL } : null };\n  }\n\n  beginOAuth(options: OAuthOptions): Promise<PalbaseResponse<OAuthTransaction>> {\n    return this.oauthFlow.begin(options);\n  }\n\n  completeOAuth(params: {\n    transactionId: string;\n    resultCode?: string;\n    callbackURL?: string;\n  }): Promise<PalbaseResponse<OAuthResult>> {\n    return this.oauthFlow.complete(params.transactionId, params.resultCode, params.callbackURL);\n  }\n\n  cancelOAuth(transactionId: string): Promise<PalbaseResponse<void>> {\n    return this.oauthFlow.cancel(transactionId);\n  }\n\n  // ── Identities ──────────────────────────────────────────\n\n  async listIdentities(): Promise<PalbaseResponse<{ identities: Identity[] }>> {\n    return this.httpClient.request<{ identities: Identity[] }>('GET', '/auth/identities');\n  }\n\n  linkIdentity(options: Omit<OAuthOptions, 'purpose'>): Promise<PalbaseResponse<OAuthTransaction>> {\n    return this.beginOAuth({ ...options, purpose: 'link' });\n  }\n\n  async unlinkIdentity(identityId: string): Promise<PalbaseResponse<{ success: boolean }>> {\n    validatePathParam('identityId', identityId);\n    return this.httpClient.request<{ success: boolean }>(\n      'DELETE',\n      `/auth/identities/${identityId}`,\n    );\n  }\n\n  // ── Magic Link ──────────────────────────────────────────\n\n  async requestMagicLink(params: MagicLinkParams): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/magic-link', {\n      body: params,\n    });\n  }\n\n  async verifyMagicLink(\n    params: MagicLinkVerifyParams,\n  ): Promise<PalbaseResponse<{ user: User; session: Session }>> {\n    const response = await this.httpClient.request<AuthResult>('POST', '/auth/magic-link/verify', {\n      body: params,\n    });\n\n    if (response.data?.access_token) {\n      const session = toSession(response.data);\n      const user = toUser(response.data);\n      this.setSessionAndWireRefresh(session);\n      return { data: { user, session }, error: null, status: response.status };\n    }\n\n    return { data: null, error: response.error, status: response.status };\n  }\n\n  // ── Trusted Devices ─────────────────────────────────────\n\n  async listTrustedDevices(): Promise<PalbaseResponse<{ trusted_devices: TrustedDevice[] }>> {\n    return this.httpClient.request<{ trusted_devices: TrustedDevice[] }>(\n      'GET',\n      '/auth/trusted-devices',\n    );\n  }\n\n  async registerTrustedDevice(\n    params: RegisterTrustedDeviceParams,\n  ): Promise<PalbaseResponse<{ trusted_device_token: string }>> {\n    return this.httpClient.request<{ trusted_device_token: string }>(\n      'POST',\n      '/auth/trusted-devices',\n      { body: params },\n    );\n  }\n\n  async revokeTrustedDevice(deviceId: string): Promise<PalbaseResponse<{ success: boolean }>> {\n    validatePathParam('deviceId', deviceId);\n    return this.httpClient.request<{ success: boolean }>(\n      'DELETE',\n      `/auth/trusted-devices/${deviceId}`,\n    );\n  }\n\n  // ── Session State ───────────────────────────────────────\n\n  getSession(): { data: Session | null; error: null } {\n    return { data: this.currentSession, error: null };\n  }\n\n  onAuthStateChange(callback: AuthStateChangeCallback): {\n    data: { subscription: { unsubscribe: () => void } };\n  } {\n    const unsubscribe = this.tokenManager.onAuthStateChange((event, session) => {\n      let authEvent: AuthEvent;\n\n      if (event === 'SESSION_SET') {\n        authEvent = this.hasSession ? 'TOKEN_REFRESHED' : 'SIGNED_IN';\n        this.hasSession = true;\n      } else {\n        authEvent = 'SIGNED_OUT';\n        this.hasSession = false;\n      }\n\n      callback(authEvent, session);\n    });\n\n    return { data: { subscription: { unsubscribe } } };\n  }\n\n  // ── Server-only ─────────────────────────────────────────\n\n  /**\n   * Verify a user's JWT token by calling GET /auth/user with their token.\n   * Server-only — should NOT be exposed in client SDK.\n   */\n  async verifyUserToken(jwt: string): Promise<PalbaseResponse<User>> {\n    const url = `${this.baseUrl}/auth/user`;\n\n    let response: Response;\n    try {\n      response = await fetch(url, {\n        method: 'GET',\n        headers: {\n          apikey: this.apiKey,\n          Authorization: `Bearer ${jwt}`,\n          'Content-Type': 'application/json',\n        },\n      });\n    } catch (error) {\n      throw new PalbaseError(\n        'network_error',\n        error instanceof Error ? error.message : 'Network request failed',\n        0,\n      );\n    }\n\n    const contentType = response.headers.get('Content-Type');\n    if (response.ok && contentType?.includes('application/json')) {\n      const data = (await response.json()) as User;\n      return { data, error: null, status: response.status };\n    }\n\n    let errorBody: { error?: string; error_description?: string } | undefined;\n    if (contentType?.includes('application/json')) {\n      errorBody = (await response.json()) as typeof errorBody;\n    }\n\n    return {\n      data: null,\n      error: new PalbaseError(\n        errorBody?.error ?? 'invalid_token',\n        errorBody?.error_description ?? 'Token verification failed',\n        response.status,\n        errorBody,\n      ),\n      status: response.status,\n    };\n  }\n\n  // ── Private ─────────────────────────────────────────────\n\n  private setSessionAndWireRefresh(session: Session): void {\n    this.tokenManager.setSession(session);\n    this.hasSession = true;\n\n    this.tokenManager.refreshFunction = (refreshToken) => this.refreshToken(refreshToken);\n  }\n\n  private refreshToken(refreshToken: string): Promise<Session> {\n    return this.coordinateRefresh\n      ? this.coordinateRefresh(refreshToken, (token) => this.requestRefresh(token))\n      : this.requestRefresh(refreshToken);\n  }\n\n  private async requestRefresh(refreshToken: string): Promise<Session> {\n    const response = await this.httpClient.request<TokenResponse>('POST', '/auth/token/refresh', {\n      body: { refresh_token: refreshToken },\n      // Rotating refresh tokens are one-use credentials. Retrying an\n      // uncertain exchange can trigger reuse detection and revoke a session.\n      retry: false,\n      skipSessionRefresh: true,\n    });\n\n    if (response.error || !response.data) {\n      throw response.error ?? new Error('Failed to refresh token');\n    }\n    return {\n      accessToken: response.data.access_token,\n      refreshToken: response.data.refresh_token,\n      expiresAt: Date.now() + response.data.expires_in * 1000,\n    };\n  }\n}\n","import type { HttpClient, PalbaseResponse } from '@palbase/core';\nimport type {\n  AttestAndroidParams,\n  AttestAndroidResult,\n  AttestiOSParams,\n  AttestiOSResult,\n  BindDeviceParams,\n  DeviceInfo,\n  VerifyRequestSignatureParams,\n} from './types.js';\n\n/** Validates that a path parameter does not contain path traversal characters. */\nfunction validatePathParam(name: string, value: string): void {\n  if (value.includes('/') || value.includes('..') || value.includes('%')) {\n    throw new Error(`Invalid ${name}: must not contain path separators`);\n  }\n}\n\nconst TOKEN_BUFFER_MS = 5 * 60 * 1000; // 5 min before expiry\n\n/**\n * Device attestation client.\n * Handles device challenge/attestation/bind and App Check JWT cache.\n */\nexport class DeviceClient {\n  private readonly httpClient: HttpClient;\n  private cachedToken: { token: string; expiresAt: number } | null = null;\n  private refreshTimer: ReturnType<typeof setTimeout> | null = null;\n\n  constructor(httpClient: HttpClient) {\n    this.httpClient = httpClient;\n  }\n\n  /** Generate a device attestation challenge. */\n  async generateChallenge(): Promise<PalbaseResponse<{ challenge: string }>> {\n    return this.httpClient.request<{ challenge: string }>('POST', '/auth/devices/challenge');\n  }\n\n  /** Attest an Android device with a Play Integrity verdict token. */\n  async attestAndroid(params: AttestAndroidParams): Promise<PalbaseResponse<AttestAndroidResult>> {\n    return this.httpClient.request<AttestAndroidResult>('POST', '/auth/devices/attest/android', {\n      body: params,\n    });\n  }\n\n  /** Attest an iOS device with App Attest attestation data. */\n  async attestiOS(params: AttestiOSParams): Promise<PalbaseResponse<AttestiOSResult>> {\n    return this.httpClient.request<AttestiOSResult>('POST', '/auth/devices/attest/ios', {\n      body: params,\n    });\n  }\n\n  /** Bind a verified device with a public key for request signing. */\n  async bind(params: BindDeviceParams): Promise<PalbaseResponse<{ success: boolean }>> {\n    return this.httpClient.request<{ success: boolean }>('POST', '/auth/devices/bind', {\n      body: params,\n    });\n  }\n\n  /** List all devices for the current user. */\n  async list(): Promise<PalbaseResponse<{ devices: DeviceInfo[] }>> {\n    return this.httpClient.request<{ devices: DeviceInfo[] }>('GET', '/auth/devices');\n  }\n\n  /** Delete a device by ID. */\n  async delete(deviceId: string): Promise<PalbaseResponse<{ success: boolean }>> {\n    validatePathParam('deviceId', deviceId);\n    return this.httpClient.request<{ success: boolean }>('DELETE', `/auth/devices/${deviceId}`);\n  }\n\n  /**\n   * Verify a request signature from a device (server-only).\n   * Should NOT be exposed in client SDK.\n   */\n  async verifyRequestSignature(\n    deviceId: string,\n    params: VerifyRequestSignatureParams,\n  ): Promise<PalbaseResponse<{ verified: boolean }>> {\n    validatePathParam('deviceId', deviceId);\n    return this.httpClient.request<{ verified: boolean }>(\n      'POST',\n      `/auth/devices/${deviceId}/verify`,\n      { body: params },\n    );\n  }\n\n  /** Get the cached App Check token, or null if not available / expired. */\n  getToken(): string | null {\n    if (!this.cachedToken) return null;\n    if (Date.now() >= this.cachedToken.expiresAt) return null;\n    return this.cachedToken.token;\n  }\n\n  /** Whether App Check is active (token cached and not expired). */\n  get isActive(): boolean {\n    return this.getToken() !== null;\n  }\n\n  /** Set a cached App Check token manually (e.g. after attest flow). */\n  setCachedToken(token: string, expiresInMs: number): void {\n    this.cachedToken = {\n      token,\n      expiresAt: Date.now() + expiresInMs,\n    };\n    this.scheduleRefresh(expiresInMs);\n  }\n\n  /** Clean up timers and cached state. */\n  dispose(): void {\n    if (this.refreshTimer) {\n      clearTimeout(this.refreshTimer);\n      this.refreshTimer = null;\n    }\n    this.cachedToken = null;\n  }\n\n  private scheduleRefresh(ttlMs: number): void {\n    if (this.refreshTimer) {\n      clearTimeout(this.refreshTimer);\n    }\n    const refreshIn = Math.max(ttlMs - TOKEN_BUFFER_MS, 0);\n    this.refreshTimer = setTimeout(() => {\n      this.cachedToken = null;\n    }, refreshIn);\n  }\n}\n","import { type HttpClient, PalbaseError, type PalbaseResponse, type Session } from '@palbase/core';\nimport type { Identity, User } from './types.js';\n\nexport type OAuthProvider = 'google' | 'apple' | 'microsoft' | 'github';\nexport type OAuthPurpose = 'sign_in' | 'link';\n\nexport interface OAuthConfig {\n  contract_revision: 1;\n  config_revision: string;\n  environment_ref: string;\n  application_key: string;\n  platform: 'web';\n  variant: string;\n  clients: Array<{\n    key: string;\n    provider: OAuthProvider;\n    mode: 'browser';\n    return_uris: string[];\n  }>;\n}\n\nexport interface OAuthOptions {\n  provider: OAuthProvider;\n  redirectTo?: string;\n  purpose?: OAuthPurpose;\n}\n\nexport interface OAuthTransaction {\n  id: string;\n  clientKey: string;\n  provider: OAuthProvider;\n  purpose: OAuthPurpose;\n  expiresAt: string;\n  authorizationURL: string;\n}\n\nexport type OAuthResult =\n  | { status: 'signedIn'; user: User; session: Session; isNewUser: boolean }\n  | { status: 'mfaRequired'; mfaToken: string; factors: string[] }\n  | { status: 'linked'; identity: Identity; userId: string };\n\n/** Per-transaction proof storage. A failed write must reject; never fall back to memory. */\nexport interface OAuthTransactionStorage {\n  load(key: string): string | null | Promise<string | null>;\n  save(key: string, value: string, expiresAt: string): void | Promise<void>;\n  remove(key: string): void | Promise<void>;\n}\n\ninterface PendingOAuth {\n  transaction: Omit<OAuthTransaction, 'authorizationURL'>;\n  scope: string;\n  returnURI: string;\n  verifier: string;\n  resultCode?: string;\n}\n\nconst providers = new Set(['google', 'apple', 'microsoft', 'github']);\nconst keyPattern = /^[a-z0-9][a-z0-9_-]{0,63}$/;\nconst transactionPattern = /^[A-Za-z0-9_-]{1,128}$/;\nconst headers = { 'Palbase-Auth-Contract': '1' };\n\nfunction invalid(message: string, code = 'invalid_oauth_contract'): never {\n  throw new PalbaseError(code, message, 0);\n}\n\nfunction record(\n  value: unknown,\n  required: string[],\n  optional: string[] = [],\n): Record<string, unknown> {\n  if (value === null || typeof value !== 'object' || Array.isArray(value))\n    invalid('Expected an OAuth object');\n  const fields = value as Record<string, unknown>;\n  if (required.some((key) => !Object.hasOwn(fields, key))) invalid('Missing required OAuth field');\n  const allowed = new Set([...required, ...optional]);\n  if (\n    Object.keys(fields).some(\n      (key) => !allowed.has(key) || fields[key] === null || fields[key] === undefined,\n    )\n  ) {\n    invalid('Unknown or null OAuth field');\n  }\n  return fields;\n}\n\nfunction text(value: unknown): string {\n  if (typeof value !== 'string' || value.length === 0) invalid('Expected a nonempty OAuth string');\n  return value;\n}\n\nfunction matches(value: string, pattern: RegExp): boolean {\n  return pattern.exec(value)?.[0] === value;\n}\n\nfunction textArray(value: unknown): string[] {\n  if (!Array.isArray(value)) invalid('Expected an OAuth string array');\n  return value.map(text);\n}\n\nfunction provider(value: unknown): OAuthProvider {\n  if (typeof value !== 'string' || !providers.has(value)) invalid('Unsupported OAuth provider');\n  return value as OAuthProvider;\n}\n\nfunction returnURL(value: string): URL {\n  // Reject before URL parsing can strip whitespace or normalize backslashes.\n  if (/\\s|\\\\/.test(value)) invalid('Invalid OAuth return URI');\n  const url = new URL(value);\n  const loopback = ['localhost', '127.0.0.1', '[::1]'].includes(url.hostname);\n  if (\n    (url.protocol !== 'https:' && !(url.protocol === 'http:' && loopback)) ||\n    url.username ||\n    url.password ||\n    url.search ||\n    url.hash\n  ) {\n    invalid(\n      'OAuth return URI must use HTTPS, or HTTP on loopback, without credentials, query or fragment',\n    );\n  }\n  return url;\n}\n\n/** The web reader accepts only a complete web snapshot emitted by `palbase link`. */\nexport function parseOAuthConfig(value: unknown, environmentRef?: string): OAuthConfig {\n  const c = record(value, [\n    'contract_revision',\n    'config_revision',\n    'environment_ref',\n    'application_key',\n    'platform',\n    'variant',\n    'clients',\n  ]);\n  if (\n    c.contract_revision !== 1 ||\n    c.platform !== 'web' ||\n    !matches(text(c.config_revision), /^[1-9][0-9]*$/)\n  )\n    invalid('Unsupported OAuth revision or platform');\n  if (!matches(text(c.application_key), keyPattern) || !matches(text(c.variant), keyPattern))\n    invalid('Invalid OAuth application or variant');\n  const ref = text(c.environment_ref);\n  if (environmentRef !== undefined && ref !== environmentRef)\n    invalid('OAuth snapshot belongs to a different environment');\n  if (!Array.isArray(c.clients)) invalid('Expected OAuth clients');\n  const keys = new Set<string>();\n  const names = new Set<OAuthProvider>();\n  const clients = c.clients.map((value) => {\n    const client = record(value, ['key', 'provider', 'mode', 'return_uris']);\n    const key = text(client.key);\n    const name = provider(client.provider);\n    const uris = textArray(client.return_uris);\n    if (\n      client.mode !== 'browser' ||\n      !matches(key, keyPattern) ||\n      keys.has(key) ||\n      names.has(name) ||\n      uris.length === 0 ||\n      new Set(uris).size !== uris.length\n    ) {\n      invalid('Invalid or ambiguous OAuth client selection');\n    }\n    for (const uri of uris) returnURL(uri);\n    keys.add(key);\n    names.add(name);\n    return { key, provider: name, mode: 'browser' as const, return_uris: uris };\n  });\n  return {\n    contract_revision: 1,\n    config_revision: text(c.config_revision),\n    environment_ref: ref,\n    application_key: text(c.application_key),\n    platform: 'web',\n    variant: text(c.variant),\n    clients,\n  };\n}\n\nfunction browserStorage(): OAuthTransactionStorage {\n  const storage = (): Storage => {\n    if (typeof window === 'undefined')\n      invalid(\n        'Server OAuth requires request-scoped proof storage; use pbServer() in Next.js',\n        'oauth_storage_required',\n      );\n    return window.sessionStorage;\n  };\n  return {\n    load: (key) => storage().getItem(key),\n    save: (key, value) => storage().setItem(key, value),\n    remove: (key) => storage().removeItem(key),\n  };\n}\n\nfunction base64URL(bytes: Uint8Array): string {\n  return btoa(String.fromCharCode(...bytes))\n    .replaceAll('+', '-')\n    .replaceAll('/', '_')\n    .replaceAll('=', '');\n}\n\nfunction decodeResult(value: unknown, pending: PendingOAuth): OAuthResult {\n  if (value === null || typeof value !== 'object' || !('status' in value))\n    invalid('Missing OAuth result status');\n  if (value.status === 'signed_in' && pending.transaction.purpose === 'sign_in') {\n    const r = record(value, ['status', 'session', 'user', 'is_new_user']);\n    const s = record(r.session, ['access_token', 'refresh_token', 'token_type', 'expires_in']);\n    const u = record(r.user, ['id', 'email_verified', 'created_at', 'roles'], ['email']);\n    if (\n      s.token_type !== 'Bearer' ||\n      !Number.isSafeInteger(s.expires_in) ||\n      Number(s.expires_in) <= 0 ||\n      Number(s.expires_in) > 2147483647 ||\n      typeof u.email_verified !== 'boolean' ||\n      typeof r.is_new_user !== 'boolean'\n    )\n      invalid('Invalid signed-in OAuth result');\n    const createdAt = text(u.created_at);\n    return {\n      status: 'signedIn',\n      isNewUser: r.is_new_user,\n      session: {\n        accessToken: text(s.access_token),\n        refreshToken: text(s.refresh_token),\n        expiresAt: Date.now() + Number(s.expires_in) * 1000,\n      },\n      user: {\n        id: text(u.id),\n        email: u.email === undefined ? '' : text(u.email),\n        emailVerified: u.email_verified,\n        createdAt,\n        updatedAt: createdAt,\n        roles: textArray(u.roles),\n      },\n    };\n  }\n  if (value.status === 'mfa_required' && pending.transaction.purpose === 'sign_in') {\n    const r = record(value, ['status', 'mfa_token', 'factors']);\n    const factors = textArray(r.factors);\n    if (factors.length === 0 || new Set(factors).size !== factors.length)\n      invalid('Invalid MFA factors');\n    return { status: 'mfaRequired', mfaToken: text(r.mfa_token), factors };\n  }\n  if (value.status === 'linked' && pending.transaction.purpose === 'link') {\n    const r = record(value, ['status', 'identity', 'user_id']);\n    const i = record(r.identity, ['id', 'provider', 'provider_user_id', 'created_at']);\n    if (i.provider !== pending.transaction.provider)\n      invalid('Linked identity belongs to a different OAuth provider');\n    return {\n      status: 'linked',\n      userId: text(r.user_id),\n      identity: {\n        id: text(i.id),\n        provider: text(i.provider),\n        provider_user_id: text(i.provider_user_id),\n        created_at: text(i.created_at),\n      },\n    };\n  }\n  return invalid('OAuth result does not match this transaction');\n}\n\n/** One protocol implementation for AuthClient, the web facade and Next.js. */\nexport class OAuthFlow {\n  private readonly config?: OAuthConfig;\n  private readonly storage: OAuthTransactionStorage;\n  private readonly scope: string;\n  private readonly completing = new Map<\n    string,\n    { resultCode?: string; callbackURL?: string; promise: Promise<PalbaseResponse<OAuthResult>> }\n  >();\n\n  constructor(\n    private readonly http: HttpClient,\n    config: OAuthConfig | undefined,\n    storage: OAuthTransactionStorage | undefined,\n    private readonly adopt: (result: Extract<OAuthResult, { status: 'signedIn' }>) => void,\n    baseURL: string,\n  ) {\n    this.config = config === undefined ? undefined : parseOAuthConfig(config);\n    this.storage = storage ?? browserStorage();\n    this.scope = config\n      ? [\n          new URL(baseURL).href.replace(/\\/$/, ''),\n          config.environment_ref,\n          config.application_key,\n          config.platform,\n          config.variant,\n        ].join('/')\n      : '';\n  }\n\n  private key(id: string): string {\n    if (!matches(id, transactionPattern)) invalid('Invalid OAuth transaction ID');\n    return `palbe.oauth.${this.scope}.${id}`;\n  }\n\n  private client(name: OAuthProvider) {\n    const client = this.config?.clients.find((client) => client.provider === name);\n    if (!client)\n      invalid(\n        `${name} OAuth is not configured for this application and build; run palbase link after configuring the client`,\n        'auth_client_not_configured',\n      );\n    return client;\n  }\n\n  private async guard<T>(\n    operation: () => Promise<PalbaseResponse<T>>,\n  ): Promise<PalbaseResponse<T>> {\n    try {\n      return await operation();\n    } catch (error) {\n      const problem =\n        error instanceof PalbaseError\n          ? error\n          : new PalbaseError(\n              'oauth_failed',\n              error instanceof Error ? error.message : 'OAuth failed',\n              0,\n            );\n      return { data: null, error: problem, status: problem.status };\n    }\n  }\n\n  begin(options: OAuthOptions): Promise<PalbaseResponse<OAuthTransaction>> {\n    return this.guard(async () => {\n      const client = this.client(options.provider);\n      const purpose = options.purpose ?? 'sign_in';\n      if (purpose !== 'sign_in' && purpose !== 'link') invalid('Invalid OAuth purpose');\n      const returnURI =\n        options.redirectTo ?? (client.return_uris.length === 1 ? client.return_uris[0] : undefined);\n      if (returnURI === undefined || !client.return_uris.includes(returnURI))\n        invalid('Choose a configured OAuth return URI', 'invalid_return_uri');\n      const verifier = base64URL(crypto.getRandomValues(new Uint8Array(32)));\n      const challenge = base64URL(\n        new Uint8Array(await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier))),\n      );\n      const response = await this.http.request<unknown>('POST', '/auth/oauth/transactions', {\n        headers,\n        retry: false,\n        body: {\n          client_key: client.key,\n          purpose,\n          completion_challenge: challenge,\n          completion_challenge_method: 'S256',\n          return_uri: returnURI,\n        },\n      });\n      if (response.error) return { data: null, error: response.error, status: response.status };\n      const r = record(response.data, [\n        'transaction_id',\n        'client_key',\n        'provider',\n        'purpose',\n        'mode',\n        'expires_at',\n        'authorization_url',\n      ]);\n      const id = text(r.transaction_id);\n      const expiresAt = text(r.expires_at);\n      const authorizationURL = text(r.authorization_url);\n      const authorize = new URL(authorizationURL);\n      const host = {\n        google: 'accounts.google.com',\n        apple: 'appleid.apple.com',\n        microsoft: 'login.microsoftonline.com',\n        github: 'github.com',\n      }[client.provider];\n      if (\n        r.client_key !== client.key ||\n        r.provider !== client.provider ||\n        r.purpose !== purpose ||\n        r.mode !== 'browser' ||\n        !matches(id, transactionPattern) ||\n        !(Date.parse(expiresAt) > Date.now()) ||\n        authorize.protocol !== 'https:' ||\n        authorize.hostname !== host ||\n        authorize.username ||\n        authorize.password ||\n        authorize.port ||\n        authorize.hash\n      )\n        invalid('Server returned an invalid OAuth transaction');\n      const transaction: OAuthTransaction = {\n        id,\n        clientKey: client.key,\n        provider: client.provider,\n        purpose,\n        expiresAt,\n        authorizationURL,\n      };\n      const pending: PendingOAuth = {\n        transaction: { id, clientKey: client.key, provider: client.provider, purpose, expiresAt },\n        scope: this.scope,\n        returnURI,\n        verifier,\n      };\n      await this.storage.save(this.key(id), JSON.stringify(pending), expiresAt);\n      return { data: transaction, error: null, status: response.status };\n    });\n  }\n\n  private async pending(id: string): Promise<PendingOAuth> {\n    const raw = await this.storage.load(this.key(id));\n    if (!raw || raw.length > 16 * 1024)\n      invalid('OAuth transaction is missing or expired', 'auth_transaction_expired');\n    const p = record(\n      JSON.parse(raw),\n      ['transaction', 'scope', 'returnURI', 'verifier'],\n      ['resultCode'],\n    );\n    const t = record(p.transaction, ['id', 'clientKey', 'provider', 'purpose', 'expiresAt']);\n    const name = provider(t.provider);\n    const client = this.client(name);\n    if (\n      p.scope !== this.scope ||\n      t.id !== id ||\n      t.clientKey !== client.key ||\n      (t.purpose !== 'sign_in' && t.purpose !== 'link') ||\n      !(Date.parse(text(t.expiresAt)) > Date.now()) ||\n      !client.return_uris.includes(text(p.returnURI)) ||\n      !matches(text(p.verifier), /^[A-Za-z0-9_-]{43}$/)\n    )\n      invalid(\n        'OAuth transaction does not belong to this application or has expired',\n        'auth_transaction_expired',\n      );\n    return {\n      transaction: {\n        id,\n        clientKey: client.key,\n        provider: name,\n        purpose: t.purpose,\n        expiresAt: text(t.expiresAt),\n      },\n      scope: this.scope,\n      returnURI: text(p.returnURI),\n      verifier: text(p.verifier),\n      ...(p.resultCode === undefined ? {} : { resultCode: text(p.resultCode) }),\n    };\n  }\n\n  complete(\n    id: string,\n    resultCode?: string,\n    callbackURL?: string,\n  ): Promise<PalbaseResponse<OAuthResult>> {\n    const current = this.completing.get(id);\n    if (current) {\n      if (current.resultCode !== resultCode || current.callbackURL !== callbackURL) {\n        return this.guard(async () =>\n          invalid('A different OAuth completion is already in progress', 'invalid_result_code'),\n        );\n      }\n      return current.promise;\n    }\n    const operation = this.guard(async () => {\n      const p = await this.pending(id);\n      if (callbackURL !== undefined) {\n        const url = new URL(callbackURL);\n        const target = returnURL(p.returnURI);\n        if (\n          url.origin !== target.origin ||\n          url.pathname !== target.pathname ||\n          url.username ||\n          url.password ||\n          url.hash ||\n          url.searchParams.size !== 2 ||\n          url.searchParams.getAll('transaction_id').length !== 1 ||\n          url.searchParams.getAll('result_code').length !== 1 ||\n          url.searchParams.get('transaction_id') !== id ||\n          url.searchParams.get('result_code') !== resultCode\n        )\n          invalid('Callback does not match this OAuth transaction', 'invalid_callback');\n      }\n      if (resultCode !== undefined) {\n        if (\n          !matches(resultCode, /^[A-Za-z0-9_-]{32,128}$/) ||\n          (p.resultCode !== undefined && p.resultCode !== resultCode)\n        )\n          invalid('OAuth completion cannot change its provider result', 'invalid_result_code');\n        p.resultCode = resultCode;\n        await this.storage.save(this.key(id), JSON.stringify(p), p.transaction.expiresAt);\n      }\n      if (!p.resultCode) invalid('OAuth transaction has no browser result');\n      const response = await this.http.request<unknown>(\n        'POST',\n        `/auth/oauth/transactions/${id}/complete`,\n        {\n          headers,\n          retry: false,\n          body: { completion_verifier: p.verifier, result_code: p.resultCode },\n        },\n      );\n      if (response.error) {\n        if (\n          response.status >= 400 &&\n          response.status < 500 &&\n          response.status !== 408 &&\n          response.status !== 429\n        )\n          await this.storage.remove(this.key(id));\n        return { data: null, error: response.error, status: response.status };\n      }\n      const result = decodeResult(response.data, p);\n      await this.storage.remove(this.key(id));\n      if (result.status === 'signedIn') this.adopt(result);\n      return { data: result, error: null, status: response.status };\n    });\n    this.completing.set(id, { resultCode, callbackURL, promise: operation });\n    void operation.finally(() => this.completing.delete(id));\n    return operation;\n  }\n\n  cancel(id: string): Promise<PalbaseResponse<void>> {\n    return this.guard(async () => {\n      const p = await this.pending(id);\n      const response = await this.http.request<void>(\n        'POST',\n        `/auth/oauth/transactions/${id}/cancel`,\n        { headers, retry: false, body: { completion_verifier: p.verifier } },\n      );\n      if (!response.error) await this.storage.remove(this.key(id));\n      return response;\n    });\n  }\n}\n","/**\n * `pb_<environmentRef>_<scope><random>` → environmentRef ('' if malformed).\n *\n * THE KEY IS THE ONLY SOURCE. There is no `environmentRef` on `PalbeConfig` to\n * prefer over this parse: the field was a second copy of what the key already\n * carries, `palbase link` was measured writing one value while minting a key\n * carrying another, and it was removed everywhere (see `runtime.ts`'s note).\n * So app-bound runtime storage (`runtime.ts`) and palbe/next cookie naming\n * (client, server, proxy, callback) all reach the ref through the publishable\n * parser below, off `config.apiKey`.\n *\n * The key is shape-validated (prefix `pb`, a 4-24 character lowercase ASCII\n * alphanumeric environmentRef, and a `<scope><at-least-20-base62-random>` secret\n * segment where scope ∈ {c,s}) before a ref is returned.\n *\n * THE SECRET'S LENGTH IS NOT PART OF THE CONTRACT — only its floor is. Two\n * minters ship two lengths (the stack's own `initenv` writes 20 base62, the\n * cloud control plane writes 32), and the gate that actually admits a request\n * says so outright: *\"a shorter or longer secret is not a security property\n * this door can rule on, and refusing one would only turn off a stack whose key\n * works everywhere else\"* (v2/internal/platform/identitymw.go: parseAPIKey).\n * Pinning EXACTLY 20 here made this SDK refuse every key the cloud has ever\n * minted (measured 2026-08-25: `buildRuntime` threw and palbe-gen never ran).\n * The floor stays, because the short/loose body is what the finding below was\n * about; the ceiling was never anyone's rule. A structurally-invalid key returns\n * '' so session storage stays\n * UNSCOPED rather than getting bound to a partially-parsed ref — a loose parse\n * (e.g. `pb_victim_cXX`) must not scope persisted sessions to `victim` and\n * hydrate a session belonging to a different, real key. The backend remains the\n * authority that rejects a bad key on the first request; this keeps the client's\n * local session-storage scoping honest. (Audit finding apikey-ref-mismatch.)\n */\nconst API_KEY_RE = /^pb_([a-z0-9]{4,24})_[cs][A-Za-z0-9]{20,}$/;\nconst PUBLISHABLE_API_KEY_RE = /^pb_([a-z0-9]{4,24})_c[A-Za-z0-9]{20,}$/;\n\nexport function environmentRefFromApiKey(apiKey: string): string {\n  const m = API_KEY_RE.exec(apiKey);\n  return m ? (m[1] ?? '') : '';\n}\n\n/** Internal app-runtime parser: browser config accepts publishable keys only. */\nexport function environmentRefFromPublishableApiKey(apiKey: string): string {\n  const match = PUBLISHABLE_API_KEY_RE.exec(apiKey);\n  return match ? (match[1] ?? '') : '';\n}\n","// palbe.gen.ts emitter — TypeScript port of the CLI's Go endpoint emitter.\n// The checked-in golden locks the complete app-bound runtime config and endpoint\n// output shape.\n\nimport { type OAuthConfig, parseOAuthConfig } from '@palbase/auth';\nimport type { ErrorDef, Op, RoomDecl, Schema } from './parser.js';\n\nexport type { OAuthConfig } from '@palbase/auth';\n\n// GeneratedConfig carries the runtime config values the generated palbe.gen.ts\n// writes into __configure() (the web SDK seam — web embeds config in the\n// generated module, unlike iOS which reads the per-env plist).\nexport interface GeneratedConfig {\n  url: string;\n  apiKey: string;\n  appId: string;\n  sealedRoot?: string;\n  oauth?: OAuthConfig;\n}\n\n// --- Naming -----------------------------------------------------------------\n\nexport function opSegments(opId: string): string[] {\n  return opId.split('.').filter((p) => p !== '');\n}\n\nfunction typeNameOf(s: string): string {\n  return sanitize(s, true);\n}\n\n// typePrefix builds the PascalCase concatenation of all op-id segments, used\n// as the BASE for top-level <Prefix>Request / <Prefix>Response / <Prefix>Error\n// type names. Example: \"rooms.create\" → \"RoomsCreate\".\nfunction typePrefix(opId: string): string {\n  return opSegments(opId).map(typeNameOf).join('');\n}\n\nfunction sanitize(s: string, firstUpper: boolean): string {\n  const parts: string[] = [];\n  let cur = '';\n  for (const ch of s) {\n    if (/^[A-Za-z0-9]$/.test(ch)) {\n      cur += ch;\n    } else if (cur.length > 0) {\n      parts.push(cur);\n      cur = '';\n    }\n  }\n  if (cur.length > 0) parts.push(cur);\n  if (parts.length === 0) return firstUpper ? 'Op' : 'op';\n  let out = '';\n  parts.forEach((p, i) => {\n    out +=\n      i === 0 && !firstUpper\n        ? p.charAt(0).toLowerCase() + p.slice(1)\n        : p.charAt(0).toUpperCase() + p.slice(1);\n  });\n  if (out.charAt(0) >= '0' && out.charAt(0) <= '9') out = `_${out}`;\n  return out;\n}\n\n// --- Emit -------------------------------------------------------------------\n\n// emitTypeScript turns parsed operations into a palbe.gen.ts module.\n// The file structure:\n//   header → imports → __configure → types section → typed-errors section →\n//   namespaces section (skip comments + __registerNamespaces) → declare module\nexport function emitTypeScript(\n  ops: Op[],\n  cfg: GeneratedConfig,\n  rooms: RoomDecl[] = [],\n  rolesArtifact = '',\n): string {\n  // Filter reserved top-level namespaces; collect skip comments.\n  // Single-segment operationIds (the live wire shape — verb-prefixed ids like\n  // `getHello`) pass the same filter and later register as ROOT-LEVEL\n  // descriptor keys. Skip-comment dedup is case-insensitive (auth/Auth are the\n  // same reserved surface); the first-seen casing is printed.\n  const usable: Op[] = [];\n  const skippedNS: string[] = [];\n  const seenSkip = new Set<string>();\n  for (const op of ops) {\n    const [ns] = opSegments(op.operationId);\n    if (ns === undefined) continue;\n    if (tsReservedTopLevel(ns)) {\n      const key = ns.toLowerCase();\n      if (!seenSkip.has(key)) {\n        seenSkip.add(key);\n        skippedNS.push(ns);\n      }\n      continue;\n    }\n    usable.push(op);\n  }\n  skippedNS.sort();\n\n  // Per-operation gates: nested-reserved / body+query / non-primitive-query /\n  // kind-mismatch filtering happens BEFORE type emission, so skipped ops\n  // neither emit dead types nor squat type-name prefixes against later ops.\n  const [candidates, opSkips] = filterTSOps(usable);\n\n  // Build all content sections FIRST (in-memory), so the import lines can be\n  // derived from what is ACTUALLY emitted — an error-bearing op dropped by a\n  // gate must not leave a stray `BackendError` import behind.\n  const [typesOut, collisionSkips, typeCollisionOps] = emitTSTypes(candidates);\n\n  // Type-collision ops have no usable types — they must not be callable-typed.\n  const registerable = candidates.filter((op) => !typeCollisionOps.has(op.operationId));\n\n  const [errorsOut, classCount] = emitTSTypedErrors(registerable);\n\n  // --- Assemble ---\n  let b = '';\n\n  // Header.\n  b += '// AUTO-GENERATED by `palbe-gen` — DO NOT EDIT.\\n';\n  b += '// Regenerate: palbe-gen   (or automatically via the predev/prebuild script)\\n';\n\n  // Imports. `BackendError` is referenced only by emitted error classes;\n  // `CallOptions` only by augmentation method signatures. When neither is\n  // used, the whole `import type ...` line is omitted — the runtime import\n  // from '@palbase/web/internal' always stays.\n  const typeImports: string[] = [];\n  if (classCount > 0) typeImports.push('BackendError');\n  if (registerable.length > 0) typeImports.push('CallOptions');\n  if (typeImports.length > 0) {\n    b += `import type { ${typeImports.join(', ')} } from '@palbase/web';\\n`;\n  }\n  b += \"import { __configure, __registerNamespaces } from '@palbase/web/internal';\\n\\n\";\n\n  b += emitTSConfigure(cfg);\n  b += '\\n';\n\n  // Types + typed errors (either may be empty).\n  b += typesOut;\n  b += errorsOut;\n\n  // Namespaces section.\n  b += '// ── Namespaces ─────────────────────────────────────────────────────\\n\\n';\n  // Skip comments: reserved-namespace, then per-op gates, then type collisions.\n  for (const ns of skippedNS) {\n    b += `// codegen: skipped reserved namespace \"${commentSafe(ns)}\"\\n`;\n  }\n  for (const l of opSkips) {\n    b += `${l}\\n`;\n  }\n  for (const c of collisionSkips) {\n    b += `${c}\\n`;\n  }\n  b += emitTSRegistration(registerable);\n\n  // declare module augmentation — omitted entirely when nothing registers.\n  if (registerable.length > 0) {\n    b += '\\n';\n    b += emitTSAugmentation(registerable);\n  }\n\n  // Rooms last, and only when there are any: a project that never declared one\n  // must get the file it got before, byte for byte (NFR-004).\n  if (rooms.length > 0) {\n    b +=\n      '\\n// \\u2500\\u2500 Rooms (@Room) \\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\u2500\\n\\n';\n    for (const room of rooms) {\n      b += emitTSRoom(room);\n    }\n  }\n\n  // Roles last, and only when an artifact was handed over: a project whose last\n  // `palbase spec` predates roles has none, and it must get the module it got\n  // before, byte for byte. An artifact that is PRESENT but unreadable throws\n  // from here rather than emitting nothing — see parseRolesArtifact.\n  if (rolesArtifact !== '') {\n    b += emitRoles(rolesArtifact);\n  }\n\n  return b;\n}\n\n// emitEnvironmentConfigModule renders the LEAF module the Next proxy imports.\n//\n// NOTHING IS IMPORTED HERE, and that is the entire point. Next compiles the\n// proxy into its OWN bundle, so every module this file reaches is weight paid\n// on every request path — and palbe.gen.ts reaches __configure -> buildRuntime\n// -> messaging/wasm/loader (measured: 2.4 MB against 168 KB). A leaf has no\n// graph to drag, so the proxy can read the selected environment without any of\n// it. __tests__/next-proxy-bundle.test.ts measures that, it does not assume it.\n//\n// It carries the same two published values palbe.gen.ts is configured with —\n// the api_key is always the publishable (anon) key, never service_role.\nexport function emitEnvironmentConfigModule(cfg: GeneratedConfig): string {\n  let b = '// AUTO-GENERATED by `palbe-gen` — DO NOT EDIT.\\n';\n  b += '// The environment is chosen by PALBASE_ENV (default: local).\\n';\n  b += '//\\n';\n  b += '// IMPORT-FREE AND SIDE-EFFECT-FREE ON PURPOSE: the Next proxy reads the\\n';\n  b += '// environment from here precisely because this module reaches nothing else.\\n';\n  b += 'export const environmentConfig = {\\n';\n  b += `  url: ${tsStringLit(cfg.url)},\\n`;\n  b += `  apiKey: ${tsStringLit(cfg.apiKey)},\\n`;\n  if (cfg.sealedRoot) b += `  sealed: { root: ${tsStringLit(cfg.sealedRoot)} },\\n`;\n  b += '} as const;\\n';\n  return b;\n}\n\n// emitTSConfigure renders the __configure({…}) call, and re-exports\n// environmentConfig from the sibling leaf module.\n//\n// WHY THE EXPORT: after this line the address and the publishable key live only\n// inside the SDK's runtime, and the accessor for that runtime is `@internal` —\n// stripped from the published types deliberately. Server code in a Next.js app\n// legitimately needs the same plane (an OIDC leg a browser cannot walk, a\n// webhook verifier, a server action) and would otherwise write the literals a\n// second time.\n//\n// WHY IT IS A RE-EXPORT AND NOT A LITERAL: the Next proxy needs those same two\n// values, and it CANNOT import this file — Next compiles the proxy into its own\n// bundle and this module's __configure call reaches buildRuntime and from there\n// livekit + the MLS WASM loader. So the values live in `palbe.config.ts`, an\n// import-free leaf written beside this file, and both readers take them from\n// there. __configure's own arguments stay literal: the leaf carries no appId\n// and no oauth block, and configuring the runtime is this file's job.\nfunction emitTSConfigure(cfg: GeneratedConfig): string {\n  let b = '__configure({\\n';\n  b += `  url: ${tsStringLit(cfg.url)},\\n`;\n  b += `  apiKey: ${tsStringLit(cfg.apiKey)},\\n`;\n  b += `  appId: ${tsStringLit(cfg.appId)},\\n`;\n  if (cfg.sealedRoot) b += `  sealed: { root: ${tsStringLit(cfg.sealedRoot)} },\\n`;\n  const oauth = renderTSOAuth(cfg.oauth);\n  if (oauth !== '') {\n    b += '  oauth: {\\n';\n    b += oauth;\n    b += '  },\\n';\n  }\n  b += '});\\n\\n';\n  b += '/** The Environment this file was generated against. Server code reads it from here. */\\n';\n  b += \"export { environmentConfig } from './palbe.config';\\n\";\n  return b;\n}\n\n// Emit the selected web snapshot without provider-specific field renaming.\nfunction renderTSOAuth(o: OAuthConfig | undefined): string {\n  if (o === undefined) return '';\n  return JSON.stringify(parseOAuthConfig(o), null, 2)\n    .split('\\n')\n    .slice(1, -1)\n    .map((line) => `  ${line}\\n`)\n    .join('');\n}\n\n// --- Per-operation gates ------------------------------------------------\n\n// filterTSOps applies the per-op gates that decide whether an operation can\n// register at all: reserved nested segments, body+query conflict, query params\n// the runtime's serializeQuery cannot handle, and namespace/method kind\n// mismatches. Returns the surviving ops (input order preserved) plus loud\n// skip-comment lines.\nfunction filterTSOps(ops: Op[]): [Op[], string[]] {\n  const out: Op[] = [];\n  const skips: string[] = [];\n  const root = new TSNode(); // shape-only trie for kind-mismatch detection\n\n  for (const op of ops) {\n    const segs = opSegments(op.operationId);\n    const lastSeg = segs[segs.length - 1];\n    if (lastSeg === undefined) continue;\n    // Nested reserved check covers EVERY non-first segment — both the\n    // intermediate namespace segments and the final method segment.\n    let skip = false;\n    for (const seg of segs.slice(1)) {\n      if (tsReservedNested(seg)) {\n        skips.push(\n          `// codegen: skipped operation \"${commentSafe(op.operationId)}\" (reserved segment \"${commentSafe(seg)}\")`,\n        );\n        skip = true;\n        break;\n      }\n    }\n    if (skip) continue;\n    // A descriptor's `input` is single-valued: body (default) or query.\n    if (op.input && op.query) {\n      skips.push(\n        `// codegen: skipped operation \"${commentSafe(op.operationId)}\" (both body and query declared — unsupported)`,\n      );\n      continue;\n    }\n    // Non-primitive query params would make the runtime's serializeQuery throw.\n    if (op.query) {\n      const bad = firstNonPrimitiveQueryProp(op.query);\n      if (bad !== undefined) {\n        skips.push(\n          `// codegen: skipped operation \"${commentSafe(op.operationId)}\" (non-primitive query parameter \"${commentSafe(bad)}\")`,\n        );\n        continue;\n      }\n    }\n    // Kind-mismatch: a key claimed as both namespace and method.\n    let node: TSNode | undefined = root;\n    for (const seg of segs.slice(0, -1)) {\n      node = node.childNode(seg);\n      if (!node) break;\n    }\n    if (!node?.addMethod(lastSeg, op)) {\n      skips.push(\n        `// codegen: skipped operation \"${commentSafe(op.operationId)}\" (key collides with existing namespace/method)`,\n      );\n      continue;\n    }\n    out.push(op);\n  }\n  return [out, skips];\n}\n\n// firstNonPrimitiveQueryProp returns the name of the first query property whose\n// schema cannot be serialized into a query string, or undefined when all are\n// primitive.\nfunction firstNonPrimitiveQueryProp(q: Schema): string | undefined {\n  for (const p of q.props) {\n    switch (p.schema.kind) {\n      case 'string':\n      case 'number':\n      case 'integer':\n      case 'boolean':\n      case 'enum':\n        break; // primitive — serializeQuery handles it\n      default:\n        return p.name;\n    }\n  }\n  return undefined;\n}\n\n// --- Types section ----------------------------------------------------------\n\n// emitTSTypes emits the `// ── Types ──` section: one named interface or type\n// alias per op schema (request, response, query, error-data). Returns the\n// rendered section (empty when no ops produce types), collision skip comment\n// lines, and the set of colliding op ids.\nfunction emitTSTypes(ops: Op[]): [string, string[], Set<string>] {\n  const collisionOps = new Set<string>();\n  // seenPrefix maps PascalCase typePrefix → first operationId that claimed it.\n  const seenPrefix = new Map<string, string>();\n  const collisionSkips: string[] = [];\n  const lines: string[] = [];\n\n  for (const op of ops) {\n    const pfx = typePrefix(op.operationId);\n    const first = seenPrefix.get(pfx);\n    if (first !== undefined) {\n      collisionSkips.push(\n        `// codegen: skipped type \"${commentSafe(pfx)}\" (collides with operation \"${commentSafe(first)}\")`,\n      );\n      collisionOps.add(op.operationId);\n      continue;\n    }\n    seenPrefix.set(pfx, op.operationId);\n\n    // Request type (input body).\n    if (op.input) {\n      lines.push(...tsNamedTypeLines(`${pfx}Request`, op.input));\n    }\n    // Query type (emitted before Response, per golden contract order).\n    if (op.query) {\n      lines.push(...tsNamedTypeLines(`${pfx}Query`, op.query));\n    }\n    // Response type (output).\n    if (op.output) {\n      lines.push(...tsResponseTypeLines(pfx, op.output));\n    }\n    // Error data interfaces (after response) — only for errors that actually\n    // lift; filtered errors emit no class, so a Data interface would orphan.\n    const liftable = tsLiftableErrors(op);\n    for (const e of liftable) {\n      if (!e.data) continue;\n      const dataName = `${pfx}${typeNameOf(e.name)}Data`;\n      lines.push(`/** ${e.code} (${e.status}): ${e.description} */`);\n      lines.push(...tsNamedTypeLines(dataName, e.data));\n    }\n  }\n\n  if (lines.length === 0) {\n    return ['', collisionSkips, collisionOps];\n  }\n\n  let b = '// ── Types ──────────────────────────────────────────────────────────\\n\\n';\n  for (const l of lines) {\n    b += `${l}\\n`;\n  }\n  // Note: each type block ends with an empty-string entry that renders as a\n  // blank separator line. No extra trailing newline needed here.\n  return [b, collisionSkips, collisionOps];\n}\n\n// tsNamedTypeLines renders a named top-level type declaration: `export\n// interface` for object schemas, `export type` alias otherwise.\nfunction tsNamedTypeLines(name: string, s: Schema): string[] {\n  if (s.kind === 'object' && !s.nullable && s.props.length > 0 && !s.additional) {\n    return tsInterfaceLines(name, s);\n  }\n  return [`export type ${name} = ${tsTypeOf(s)};`, ''];\n}\n\n// tsResponseTypeLines handles the special case where a response is an array of\n// objects: emits `<Prefix>ResponseItem` interface + `<Prefix>Response` alias.\nfunction tsResponseTypeLines(pfx: string, s: Schema): string[] {\n  if (\n    s.kind === 'array' &&\n    !s.empty &&\n    s.elem &&\n    s.elem.kind === 'object' &&\n    !s.elem.nullable &&\n    s.elem.props.length > 0 &&\n    !s.elem.additional\n  ) {\n    return [\n      ...tsInterfaceLines(`${pfx}ResponseItem`, s.elem),\n      `export type ${pfx}Response = ${pfx}ResponseItem[]${s.nullable ? ' | null' : ''};`,\n      '',\n    ];\n  }\n  return tsNamedTypeLines(`${pfx}Response`, s);\n}\n\n// tsInterfaceLines renders `export interface Name { ... }` with sorted props.\n// A property named __proto__ is skipped loudly: writing it in a JS object\n// literal sets the prototype, and JSON.stringify drops it — wire-dead anyway.\nfunction tsInterfaceLines(name: string, s: Schema): string[] {\n  const lines: string[] = [`export interface ${name} {`];\n  for (const p of s.props) {\n    if (p.name === '__proto__') {\n      lines.push('  // codegen: skipped property \"__proto__\"');\n      continue;\n    }\n    const opt = p.required ? '' : '?';\n    lines.push(`  ${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)};`);\n  }\n  lines.push('}', '');\n  return lines;\n}\n\n// tsTypeOf converts a Schema to its TypeScript type string. For NESTED object\n// schemas (appearing as property values) it emits an inline literal\n// `{ k: T; ... }` rather than a named interface.\nfunction tsTypeOf(s: Schema): string {\n  switch (s.kind) {\n    case 'string':\n      return s.nullable ? 'string | null' : 'string';\n    case 'number':\n    case 'integer':\n      return s.nullable ? 'number | null' : 'number';\n    case 'boolean':\n      return s.nullable ? 'boolean | null' : 'boolean';\n    case 'null':\n      return 'null';\n    case 'literal': {\n      const value =\n        typeof s.literal === 'string' ? tsStringLit(s.literal) : JSON.stringify(s.literal);\n      return s.nullable ? `${value} | null` : value!;\n    }\n    case 'union': {\n      const members = (s.members ?? []).map(tsTypeOf);\n      if (s.nullable) members.push('null');\n      return members.join(' | ');\n    }\n    case 'enum': {\n      const union = s.enumVals.map(tsStringLit).join(' | ');\n      return s.nullable ? `(${union}) | null` : union;\n    }\n    case 'array': {\n      if (s.empty) return s.nullable ? '[] | null' : '[]';\n      if (!s.elem) {\n        return s.nullable ? 'unknown[] | null' : 'unknown[]';\n      }\n      let elem = tsTypeOf(s.elem);\n      // Parenthesise union element types (enum or nullable) so `T[]` parses.\n      if (elem.includes(' | ') || elem.startsWith('(')) {\n        elem = `(${elem})`;\n      }\n      const arr = `${elem}[]`;\n      return s.nullable ? `${arr} | null` : arr;\n    }\n    case 'object': {\n      const inline = tsInlineObject(s);\n      return s.nullable ? `${inline} | null` : inline;\n    }\n    default: // 'any' or unknown\n      return s.nullable ? 'unknown | null' : 'unknown';\n  }\n}\n\n// tsInlineObject renders `{ k: T; k2?: U }` for a nested object schema.\n// __proto__ props are dropped here too (no comment slot inside a single-line\n// literal).\nfunction tsInlineObject(s: Schema): string {\n  const parts: string[] = [];\n  for (const p of s.props) {\n    if (p.name === '__proto__') continue;\n    const opt = p.required ? '' : '?';\n    parts.push(`${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`);\n  }\n  if (s.additional) {\n    const record = `Record<string, ${tsTypeOf(s.additional)}>`;\n    return parts.length === 0 ? record : `({ ${parts.join('; ')} } & ${record})`;\n  }\n  if (parts.length === 0)\n    return s.additional === false ? 'Record<string, never>' : 'Record<string, unknown>';\n  return `{ ${parts.join('; ')} }`;\n}\n\n// tsClientSynthesizedCodes are the error codes the web client produces ITSELF,\n// for failures that never reached the backend (errors.ts, namespaces.ts,\n// call.ts, upload.ts, auth-facade.ts, next/proxy.ts, and `fromEnvelope`'s\n// fallback). A contract that declared one of them could not be told apart from\n// the client's own error. `unauthorized` and `rate_limited` are NOT here: the\n// client never makes them up, they are what the server answers — an endpoint\n// throwing the SDK's `Unauthorized` declares `unauthorized`, and its typed class\n// must reach the caller like any other.\nconst tsClientSynthesizedCodes = new Set([\n  'not_configured',\n  'network_error',\n  'decode_error',\n  'validation_error',\n  'invalid_endpoint_name',\n  'unsupported_get_input',\n  'missing_path_param',\n  'unexpected_argument',\n  'invalid_query_value',\n  'reserved_namespace',\n  'invalid_namespace_tree',\n  'aborted',\n  'http_error',\n]);\n\n// tsLiftableErrors is the per-op set of typed error classes, sorted by wire\n// code. Every error the contract declares gets one — an error left out would\n// reach the caller as an untyped `BackendError` although the contract names it\n// — so a declaration no class can honestly carry stops generation, naming the\n// operation and the fix:\n//   - a code the client synthesizes itself (tsClientSynthesizedCodes);\n//   - `__proto__` (an object-literal key the lift map cannot hold);\n//   - the same code twice;\n//   - two errors whose class names collide (roomLocked + room_locked both\n//     PascalCase to RoomLocked).\nfunction tsLiftableErrors(op: Op): ErrorDef[] {\n  if (op.errors.length === 0) return [];\n  const refuse = (why: string): never => {\n    throw new Error(`${op.operationId}: ${why} — rename the error in the backend and push again`);\n  };\n  const sorted = [...op.errors].sort((a, b) => (a.code < b.code ? -1 : a.code > b.code ? 1 : 0));\n  const seenCode = new Set<string>();\n  const seenClass = new Map<string, string>(); // PascalCase class-name stem → first error name\n  for (const e of sorted) {\n    if (e.code === '__proto__')\n      refuse('declares the error code \"__proto__\", which no lookup can hold');\n    if (tsClientSynthesizedCodes.has(e.code)) {\n      refuse(\n        `declares the error \"${e.code}\", a code the web client produces itself — the two could not be told apart`,\n      );\n    }\n    if (seenCode.has(e.code)) refuse(`declares the error code \"${e.code}\" twice`);\n    const stem = typeNameOf(e.name);\n    const first = seenClass.get(stem);\n    if (first !== undefined) {\n      refuse(`declares errors \"${first}\" and \"${e.name}\", which both become the class ${stem}`);\n    }\n    seenCode.add(e.code);\n    seenClass.set(stem, e.name);\n  }\n  return sorted;\n}\n\n// emitTSTypedErrors emits the `// ── Typed errors ──` section: one exported\n// class per declared error across all registrable ops. Returns the section text\n// plus the emitted class COUNT (the import line includes `BackendError` iff\n// count ≥ 1).\nfunction emitTSTypedErrors(ops: Op[]): [string, number] {\n  let count = 0;\n  const lines: string[] = [];\n  for (const op of ops) {\n    const pfx = typePrefix(op.operationId);\n    const liftable = tsLiftableErrors(op);\n    for (const e of liftable) {\n      const className = `${pfx}${typeNameOf(e.name)}Error`;\n      const hasData = e.data !== undefined;\n      lines.push(`export class ${className} extends Error {`);\n      lines.push(`  readonly name = '${className}';`);\n      lines.push(`  readonly code = '${e.code}';`);\n      lines.push(`  readonly status = ${e.status};`);\n      if (hasData) {\n        lines.push(`  readonly data: ${pfx}${typeNameOf(e.name)}Data;`);\n      }\n      lines.push('  readonly cause: BackendError;');\n      lines.push('  constructor(cause: BackendError) {');\n      lines.push('    super(cause.message);');\n      lines.push('    this.cause = cause;');\n      if (hasData) {\n        lines.push(`    this.data = cause.data as ${pfx}${typeNameOf(e.name)}Data;`);\n      }\n      lines.push('  }');\n      lines.push('}');\n      lines.push('');\n      count++;\n    }\n  }\n\n  if (count === 0) return ['', 0];\n\n  let b = '// ── Typed errors ───────────────────────────────────────────────────\\n\\n';\n  for (const l of lines) {\n    b += `${l}\\n`;\n  }\n  return [b, count];\n}\n\n// --- Registration tree --------------------------------------------------\n\n// TSNode is one level of the __registerNamespaces object literal. Entries keep\n// insertion order (ops arrive sorted by operationId, so rendered keys come out\n// alphabetically), each entry being either a nested namespace (child set) or a\n// method descriptor (op set).\ninterface TSEntry {\n  key: string;\n  child?: TSNode;\n  op?: Op;\n}\n\nclass TSNode {\n  entries: TSEntry[] = [];\n  index = new Map<string, TSEntry>();\n\n  // childNode returns (creating if needed) the nested namespace node for key.\n  // Returns undefined if a METHOD entry already occupies the key (kind\n  // mismatch).\n  childNode(key: string): TSNode | undefined {\n    const e = this.index.get(key);\n    if (e) return e.child; // undefined when a method claims the key\n    const child = new TSNode();\n    const entry: TSEntry = { key, child };\n    this.entries.push(entry);\n    this.index.set(key, entry);\n    return child;\n  }\n\n  // addMethod registers a method at key. Returns false if the key is already\n  // occupied (either by another method or by a namespace node).\n  addMethod(key: string, op: Op): boolean {\n    if (this.index.has(key)) return false;\n    const entry: TSEntry = { key, op };\n    this.entries.push(entry);\n    this.index.set(key, entry);\n    return true;\n  }\n}\n\n// buildTSTrie arranges PRE-FILTERED ops (filterTSOps survivors, possibly minus\n// type-collision ops) into the namespace trie. Kind mismatches are impossible\n// here — removing ops from a mismatch-free set never creates one.\nfunction buildTSTrie(ops: Op[]): TSNode {\n  const root = new TSNode();\n  for (const op of ops) {\n    const segs = opSegments(op.operationId);\n    const lastSeg = segs[segs.length - 1];\n    if (lastSeg === undefined) continue;\n    let node: TSNode | undefined = root;\n    for (const seg of segs.slice(0, -1)) {\n      node = node.childNode(seg);\n      if (!node) break; // unreachable: pre-filtered by filterTSOps\n    }\n    if (node) {\n      node.addMethod(lastSeg, op);\n    }\n  }\n  return root;\n}\n\n// emitTSRegistration renders the __registerNamespaces({…}) call (no section\n// header or skip comments — those are written by emitTypeScript above). With\n// zero ops the call renders single-line.\nfunction emitTSRegistration(ops: Op[]): string {\n  if (ops.length === 0) {\n    return '__registerNamespaces({});\\n';\n  }\n  let b = '__registerNamespaces({\\n';\n  b += renderTSNode(buildTSTrie(ops), 2);\n  b += '});\\n';\n  return b;\n}\n\n// renderTSNode renders one tree level at the given indent, recursing into\n// nested namespaces.\nfunction renderTSNode(node: TSNode, indentSpaces: number): string {\n  const ind = ' '.repeat(indentSpaces);\n  let b = '';\n  for (const e of node.entries) {\n    if (e.child) {\n      b += `${ind}${tsPropKey(e.key)}: {\\n`;\n      b += renderTSNode(e.child, indentSpaces + 2);\n      b += `${ind}},\\n`;\n      continue;\n    }\n    if (e.op) {\n      b += renderTSDescriptor(e.op, e.key, indentSpaces);\n    }\n  }\n  return b;\n}\n\n// renderTSDescriptor renders one method descriptor entry at the given indent\n// depth. Single-line when no errors survive filtering; multi-line when an\n// errors map is emitted.\n//\n// Descriptor field rules:\n//   - `method` and `path` always present\n//   - `pathParams` present when op.pathParams is non-empty\n//   - `input: 'none'` when no body and no query\n//   - `input: 'query'` when query declared (body+query handled upstream)\n//   - no `input` key when a body is declared (body is the default)\n//   - `errors` map when liftable errors exist → forces multi-line\nfunction renderTSDescriptor(op: Op, methodSeg: string, indentSpaces: number): string {\n  const ind = ' '.repeat(indentSpaces);\n  const key = tsPropKey(methodSeg);\n\n  const liftable = tsLiftableErrors(op);\n  const hasErrors = liftable.length > 0;\n\n  const hasPathParams = op.pathParams.length > 0;\n  const hasInput = op.input !== undefined;\n  const hasQuery = op.query !== undefined;\n\n  // Determine input field: '' = omit (body default).\n  let inputVal = '';\n  if (!hasInput && !hasQuery) {\n    inputVal = 'none';\n  } else if (hasQuery) {\n    inputVal = 'query';\n  }\n\n  let b = '';\n  if (!hasErrors) {\n    // Single-line format: `key: { method: 'X', path: '...', [extras...] },`\n    const parts = [`method: ${tsStringLit(op.method)}`, `path: ${tsStringLit(op.path)}`];\n    if (hasPathParams) {\n      parts.push(`pathParams: [${renderTSStringArray(op.pathParams)}]`);\n    }\n    if (inputVal !== '') {\n      parts.push(`input: ${tsStringLit(inputVal)}`);\n    }\n    // The descriptor carries the marker so the runtime knows to consume the\n    // body as a stream. Without it the signature would promise an iterable the\n    // runtime never produces.\n    if (op.sse) {\n      parts.push('sse: true');\n    }\n    b += `${ind}${key}: { ${parts.join(', ')} },\\n`;\n    return b;\n  }\n\n  // Multi-line format.\n  const innerInd = ' '.repeat(indentSpaces + 2);\n  b += `${ind}${key}: {\\n`;\n  b += `${innerInd}method: ${tsStringLit(op.method)},\\n`;\n  b += `${innerInd}path: ${tsStringLit(op.path)},\\n`;\n  if (hasPathParams) {\n    b += `${innerInd}pathParams: [${renderTSStringArray(op.pathParams)}],\\n`;\n  }\n  if (inputVal !== '') {\n    b += `${innerInd}input: ${tsStringLit(inputVal)},\\n`;\n  }\n  if (op.sse) {\n    b += `${innerInd}sse: true,\\n`;\n  }\n  b += `${innerInd}errors: { `;\n  liftable.forEach((e, i) => {\n    if (i > 0) b += ', ';\n    const className = `${typePrefix(op.operationId)}${typeNameOf(e.name)}Error`;\n    b += `${tsPropKey(e.code)}: (e) => new ${className}(e)`;\n  });\n  b += ' },\\n';\n  b += `${ind}},\\n`;\n  return b;\n}\n\n// renderTSStringArray renders string-array literal elements: `'a', 'b'` (no\n// surrounding brackets — caller adds them).\nfunction renderTSStringArray(ss: string[]): string {\n  return ss.map(tsStringLit).join(', ');\n}\n\n// --- Augmentation (declare module '@palbase/web') ---------------------------\n\n// emitTSAugmentation renders the `declare module '@palbase/web' { interface PB\n// { ... } }` block, mirroring the registration trie shape with typed method\n// signatures. Ops arrive pre-filtered (same set as emitTSRegistration).\nfunction emitTSAugmentation(ops: Op[]): string {\n  let b = \"declare module '@palbase/web' {\\n\";\n  b += '  interface PB {\\n';\n  b += renderTSAugNode(buildTSTrie(ops), 4);\n  b += '  }\\n';\n  b += '}\\n';\n  return b;\n}\n\n// renderTSAugNode renders augmentation entries at the given indent.\nfunction renderTSAugNode(node: TSNode, indentSpaces: number): string {\n  const ind = ' '.repeat(indentSpaces);\n  let b = '';\n  for (const e of node.entries) {\n    if (e.child) {\n      b += `${ind}${tsPropKey(e.key)}: {\\n`;\n      b += renderTSAugNode(e.child, indentSpaces + 2);\n      b += `${ind}};\\n`;\n      continue;\n    }\n    if (e.op) {\n      b += `${ind}${tsPropKey(e.key)}${renderTSMethodSignature(e.op)};\\n`;\n    }\n  }\n  return b;\n}\n\n// renderTSMethodSignature builds the TypeScript method signature for one op.\n// Shape: (pathParam: string, ..., input?: T, options?: CallOptions): Promise<R>\nfunction renderTSMethodSignature(op: Op): string {\n  const pfx = typePrefix(op.operationId);\n  const args: string[] = [];\n\n  // Leading path params. Wire names are sanitized into valid TS identifiers\n  // (`{user-id}` → userId, reserved words escaped, repeats deduped) — names\n  // are purely positional: the runtime substitutes via the descriptor's\n  // pathParams, which keep the WIRE names, so renaming here is safe.\n  const used = new Set<string>();\n  for (const p of op.pathParams) {\n    args.push(`${tsParamIdent(p, used)}: string`);\n  }\n\n  // Input arg. A zero-prop object body still takes a real `input` arg: `{}` is\n  // a valid wire body and the descriptor defaults to body.\n  if (op.input) {\n    args.push(`input: ${pfx}Request`);\n  } else if (op.query) {\n    args.push(`query: ${pfx}Query`);\n  }\n\n  // Options arg: fold headers when present.\n  args.push(buildOptionsArg(op.headers));\n\n  // A streaming op hands back the SEQUENCE. Typing it as `Promise<Response>`\n  // would be a lie the compiler enforces on the caller: they would `await` once,\n  // get one value, and never see the rest — the silent wrongness this extension\n  // exists to prevent.\n  const ret = op.sse\n    ? `Promise<AsyncIterable<${pfx}Response>>`\n    : op.output\n      ? `Promise<${pfx}Response>`\n      : 'Promise<void>';\n  return `(${args.join(', ')}): ${ret}`;\n}\n\n// buildOptionsArg constructs the options parameter (with or without headers).\n// Required when any declared header is required; optional otherwise.\nfunction buildOptionsArg(headers: Schema | undefined): string {\n  if (!headers || headers.props.length === 0) {\n    return 'options?: CallOptions';\n  }\n  const anyRequired = headers.props.some((p) => p.required);\n\n  const hParts = headers.props.map((p) => {\n    const opt = p.required ? '' : '?';\n    return `${tsPropKey(p.name)}${opt}: ${tsTypeOf(p.schema)}`;\n  });\n  const headersType = `{ ${hParts.join('; ')} }`;\n\n  if (anyRequired) {\n    return `options: CallOptions & { headers: ${headersType} }`;\n  }\n  return `options?: CallOptions & { headers?: ${headersType} }`;\n}\n\n// tsParamIdent converts a wire path-param name into a safe TS parameter\n// identifier: camelCase-sanitized (`user-id` → userId), reserved words and the\n// fixed signature arg names (input/query/options) escaped with a trailing\n// underscore, repeats deduped with a numeric suffix. Records the chosen name.\nfunction tsParamIdent(name: string, used: Set<string>): string {\n  let id = sanitize(name, false);\n  if (tsReservedWords.has(id) || id === 'input' || id === 'query' || id === 'options') {\n    id += '_';\n  }\n  let candidate = id;\n  for (let n = 2; used.has(candidate); n++) {\n    candidate = id + n;\n  }\n  used.add(candidate);\n  return candidate;\n}\n\n// tsReservedWords are ECMAScript keywords plus strict-mode reserved names that\n// cannot be used as parameter binding identifiers in a module.\nconst tsReservedWords = new Set([\n  'await',\n  'break',\n  'case',\n  'catch',\n  'class',\n  'const',\n  'continue',\n  'debugger',\n  'default',\n  'delete',\n  'do',\n  'else',\n  'enum',\n  'export',\n  'extends',\n  'false',\n  'finally',\n  'for',\n  'function',\n  'if',\n  'import',\n  'in',\n  'instanceof',\n  'new',\n  'null',\n  'return',\n  'super',\n  'switch',\n  'this',\n  'throw',\n  'true',\n  'try',\n  'typeof',\n  'var',\n  'void',\n  'while',\n  'with',\n  'yield',\n  // strict-mode reserved / restricted binding names\n  'implements',\n  'interface',\n  'let',\n  'package',\n  'private',\n  'protected',\n  'public',\n  'static',\n  'arguments',\n  'eval',\n]);\n\n// tsBareKeyRe matches identifiers that are valid bare TS object keys.\nconst tsBareKeyRe = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\n// tsPropKey renders an object-literal property key: bare when it is a valid\n// identifier, single-quoted via tsStringLit otherwise (kebab-case segments,\n// codes with dots, …).\nfunction tsPropKey(name: string): string {\n  return tsBareKeyRe.test(name) ? name : tsStringLit(name);\n}\n\n// commentSafe makes a server-supplied string safe to sit inside a `//` comment.\n//\n// Every `// codegen: skipped …` line below interpolates a name the GENERATOR\n// did not choose — a role, a permission, an operationId, an error code — and a\n// line comment ends at the first newline. A value carrying one closes the\n// comment and everything after it becomes free TypeScript in the customer's\n// generated module. Measured: the roles door accepts `a%0Ab`, chi decodes it,\n// and the name reaches this file as `a\\nb`.\n//\n// Nothing is dropped silently: the escapes stay visible so a reader sees WHY\n// the name looks odd rather than seeing a truncated one. `*/` is neutralised\n// too, so moving one of these lines into a block comment cannot reopen the\n// hole.\nfunction commentSafe(s: string): string {\n  return s\n    .replaceAll('\\\\', '\\\\\\\\')\n    .replaceAll('\\r', '\\\\r')\n    .replaceAll('\\n', '\\\\n')\n    .replaceAll('*/', '*\\\\/');\n}\n\n// tsStringLit returns a single-quoted TypeScript string literal, escaping\n// backslash and single quotes (and newlines/carriage returns defensively).\nfunction tsStringLit(s: string): string {\n  return `'${s\n    .replaceAll('\\\\', '\\\\\\\\')\n    .replaceAll(\"'\", \"\\\\'\")\n    .replaceAll('\\n', '\\\\n')\n    .replaceAll('\\r', '\\\\r')}'`;\n}\n\n// tsReservedTopLevel reports whether the top-level namespace segment is\n// reserved. Case-insensitive for the iOS SDK set (auth/analytics/flags/\n// realtime) + case-sensitive for the web-only set (call, upload, then) and all\n// Object.prototype members.\nfunction tsReservedTopLevel(seg: string): boolean {\n  switch (seg.toLowerCase()) {\n    case 'auth':\n    case 'analytics':\n    case 'flags':\n    case 'realtime':\n      return true;\n    default:\n      return tsReservedWebOnly(seg);\n  }\n}\n\n// tsReservedNested reports whether a non-first segment is reserved for nested\n// positions: the Object.prototype members + `then`, but NOT `call` or `upload`\n// (those are only reserved at the top level). Applied to every non-first\n// segment including the final method segment.\nfunction tsReservedNested(seg: string): boolean {\n  if (seg === 'then') return true;\n  return tsObjectPrototypeMember(seg);\n}\n\n// tsReservedWebOnly contains the web-only reserved set (call/upload/then) plus\n// Object.prototype members. Case-sensitive.\nfunction tsReservedWebOnly(seg: string): boolean {\n  switch (seg) {\n    case 'call':\n    case 'upload':\n    case 'then':\n      return true;\n    default:\n      return tsObjectPrototypeMember(seg);\n  }\n}\n\n// tsObjectPrototypeMember reports whether seg is an Object.prototype member.\nfunction tsObjectPrototypeMember(seg: string): boolean {\n  switch (seg) {\n    case 'constructor':\n    case 'hasOwnProperty':\n    case 'isPrototypeOf':\n    case 'propertyIsEnumerable':\n    case 'toLocaleString':\n    case 'toString':\n    case 'valueOf':\n    case '__proto__':\n    case '__defineGetter__':\n    case '__defineSetter__':\n    case '__lookupGetter__':\n    case '__lookupSetter__':\n      return true;\n    default:\n      return false;\n  }\n}\n\n/** The TS type name for a room: `ai:{sessionId}` \\u2192 `AiSessionIdRoom`. */\nfunction roomTypeName(pattern: string): string {\n  return `${typeNameOf(pattern)}Room`;\n}\n\n/**\n * Emit one room as a descriptor an app hands to `pb.join`.\n *\n * The shape is chosen so an app writes NO strings and NO types of its own: the\n * pattern, the event names and the message names all live here. Events come out\n * as a discriminated union keyed by `event`, which is what makes a `switch` in\n * an app exhaustive \\u2014 the compiler, not the developer, notices when the server\n * adds one.\n */\nfunction emitTSRoom(room: RoomDecl): string {\n  const name = roomTypeName(room.pattern);\n  const lines: string[] = [];\n\n  for (const e of room.events) {\n    lines.push(...tsNamedTypeLines(`${name}${typeNameOf(e.name)}Event`, e.schema));\n  }\n  for (const m of room.messages) {\n    lines.push(...tsNamedTypeLines(`${name}${typeNameOf(m.name)}Message`, m.schema));\n  }\n\n  // The union. `event` is the discriminant, so `switch (e.event)` narrows\n  // `e.payload` with no cast anywhere in the app.\n  if (room.events.length > 0) {\n    lines.push(`export type ${name}Event =`);\n    for (const e of room.events) {\n      lines.push(`  | { event: '${e.name}'; payload: ${name}${typeNameOf(e.name)}Event }`);\n    }\n    lines[lines.length - 1] += ';';\n  } else {\n    lines.push(`export type ${name}Event = never;`);\n  }\n  lines.push('');\n\n  // The descriptor. `send` exists only as a TYPE carrier \\u2014 its value is never\n  // read \\u2014 so `room.send('say', {...})` checks the payload against the right\n  // shape without the app ever naming it.\n  const params = room.params.map((p) => `${tsPropKey(p)}: string`).join('; ');\n  lines.push(`export interface ${name}Params { ${params} }`);\n  lines.push(`export const ${name} = {`);\n  lines.push(`  pattern: '${room.pattern}',`);\n  lines.push(`  params: [${room.params.map((p) => `'${p}'`).join(', ')}] as const,`);\n  // Runtime lists, not just types: `send` below is a TYPE carrier with no\n  // runtime keys, so a JavaScript caller (which has no compiler) can only be\n  // checked against these.\n  lines.push(`  events: [${room.events.map((e) => `'${e.name}'`).join(', ')}] as const,`);\n  lines.push(`  messages: [${room.messages.map((m) => `'${m.name}'`).join(', ')}] as const,`);\n  lines.push(\n    `  send: {} as { ${room.messages\n      .map((m) => `${tsPropKey(m.name)}: ${name}${typeNameOf(m.name)}Message`)\n      .join('; ')} },`,\n  );\n  lines.push(`  event: {} as ${name}Event,`);\n  lines.push('} as const;');\n  lines.push('');\n  return lines.join('\\n');\n}\n\n// --- Roles and permissions ---------------------------------------------------\n//\n// `palbase spec` writes the environment's role definitions beside its contract\n// (inside the contract, `x-palbase-roles`); this turns them into two `as const` objects plus the\n// union types derived from them, appended to the same generated module — so an\n// app has ONE committed codegen artifact rather than a second one to wire up.\n//\n// Why generate them at all: a role and a permission are plain strings on the\n// wire, and the failure mode of a typo is a 403 — the server is right, the code\n// looks right, and nothing says which of the grants was meant. A constant turns\n// that into a typecheck error. Withdrawal is the same story from the other side:\n// a role deleted upstream disappears from the regenerated module, so code that\n// still names it stops building instead of silently running without the access\n// it thinks it has.\n//\n// `as const` plus `(typeof X)[keyof typeof X]` rather than a TypeScript `enum`,\n// so the names autocomplete on BOTH sides — `Roles.moderator` as a value and\n// `Role` as the type a function parameter can be annotated with — while the\n// emitted values stay plain strings a JavaScript caller can pass too.\n//\n// There is deliberately no `userCount` and no assignment here. Who HAS a role is\n// runtime state that changes without a deploy; what a role IS is the definition,\n// and only the definition can be a type.\n\n// RoleDecl is one role as the artifact carries it.\ninterface RoleDecl {\n  name: string;\n  // Absent when the role's name says everything — the artifact omits it rather\n  // than writing '' (see the CLI's `stackRole`).\n  description?: string;\n  isDefault: boolean;\n  permissions: string[];\n}\n\n// parseRolesArtifact reads the artifact strictly.\n//\n// A MISSING artifact is an environment that predates roles, and that is the\n// caller's case to handle (no file, no section). A malformed one is a broken\n// spec round, and quietly emitting nothing for it would hand the developer a\n// module missing the very types they just added. The `roles` key specifically\n// has to be present and an array: a proxy's JSON error page parses fine and\n// would otherwise read as \"this environment defines no roles\".\nfunction parseRolesArtifact(artifact: string): RoleDecl[] {\n  let doc: unknown;\n  try {\n    doc = JSON.parse(artifact);\n  } catch (e) {\n    throw new Error(`roles artifact is not valid JSON: ${e instanceof Error ? e.message : e}`);\n  }\n  if (typeof doc !== 'object' || doc === null || !('roles' in doc) || !Array.isArray(doc.roles)) {\n    throw new Error('roles artifact has no roles list');\n  }\n  return doc.roles.map((entry: unknown, i: number): RoleDecl => {\n    if (typeof entry !== 'object' || entry === null) {\n      throw new Error(`roles artifact entry ${i} is not a role`);\n    }\n    if (!('name' in entry) || typeof entry.name !== 'string' || entry.name === '') {\n      throw new Error(`roles artifact entry ${i} has no name`);\n    }\n    const name = entry.name;\n    if (!('isDefault' in entry) || typeof entry.isDefault !== 'boolean') {\n      throw new Error(`role \"${name}\" does not say whether it is the default`);\n    }\n    if (!('permissions' in entry) || !Array.isArray(entry.permissions)) {\n      throw new Error(`role \"${name}\" does not carry a list of permission names`);\n    }\n    const permissions: string[] = [];\n    for (const permission of entry.permissions) {\n      if (typeof permission !== 'string') {\n        throw new Error(`role \"${name}\" lists a permission that is not a name`);\n      }\n      permissions.push(permission);\n    }\n    const role: RoleDecl = { name, isDefault: entry.isDefault, permissions };\n    if (\n      'description' in entry &&\n      typeof entry.description === 'string' &&\n      entry.description !== ''\n    ) {\n      role.description = entry.description;\n    }\n    return role;\n  });\n}\n\n// emitRoles renders the roles section. Returns '' when the environment defines\n// no roles, so a project that never adopted them gets a byte-identical module to\n// the one it got before.\nexport function emitRoles(artifact: string): string {\n  // Sorted here rather than trusted from the file: the artifact IS sorted today,\n  // but this generator can also be handed one written by hand, and an output\n  // whose order depends on its input's is an output nobody can diff.\n  const roles = parseRolesArtifact(artifact).sort((a, b) =>\n    a.name < b.name ? -1 : a.name > b.name ? 1 : 0,\n  );\n\n  // The permission object is the UNION across roles — a permission is a grant the\n  // environment knows about, not a property of the one role that happens to list\n  // it first. Two roles sharing `todos.read` must produce one key.\n  const permissions = [...new Set(roles.flatMap((r) => r.permissions))].sort();\n\n  const roleLines: string[] = [];\n  const seenRoleKey = new Map<string, string>();\n  for (const role of roles) {\n    const key = sanitize(role.name, false);\n    const first = seenRoleKey.get(key);\n    if (first !== undefined) {\n      roleLines.push(\n        `  // codegen: skipped duplicate role \"${commentSafe(role.name)}\" — collides with \"${commentSafe(first)}\" (both map to \\`${commentSafe(key)}\\`)`,\n      );\n      continue;\n    }\n    seenRoleKey.set(key, role.name);\n    // The description and the default flag are the only things the artifact\n    // carries beyond the name, and a doc comment is where they belong: it reaches\n    // the developer at the call site without becoming API surface the two\n    // platforms would then have to keep identical.\n    if (role.description !== undefined) {\n      roleLines.push(`  /** ${singleLine(role.description)} */`);\n    }\n    if (role.isDefault) {\n      roleLines.push('  /** Assigned to every new user at signup. */');\n    }\n    roleLines.push(`  ${key}: ${tsStringLit(role.name)},`);\n  }\n\n  const permissionLines: string[] = [];\n  const seenPermissionKey = new Map<string, string>();\n  for (const permission of permissions) {\n    const key = sanitize(permission, false);\n    const first = seenPermissionKey.get(key);\n    if (first !== undefined) {\n      permissionLines.push(\n        `  // codegen: skipped duplicate permission \"${commentSafe(permission)}\" — collides with \"${commentSafe(first)}\" (both map to \\`${commentSafe(key)}\\`)`,\n      );\n      continue;\n    }\n    seenPermissionKey.set(key, permission);\n    permissionLines.push(`  ${key}: ${tsStringLit(permission)},`);\n  }\n\n  // An empty `as const` object compiles, but the union derived from it resolves\n  // to `never` — so every assignment fails with a message about a type nobody\n  // wrote, while the module looks like it carries the feature. Each half appears\n  // only when it has a key; with neither, the whole section does not exist.\n  let b = '';\n  if (seenRoleKey.size > 0) {\n    b += 'export const Roles = {\\n';\n    b += `${roleLines.join('\\n')}\\n`;\n    b += '} as const;\\n\\n';\n    b += '/** One of the roles this environment defines. */\\n';\n    b += 'export type Role = (typeof Roles)[keyof typeof Roles];\\n';\n  }\n  if (seenPermissionKey.size > 0) {\n    if (b !== '') b += '\\n';\n    b += 'export const Permissions = {\\n';\n    b += `${permissionLines.join('\\n')}\\n`;\n    b += '} as const;\\n\\n';\n    b += \"/** One of the permissions this environment's roles grant. */\\n\";\n    b += 'export type Permission = (typeof Permissions)[keyof typeof Permissions];\\n';\n  }\n  if (b === '') return '';\n\n  let head = '\\n// ── Roles and permissions ';\n  head += '─'.repeat(42);\n  head += '\\n';\n  head += '//\\n';\n  head += '// The roles this environment defines and the permissions they grant. A name\\n';\n  head += '// typed by hand is a string the server answers 403 to; a name typed here is a\\n';\n  head += '// compile error. Regenerated by `palbase spec` — a role withdrawn upstream\\n';\n  head += '// disappears from this file, so code still naming it stops building rather\\n';\n  head += '// than silently losing access.\\n';\n  head += '\\n';\n  return head + b;\n}\n\n// singleLine flattens a tenant-written description onto one line: it lands in a\n// `/** … */` comment, and a `*/` sequence or a newline inside one ends the\n// comment early and turns the rest of the sentence into code.\nfunction singleLine(s: string): string {\n  return s\n    .split(/[\\r\\n]+/)\n    .map((l) => l.trim())\n    .filter((l) => l !== '')\n    .join(' ')\n    .replaceAll('*/', '*​/');\n}\n","// OpenAPI 3.1 → operation model parser for the palbe-gen typed-client codegen.\n// 1:1 TypeScript port of the CLI's Go parser (internal/backend/swiftgen.go —\n// dialect-neutral despite the historical \"swift\" name). Behavior parity with\n// the Go emitter is locked by the M1 cross-binding golden test.\n\n// --- Parsed model -----------------------------------------------------------\n\nexport type SchemaKind =\n  | 'string'\n  | 'number'\n  | 'integer'\n  | 'boolean'\n  | 'object'\n  | 'array'\n  | 'enum'\n  | 'literal'\n  | 'union'\n  | 'null'\n  | 'any';\n\nexport interface Schema {\n  kind: SchemaKind;\n  nullable: boolean;\n  /** object */\n  props: Prop[];\n  /** array */\n  elem?: Schema;\n  /** An array constrained to the single JSON value []. */\n  empty?: true;\n  /** JSON Schema anyOf/oneOf alternatives. */\n  members?: Schema[];\n  literal?: string | number | boolean;\n  /** Object index signature; false means no additional properties. */\n  additional?: Schema | false;\n  /** enum */\n  enumVals: string[];\n}\n\nexport interface Prop {\n  name: string;\n  schema: Schema;\n  required: boolean;\n}\n\nexport interface Op {\n  operationId: string;\n  method: string;\n  path: string;\n  /** `{name}` path segments in path order → leading string method args */\n  pathParams: string[];\n  input?: Schema;\n  output?: Schema;\n  /** declared request headers (parameters[in:header]) */\n  headers?: Schema;\n  /** declared query params (parameters[in:query]) */\n  query?: Schema;\n  /** inferred errors via the `x-palbase-errors` extension */\n  errors: ErrorDef[];\n  /** `x-palbase-sse` — the response is a stream of frames, not one document. */\n  sse: boolean;\n}\n// ponytail: the Go parser also reads `x-palbase-upload` — the TS emitter never\n// consumes it (web has no generated upload surface), so it is not parsed here.\n//\n// `x-palbase-sse` IS parsed here, and the difference is not an inconsistency.\n// Skipping upload costs web nothing: there is no generated upload surface to be\n// wrong. Skipping SSE would cost it everything — the method would still be\n// generated, would read the streaming body ONCE, and would hand back the\n// concatenation of every frame decoded as a single document. It would compile,\n// it would run, and it would be silently wrong. Web is a first-class consumer of\n// streaming, so the marker is consumed.\n\nexport interface ErrorDef {\n  /** lowerCamel error name (e.g. \"todoLocked\") — class-name stem */\n  name: string;\n  /** wire `error` value (e.g. \"todo_locked\") — matched at decode time */\n  code: string;\n  /** HTTP status — kept for doc-comments */\n  status: number;\n  description: string;\n  /** undefined when the error carries no payload */\n  data?: Schema;\n}\n\ntype JsonObject = Record<string, unknown>;\n\nfunction asObject(v: unknown): JsonObject | undefined {\n  if (typeof v === 'object' && v !== null && !Array.isArray(v)) return v as JsonObject;\n  return undefined;\n}\n\nfunction asString(v: unknown): string {\n  return typeof v === 'string' ? v : '';\n}\n\n/**\n * readSpecDeploy returns the document's `x-palbase-deploy` — the DEPLOY IDENTITY\n * the runtime stamps into every artifact it ships.\n *\n * Codegen prints it so \"generated successfully\" says WHICH contract it\n * generated from. The origin can legitimately serve the previous deploy for a\n * few seconds after a green one (a warm isolate re-reads its ACTIVE pointer on a\n * ~10s boundary), and a success line that hides that is how a client for 28\n * routes shipped after a deploy of 29 — caught only by counting operations by\n * hand.\n *\n * It is deliberately NOT `info.version`: OpenAPI requires that field, so it\n * always holds something and cannot express \"this runtime does not know\". The\n * extension is omitted instead, so absence is the answer and no placeholder\n * needs recognising.\n *\n * Returns '' when the document names no deploy, or is unreadable. It never\n * throws: parseOpenAPI owns the loud failure for a malformed document, and a\n * provenance note must not become a second, competing error path.\n */\nexport function readSpecDeploy(specText: string): string {\n  try {\n    return asString(asObject(JSON.parse(specText))?.['x-palbase-deploy']);\n  } catch {\n    return '';\n  }\n}\n\n// --- Parse ------------------------------------------------------------------\n\nexport function parseOpenAPI(specText: string): Op[] {\n  let root: JsonObject | undefined;\n  try {\n    root = asObject(JSON.parse(specText));\n  } catch (e) {\n    throw new Error(`openapi.json is not valid JSON: ${e instanceof Error ? e.message : e}`);\n  }\n  const paths = asObject(root?.paths);\n  if (!paths) {\n    throw new Error('openapi.json has no `paths`');\n  }\n\n  const ops: Op[] = [];\n  for (const [path, item] of Object.entries(paths)) {\n    const methods = asObject(item);\n    if (!methods) continue;\n    for (const [method, raw] of Object.entries(methods)) {\n      const op = asObject(raw);\n      if (!op) continue;\n      const opId = asString(op.operationId);\n      if (opId === '') continue;\n      ops.push({\n        operationId: opId,\n        method: method.toUpperCase(),\n        path: normalizePathTemplate(path),\n        pathParams: pathParamNames(path),\n        input: requestSchema(op),\n        output: responseSchema(op),\n        headers: parametersSchemaIn(op, 'header'),\n        query: parametersSchemaIn(op, 'query'),\n        errors: declaredErrors(op),\n        sse: op['x-palbase-sse'] !== undefined,\n      });\n    }\n  }\n  ops.sort((a, b) => (a.operationId < b.operationId ? -1 : a.operationId > b.operationId ? 1 : 0));\n  return ops;\n}\n\n// declaredErrors reads the `x-palbase-errors` OpenAPI extension the backend\n// runtime stashes on each operation. Returns [] when no errors were inferred.\nfunction declaredErrors(op: JsonObject): ErrorDef[] {\n  const extRaw = asObject(op['x-palbase-errors']);\n  if (!extRaw) return [];\n  const responses = asObject(op.responses);\n  const out: ErrorDef[] = [];\n  for (const [name, raw] of Object.entries(extRaw)) {\n    const entry = asObject(raw);\n    if (!entry) continue;\n    const status = typeof entry.status === 'number' ? Math.trunc(entry.status) : 0;\n    const code = asString(entry.code);\n    const description = asString(entry.description);\n    const hasData = entry.hasData === true;\n    if (code === '' || status === 0) continue;\n    const def: ErrorDef = { name, code, status, description };\n    if (hasData) {\n      def.data = errorDataSchema(responses, status, code);\n    }\n    out.push(def);\n  }\n  // Deterministic order: by error name.\n  out.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n  return out;\n}\n\n// errorDataSchema pulls the data-payload schema out of a declared error's\n// response shape. Single error on a status → the standalone schema; multiple\n// errors sharing a status → `oneOf`, pick the variant whose\n// `error: { const: <code> }` discriminator matches.\nfunction errorDataSchema(\n  responses: JsonObject | undefined,\n  status: number,\n  code: string,\n): Schema | undefined {\n  const resp = asObject(responses?.[String(status)]);\n  const jsonCt = asObject(asObject(resp?.content)?.['application/json']);\n  const schema = asObject(jsonCt?.schema);\n  if (!schema) return undefined;\n\n  const variants = schema.oneOf;\n  if (Array.isArray(variants)) {\n    for (const v of variants) {\n      const vm = asObject(v);\n      if (!vm) continue;\n      const errProp = asObject(asObject(vm.properties)?.error);\n      if (errProp && asString(errProp.const) === code) {\n        return extractDataProperty(vm);\n      }\n    }\n    return undefined;\n  }\n  return extractDataProperty(schema);\n}\n\nfunction extractDataProperty(schema: JsonObject): Schema | undefined {\n  const dm = asObject(asObject(schema.properties)?.data);\n  if (!dm) return undefined;\n  return parseSchema(dm);\n}\n\nfunction requestSchema(op: JsonObject): Schema | undefined {\n  const body = asObject(op.requestBody);\n  if (!body) return undefined;\n  return schemaFromContent(body.content);\n}\n\n// parametersSchemaIn collects the operation's `parameters[in:<where>]` entries\n// into a synthetic object Schema (one property per parameter), name-sorted for\n// deterministic output. Returns undefined when the op declares no parameter in\n// that location; path params are threaded separately (pathParamNames).\nfunction parametersSchemaIn(op: JsonObject, where: 'header' | 'query'): Schema | undefined {\n  const paramsRaw = op.parameters;\n  if (!Array.isArray(paramsRaw) || paramsRaw.length === 0) return undefined;\n  const props: Prop[] = [];\n  for (const p of paramsRaw) {\n    const pm = asObject(p);\n    if (!pm) continue;\n    if (asString(pm.in) !== where) continue;\n    const name = asString(pm.name);\n    if (name === '') continue;\n    const required = pm.required === true;\n    const sm = asObject(pm.schema);\n    const ps = sm ? parseSchema(sm) : emptySchema('string');\n    props.push({ name, schema: ps, required });\n  }\n  if (props.length === 0) return undefined;\n  props.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n  return { ...emptySchema('object'), props };\n}\n\n// pathParamNames extracts the `{name}` template segments from an OpenAPI path,\n// in left-to-right path order. Empty `{}` is ignored.\n/**\n * ACCEPTS BOTH SPELLINGS, because our own runtime writes the other one.\n *\n * OpenAPI templates a path parameter as `{name}`. The palbase backend runtime\n * stamps its contract with `:name` — Express's spelling — so every route with a\n * path parameter came through here with none found, and codegen emitted a\n * method that could not be given the value it needs. Measured against the live\n * control plane: `/v1/panel/projects/:projectId` produced\n * `projectById(options?)`.\n *\n * Normalising at the door is the narrow fix: everything downstream already\n * speaks `{name}`, so only this function has to know there are two spellings.\n */\nexport function normalizePathTemplate(path: string): string {\n  return path.replace(/:([A-Za-z_][A-Za-z0-9_]*)/g, '{$1}');\n}\n\nexport function pathParamNames(rawPath: string): string[] {\n  const path = normalizePathTemplate(rawPath);\n  const out: string[] = [];\n  let rest = path;\n  for (;;) {\n    const open = rest.indexOf('{');\n    if (open < 0) break;\n    const close = rest.indexOf('}', open);\n    if (close < 0) break;\n    const name = rest.slice(open + 1, close);\n    if (name !== '') out.push(name);\n    rest = rest.slice(close + 1);\n  }\n  return out;\n}\n\nfunction responseSchema(op: JsonObject): Schema | undefined {\n  const responses = asObject(op.responses);\n  if (!responses) return undefined;\n  // Prefer 200, then 201, then any other 2xx (sorted).\n  const others: string[] = [];\n  for (const code of Object.keys(responses)) {\n    if (code.startsWith('2') && code !== '200' && code !== '201') others.push(code);\n  }\n  others.sort();\n  for (const code of ['200', '201', ...others]) {\n    const resp = asObject(responses[code]);\n    if (!resp) continue;\n    const s = schemaFromContent(resp.content);\n    if (s) return s;\n  }\n  return undefined;\n}\n\nfunction schemaFromContent(content: unknown): Schema | undefined {\n  const jsonCt = asObject(asObject(content)?.['application/json']);\n  const schema = asObject(jsonCt?.schema);\n  if (!schema) return undefined;\n  // Skip $ref'd shared components (error envelope etc.).\n  if ('$ref' in schema) return undefined;\n  return parseSchema(schema);\n}\n\nfunction emptySchema(kind: SchemaKind): Schema {\n  return { kind, nullable: false, props: [], enumVals: [] };\n}\n\nexport function parseSchema(s: JsonObject): Schema {\n  // `type: [<t>, \"null\"]` MEANS NULLABLE and is read HERE, before the enum\n  // branch returns: `z.enum([…]).nullable()` arrives as\n  // `{\"type\":[\"string\",\"null\"],\"enum\":[…]}`, and reading the type array only\n  // further down typed a nullable enum as non-null — a server `null` then\n  // broke the app that trusted its generated type.\n  let nullable = s.nullable === true || (Array.isArray(s.type) && s.type.includes('null'));\n\n  if (s.const === null) return emptySchema('null');\n  if (['string', 'number', 'boolean'].includes(typeof s.const)) {\n    return { ...emptySchema('literal'), nullable, literal: s.const as string | number | boolean };\n  }\n  const alternatives = s.anyOf ?? s.oneOf;\n  if (Array.isArray(alternatives) && alternatives.length > 0) {\n    const members = alternatives.map((value) => parseSchema(asObject(value) ?? {}));\n    nullable ||= members.some((member) => member.kind === 'null');\n    const values = members.filter((member) => member.kind !== 'null');\n    if (values.length === 0) return emptySchema('null');\n    if (values.length === 1) return { ...values[0]!, nullable: nullable || values[0]!.nullable };\n    return { ...emptySchema('union'), nullable, members: values };\n  }\n\n  const enumRaw = s.enum;\n  if (Array.isArray(enumRaw)) {\n    const cases: string[] = [];\n    let allStrings = true;\n    for (const v of enumRaw) {\n      if (typeof v === 'string') {\n        cases.push(v);\n      } else {\n        allStrings = false;\n        break;\n      }\n    }\n    if (allStrings && cases.length > 0) {\n      return { ...emptySchema('enum'), nullable, enumVals: cases };\n    }\n    if (\n      enumRaw.length > 0 &&\n      enumRaw.every(\n        (value) => value === null || ['string', 'number', 'boolean'].includes(typeof value),\n      )\n    ) {\n      return parseSchema({ anyOf: enumRaw.map((value) => ({ const: value })), nullable });\n    }\n  }\n\n  // Draft 7 / OpenAPI 3.1 allow `type` as an array — `[\"string\",\"null\"]` is\n  // what `zod-to-json-schema` emits for `z.string().nullable()`. Lower it to\n  // the single non-null type + nullable=true.\n  let typ = asString(s.type);\n  if (typ === '' && Array.isArray(s.type)) {\n    const types = s.type.filter((value) => typeof value === 'string' && value !== 'null');\n    if (types.length > 1) {\n      return parseSchema({ anyOf: s.type.map((type) => ({ ...s, type })), nullable });\n    }\n    for (const v of s.type) {\n      if (typeof v !== 'string') continue;\n      if (v === 'null') {\n        nullable = true;\n      } else if (typ === '') {\n        typ = v;\n      }\n    }\n  }\n  switch (typ) {\n    case 'null':\n      return emptySchema('null');\n    case 'string':\n    case 'number':\n    case 'integer':\n    case 'boolean':\n      return { ...emptySchema(typ), nullable };\n    case 'array': {\n      const items = asObject(s.items);\n      const elem = items ? parseSchema(items) : emptySchema('any');\n      return {\n        ...emptySchema('array'),\n        nullable,\n        elem,\n        ...(s.maxItems === 0 ? { empty: true as const } : {}),\n      };\n    }\n    case 'object':\n      return parseObject(s, nullable);\n    default:\n      if ('properties' in s) return parseObject(s, nullable);\n      return { ...emptySchema('any'), nullable };\n  }\n}\n\nfunction parseObject(s: JsonObject, nullable: boolean): Schema {\n  const propsRaw = asObject(s.properties) ?? {};\n  const requiredSet = new Set<string>();\n  if (Array.isArray(s.required)) {\n    for (const r of s.required) {\n      if (typeof r === 'string') requiredSet.add(r);\n    }\n  }\n  const names = Object.keys(propsRaw).sort();\n  const props: Prop[] = [];\n  for (const name of names) {\n    const pm = asObject(propsRaw[name]);\n    const ps = pm ? parseSchema(pm) : emptySchema('any');\n    props.push({ name, schema: ps, required: requiredSet.has(name) });\n  }\n  const additional = asObject(s.additionalProperties);\n  return {\n    ...emptySchema('object'),\n    nullable,\n    props,\n    ...(additional\n      ? { additional: parseSchema(additional) }\n      : s.additionalProperties === false\n        ? { additional: false as const }\n        : {}),\n  };\n}\n\n// ── rooms ────────────────────────────────────────────────────────────────────\n\n/** One `@Room`, read from the DOCUMENT-level `x-palbase-room` extension. */\nexport interface RoomDecl {\n  /** The channel pattern, colon-separated: `ai:{sessionId}`. */\n  pattern: string;\n  /** The `{param}` names in order — they become named arguments, so nobody\n   *  interpolates a topic by hand. */\n  params: string[];\n  /** Events the SERVER sends. */\n  events: RoomPayload[];\n  /** Messages a CLIENT may send. */\n  messages: RoomPayload[];\n}\n\nexport interface RoomPayload {\n  name: string;\n  schema: Schema;\n}\n\n/**\n * Read `x-palbase-room` off the document root.\n *\n * DOCUMENT-level, not operation-level, and the difference matters: a room has no\n * verb and no path to hang an extension off. A generator that looks for it\n * beside `x-palbase-sse` finds nothing, emits nothing, and reports success — the\n * failure shape this codebase has already paid for once.\n *\n * A malformed entry is skipped rather than thrown on: a spec this generator\n * cannot fully read must still produce a working client for the parts it can.\n */\nexport function parseRooms(specText: string): RoomDecl[] {\n  let root: JsonObject | undefined;\n  try {\n    root = asObject(JSON.parse(specText));\n  } catch {\n    return [];\n  }\n  const ext = asObject(root?.['x-palbase-room']);\n  if (!ext || !root) return [];\n\n  const out: RoomDecl[] = [];\n  for (const [pattern, raw] of Object.entries(ext)) {\n    const decl = asObject(raw);\n    if (!decl) continue;\n    out.push({\n      pattern,\n      params: roomParamNames(pattern),\n      events: roomPayloads(decl.events, root),\n      messages: roomPayloads(decl.messages, root),\n    });\n  }\n  // Deterministic: a generator whose output depends on key order writes a\n  // different file every run and no golden can hold it.\n  out.sort((a, b) => (a.pattern < b.pattern ? -1 : a.pattern > b.pattern ? 1 : 0));\n  return out;\n}\n\nfunction roomParamNames(pattern: string): string[] {\n  const names: string[] = [];\n  for (const seg of pattern.split(':')) {\n    if (seg.startsWith('{') && seg.endsWith('}') && seg.length > 2) {\n      names.push(seg.slice(1, -1));\n    }\n  }\n  return names;\n}\n\nfunction roomPayloads(raw: unknown, root: JsonObject): RoomPayload[] {\n  const map = asObject(raw);\n  if (!map) return [];\n  const out: RoomPayload[] = [];\n  for (const [name, entry] of Object.entries(map)) {\n    const dict = asObject(entry);\n    if (!dict) continue;\n    // Room payloads always live in components — the backend registers them there\n    // precisely so a shape shared by two rooms travels once.\n    const target = resolveRoomRef(dict, root) ?? dict;\n    out.push({ name, schema: parseSchema(target) });\n  }\n  out.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));\n  return out;\n}\n\nfunction resolveRoomRef(s: JsonObject, root: JsonObject): JsonObject | undefined {\n  const ref = asString(s.$ref);\n  if (!ref.startsWith('#/')) return undefined;\n  let node: unknown = root;\n  for (const rawPart of ref.slice(2).split('/')) {\n    const part = rawPart.replace(/~1/g, '/').replace(/~0/g, '~');\n    const dict = asObject(node);\n    if (!dict || !(part in dict)) return undefined;\n    node = dict[part];\n  }\n  return asObject(node);\n}\n"],"mappings":"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","names":["import_node_process","isLE","isAligned32","encoder","encoder","value","record","b","text","resolve","process","process"]}